6 #ifndef MVTXDECODER_GBTLINK_H
7 #define MVTXDECODER_GBTLINK_H
9 #define _RAW_READER_ERROR_CHECKS_ // comment this to disable error checking
28 #define GBTLINK_DECODE_ERRORCHECK(errRes, errEval) \
30 if ((errRes)&uint8_t(ErrorPrinted)) { \
31 ruPtr->linkHBFToDump[(uint64_t(subSpec) << 32) + hbfEntry] = irHBF.orbit; \
32 errRes &= ~uint8_t(ErrorPrinted); \
34 if ((errRes)&uint8_t(Abort)) { \
36 return AbortedOnError; \
41 using namespace mvtx_utils;
48 size_t first_hit_pos = 0;
51 TRGData(uint64_t orb, uint16_t
b) : ir(orb, b) {};
65 uint8_t chip_id = 0xf;
66 uint16_t bunchcounter = 0xFFFF;
67 uint16_t row_pos = 0xFFFF;
68 uint16_t col_pos = 0xFFFF;
90 static constexpr
int RawBufferMargin = 5000000;
91 static constexpr
int RawBufferSize = 10000000 + 2 * RawBufferMargin;
92 static constexpr uint8_t MaxCablesPerLink = 3;
103 uint32_t hbfEntry = 0;
107 bool hbf_found =
false;
109 uint32_t hbf_length = 0;
110 uint32_t prev_pck_cnt = 0;
111 uint32_t hbf_count = 0;
114 size_t dataOffset = 0;
118 std::vector<mvtx_hit *> hit_vector = {};
122 GBTLink(uint16_t _flx, uint16_t _fee);
123 void clear(
bool resetStat =
true,
bool resetTFRaw =
false);
125 CollectedDataStatus collectROFCableData();
127 void cacheData(
size_t start,
size_t sz)
132 void clearCableData()
134 for (
auto&&
data : cableData )
140 int readFlxWord(
GBTWord* gbtwords, uint16_t &w16 );
143 void getRowCol(
const uint8_t reg,
const uint16_t addr, uint16_t& row, uint16_t&
col)
145 row = ( addr >> 0x1 ) & 0x1FF;
146 col = ( reg << 5 | ( (addr >> 9) & 0x1E ) ) | ( (addr ^ addr >> 1) & 0x1 );
149 void addHit(
const uint8_t laneId,
const uint8_t bc, uint8_t reg,
const uint16_t addr)
152 memset(hit, 0,
sizeof(*hit));
154 hit->chip_id = laneId;
155 hit->bunchcounter = bc;
156 getRowCol(reg, addr, hit->row_pos, hit->col_pos);
158 hit_vector.push_back(hit);
161 void check_APE(
const uint8_t& chipId,
const uint8_t& dataC)
163 std::cerr <<
"Link: " << feeId <<
", Chip: " << (int)chipId;
167 std::cerr <<
" APE_STRIP_START" << std::endl;
170 std::cerr <<
" APE_DET_TIMEOUT" << std::endl;
173 std::cerr <<
" APE_OOT" << std::endl;
176 std::cerr <<
" APE_PROTOCOL_ERROR" << std::endl;
179 std::cerr <<
" APE_LANE_FIFO_OVERFLOW_ERROR" << std::endl;
182 std::cerr <<
" APE_FSM_ERROR" << std::endl;
185 std::cerr <<
" APE_PENDING_DETECTOR_EVENT_LIMIT" << std::endl;
188 std::cerr <<
" APE_PENDING_LANE_EVENT_LIMIT" << std::endl;
191 std::cerr <<
" APE_O2N_ERROR" << std::endl;
194 std::cerr <<
" APE_RATE_MISSING_TRG_ERROR" << std::endl;
197 std::cerr <<
" APE_PE_DATA_MISSING" << std::endl;
200 std::cerr <<
" APE_OOT_DATA_MISSING" << std::endl;
203 std::cerr <<
" Unknown APE code" << std::endl;
212 std::cerr <<
"Link: " << feeId <<
", Chip: " << (int)chipId;
213 std::cerr <<
" invalid byte 0x" << std::hex << (int)(dataC) << std::endl;
214 while ( buffer.
next(dataC) )
216 std::cerr <<
" " << std::hex << (int)(dataC) <<
" ";
218 std::cerr << std::endl;
223 void PrintFlxWord(std::ostream&
os, uint8_t*
pos)
225 os << std::setfill(
'0');
226 for (
int i = 0;
i < 32 ;
i++)
228 os << std::hex << std::setw(2) << (int)pos[
i] <<
" " << std::dec;
230 os << std::setfill(
' ') << std::endl;
233 void PrintBlock(std::ostream&
os, uint8_t*
pos,
size_t n)
235 for (uint32_t
i = 0;
i <
n; ++
i)
237 PrintFlxWord(os, pos + 32 *
i);
249 bool prev_evt_complete =
false;
250 bool header_found =
false;
251 bool trailer_found =
false;
252 uint8_t* hbf_start =
nullptr;
256 auto currRawPiece =
rawData.currentPiece();
260 uint32_t n_no_continuation = 0;
261 uint32_t n_packet_done = 0;
263 if (dataOffset >= currRawPiece->size)
265 data.movePtr(currRawPiece->size);
268 if ( ! (currRawPiece =
rawData.nextPiece()) )
274 if ( currRawPiece->hasError )
276 dataOffset = currRawPiece->size;
283 hbf_start =
data.getPtr();
288 uint8_t* rdh_start =
data.getPtr() + dataOffset;
298 log_error <<
"Wrong dataOffset value " << dataOffset <<
" at the start of a HBF" << std::endl;
305 if ( (rdh.
trgType >> trg) & 1 )
307 statistics.trgBitCounts[trg]++;
310 hbfEntry =
rawData.currentPieceId();
315 if (prev_evt_complete)
317 log_error <<
"Previous event was already completed" << std::endl;
323 int prev_gbt_cnt = 3;
326 for (
size_t iflx = 0; iflx < nFlxWords; ++iflx )
328 readFlxWord(gbtWords, w16);
329 int16_t n_gbt_cnt = (w16 & 0x3FF) - prev_gbt_cnt;
330 prev_gbt_cnt = (w16 & 0x3FF);
331 if (n_gbt_cnt < 1 || n_gbt_cnt > 3)
333 log_error <<
"Bad gbt counter in the flx packet. FLX: " << flxId <<
", Feeid: " << feeId <<
", n_gbt_cnt: " << n_gbt_cnt \
334 <<
", prev_gbt_cnt: " << prev_gbt_cnt <<
", size: " << currRawPiece->size <<
", dataOffset: " << dataOffset << std::endl;
335 PrintBlock(std::cerr, rdh_start, nFlxWords + 2);
336 std::cerr <<
"Full HBF" << std::endl;
337 PrintBlock(std::cerr, hbf_start, (currRawPiece->size/32) );
340 for (
int i = 0;
i < n_gbt_cnt; ++
i )
342 auto &gbtWord = gbtWords[
i];
343 if ( gbtWord.isIHW() )
346 if (! ( !gbtWord.activeLanes ||
347 ((gbtWord.activeLanes >> 0) & 0x7) == 0x7 ||
348 ((gbtWord.activeLanes >> 3) & 0x7) == 0x7 ||
349 ((gbtWord.activeLanes >> 6) & 0x7) == 0x7) )
351 log_error <<
"Expected all active lanes for links, but " << gbtWord.activeLanes <<
"found in HBF " << hbfEntry <<
", " \
352 << gbtWord.asString().data() << std::endl;
356 else if ( gbtWord.isTDH() )
359 ir.orbit = gbtWord.bco;
365 if ( trg == GBTLinkDecodingStat::BitMaps::FE_RST )
367 if ( ((gbtWord.triggerType >> trg) & 1) )
369 statistics.trgBitCounts[trg]++;
374 if ( (gbtWord.triggerType >> GBTLinkDecodingStat::BitMaps::PHYSICS) & 0x1 )
376 mL1TrgTime.push_back(ir);
379 if ( !gbtWord.continuation && !gbtWord.noData)
382 mTrgData.emplace_back(ir.orbit, ir.bc);
385 else if ( gbtWord.isCDW() )
387 mTrgData.back().hasCDW =
true;
390 else if ( gbtWord.isTDT() )
392 trailer_found =
true;
393 if ( gbtWord.packet_done )
396 if (n_packet_done < n_no_continuation)
398 log_error <<
"TDT packet done before TDH no continuation " << n_no_continuation \
399 <<
" != " << n_packet_done << std::endl;
403 prev_evt_complete = gbtWord.packet_done;
406 else if ( gbtWord.isDDW() )
414 else if ( gbtWord.isDiagnosticIB() )
416 std::cout <<
"WARNING: IB Diagnostic word found." << std::endl;
417 std::cout <<
"diagnostic_lane_id: " << (gbtWord.id >> 5);
418 std::cout <<
" lane_error_id: " << gbtWord.lane_error_id;
419 std::cout <<
" diasnotic_data: 0x" << std::hex << gbtWord.diagnostic_data << std::endl;
421 else if ( gbtWord.isData() )
425 log_error <<
"Trigger header not found before chip data" << std::endl;
428 auto lane = ( gbtWord.data8[9] & 0x1F ) % 3;
429 cableData[lane].add(gbtWord.getW8(), 9);
432 if ( prev_evt_complete )
434 auto&& trgData = mTrgData.back();
435 trgData.first_hit_pos = hit_vector.size();
436 for(
auto&& itr = cableData.begin(); itr != cableData.end(); ++itr)
443 trgData.n_hits = hit_vector.size() - trgData.first_hit_pos;
444 prev_evt_complete =
false;
445 header_found =
false;
446 trailer_found =
false;
452 return (
status = StoppedOnEndOfData);
470 bool busy_on =
false, busy_off =
false;
471 bool chip_header_found =
false;
472 bool chip_trailer_found =
false;
474 uint8_t laneId = 0xFF;
478 if ( !( (buffer[0] & 0xF0) == 0xE0 || (buffer[0] & 0xF0) == 0xA0 ||\
479 (buffer[0] == 0xF0) || (buffer[0] == 0xF1) || (buffer[0] & 0xF0) == 0xF0 ) )
481 AlpideByteError(chipId, buffer);
485 while ( buffer.
next(dataC) )
491 else if ( dataC == 0xF0 )
495 else if ( (dataC & 0xF0) == 0xF0)
497 check_APE(chipId, dataC);
498 chip_trailer_found = 1;
499 busy_on = busy_off = chip_header_found = 0;
501 else if ( (dataC & 0xF0) == 0xE0 )
503 chip_header_found =
false;
504 chip_trailer_found =
true;
505 laneId = (dataC & 0x0F) % 3;
506 if ( laneId != chipId )
508 log_error <<
"Error laneId " << laneId <<
" (" << (dataC & 0xF) <<
") and chipId " << chipId << std::endl;
512 busy_on = busy_off =
false;
516 if ( chip_header_found )
518 if ( (dataC & 0xE0) == 0xC0 )
522 log_error <<
"No data short would fit (at least a data short after region header!)" << std::endl;
528 else if ( (dataC & 0xC0) == 0x40 )
532 log_error <<
"data short do not fit" << std::endl;
537 log_error <<
"data short at " << buffer.
getOffset() <<
" before region header" << std::endl;
540 dataS = (dataC << 8);
543 addHit(laneId, bc, reg, (dataS & 0x3FFF));
545 else if ( (dataC & 0xC0) == 0x00)
549 log_error <<
"No data long would fit (at least a data short after region header!)" << std::endl;
554 log_error <<
"data short at " << buffer.
getOffset() <<
" before region header" << std::endl;
558 uint16_t addr = ((dataC & 0x3F) << 8) | ( (dataS >> 8) & 0xFF );
559 addHit(laneId, bc, reg, addr);
560 uint8_t hit_map = (dataS & 0xFF);
561 if ( hit_map & 0x80 )
563 log_error <<
"Wrong bit before DATA LONG bit map" << std::endl;
566 while( hit_map != 0x00 )
571 addHit(laneId, bc, reg, addr);
576 else if ( (dataC & 0xF0) == 0xB0 )
580 chip_trailer_found = 1;
581 busy_on = busy_off = chip_header_found = 0;
585 AlpideByteError(chipId, buffer);
590 if ( (dataC & 0xF0) == 0xA0 )
592 chip_header_found =
true;
593 chip_trailer_found =
false;
594 laneId = (dataC & 0x0F) % 3;
595 if (laneId != chipId )
597 log_error <<
"Error laneId " << laneId <<
" (" << (dataC & 0xF) <<
") and chipId " << chipId << std::endl;
603 else if ( dataC == 0x00 )
609 AlpideByteError(chipId, buffer);
621 #endif // _MVTX_DECODER_ITSMFT_GBTLINK_H_