ATLAS Offline Software
Loading...
Searching...
No Matches
L1CaloSubBlock.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
3*/
4
5
6#include "L1CaloSubBlock.h"
7
8namespace LVL1BS
9{
10
11// Static constant definitions
12
19
21
38
48
53
56
63 m_unpackerFlag(false),
67{
68 // Initialize unpacking masks
69 m_unpackingMasks.assign(s_maxWordBits + 1, 0);
70 for (int i = 1; i <= s_maxWordBits; ++i)
71 {
72 m_unpackingMasks[i] = (m_unpackingMasks[i - 1] << 1) | 0x1;
73 }
74}
75
79
80// Clear all data
81
83{
84 m_header = 0;
85 m_trailer = 0;
88 m_bitword = 0;
89 m_currentBit = 0;
90 m_unpackerFlag = false;
91 m_currentPinBit.assign(s_maxPins, 0);
92 m_oddParity.assign(s_maxPins, 1);
93 m_dataWords = 0;
94 m_data.clear();
95}
96
97// Store header data
98
99void L1CaloSubBlock::setHeader(const int wordId, const int version,
100 const int format, const int seqno,
101 const int crate, const int module,
102 const int slices2, const int slices1)
103{
104 uint32_t word = 0;
105 word |= (wordId & s_wordIdMask) << s_wordIdBit;
106 word |= (version & s_versionMask) << s_versionBit;
107 word |= (format & s_formatMask) << s_formatBit;
108 word |= (seqno & s_seqnoMask) << s_seqnoBit;
109 word |= (crate & s_crateMask) << s_crateBit;
110 word |= (module & s_moduleMask) << s_moduleBit;
111 word |= (slices2 & s_slices2Mask) << s_slices2Bit;
112 word |= (slices1 & s_slices1Mask) << s_slices1Bit;
113 m_header = word;
114}
115
116// Input complete packed sub-block from ROD vector
117
121{
122 m_dataWords = 0;
123 m_unpackerFlag = true;
126 for (; pos != pose; ++pos)
127 {
128 const uint32_t word = *pos;
129 const SubBlockWordType type = wordType(word);
130 if (type == HEADER)
131 {
132 if (m_header) return pos;
133 m_header = word;
134 }
135 else if (type == STATUS)
136 {
137 // Word ID should be consistent with header
138 if (m_trailer || (wordId(word) != wordId() + 1)) return pos;
139 m_trailer = word;
140 }
141 else
142 {
143 // Check data word IDs
144 const int id = wordId(word);
145 bool badId = false;
146 // All neutral format '0000'
147 if (format() == NEUTRAL) badId = (id != 0);
148 // Other PPM '0xxx'
149 else if (crate() < s_ppmCrates) badId = ((id & 0x8) != 0);
150 // Other CPM/JEM '01xx' or '10xx'
151 else if (wordId() == 0xc) badId = (((id & 0xc) != 0x4) &&
152 ((id & 0xc) != 0x8));
153 // Other CMM/CMX '00xx'
154 else badId = ((id & 0xc) != 0);
155 if (m_trailer || badId) return pos;
156 m_data.push_back(word);
157 ++m_dataWords;
158 }
159 }
160 return pose;
161}
162
163// Output complete packed sub-block to ROD vector
164
167{
168 theROD->push_back(m_header);
169 std::vector<uint32_t>::const_iterator pos;
170 for (pos = m_data.begin(); pos != m_data.end(); ++pos)
171 {
172 theROD->push_back(*pos);
173 }
174 if (m_trailer) theROD->push_back(m_trailer);
175}
176
177// Store error status trailer
178
180 const bool glinkTimeout, const bool glinkDown, const bool upstreamError,
181 const bool daqOverflow, const bool bcnMismatch,
182 const bool glinkProtocol, const bool glinkParity)
183{
184 uint32_t word = 0;
187 word |= glinkDown << s_glinkDownBit;
189 word |= daqOverflow << s_daqOverflowBit;
190 word |= bcnMismatch << s_bcnMismatchBit;
192 word |= glinkParity << s_glinkParityBit;
193 if (word)
194 {
195 word |= (wordId() & s_wordIdMask) << s_wordIdBit;
196 word |= (s_statusVal & s_statusMask) << s_statusBit;
197 word |= (seqno() & s_seqnoMask) << s_seqnoBit;
198 word |= (crate() & s_crateMask) << s_crateBit;
199 word |= (module() & s_moduleMask) << s_moduleBit;
200 }
201 m_trailer = word;
202}
203
204// Set DAQ FIFO Overflow bit in Sub-status word
205
207{
208 if (bit)
209 {
210 if (m_trailer) m_trailer |= (1 << s_daqOverflowBit);
211 else setStatus(0, false, false, false, true, false, false, false);
212 }
213}
214
215// Set G-Link Parity bit in Sub-status word
216
218{
219 if (bit)
220 {
221 if (m_trailer) m_trailer |= (1 << s_glinkParityBit);
222 else setStatus(0, false, false, false, false, false, false, true);
223 }
224}
225
226// Return the unpacking error message for printing
227
229{
230 std::string msg;
231 switch (m_unpackError)
232 {
233 case UNPACK_NONE:
234 msg = "No error";
235 break;
236 case UNPACK_VERSION:
237 msg = "Unsupported Data Version";
238 break;
239 case UNPACK_FORMAT:
240 msg = "Unsupported Data Format";
241 break;
243 msg = "Unsupported Compression Version";
244 break;
246 msg = "Unsupported Number of Slices for Compression Version";
247 break;
249 msg = "Premature End of Sub-block Data";
250 break;
252 msg = "Excess Data in Sub-block";
253 break;
254 case UNPACK_SOURCE_ID:
255 msg = "Invalid Source ID in Sub-block Data";
256 break;
258 msg = "Excess TOBs in Sub-block Data";
259 break;
260 case UNPACK_DATA_ID:
261 msg = "Invalid word ID in Sub-block Data";
262 break;
263 default:
264 msg = "Unknown Error Code";
265 break;
266 }
267 return msg;
268}
269
270// Packing utilities
271
272// Return the minimum number of bits needed for given data
273
274int L1CaloSubBlock::minBits(const uint32_t datum) const
275{
276 const int maxBits = 32;
277 int nbits = maxBits;
278 for (int i = 0; i < maxBits; ++i)
279 {
280 if ( !(datum >> i))
281 {
282 nbits = i;
283 break;
284 }
285 }
286 return nbits;
287}
288
289// Return the parity bit for given data
290
291int L1CaloSubBlock::parityBit(const int init, const uint32_t datum,
292 const int nbits) const
293{
294 // set init to 0/1 for even/odd parity
295 int parity = init;
296 for (int bit = 0; bit < nbits; ++bit) parity ^= (datum >> bit) & 0x1;
297 return parity;
298}
299
300// Pack given data into given number of bits
301
302void L1CaloSubBlock::packer(const uint32_t datum, const int nbits)
303{
304 if (nbits > 0)
305 {
306 uint32_t mask = m_unpackingMasks[nbits];
307 m_bitword |= (datum & mask) << m_currentBit;
308 m_currentBit += nbits;
309 if (m_currentBit >= m_maxBits)
310 {
312 m_data.push_back(m_bitword);
313 ++m_dataWords;
314 const int bitsLeft = m_currentBit - m_maxBits;
315 if (bitsLeft > 0)
316 {
317 m_bitword = (datum & mask) >> (nbits - bitsLeft);
318 m_currentBit = bitsLeft;
319 }
320 else
321 {
322 m_bitword = 0;
323 m_currentBit = 0;
324 }
325 }
326 }
327}
328
329// Flush the current data word padded with zeros
330
332{
333 if (m_currentBit > 0)
334 {
336 m_data.push_back(m_bitword);
337 ++m_dataWords;
338 m_bitword = 0;
339 m_currentBit = 0;
340 }
341}
342
343// Unpack given number of bits of data
344
345uint32_t L1CaloSubBlock::unpacker(const int nbits)
346{
347 uint32_t word = 0;
348 if (nbits > 0)
349 {
350 if (m_dataPos == m_dataPosEnd)
351 {
352 m_unpackerFlag = false;
353 return 0;
354 }
355 int nbitsDone = nbits;
356 if (nbitsDone > m_maxBits - m_currentBit)
357 {
358 nbitsDone = m_maxBits - m_currentBit;
359 }
360 word = (m_bitword >> m_currentBit) & m_unpackingMasks[nbitsDone];
361 m_currentBit += nbits;
362
363 if (m_currentBit >= m_maxBits)
364 {
365 m_bitword = 0;
366 if (m_dataPos != m_dataPosEnd)
367 {
368 ++m_dataPos;
369 if (m_dataPos != m_dataPosEnd)
370 {
372 }
373 }
374 m_currentBit = 0;
375 const int bitsLeft = nbits - nbitsDone;
376 if (bitsLeft > 0)
377 {
378 if (m_dataPos == m_dataPosEnd)
379 {
380 m_unpackerFlag = false;
381 return word;
382 }
383 word |= (m_bitword & m_unpackingMasks[bitsLeft]) << nbitsDone;
384 m_currentBit = bitsLeft;
385 }
386 }
387 }
388 return word;
389}
390
391// Initialise unpacker
392
394{
395 m_bitword = 0;
396 m_currentBit = 0;
397 m_unpackerFlag = true;
398 m_dataPos = m_data.begin();
399 m_dataPosEnd = m_data.end();
400 // std::cout << "SASHA4 m_dataPosEnd - m_dataPos=" << (m_dataPosEnd - m_dataPos) << std::endl;
401 // uint16_t a = (*m_dataPos) & 0xFF;
402 // uint16_t b = (*m_dataPos >> 11) & 0xFF;
403
404 // std::cout << "SASHA5 first " << a << std::endl;
405 // std::cout << "SASHA5 second " << b << std::endl;
406 // std::cout << "SASHA5 datawords " << m_data.size() << std::endl;
407
409}
410
411// Pack given neutral data from given pin
412
413void L1CaloSubBlock::packerNeutral(const int pin, const uint32_t datum,
414 const int nbits)
415{
416 if (pin >= 0 && pin < s_maxPins && nbits > 0)
417 {
418 if (m_currentPinBit[pin] + nbits > m_dataWords)
419 {
420 m_dataWords = m_currentPinBit[pin] + nbits;
422 }
423 for (int bit = 0; bit < nbits; ++bit)
424 {
425 m_data[m_currentPinBit[pin] + bit] |= ((datum >> bit) & 0x1) << pin;
426 }
427 m_currentPinBit[pin] += nbits;
428 m_oddParity[pin] = parityBit(m_oddParity[pin], datum, nbits);
429 }
430}
431
432// Pack current G-Link parity bit for given pin
433
435{
436 if (pin >= 0 && pin < s_maxPins)
437 {
438 packerNeutral(pin, m_oddParity[pin], 1);
439 m_oddParity[pin] = 1;
440 }
441}
442
443// Unpack given number of bits of neutral data for given pin
444
445uint32_t L1CaloSubBlock::unpackerNeutral(const int pin, const int nbits)
446{
447 uint32_t word = 0;
448 if (pin >= 0 && pin < s_maxPins && nbits > 0
449 && m_currentPinBit[pin] + nbits <= m_dataWords)
450 {
451 for (int bit = 0; bit < nbits; ++bit)
452 {
453 word |= ((m_data[m_currentPinBit[pin] + bit] >> pin) & 0x1) << bit;
454 }
455 m_currentPinBit[pin] += nbits;
456 m_oddParity[pin] = parityBit(m_oddParity[pin], word, nbits);
457 }
458 else m_unpackerFlag = false;
459 return word;
460}
461
462// Unpack and test G-Link parity bit for given pin
463
465{
466 bool error = true;
467 if (pin >= 0 && pin < s_maxPins)
468 {
469 int parity = m_oddParity[pin];
470 int bit = unpackerNeutral(pin, 1);
471 m_oddParity[pin] = 1;
472 error = !(bit == parity);
473 }
474 return error;
475}
476
477// Static function to determine word type
478
480{
482 if (((word >> s_headerBit) & s_headerMask) == s_headerVal)
483 {
484 if (((word >> s_statusBit) & s_statusMask) == s_statusVal) type = STATUS;
485 else type = HEADER;
486 }
487 return type;
488}
489
490// Return wordID field from given header word
491
492int L1CaloSubBlock::wordId(const uint32_t word)
493{
494 return (word >> s_wordIdBit) & s_wordIdMask;
495}
496
497// Return version number from given header word
498
499int L1CaloSubBlock::version(const uint32_t word)
500{
501 return (word >> s_versionBit) & s_versionMask;
502}
503
504// Return data format from given header word
505
506int L1CaloSubBlock::format(const uint32_t word)
507{
508 return (word >> s_formatBit) & s_formatMask;
509}
510
511// Return seqno field from given header word
512
513int L1CaloSubBlock::seqno(const uint32_t word)
514{
515 return (word >> s_seqnoBit) & s_seqnoMask;
516}
517
518// Return module field from given header word
519
520int L1CaloSubBlock::module(const uint32_t word)
521{
522 return (word >> s_moduleBit) & s_moduleMask;
523}
524
525} // end namespace
std::vector< uint32_t > RODDATA
ROD data as a vector of unsigned int.
static const int s_maxWordBits
uint32_t m_trailer
Sub-Block Status Trailer.
void setDaqOverflow(int bit=1)
Set DAQ FIFO Overflow bit in Sub-status word.
static const uint32_t s_failingBcnMask
void setGlinkParity(int bit=1)
Set G-Link Parity bit in Sub-status word.
static const int s_glinkProtocolBit
static const uint32_t s_wordIdMask
void packer(uint32_t datum, int nbits)
Pack given data into given number of bits.
void setStatus(uint32_t failingBCN, bool glinkTimeout, bool glinkDown, bool upstreamError, bool daqOverflow, bool bcnMismatch, bool glinkProtocol, bool glinkParity)
Store error status trailer.
static const int s_formatBit
std::vector< int > m_oddParity
static const int s_headerBit
std::vector< uint32_t >::const_iterator m_dataPos
static const uint32_t s_crateMask
std::vector< uint32_t > m_data
Sub-Block data.
static const int s_maxPins
int parityBit(int init, uint32_t datum, int nbits) const
Return the parity bit for given data.
int m_bunchCrossing
Bunch Crossing number (neutral format only)
uint32_t unpacker(int nbits)
Unpack given number of bits of data.
static const int s_upstreamErrorBit
static const int s_glinkTimeoutBit
static const uint32_t s_formatMask
static const int s_glinkParityBit
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.
uint32_t failingBCN() const
static const uint32_t s_maxWordMask
static const uint32_t s_seqnoMask
static const uint32_t s_headerVal
static const int s_ppmCrates
static SubBlockWordType wordType(uint32_t word)
Word identification.
void clear()
Clear all data.
static const uint32_t s_glinkDavSet
static const uint32_t s_slices1Mask
static const int s_slices2Bit
static const int s_crateBit
static const int s_versionBit
void packerNeutralParity(int pin)
Pack current G-Link parity bit for given pin.
void write(FullEventAssembler< L1CaloSrcIdMap >::RODDATA *theROD) const
Output complete packed sub-block to ROD vector.
static const int s_daqOverflowBit
std::vector< uint32_t >::const_iterator m_dataPosEnd
std::vector< int > m_currentPinBit
static const int s_seqnoBit
std::vector< uint32_t > m_unpackingMasks
Unpacking masks.
static const int s_moduleBit
static const uint32_t s_statusVal
void packerFlush()
Flush the current data word padded with zeros.
static const int s_failingBcnBit
uint32_t unpackerNeutral(int pin, int nbits)
Unpack given number of bits of neutral data for given pin.
static const int s_statusBit
uint32_t m_header
Sub-Block Header.
static const uint32_t s_maxStreamedMask
static const int s_maxStreamedBits
static const uint32_t s_moduleMask
void unpackerInit()
Initialise unpacker.
static const int s_slices1Bit
std::string unpackErrorMsg() const
Return the unpacking error message for printing.
int minBits(uint32_t datum) const
Return the minimum number of bits needed for given data.
int m_dataWords
Current number of data words.
OFFLINE_FRAGMENTS_NAMESPACE::PointerType read(const OFFLINE_FRAGMENTS_NAMESPACE::PointerType beg, const OFFLINE_FRAGMENTS_NAMESPACE::PointerType end)
Input complete packed sub-block from ROD array.
static const int s_wordIdBit
int m_unpackError
Unpacking error code.
void packerNeutral(int pin, uint32_t datum, int nbits)
Pack given neutral data from given pin.
static const uint32_t s_versionMask
static const uint32_t s_statusMask
static const uint32_t s_headerMask
static const int s_bcnMismatchBit
static const uint32_t s_slices2Mask
static const int s_glinkDownBit
const DataType * PointerType
Definition RawEvent.h:25
setEventNumber uint32_t
MsgStream & msg
Definition testRead.cxx:32