Belle II Software  release-08-01-10
CDCTriggerTSFFirmwareModule.h
1 /**************************************************************************
2  * basf2 (Belle II Analysis Software Framework) *
3  * Author: The Belle II Collaboration *
4  * *
5  * See git log for contributors and copyright holders. *
6  * This file is licensed under LGPL-3.0, see LICENSE.md. *
7  **************************************************************************/
8 #pragma once
9 #include <framework/core/Module.h>
10 #include <cdc/dataobjects/CDCHit.h>
11 #include <framework/datastore/StoreArray.h>
12 #include <trg/cdc/dataobjects/Bitstream.h>
13 #include <trg/cdc/dataobjects/CDCTriggerSegmentHit.h>
14 #include <trg/cdc/Cosim.h>
15 
16 #include <string>
17 #include <vector>
18 #include <bitset>
19 #include <array>
20 #include <tuple>
21 #include <unordered_map>
22 
23 #include <unistd.h>
24 #include <cstdio>
25 
26 namespace Belle2 {
32  namespace CDCTrigger {
33  enum class Priority : unsigned char {nothing, first, second};
35  std::unordered_map<unsigned, Priority> toPriorityMap = {{0, Priority::nothing},
36  {1, Priority::second},
37  {2, Priority::second},
38  {3, Priority::first}
39  };
40  Priority toPriority(unsigned priorityPosition)
41  {
42  return toPriorityMap[priorityPosition];
43  }
44  enum MergerOut : long unsigned int {priorityTime, fastestTime, edgeTime, hitmap, secondPriorityHit};
45  }
46 
56  public:
59 
60  virtual ~CDCTriggerTSFFirmwareModule();
61 
65  void initialize() override;
66 
70  void terminate() override;
71 
78  void event() override;
79 
81  static constexpr int m_nSubModules = 5;
82 
84  static constexpr std::array<int, 9> nMergers = {10, 10, 12, 14, 16, 18, 20, 22, 24};
85 
87  static constexpr std::array<int, m_nSubModules> nAxialMergers = {10, 12, 16, 20, 24};
88 
90  static constexpr int nTrackers = 4;
91 
93  static constexpr int mergerWidth = 256;
94 
96  static constexpr int width_out = 429;
97 
99  static constexpr int nWiresInMerger = 80;
100 
102  static constexpr int nCellsInLayer = 16;
103 
105  static constexpr int nSegmentsInMerger = 16;
106 
108  static constexpr size_t timeWidth = 4;
109 
111  static constexpr int m_nClockPerEvent = 44;
112 
114  static constexpr int clockPeriod = 16;
115 
116  protected:
118  std::string m_hitCollectionName;
119 
122 
125 
128 
131 
133  using outputVector = std::array<char, width_out>;
135  using outputArray = std::array<outputVector, nTrackers>;
136 
138  using signalBus = std::array<outputArray, m_nSubModules>;
141 
144 
147 
150 
153 
155  std::vector<bool> m_stubLUT;
156 
158  int m_debugLevel = 0; //TODO what should be default?
159 
161  int m_TDCCountForT0 = 4988;
162 
167  bool m_allPositiveTime = true;
168 
170  std::string lib_extension = ".so";
172  std::string cwd = getcurrentdir();
174  std::string design_libname_pre = cwd + "/xsim.dir/tsf";
176  std::string design_libname_post = "/xsimk" + lib_extension;
178  std::string simengine_libname = "librdi_simulator_kernel" + lib_extension;
180  std::string wdbName_pre = "tsf";
182  std::string wdbName_post = ".wdb";
183 
185  /* static constexpr char one_val = 3; */
187  /* static constexpr char zero_val = 2; */
188 
190  std::array<pid_t, m_nSubModules> m_pid;
191 
193  using mergerVector = std::bitset<mergerWidth>;
195  using mergerOutput = std::vector<mergerVector>;
197  using mergerOutArray = std::array<mergerOutput, m_nSubModules>;
200 
202  using inputVector = std::array<char, mergerWidth>;
204  using inputFromMerger = std::vector<inputVector>;
206  using inputToTSFArray = std::array<inputFromMerger, m_nSubModules>;
209 
211  std::array<outputArray, m_nSubModules> outputToTracker;
212 
214  template<int iSL>
215  char* getData(inputToTSFArray);
216 
218  using streamPair = std::array<FILE*, 2>;
220  std::array<streamPair, m_nSubModules> stream;
221 
223  std::array<std::array<int, 2>, m_nSubModules> inputFileDescriptor;
225  std::array<std::array<int, 2>, m_nSubModules> outputFileDescriptor;
226 
234  void write(const char* message, FILE* outstream);
235 
243  outputArray read(FILE* instream);
244 
246  std::istream* ins = nullptr;
247 
248  /**************************************************
249  * Merger simulation
250  **************************************************/
251 
253  using timeVec = std::bitset<timeWidth>;
260  template<size_t nEdges>
261  using mergerStructElement = std::tuple <
262  std::array<timeVec, nSegmentsInMerger>,
263  std::array<timeVec, nSegmentsInMerger>,
264  std::array<timeVec, nEdges>,
265  std::array<std::bitset<nWiresInMerger>, 1>,
266  std::array<std::bitset<nSegmentsInMerger>, 1> >;
268  template<size_t nEdges>
269  using mergerStruct = std::vector<mergerStructElement<nEdges> >;
271  std::map<unsigned, mergerStruct<5> > dataAcrossClocks;
272 
275  using registeredStructElement = std::array<std::bitset<nCellsInLayer>, 3>;
277  using registeredStruct = std::vector<registeredStructElement>;
278 
280  using priorityHitInMerger = std::map<unsigned, int>;
282  using priorityHitStructInSL = std::vector<priorityHitInMerger>;
284  using priorityHitStructInClock = std::map<unsigned, priorityHitStructInSL>;
286  using priorityHitStruct = std::array<priorityHitStructInClock, m_nClockPerEvent>;
290  std::vector<std::vector<int> > iAxialHitInClock;
291 
293  using WireSet = std::vector<short>;
295  using TSMap = std::unordered_map<short, WireSet>;
297  std::array<TSMap, 2> m_tsMap;
298 
300  using edgeMap = std::unordered_map<unsigned short, timeVec*>;
302  using cellList = std::vector<unsigned short>;
304  std::array<cellList, 5> innerInvEdge = {cellList {31},
305  cellList {64},
306  cellList {32, 48, 64, 65},
307  cellList {31, 47, 62, 63, 78},
308  cellList {63, 79}
309  };
310 
312  std::array<cellList, 3> outerInvEdge = {cellList {63},
313  cellList {0, 64},
314  cellList {15, 31, 63, 79}
315  };
317  using edgeList = std::unordered_map<unsigned short, std::vector<unsigned short>>;
319  std::array<edgeList, 2> m_edge;
320 
322  int m_iFirstHit = std::numeric_limits<int>::quiet_NaN();
323 
331  CDCTrigger::Priority priority(int index);
332 
342  unsigned short trgTime(int index, int iFirstHit);
343 
351  unsigned short mergerCellID(int index);
352 
360  unsigned short mergerNumber(int index);
361 
369  WireSet segmentID(int iHit);
370 
380  std::bitset<4> timeStamp(int index, int iFirstHit);
381 
385  void computeEdges();
386 
391  void initializeMerger();
392 
398  void simulateMerger(unsigned iclock);
399 
413  template<CDCTrigger::MergerOut field, size_t width>
414  void pack(inputVector::reverse_iterator& rInput,
415  unsigned number, mergerStructElement<5>& output);
416 
428  bool notHit(CDCTrigger::MergerOut field, unsigned iTS, registeredStructElement& reg);
429 
439  void registerHit(CDCTrigger::MergerOut field, unsigned iTS, registeredStructElement& reg);
440 
442  void saveFirmwareOutput();
443 
445  void saveFastOutput(short iclock);
446 
448  void setSecondPriority(unsigned priTS,
449  unsigned iHit,
450  timeVec hitTime,
451  unsigned lr,
452  mergerStructElement<5>& mergerData,
453  registeredStructElement& registeredCell,
454  priorityHitInMerger& priorityHit);
455  };
457 }
Class to hold one clock cycle of raw bit content.
Definition: Bitstream.h:54
This class is the interface between TSim/basf2 TSF module and the firmware simulation core of XSim/IS...
std::array< priorityHitStructInClock, m_nClockPerEvent > priorityHitStruct
all priority hits map in Merger
std::vector< mergerStructElement< nEdges > > mergerStruct
data structure to hold merger output
int m_iFirstHit
ID of the earlist CDC hit in an event.
void initializeMerger()
Get CDC hits from the DataStore and distribute them to clocks.
std::array< FILE *, 2 > streamPair
file handlers of pipes
static constexpr std::array< int, 9 > nMergers
number of mergers in each super layer
void computeEdges()
Compute the map from merger cell ID to all its related edge fields.
bool m_simulateCC
flag to simulate front-end clock counter
int m_debugLevel
debug level specified in the steering file
unsigned short trgTime(int index, int iFirstHit)
Get the trigger time of the CDC hit.
Belle2::StoreArray< CDCHit > m_cdcHits
CDCHit array.
std::array< edgeList, 2 > m_edge
map from cell ID to related edge ID
std::bitset< 4 > timeStamp(int index, int iFirstHit)
Get the trigger time stamp of a hit.
std::string design_libname_post
path to the simulation snapshot
outputArray read(FILE *instream)
write TSF output signals from the worker
std::array< mergerOutput, m_nSubModules > mergerOutArray
Merger output array.
static constexpr int nCellsInLayer
Number of wire/cells in a single layer per merger unit.
std::tuple< std::array< timeVec, nSegmentsInMerger >, std::array< timeVec, nSegmentsInMerger >, std::array< timeVec, nEdges >, std::array< std::bitset< nWiresInMerger >, 1 >, std::array< std::bitset< nSegmentsInMerger >, 1 > > mergerStructElement
data structure to hold merger output <priority time (4 bits x 16), fast time (4 bits x 16),...
std::array< cellList, 5 > innerInvEdge
list of cell ID related to edge timing
StoreArray< CDCTriggerSegmentHit > m_tsHits
unpacked track segment hit
std::vector< registeredStructElement > registeredStruct
vector of registeredStructElement
bool notHit(CDCTrigger::MergerOut field, unsigned iTS, registeredStructElement &reg)
Whether a time field in a merger has been hit in the clock cycle.
priorityHitStruct m_priorityHit
list keeping the index of priority hit of a TS for making fastsim ts hit object
WireSet segmentID(int iHit)
Get the list of associated track segments with a hit.
void initialize() override
spawn child process for workers, open pipes to pass data
mergerOutArray outputFromMerger
bits format of merger output / TSF input
void pack(inputVector::reverse_iterator &rInput, unsigned number, mergerStructElement< 5 > &output)
Pack the merger output data structure to TSF input vector.
void event() override
Things to do for each event.
CDCTrigger::Priority priority(int index)
write TSF input signals to the worker
std::map< unsigned, priorityHitStructInSL > priorityHitStructInClock
priority hits map in Merger for a clock
static constexpr size_t timeWidth
bit width for priority time and fast time
std::bitset< mergerWidth > mergerVector
Merger vector.
static constexpr int nTrackers
number of trackers
std::vector< unsigned short > cellList
cell list
std::string m_outputCollectionName
Name of the StoreArray holding the found TS hits.
std::array< inputFromMerger, m_nSubModules > inputToTSFArray
input array to TSF
std::string design_libname_pre
path to the simulation snapshot
std::bitset< timeWidth > timeVec
element of data structure to hold merger output
std::vector< mergerVector > mergerOutput
Merger output.
std::array< std::array< int, 2 >, m_nSubModules > inputFileDescriptor
array holding file descriptors of pipes
static constexpr int m_nClockPerEvent
how many clocks to simulate per event
std::string m_outputBitstreamNameTo2D
Name of the StoreArray holding the raw bit content to 2D trackers.
void terminate() override
close the pipes and wait for children to die.
std::array< outputVector, nTrackers > outputArray
output array
std::array< outputArray, m_nSubModules > outputToTracker
array holding TSF output data
std::array< char, width_out > outputVector
output vector
std::vector< inputVector > inputFromMerger
input array from Merger
std::array< char, mergerWidth > inputVector
input array
StoreArray< signalBitStream > m_bitsTo2D
bitstream of TSF output to 2D tracker
std::array< std::array< int, 2 >, m_nSubModules > outputFileDescriptor
array holding file descriptors of pipes
void setSecondPriority(unsigned priTS, unsigned iHit, timeVec hitTime, unsigned lr, mergerStructElement< 5 > &mergerData, registeredStructElement &registeredCell, priorityHitInMerger &priorityHit)
set 2nd priority info
static constexpr std::array< int, m_nSubModules > nAxialMergers
number of mergers in axial super layers
std::array< TSMap, 2 > m_tsMap
map from cell ID to TS ID, for inner and outer Merger
std::vector< bool > m_stubLUT
list of flags to run a TSF firmware simulation with dummy L/R LUT (to speed up loading)
std::unordered_map< unsigned short, timeVec * > edgeMap
edge wire list
std::string simengine_libname
path to the simulation engine
char * getData(inputToTSFArray)
get the XSI compliant format from the bits format TSF input
void write(const char *message, FILE *outstream)
write TSF input signals to the worker
inputToTSFArray inputToTSF
XSI compliant format of input to TSF.
void saveFastOutput(short iclock)
save fast TSIM output
static constexpr int nSegmentsInMerger
number of track segments in a single merger unit
bool m_allPositiveTime
switch If true, the trigger time of the hit with largest TDC count becomes 0.
std::array< pid_t, m_nSubModules > m_pid
'1' in XSI VHDL simulation
static constexpr int mergerWidth
merger output data width
std::array< outputArray, m_nSubModules > signalBus
signal bus
static constexpr int clockPeriod
data clock period (32ns) in unit of 2ns
unsigned short mergerNumber(int index)
Get the merger unit ID in a super layer.
static constexpr int nWiresInMerger
number of wire/cell in a single merger unit
bool m_mergerOnly
flag to only simulation merger and not TSF
std::array< cellList, 3 > outerInvEdge
list of cell ID related to edge timing
std::map< unsigned, mergerStruct< 5 > > dataAcrossClocks
data structure to hold merger output
void simulateMerger(unsigned iclock)
Simulate 1 clock of merger.
std::string m_hitCollectionName
Name of the StoreArray containing the input CDC hits.
std::array< std::bitset< nCellsInLayer >, 3 > registeredStructElement
record when a time slow has been registered by a hit <priority time, fast time, edge timing>
std::unordered_map< short, WireSet > TSMap
TS map.
static constexpr int m_nSubModules
number of TSF to simulate
std::vector< priorityHitInMerger > priorityHitStructInSL
priority hits map in Merger for a SL
std::map< unsigned, int > priorityHitInMerger
priority hits map in Merger
std::array< streamPair, m_nSubModules > stream
array holding file handlers of pipes
unsigned short mergerCellID(int index)
Get the cell ID in the merger.
std::unordered_map< unsigned short, std::vector< unsigned short > > edgeList
edge wire list
static constexpr int width_out
width of output data width
void registerHit(CDCTrigger::MergerOut field, unsigned iTS, registeredStructElement &reg)
Register the timing field so that later hits won't overwrite it.
std::vector< std::vector< int > > iAxialHitInClock
CDC hit ID in each clock.
std::string m_outputBitstreamNameToETF
Name of the StoreArray holding the raw bit content to ETF.
Base class for Modules.
Definition: Module.h:72
Accessor to arrays stored in the data store.
Definition: StoreArray.h:113
Abstract base class for different kinds of events.