ATLAS Offline Software
EfexLatomeFibrePacker.cxx
Go to the documentation of this file.
2 
3 #include <iostream>
4 #include <cstdlib>
5 #include <cmath>
6 #include <map>
7 
8 
9 std::vector<FibrePackerBase::myDataWord> EfexLatomeFibrePacker::getPackedData(const std::vector<myDataWord>& inFrame,
10  myDataWord bcNumber,
11  InputDataFrameType frameType) const {
12 
13  std::vector<myDataWord> dataToLoad(FexDefs::num32BitWordsPerFibre(),0);
14  auto supercells = inFrame;
15 
16  switch(frameType){
17 
18  case InputDataFrameType::Normal: // Standard data pattern
19  {
20  for(auto& icell:supercells)
21  icell = icell & 0x3ff; // truncate to 10 bits
22 
23  myDataWord bcId = bcNumber & 0x7f ; // 7 bits from BCID
24 
25  myDataWord bcId02 = bcId & 0x7;
26  myDataWord bcId34 = (bcId >> 3) & 0x3;
27  myDataWord bcId56 = (bcId >> 5) & 0x3;
28 
29  dataToLoad.at(0) = (bcId56 << 8) | (supercells.at(0) <<10) |
30  (supercells.at(1) << 20) | (bcId34 << 30);
31  dataToLoad.at(1) = supercells.at(2) | (supercells.at(3) << 10) |
32  (supercells.at(4) << 20) | (((supercells.at(19) >>8) & 0x3) << 30);
33  dataToLoad.at(2) = supercells.at(5) | (supercells.at(6) << 10) |
34  (supercells.at(7) << 20) | (((supercells.at(19) >>6) & 0x3) << 30);
35  dataToLoad.at(3) = supercells.at(8) | (supercells.at(9) << 10) |
36  (supercells.at(10) << 20) | (((supercells.at(19) >>4) & 0x3) << 30);
37  dataToLoad.at(4) = supercells.at(11) | (supercells.at(12) << 10) |
38  (supercells.at(13) << 20) | (((supercells.at(19) >>2) & 0x3) << 30);
39  dataToLoad.at(5) = supercells.at(14) | (supercells.at(15) << 10) |
40  (supercells.at(16) << 20) | (((supercells.at(19) ) & 0x3) << 30);
41  dataToLoad.at(6) = supercells.at(17) | (supercells.at(18) << 10)| bcId02 << 20;
42 
43  // original code
44  // myDataWord tempCRC = crc9d32(dataToLoad,6l,true); // calculate CRC32 on first 6 words
45  // myDataWord myCRCReminder = crc9d23(dataToLoad[6],tempCRC,true); // CRC23 on the last word
46  // new code
47  myDataWord myCRCReminder = crc9full(dataToLoad,215); // 215 = 32*6+23
48 
49  dataToLoad.at(0) = K_28_5 | dataToLoad.at(0) ; // add K-character
50  dataToLoad[6] = dataToLoad[6] | ( myCRCReminder << 23) ; // add CRC check
51 
52  break;
53  }
54  case InputDataFrameType::Alignement: // Special pattern, LATOME alignement/mapping frame
55  {
56 
57  myDataWord latome_id = supercells.at(0) & 0xff; // 8b
58  myDataWord latome_src_id = supercells.at(1) & 0xffffffff; // 32b
59  myDataWord fiber_id = supercells.at(2) & 0x3f; // 6b
60  myDataWord bcId = bcNumber & 0xfff ; // 12 bits of BCID
61 
62  dataToLoad.at(0) = (fiber_id << 16) | (latome_id << 24);
63  dataToLoad.at(1) = latome_src_id;
64  dataToLoad.at(6) = bcId;
65 
66  dataToLoad.at(0) = (K_28_0 << 8) | dataToLoad.at(0) ; // add K_28_0, this is used for CRC calculation
67 
68  // original code
69  // myDataWord tempCRC = crc9d32(dataToLoad,6l,true); // calculate CRC32 on first 6 words
70  //myDataWord myCRCReminder = crc9d23(dataToLoad[6],tempCRC,true); // CRC23 on the last word
71  // new code
72  myDataWord myCRCReminder = crc9full(dataToLoad,215); // 215 = 32*6+23
73 
74  dataToLoad.at(0) = K_28_5 | dataToLoad.at(0) ; // add K_28_5, this is not used for CRC calculation
75  dataToLoad[6] = dataToLoad[6] | ( myCRCReminder << 23) ; // add CRC check to the famous last word
76 
77  break;
78  }
79  }
80 
81  return dataToLoad;
82 
83 }
84 
85 std::vector<FibrePackerBase::myDataWord> EfexLatomeFibrePacker::getPackedControl(const std::vector<myDataWord>& /*inFrame*/,
86  myDataWord /*bcNumber*/,
87  InputDataFrameType frameType) const {
88 
89  std::vector<myDataWord> controlWords(FexDefs::num32BitWordsPerFibre(),0);
90 
91  switch(frameType){
92 
93  case InputDataFrameType::Normal: // one K character in first data word
94  controlWords.at(0) = 0x1;
95  break;
96 
97  case InputDataFrameType::Alignement: // two K characters in first data word
98  controlWords.at(0) = 0x3;
99  break;
100 
101  }
102 
103  return controlWords;
104 }
105 
106 bool EfexLatomeFibrePacker::checkCRC(const std::vector<myDataWord>& encodedData,
107  InputDataFrameType frameType) const {
108 
109  auto inputData = encodedData;
110  myDataWord CRCCheck = 0;
111 
112  // Comment SJH: why do we need two cases here
113  // (may have been different originally, but not now?)
114  switch(frameType){
115 
116  case InputDataFrameType::Normal: // one K character in first data word
117  inputData.at(0) = inputData.at(0) & 0xffffff00;
118  // old code
119  // CRCCheck = crc9d32(inputData,7l,true); // calculate CRC32 on first 6 words
120  // new code
121  CRCCheck = crc9full(inputData,224); // calculate CRC on 224 bits = 7*32 bit words
122  break;
123 
124  case InputDataFrameType::Alignement: // two K characters in first data word, but zeroing only the first one
125  inputData.at(0) = inputData.at(0) & 0xffffff00;
126  // old code
127  // CRCCheck = crc9d32(inputData,7l,true); // calculate CRC32 on first 6 words
128  // new code
129  CRCCheck = crc9full(inputData,224); // calculate CRC on 224 bits = 7*32 bit words
130  break;
131 
132  }
133 
134  return (CRCCheck == 0);
135 }
136 
137 FibrePackerBase::myDataWord EfexLatomeFibrePacker::getBcNumber(const std::vector<myDataWord>& encodedData,
138  InputDataFrameType frameType) const {
139  myDataWord BcNumber =0;
140 
141  switch(frameType){
142 
144  {
145  myDataWord bcId02 = (encodedData.at(6) >> 20 ) & 0x7;
146  myDataWord bcId34 = (encodedData.at(0) >> 30 ) & 0x3;
147  myDataWord bcId56 = (encodedData.at(0) >> 8 ) & 0x3;
148 
149  BcNumber = bcId02 | (bcId34 << 3) | (bcId56 << 5);
150  break;
151  }
153  {
154  BcNumber = encodedData.at(6) & 0xfff;
155  break;
156  }
157  }
158 
159  return BcNumber;
160 }
161 
163  // BC number is just 7 bits for normal frames
164  // but the full 12 bits from align frames.
165  return (frameType == InputDataFrameType::Alignement) ? 0xfff : 0x07f;
166 }
167 
168 std::vector<FibrePackerBase::myDataWord> EfexLatomeFibrePacker::getUnpackedData(const std::vector<myDataWord>& encodedData,
169  InputDataFrameType frameType) const {
170  std::vector<myDataWord> unpackedData;
171 
172  switch(frameType){
173 
175  {
176  std::vector<myDataWord> supercells(EfexDefs::maxSuperCellsPerFibre(),0);
177 
178  // see: https://gitlab.cern.ch/atlas-l1calo-online/infraL1Calo/-/commit/1dc82d1ce21c14ca56d90e1af7d1af9bdb7990df#note_5865270
179  // 20 10-bit counts encoded in 7 32-bit words
180  // word 0 has 2, word 1-5 have 3 each (so 15 in total),
181  // word 6 has 2 more, and the last count is spread over the extra
182  // 2 bits in words 1-5
183 
184  supercells.at(0) = (encodedData.at(0) >> 10) & 0x3ff;
185  supercells.at(1) = (encodedData.at(0) >> 20) & 0x3ff;
186  supercells.at(2) = (encodedData.at(1) ) & 0x3ff;
187  supercells.at(3) = (encodedData.at(1) >> 10) & 0x3ff;
188  supercells.at(4) = (encodedData.at(1) >> 20) & 0x3ff;
189  supercells.at(5) = (encodedData.at(2) ) & 0x3ff;
190  supercells.at(6) = (encodedData.at(2) >> 10) & 0x3ff;
191  supercells.at(7) = (encodedData.at(2) >> 20) & 0x3ff;
192  supercells.at(8) = (encodedData.at(3) ) & 0x3ff;
193  supercells.at(9) = (encodedData.at(3) >> 10) & 0x3ff;
194  supercells.at(10) = (encodedData.at(3) >> 20) & 0x3ff;
195  supercells.at(11) = (encodedData.at(4) ) & 0x3ff;
196  supercells.at(12) = (encodedData.at(4) >> 10) & 0x3ff;
197  supercells.at(13) = (encodedData.at(4) >> 20) & 0x3ff;
198  supercells.at(14) = (encodedData.at(5) ) & 0x3ff;
199  supercells.at(15) = (encodedData.at(5) >> 10) & 0x3ff;
200  supercells.at(16) = (encodedData.at(5) >> 20) & 0x3ff;
201  supercells.at(17) = (encodedData.at(6) ) & 0x3ff;
202  supercells.at(18) = (encodedData.at(6) >> 10) & 0x3ff;
203  supercells.at(19) = ((encodedData.at(5) >> 30) & 0x3) |
204  ((encodedData.at(4) >> 30) & 0x3) << 2 |
205  ((encodedData.at(3) >> 30) & 0x3) << 4 |
206  ((encodedData.at(2) >> 30) & 0x3) << 6 |
207  ((encodedData.at(1) >> 30) & 0x3) << 8 ;
208  unpackedData=supercells;
209  break;
210  }
212  {
213  myDataWord latome_id = (encodedData.at(0) >> 24) & 0xff; // 8b
214  myDataWord latome_src_id = encodedData.at(1) & 0xffffffff; // 32b
215  myDataWord fiber_id = (encodedData.at(0) >> 16) & 0x3f; // 6b
216 
217  unpackedData.push_back(latome_id);
218  unpackedData.push_back(latome_src_id);
219  unpackedData.push_back(fiber_id);
220  break;
221  }
222  }
223 
224 
225  return unpackedData;
226 
227 }
228 
EfexLatomeFibrePacker::getBcMask
virtual myDataWord getBcMask(InputDataFrameType frameType) const override
Definition: EfexLatomeFibrePacker.cxx:162
FexDefs::num32BitWordsPerFibre
static int num32BitWordsPerFibre()
Definition: FexDefs.h:17
EfexLatomeFibrePacker.h
WriteCellNoiseToCool.icell
icell
Definition: WriteCellNoiseToCool.py:339
EfexLatomeFibrePacker::getPackedData
virtual std::vector< myDataWord > getPackedData(const std::vector< myDataWord > &inFrame, myDataWord bcNumber, InputDataFrameType frameType) const override
Function packing the data into the LATOME format, either standard or alignement frame.
Definition: EfexLatomeFibrePacker.cxx:9
FibrePackerBase::K_28_5
myDataWord K_28_5
Definition: FibrePackerBase.h:30
EfexLatomeFibrePacker::getPackedControl
virtual std::vector< myDataWord > getPackedControl(const std::vector< myDataWord > &inFrame, myDataWord bcNumber, InputDataFrameType frameType) const override
Function returning control words.
Definition: EfexLatomeFibrePacker.cxx:85
EfexLatomeFibrePacker::checkCRC
virtual bool checkCRC(const std::vector< myDataWord > &encodedData, InputDataFrameType frameType) const override
Definition: EfexLatomeFibrePacker.cxx:106
EfexLatomeFibrePacker::getBcNumber
virtual myDataWord getBcNumber(const std::vector< myDataWord > &encodedData, InputDataFrameType frameType) const override
Definition: EfexLatomeFibrePacker.cxx:137
EfexDefs::maxSuperCellsPerFibre
static int maxSuperCellsPerFibre()
Definition: EfexDefs.h:27
FibrePackerBase::crc9full
virtual myDataWord crc9full(const std::vector< myDataWord > &inwords, size_t num_bits) const
Functions calculating CRC over input data.
Definition: FibrePackerBase.cxx:8
FibrePackerBase::K_28_0
myDataWord K_28_0
Definition: FibrePackerBase.h:32
EfexLatomeFibrePacker::getUnpackedData
virtual std::vector< myDataWord > getUnpackedData(const std::vector< myDataWord > &encodedData, InputDataFrameType frameType) const override
Function unpacking the data from LATOME format, either standard or alignement frame.
Definition: EfexLatomeFibrePacker.cxx:168
bcId
uint16_t bcId(uint32_t data)
Definition: TgcByteStreamData.h:326
FibrePackerBase::InputDataFrameType::Alignement
@ Alignement
Special mapping/alignement frame.
FibrePackerBase::InputDataFrameType
InputDataFrameType
type of input data frame
Definition: FibrePackerBase.h:37
FibrePackerBase::myDataWord
uint32_t myDataWord
Definition: FibrePackerBase.h:25
FibrePackerBase::InputDataFrameType::Normal
@ Normal
Standard data frame.