Belle II Software development
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
26namespace 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
53 public:
56
58
62 void initialize() override;
63
67 void terminate() override;
68
75 void event() override;
76
78 static constexpr int m_nSubModules = 5;
79
81 static constexpr std::array<int, 9> nMergers = {10, 10, 12, 14, 16, 18, 20, 22, 24};
82
84 static constexpr std::array<int, m_nSubModules> nAxialMergers = {10, 12, 16, 20, 24};
85
87 static constexpr int nTrackers = 4;
88
90 static constexpr int mergerWidth = 256;
91
93 static constexpr int width_out = 429;
94
96 static constexpr int nWiresInMerger = 80;
97
99 static constexpr int nCellsInLayer = 16;
100
102 static constexpr int nSegmentsInMerger = 16;
103
105 static constexpr size_t timeWidth = 4;
106
108 static constexpr int m_nClockPerEvent = 44;
109
111 static constexpr int clockPeriod = 16;
112
113 protected:
116
119
122
125
128
130 using outputVector = std::array<char, width_out>;
132 using outputArray = std::array<outputVector, nTrackers>;
133
135 using signalBus = std::array<outputArray, m_nSubModules>;
138
141
144
147
150
152 std::vector<bool> m_stubLUT;
153
155 int m_debugLevel = 0; //TODO what should be default?
156
158 int m_TDCCountForT0 = 4988;
159
164 bool m_allPositiveTime = true;
165
167 std::string lib_extension = ".so";
169 std::string cwd = getcurrentdir();
171 std::string design_libname_pre = cwd + "/xsim.dir/tsf";
173 std::string design_libname_post = "/xsimk" + lib_extension;
175 std::string simengine_libname = "librdi_simulator_kernel" + lib_extension;
177 std::string wdbName_pre = "tsf";
179 std::string wdbName_post = ".wdb";
180
182 /* static constexpr char one_val = 3; */
184 /* static constexpr char zero_val = 2; */
185
187 std::array<pid_t, m_nSubModules> m_pid;
188
190 using mergerVector = std::bitset<mergerWidth>;
192 using mergerOutput = std::vector<mergerVector>;
194 using mergerOutArray = std::array<mergerOutput, m_nSubModules>;
197
199 using inputVector = std::array<char, mergerWidth>;
201 using inputFromMerger = std::vector<inputVector>;
203 using inputToTSFArray = std::array<inputFromMerger, m_nSubModules>;
206
208 std::array<outputArray, m_nSubModules> outputToTracker;
209
211 template<int iSL>
213
215 using streamPair = std::array<FILE*, 2>;
217 std::array<streamPair, m_nSubModules> stream;
218
220 std::array<std::array<int, 2>, m_nSubModules> inputFileDescriptor;
222 std::array<std::array<int, 2>, m_nSubModules> outputFileDescriptor;
223
231 void write(const char* message, FILE* outstream);
232
240 outputArray read(FILE* instream);
241
243 std::istream* ins = nullptr;
244
245 /**************************************************
246 * Merger simulation
247 **************************************************/
248
250 using timeVec = std::bitset<timeWidth>;
257 template<size_t nEdges>
258 using mergerStructElement = std::tuple <
259 std::array<timeVec, nSegmentsInMerger>,
260 std::array<timeVec, nSegmentsInMerger>,
261 std::array<timeVec, nEdges>,
262 std::array<std::bitset<nWiresInMerger>, 1>,
263 std::array<std::bitset<nSegmentsInMerger>, 1> >;
265 template<size_t nEdges>
266 using mergerStruct = std::vector<mergerStructElement<nEdges> >;
268 std::map<unsigned, mergerStruct<5> > dataAcrossClocks;
269
272 using registeredStructElement = std::array<std::bitset<nCellsInLayer>, 3>;
274 using registeredStruct = std::vector<registeredStructElement>;
275
277 using priorityHitInMerger = std::map<unsigned, int>;
279 using priorityHitStructInSL = std::vector<priorityHitInMerger>;
281 using priorityHitStructInClock = std::map<unsigned, priorityHitStructInSL>;
283 using priorityHitStruct = std::array<priorityHitStructInClock, m_nClockPerEvent>;
287 std::vector<std::vector<int> > iAxialHitInClock;
288
290 using WireSet = std::vector<short>;
292 using TSMap = std::unordered_map<short, WireSet>;
294 std::array<TSMap, 2> m_tsMap;
295
297 using edgeMap = std::unordered_map<unsigned short, timeVec*>;
299 using cellList = std::vector<unsigned short>;
301 std::array<cellList, 5> innerInvEdge = {cellList {31},
302 cellList {64},
303 cellList {32, 48, 64, 65},
304 cellList {31, 47, 62, 63, 78},
305 cellList {63, 79}
306 };
307
309 std::array<cellList, 3> outerInvEdge = {cellList {63},
310 cellList {0, 64},
311 cellList {15, 31, 63, 79}
312 };
314 using edgeList = std::unordered_map<unsigned short, std::vector<unsigned short>>;
316 std::array<edgeList, 2> m_edge;
317
319 int m_iFirstHit = std::numeric_limits<int>::quiet_NaN();
320
328 CDCTrigger::Priority priority(int index);
329
339 unsigned short trgTime(int index, int iFirstHit);
340
348 unsigned short mergerCellID(int index);
349
357 unsigned short mergerNumber(int index);
358
366 WireSet segmentID(int iHit);
367
377 std::bitset<4> timeStamp(int index, int iFirstHit);
378
382 void computeEdges();
383
388 void initializeMerger();
389
395 void simulateMerger(unsigned iclock);
396
409 template<CDCTrigger::MergerOut field, size_t width>
410 void pack(inputVector::reverse_iterator& rInput,
411 unsigned number, mergerStructElement<5>& output);
412
424 bool notHit(CDCTrigger::MergerOut field, unsigned iTS, registeredStructElement& reg);
425
435 void registerHit(CDCTrigger::MergerOut field, unsigned iTS, registeredStructElement& reg);
436
438 void saveFirmwareOutput();
439
441 void saveFastOutput(short iclock);
442
444 void setSecondPriority(unsigned priTS,
445 unsigned iHit,
446 timeVec hitTime,
447 unsigned lr,
448 mergerStructElement<5>& mergerData,
449 registeredStructElement& registeredCell,
450 priorityHitInMerger& priorityHit);
451 };
453}
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.