Belle II Software release-09-00-00
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
56 public:
59
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:
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>
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
412 template<CDCTrigger::MergerOut field, size_t width>
413 void pack(inputVector::reverse_iterator& rInput,
414 unsigned number, mergerStructElement<5>& output);
415
427 bool notHit(CDCTrigger::MergerOut field, unsigned iTS, registeredStructElement& reg);
428
438 void registerHit(CDCTrigger::MergerOut field, unsigned iTS, registeredStructElement& reg);
439
441 void saveFirmwareOutput();
442
444 void saveFastOutput(short iclock);
445
447 void setSecondPriority(unsigned priTS,
448 unsigned iHit,
449 timeVec hitTime,
450 unsigned lr,
451 mergerStructElement<5>& mergerData,
452 registeredStructElement& registeredCell,
453 priorityHitInMerger& priorityHit);
454 };
456}
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.