ATLAS Offline Software
Loading...
Searching...
No Matches
PpmSubBlockV1.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
3*/
4
5
6#include "PpmCompressionV1.h"
7#include "PpmSubBlockV1.h"
8
9namespace LVL1BS {
10
11// Constant definitions
12
15
25
32
42
49
53
54// Clear all data
55
57{
59 m_globalError = 0;
60 m_lutOffset = -1;
61 m_fadcOffset = -1;
62 m_datamap.clear();
63 m_errormap.clear();
64}
65
66// Store PPM header
67
68void PpmSubBlockV1::setPpmHeader(const int version, const int format,
69 const int seqno, const int crate,
70 const int module, const int slicesFadc,
71 const int slicesLut)
72{
75}
76
77// Store PPM error block header
78
80 const int crate, const int module,
81 const int slicesFadc, const int slicesLut)
82{
85}
86
87// Return the number of FADC slices
88
90{
91 int slices = slices2();
92 if (slices == 0 && format() == NEUTRAL) {
93 slices = dataWords() / (s_asicChannels * s_dataBits) - slicesLut();
94 }
95 if (slices <= 0) slices = 1;
96 return slices;
97}
98
99// Return the number of LUT slices
100
102{
103 int slices = slices1();
104 if (slices == 0) slices = 1;
105 return slices;
106}
107
108// Store PPM data for later packing
109
110void PpmSubBlockV1::fillPpmData(const int chan, const std::vector<int>& lut,
111 const std::vector<int>& fadc,
112 const std::vector<int>& bcidLut,
113 const std::vector<int>& bcidFadc)
114{
115 const int sliceL = slicesLut();
116 const int sliceF = slicesFadc();
117 const int slices = sliceL + sliceF;
118 const int chanPerSubBlock = channelsPerSubBlock();
119 int dataSize = m_datamap.size();
120 if (dataSize == 0) {
121 dataSize = slices * chanPerSubBlock;
122 m_datamap.resize(dataSize);
123 }
124 // coverity[divide_by_zero : FALSE]
125 int offset = (chan % chanPerSubBlock) * slices;
126 if (offset + slices <= dataSize) {
127 for (int pos = 0; pos < sliceL; ++pos) {
128 uint32_t datum = (lut[pos] & s_lutMask) << s_lutBit;
129 datum |= (bcidLut[pos] & s_bcidLutMask) << s_bcidLutBit;
130 m_datamap[offset + pos] = datum;
131 }
132 offset += sliceL;
133 for (int pos = 0; pos < sliceF; ++pos) {
134 const int adc = (fadc[pos] > 0) ? fadc[pos] : 0;
135 uint32_t datum = (adc & s_fadcMask) << s_fadcBit;
136 datum |= (bcidFadc[pos] & s_bcidFadcMask) << s_bcidFadcBit;
137 m_datamap[offset + pos] = datum;
138 }
139 }
140}
141
142// Return unpacked data for given channel
143
144void PpmSubBlockV1::ppmData(const int chan, std::vector<int>& lut,
145 std::vector<int>& fadc,
146 std::vector<int>& bcidLut,
147 std::vector<int>& bcidFadc)
148{
149 lut.clear();
150 fadc.clear();
151 bcidLut.clear();
152 bcidFadc.clear();
153 const int sliceL = slicesLut();
154 const int sliceF = slicesFadc();
155 // coverity[divide_by_zero : FALSE]
156 int beg = (chan % channelsPerSubBlock()) * (sliceL + sliceF);
157 int end = beg + sliceL;
158 if (size_t(end + sliceF) <= m_datamap.size()) {
159 for (int pos = beg; pos < end; ++pos) {
160 const uint32_t word = m_datamap[pos];
161 lut.push_back((word >> s_lutBit) & s_lutMask);
162 bcidLut.push_back((word >> s_bcidLutBit) & s_bcidLutMask);
163 }
164 beg += sliceL;
165 end += sliceF;
166 for (int pos = beg; pos < end; ++pos) {
167 const uint32_t word = m_datamap[pos];
168 fadc.push_back((word >> s_fadcBit) & s_fadcMask);
169 bcidFadc.push_back((word >> s_bcidFadcBit) & s_bcidFadcMask);
170 }
171 } else {
172 lut.resize(sliceL);
173 fadc.resize(sliceF);
174 bcidLut.resize(sliceL);
175 bcidFadc.resize(sliceF);
176 }
177}
178
179// Store an error word corresponding to a data channel
180
181void PpmSubBlockV1::fillPpmError(const int chan, const int errorWord)
182{
183 if (m_errormap.empty()) m_errormap.resize(s_glinkPins);
184 // Expand one ASIC channel disabled bit to four
185 const uint32_t chanDisabled = (errorWord & 0x1) << asic(chan);
186 uint32_t word = (((errorWord >> 1) << s_asicChannels)
187 | chanDisabled) & s_errorMask;
188 m_errormap[pin(chan)] |= word;
189 m_globalError |= word;
190}
191
192// Store an error word corresponding to a G-Link pin
193
194void PpmSubBlockV1::fillPpmPinError(const int pin, const int errorWord)
195{
196 if (m_errormap.empty()) m_errormap.resize(s_glinkPins);
197 m_errormap[pin] = errorWord & s_errorMask;
198 m_globalError = 0;
199 for (uint32_t word : m_errormap) {
200 m_globalError |= word;
201 }
202}
203
204// Return the error word for a data channel
205
206int PpmSubBlockV1::ppmError(const int chan) const
207{
208 int err = 0;
209 if ( !m_errormap.empty()) {
210 // Replace the four ASIC channel disabled bits with just the one
211 // corresponding to the data channel
212 err = (((m_errormap[pin(chan)] & s_errorMask) >> s_asicChannels) << 1)
213 | channelDisabled(chan);
214 }
215 return err;
216}
217
218// Return the error word for a G-Link pin
219
220int PpmSubBlockV1::ppmPinError(const int pin) const
221{
222 int err = 0;
223 if ( !m_errormap.empty()) err = m_errormap[pin] & s_errorMask;
224 return err;
225}
226
227// Return global error bit
228
229bool PpmSubBlockV1::errorBit(const int bit) const
230{
231 return m_globalError & (0x1 << bit);
232}
233
234// Packing/Unpacking routines
235
237{
238 bool rc = false;
239 switch (version()) {
240 case 1:
241 switch (format()) {
242 case NEUTRAL:
243 rc = packNeutral();
244 break;
245 case UNCOMPRESSED:
246 switch (seqno()) {
247 case s_errorMarker:
249 break;
250 default:
252 break;
253 }
254 break;
255 case COMPRESSED:
256 case SUPERCOMPRESSED:
257 rc = PpmCompressionV1::pack(*this);
258 break;
259 default:
260 break;
261 }
262 break;
263 default:
264 break;
265 }
266 return rc;
267}
268
270{
271 bool rc = false;
272 switch (version()) {
273 case 1:
274 switch (format()) {
275 case NEUTRAL:
276 rc = unpackNeutral();
277 break;
278 case UNCOMPRESSED:
279 switch (seqno()) {
280 case s_errorMarker:
282 break;
283 default:
285 break;
286 }
287 break;
288 case COMPRESSED:
289 case SUPERCOMPRESSED:
291 break;
292 default:
294 break;
295 }
296 break;
297 default:
299 break;
300 }
301 return rc;
302}
303
304// Pack neutral data
305
307{
308 const int slices = slicesLut() + slicesFadc();
309 const int channels = channelsPerSubBlock();
310 if (m_datamap.empty()) m_datamap.resize(slices * channels);
311 // Bunch crossing number
312 for (int pin = 0; pin < s_glinkPins; ++pin) {
313 uint32_t bc = 0;
314 if (pin < s_bunchCrossingBits) bc = (bunchCrossing() >> pin) & 0x1;
315 packerNeutral(pin, bc, 1);
316 }
317 // Data
318 std::vector<uint32_t>::const_iterator pos = m_datamap.begin();
319 for (int asic = 0; asic < s_asicChannels; ++asic) {
320 for (int pin = 0; pin < s_glinkPins; ++pin) {
321 for (int sl = 0; sl < slices; ++sl) {
323 ++pos;
324 }
325 }
326 }
327 // Errors, including GP
328 if (m_errormap.empty()) m_errormap.resize(s_glinkPins);
329 pos = m_errormap.begin();
330 for (int pin = 0; pin < s_glinkPins; ++pin) {
333 ++pos;
334 }
335 return true;
336}
337
338// Pack uncompressed data
339
341{
342 const int slices = slicesLut() + slicesFadc();
343 const int channels = channelsPerSubBlock();
344 if (m_datamap.empty()) m_datamap.resize(slices * channels);
345 for (int sl = 0; sl < slices; ++sl) {
346 for (int chan = 0; chan < channels; ++chan) {
347 packer(m_datamap[sl + chan * slices], s_wordLen);
348 }
349 }
350 packerFlush();
351 return true;
352}
353
354// Pack uncompressed error data
355
357{
358 if (m_errormap.empty()) m_errormap.resize(s_glinkPins);
359 for (int pin = 0; pin < s_glinkPins; ++pin) {
361 }
362 packerFlush();
363 return true;
364}
365
366// Unpack neutral data
367
369{
370 const int slices = slicesLut() + slicesFadc();
371 m_datamap.clear();
372 // Bunch Crossing number
373 int bunchCrossing = 0;
374 for (int pin = 0; pin < s_glinkPins; ++pin) {
375 const int bc = unpackerNeutral(pin, 1);
377 }
379 // Data
380 for (int asic = 0; asic < s_asicChannels; ++asic) {
381 for (int pin = 0; pin < s_glinkPins; ++pin) {
382 for (int sl = 0; sl < slices; ++sl) {
384 }
385 }
386 }
387 const bool rc = unpackerSuccess();
389 // Errors
390 m_errormap.clear();
391 m_globalError = 0;
392 for (int pin = 0; pin < s_glinkPins; ++pin) {
395 m_errormap.push_back(error);
397 }
398 return rc;
399}
400
401// Unpack uncompressed data
402
404{
405 const int slices = slicesLut() + slicesFadc();
406 const int channels = channelsPerSubBlock();
407 m_datamap.resize(slices * channels);
408 unpackerInit();
409 for (int sl = 0; sl < slices; ++sl) {
410 for (int chan = 0; chan < channels; ++chan) {
411 m_datamap[sl + chan * slices] = unpacker(s_wordLen);
412 }
413 }
414 bool rc = unpackerSuccess();
416 else {
417 // Check no more non-zero data
418 while (unpackerSuccess()) {
419 if (unpacker(s_wordLen)) {
421 rc = false;
422 break;
423 }
424 }
425 }
426 return rc;
427}
428
429// Unpack uncompressed error data
430
432{
433 unpackerInit();
434 m_errormap.clear();
435 m_globalError = 0;
436 for (int pin = 0; pin < s_glinkPins; ++pin) {
437 uint32_t word = unpacker(s_wordLen);
438 m_errormap.push_back(word);
439 m_globalError |= word;
440 }
441 bool rc = unpackerSuccess();
443 else {
444 while (unpackerSuccess()) {
445 if (unpacker(s_wordLen)) {
447 rc = false;
448 break;
449 }
450 }
451 }
452 return rc;
453}
454
455// Return the number of channels per sub-block
456
458{
459 int chan = 0;
460 switch (version) {
461 case 1:
462 switch (format) {
463 case UNCOMPRESSED:
464 chan = s_channels / s_asicChannels;
465 break;
466 case NEUTRAL:
467 case COMPRESSED:
468 case SUPERCOMPRESSED:
469 chan = s_channels;
470 break;
471 default:
473 break;
474 }
475 break;
476 default:
478 break;
479 }
480 return chan;
481}
482
487
488// Check if a header word is for an error block
489
490bool PpmSubBlockV1::errorBlock(const uint32_t word)
491{
492 bool rc = false;
493 if (format(word) == UNCOMPRESSED &&
494 seqno(word) == s_errorMarker) rc = true;
495 return rc;
496}
497
498} // end namespace
static Double_t rc
void packer(uint32_t datum, int nbits)
Pack given data into given number of bits.
uint32_t unpacker(int nbits)
Unpack given number of bits of data.
void setUnpackErrorCode(int code)
Set the unpacking error code.
bool unpackerSuccess() const
Return unpacker success flag.
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 dataWords() const
Return number of data words.
void clear()
Clear all data.
void packerNeutralParity(int pin)
Pack current G-Link parity bit for given pin.
void packerFlush()
Flush the current data word padded with zeros.
uint32_t unpackerNeutral(int pin, int nbits)
Unpack given number of bits of neutral data for given pin.
int bunchCrossing() const
Return the Bunch Crossing number (neutral format only)
void unpackerInit()
Initialise unpacker.
void packerNeutral(int pin, uint32_t datum, int nbits)
Pack given neutral data from given pin.
void setBunchCrossing(int bc)
Set the Bunch Crossing number (neutral format only)
static bool unpack(PpmSubBlockV1 &subBlock)
Unpack data.
static bool pack(PpmSubBlockV1 &subBlock)
Pack data.
int asic(int chan) const
Return the ASIC channel corresponding to a data channel.
void clear()
Clear all data.
bool packUncompressedData()
Pack uncompressed data.
int pin(int chan) const
Return the G-Link pin corresponding to a data channel.
static const uint32_t s_bcidFadcMask
static const int s_dataBits
static const int s_bcidFadcBit
static const uint32_t s_errorMask
static const int s_wordLen
int ppmPinError(int pin) const
Return the error word for a G-Link pin.
void fillPpmPinError(int pin, int errorWord)
Store an error word corresponding to a G-Link pin.
static const int s_channels
static const uint32_t s_fadcMask
static const int s_eventMismatchBit
bool packUncompressedErrors()
Pack uncompressed error data.
void setPpmErrorHeader(int version, int format, int crate, int module, int slicesFadc, int slicesLut)
Store PPM error block header.
static const int s_fadcBit
static bool errorBlock(uint32_t word)
Check if a header word is for an error block.
std::vector< uint32_t > m_errormap
Vector for intermediate error data.
int ppmError(int chan) const
Return the error word for a data channel.
bool errorBit(int pin, int bit) const
Error bit extraction.
static const int s_bunchCrossingBits
bool unpackUncompressedData()
Unpack uncompressed data.
static const uint32_t s_lutMask
static const int s_timeoutBit
bool channelDisabled(int chan) const
static const int s_glinkPins
static const uint32_t s_wordIdVal
bool pack()
Pack data.
bool unpackUncompressedErrors()
Unpack uncompressed error data.
static const int s_errorMarker
static const int s_bunchMismatchBit
void setPpmHeader(int version, int format, int seqno, int crate, int module, int slicesFadc, int slicesLut)
Store PPM header.
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.
std::vector< uint32_t > m_datamap
Vector for intermediate data.
void ppmData(int chan, std::vector< int > &lut, std::vector< int > &fadc, std::vector< int > &bcidLut, std::vector< int > &bcidFadc)
Return unpacked data for given channel.
static const int s_channelDisabledBit
static const int s_lutBit
void fillPpmError(int chan, int errorWord)
Store an error word corresponding to a data channel.
static const int s_bcidLutBit
static const int s_fpgaCorruptBit
static const uint32_t s_bcidLutMask
static const int s_errorBits
static const int s_asicFullBit
static const int s_asicChannels
bool packNeutral()
Pack neutral data.
static const int s_glinkPinParityBit
bool unpack()
Unpack data.
static const int s_mcmAbsentBit
setEventNumber uint32_t