ATLAS Offline Software
Loading...
Searching...
No Matches
ZdcPpmSubBlock.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
3*/
4
12
14
16
17
18// Constant definitions
19
22
32
39
49
50// This is faster than going through a operation for every channel for every event
51//As tested, the right order is A D B C
52const int ZdcPpmSubBlock::s_ppmChannel[64] = {0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60,
53 3, 7, 11, 15, 19, 23, 27, 31, 35, 39, 43, 47, 51, 55, 59, 63,
54 1, 5, 9, 13, 17, 21, 25, 29, 33, 37, 41, 45, 49, 53, 57, 61,
55 2, 6, 10, 14, 18, 22, 26, 30, 34, 38, 42, 46, 50, 54, 58, 62 };
56
57
68
72
73// Clear all data
74
76{
78 m_globalError = 0;
79 m_lutOffset = -1;
80 m_fadcOffset = -1;
81 m_datamap.clear();
82 m_errormap.clear();
83}
84
85// Store PPM header
86
88 const int seqno, const int crate,
89 const int module, const int slicesFadc,
90 const int slicesLut)
91{
94}
95
96// Store PPM error block header
97
99 const int crate, const int module,
100 const int slicesFadc, const int slicesLut)
101{
104}
105
106// Return the number of FADC slices
107
109{
110 int slices = slices2();
111 if (slices == 0 && format() == NEUTRAL) {
113 }
114 if (slices <= 0) slices = 1;
115 return slices;
116}
117
118// Return the number of LUT slices
119
121{
122 int slices = slices1();
123 if (slices == 0) slices = 1;
124 return slices;
125}
126
127// Store PPM data for later packing
128
129void ZdcPpmSubBlock::fillPpmData(const int chan, const std::vector<int>& lut,
130 const std::vector<int>& fadc,
131 const std::vector<int>& bcidLut,
132 const std::vector<int>& bcidFadc)
133{
134 const int sliceL = slicesLut();
135 const int sliceF = slicesFadc();
136 const int slices = sliceL + sliceF;
137 const int chanPerSubBlock = channelsPerSubBlock();
138 if (chanPerSubBlock == 0) {
140 m_datamap.clear();
141 return;
142 }
143 int dataSize = m_datamap.size();
144 if (dataSize == 0) {
145 dataSize = slices * chanPerSubBlock;
146 m_datamap.resize(dataSize);
147 }
148 int offset = (chan % chanPerSubBlock) * slices;
149 if (offset + slices <= dataSize) {
150 for (int pos = 0; pos < sliceL; ++pos) {
151 uint32_t datum = (lut[pos] & s_lutMask) << s_lutBit;
152 datum |= (bcidLut[pos] & s_bcidLutMask) << s_bcidLutBit;
153 m_datamap[offset + pos] = datum;
154 }
155 offset += sliceL;
156 for (int pos = 0; pos < sliceF; ++pos) {
157 const int adc = (fadc[pos] > 0) ? fadc[pos] : 0;
158 uint32_t datum = (adc & s_fadcMask) << s_fadcBit;
159 datum |= (bcidFadc[pos] & s_bcidFadcMask) << s_bcidFadcBit;
160 m_datamap[offset + pos] = datum;
161 }
162 }
163}
164
165// Return unpacked data for given channel
166
167void ZdcPpmSubBlock::ppmData(const int chan, std::vector<int>& lut,
168 std::vector<int>& fadc,
169 std::vector<int>& bcidLut,
170 std::vector<int>& bcidFadc) const
171{
172 lut.clear();
173 fadc.clear();
174 bcidLut.clear();
175 bcidFadc.clear();
176 const int sliceL = slicesLut();
177 const int sliceF = slicesFadc();
178 const int chans = channelsPerSubBlock();
179 if (chans == 0) {
180 return;
181 }
182 int beg = (chan % chans) * (sliceL + sliceF);
183 int end = beg + sliceL;
184 if (size_t(end + sliceF) <= m_datamap.size()) {
185 for (int pos = beg; pos < end; ++pos) {
186 const uint32_t word = m_datamap[pos];
187 lut.push_back((word >> s_lutBit) & s_lutMask);
188 bcidLut.push_back((word >> s_bcidLutBit) & s_bcidLutMask);
189 }
190 beg += sliceL;
191 end += sliceF;
192 for (int pos = beg; pos < end; ++pos) {
193 const uint32_t word = m_datamap[pos];
194 fadc.push_back((word >> s_fadcBit) & s_fadcMask);
195 bcidFadc.push_back((word >> s_bcidFadcBit) & s_bcidFadcMask);
196 }
197 } else {
198 lut.resize(sliceL);
199 fadc.resize(sliceF);
200 bcidLut.resize(sliceL);
201 bcidFadc.resize(sliceF);
202 }
203}
204
205// Store an error word corresponding to a data channel
206
207void ZdcPpmSubBlock::fillPpmError(const int chan, const int errorWord)
208{
209 if (m_errormap.empty()) m_errormap.resize(s_glinkPins);
210 // Expand one ASIC channel disabled bit to four
211 const uint32_t chanDisabled = (errorWord & 0x1) << asic(chan);
212 uint32_t word = (((errorWord >> 1) << s_asicChannels)
213 | chanDisabled) & s_errorMask;
214 m_errormap[pin(chan)] |= word;
215 m_globalError |= word;
216}
217
218// Store an error word corresponding to a G-Link pin
219
220void ZdcPpmSubBlock::fillPpmPinError(const int pin, const int errorWord)
221{
222 if (m_errormap.empty()) m_errormap.resize(s_glinkPins);
223 m_errormap[pin] = errorWord & s_errorMask;
224 m_globalError = 0;
225 for (uint32_t word : m_errormap) {
226 m_globalError |= word;
227 }
228}
229
230// Return the error word for a data channel
231
232int ZdcPpmSubBlock::ppmError(const int chan) const
233{
234 int err = 0;
235 if ( !m_errormap.empty()) {
236 // Replace the four ASIC channel disabled bits with just the one
237 // corresponding to the data channel
238 err = (((m_errormap[pin(chan)] & s_errorMask) >> s_asicChannels) << 1)
239 | channelDisabled(chan);
240 }
241 return err;
242}
243
244// Return the error word for a G-Link pin
245
247{
248 int err = 0;
249 if ( !m_errormap.empty()) err = m_errormap[pin] & s_errorMask;
250 return err;
251}
252
253// Return global error bit
254
255bool ZdcPpmSubBlock::errorBit(const int bit) const
256{
257 return m_globalError & (0x1 << bit);
258}
259
260// Packing/Unpacking routines
261
263{
264 bool rc = false;
265 switch (version()) {
266 case 1:
267 switch (format()) {
268 case NEUTRAL:
269 rc = packNeutral();
270 break;
271 case UNCOMPRESSED:
272 switch (seqno()) {
273 case s_errorMarker:
275 break;
276 default:
278 break;
279 }
280 break;
281 case COMPRESSED:
282 case SUPERCOMPRESSED:
284 break;
285 default:
286 break;
287 }
288 break;
289 default:
290 break;
291 }
292 return rc;
293}
294
296{
297 bool rc = false;
298 switch (version()) {
299 case 1:
300 switch (format()) {
301 case NEUTRAL:
302 rc = unpackNeutral();
303 break;
304 case UNCOMPRESSED:
305 switch (seqno()) {
306 case s_errorMarker:
308 break;
309 default:
311 break;
312 }
313 break;
314 case COMPRESSED:
315 case SUPERCOMPRESSED:
317 break;
318 default:
320 break;
321 }
322 break;
323 default:
325 break;
326 }
327 return rc;
328}
329
330// Pack neutral data
331
333{
334 const int slices = slicesLut() + slicesFadc();
335 const int channels = channelsPerSubBlock();
336 if (m_datamap.empty()) m_datamap.resize(slices * channels);
337 // Bunch crossing number
338 for (int pin = 0; pin < s_glinkPins; ++pin) {
339 uint32_t bc = 0;
340 if (pin < s_bunchCrossingBits) bc = (bunchCrossing() >> pin) & 0x1;
341 packerNeutral(pin, bc, 1);
342 }
343 // Data
344 std::vector<uint32_t>::const_iterator pos = m_datamap.begin();
345 for (int asic = 0; asic < s_asicChannels; ++asic) {
346 for (int pin = 0; pin < s_glinkPins; ++pin) {
347 for (int sl = 0; sl < slices; ++sl) {
349 ++pos;
350 }
351 }
352 }
353 // Errors, including GP
354 if (m_errormap.empty()) m_errormap.resize(s_glinkPins);
355 pos = m_errormap.begin();
356 for (int pin = 0; pin < s_glinkPins; ++pin) {
359 ++pos;
360 }
361 return true;
362}
363
364// Pack uncompressed data
365
367{
368 const int slices = slicesLut() + slicesFadc();
369 const int channels = channelsPerSubBlock();
370 if (m_datamap.empty()) m_datamap.resize(slices * channels);
371 for (int sl = 0; sl < slices; ++sl) {
372 for (int chan = 0; chan < channels; ++chan) {
373 packer(m_datamap[sl + chan*slices], s_wordLen);
374 }
375 }
376 packerFlush();
377 return true;
378}
379
380// Pack uncompressed error data
381
383{
384 if (m_errormap.empty()) m_errormap.resize(s_glinkPins);
385 for (int pin = 0; pin < s_glinkPins; ++pin) {
387 }
388 packerFlush();
389 return true;
390}
391
392// Unpack neutral data
393
395{
396 const int slices = slicesLut() + slicesFadc();
397 m_datamap.clear();
398 // Bunch Crossing number
399 int bunchCrossing = 0;
400 for (int pin = 0; pin < s_glinkPins; ++pin) {
401 const int bc = unpackerNeutral(pin, 1);
403 }
405 // Data
406 for (int asic = 0; asic < s_asicChannels; ++asic) {
407 for (int pin = 0; pin < s_glinkPins; ++pin) {
408 for (int sl = 0; sl < slices; ++sl) {
410 }
411 }
412 }
413 const bool rc = unpackerSuccess();
415 // Errors
416 m_errormap.clear();
417 m_globalError = 0;
418 for (int pin = 0; pin < s_glinkPins; ++pin) {
421 m_errormap.push_back(error);
423 }
424 return rc;
425}
426
427// Unpack uncompressed data
428
430{
431 const int slices = slicesLut() + slicesFadc();
432 const int channels = channelsPerSubBlock();
433 m_datamap.resize(slices * channels);
434 unpackerInit();
435 for (int sl = 0; sl < slices; ++sl) {
436 for (int chan = 0; chan < channels; ++chan) {
437 m_datamap[sl + chan*slices] = unpacker(s_wordLen);
438 }
439 }
440 const bool rc = unpackerSuccess();
442 return rc;
443}
444
445// Unpack uncompressed error data
446
448{
449 unpackerInit();
450 m_errormap.clear();
451 m_globalError = 0;
452 for (int pin = 0; pin < s_glinkPins; ++pin) {
453 uint32_t word = unpacker(s_wordLen);
454 m_errormap.push_back(word);
455 m_globalError |= word;
456 }
457 const bool rc = unpackerSuccess();
459 return rc;
460}
461
462// Return the number of channels per sub-block
463
465{
466 int chan = 0;
467 switch (version) {
468 case 1:
469 switch (format) {
470 case UNCOMPRESSED:
472 break;
473 case NEUTRAL:
474 case COMPRESSED:
475 case SUPERCOMPRESSED:
476 chan = s_channels;
477 break;
478 default:
479 break;
480 }
481 break;
482 default:
483 break;
484 }
485 return chan;
486}
487
492
493// Check if a header word is for an error block
494
495bool ZdcPpmSubBlock::errorBlock(const uint32_t word)
496{
497 bool rc = false;
498 if (format(word) == UNCOMPRESSED &&
499 seqno(word) == s_errorMarker) rc = true;
500 return rc;
501}
502
503
static Double_t rc
static bool unpack(ZdcPpmSubBlock &subBlock)
Unpack data.
static bool pack(ZdcPpmSubBlock &subBlock)
Pack data.
int pin(int chan) const
Return the G-Link pin corresponding to a data channel.
bool unpackNeutral()
Unpack neutral data.
void fillPpmData(int chan, const std::vector< int > &lut, const std::vector< int > &fadc, const std::vector< int > &bcidLut, const std::vector< int > &bcidFadc)
Store PPM data for later packing.
int channelsPerSubBlock() const
static const uint32_t s_bcidFadcMask
static const int s_glinkPins
static const int s_eventMismatchBit
int ppmPinError(int pin) const
Return the error word for a G-Link pin.
bool unpackUncompressedData()
Unpack uncompressed data.
void ppmData(int chan, std::vector< int > &lut, std::vector< int > &fadc, std::vector< int > &bcidLut, std::vector< int > &bcidFadc) const
Return unpacked data for given channel.
static const int s_ppmChannel[]
static const uint32_t s_bcidLutMask
bool packNeutral()
Pack neutral data.
static const int s_dataBits
static const uint32_t s_fadcMask
void fillPpmPinError(int pin, int errorWord)
Store an error word corresponding to a G-Link pin.
static const int s_fpgaCorruptBit
bool channelDisabled(int chan) const
bool unpack()
Unpack data.
static const int s_glinkPinParityBit
int asic(int chan) const
Return the ASIC channel corresponding to a data channel.
static const int s_bunchMismatchBit
bool packUncompressedErrors()
Pack uncompressed error data.
static const int s_bcidLutBit
static const int s_asicChannels
uint32_t m_globalError
static const int s_bunchCrossingBits
int slicesFadc() const
std::vector< uint32_t > m_datamap
Vector for intermediate data.
bool packUncompressedData()
Pack uncompressed data.
bool pack()
Pack data.
int ppmError(int chan) const
Return the error word for a data channel.
static const int s_asicFullBit
static bool errorBlock(uint32_t word)
Check if a header word is for an error block.
static const int s_wordLen
void fillPpmError(int chan, int errorWord)
Store an error word corresponding to a data channel.
static const uint32_t s_wordIdVal
Sub-Block class for PPM data.
static const int s_errorBits
static const int s_errorMarker
static const int s_timeoutBit
static const int s_channelDisabledBit
static const int s_fadcBit
bool errorBit(int pin, int bit) const
Error bit extraction.
void clear()
Clear all data.
int slicesLut() const
void setPpmErrorHeader(int version, int format, int crate, int module, int slicesFadc, int slicesLut)
Store PPM error block header.
std::vector< uint32_t > m_errormap
Vector for intermediate error data.
void setPpmHeader(int version, int format, int seqno, int crate, int module, int slicesFadc, int slicesLut)
Store PPM header.
bool unpackUncompressedErrors()
Unpack uncompressed error data.
static const int s_mcmAbsentBit
static const uint32_t s_lutMask
static const int s_channels
static const int s_bcidFadcBit
static const int s_lutBit
static const uint32_t s_errorMask
uint32_t unpackerNeutral(int pin, int nbits)
Unpack given number of bits of neutral data for given pin.
int slices2() const
int version() const
void unpackerInit()
Initialise unpacker.
uint32_t unpacker(int nbits)
Unpack given number of bits of data.
int bunchCrossing() const
Return the Bunch Crossing number (neutral format only)
void packerNeutral(int pin, uint32_t datum, int nbits)
Pack given neutral data from given pin.
@ UNPACK_DATA_TRUNCATED
Definition ZdcSubBlock.h:51
int dataWords() const
Return number of data words.
bool unpackerSuccess() const
Return unpacker success flag.
int format() const
int slices1() const
void setUnpackErrorCode(int code)
Set the unpacking error code.
void setHeader(int wordId, int version, int format, int seqno, int crate, int module, int slices2, int slices1)
Store header data.
bool unpackerNeutralParityError(int pin)
Unpack and test G-Link parity bit for given pin.
int crate() const
void packer(uint32_t datum, int nbits)
Pack given data into given number of bits.
void setBunchCrossing(int bc)
Set the Bunch Crossing number (neutral format only)
void packerNeutralParity(int pin)
Pack current G-Link parity bit for given pin.
void packerFlush()
Flush the current data word padded with zeros.
void clear()
Clear all data.
int module() const
int seqno() const
setEventNumber uint32_t