Project
Loading...
Searching...
No Matches
GBTLink.cxx
Go to the documentation of this file.
1// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
2// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3// All rights not expressly granted are reserved.
4//
5// This software is distributed under the terms of the GNU General Public
6// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7//
8// In applying this license CERN does not waive the privileges and immunities
9// granted to it by virtue of its status as an Intergovernmental Organization
10// or submit itself to any jurisdiction.
11
14
15#include <bitset>
16#include <iomanip>
20#include "Framework/Logger.h"
22
23using namespace o2::itsmft;
24
27
31
34GBTLink::GBTLink(uint16_t _cru, uint16_t _fee, uint8_t _ep, uint8_t _idInCru, uint16_t _chan) : idInCRU(_idInCru), cruID(_cru), feeID(_fee), endPointID(_ep), channelID(_chan)
35{
36 chipStat.feeID = _fee;
37 statistics.feeID = _fee;
38}
39
42std::string GBTLink::describe() const
43{
44 std::string ss = fmt::format("link cruID:{:#06x}/lID{} feeID:{:#06x}", cruID, int(idInCRU), feeID);
45 if (lanes) {
46 ss += fmt::format(" lanes {}", std::bitset<28>(lanes).to_string());
47 }
48 return ss;
49}
50
53void GBTLink::clear(bool resetStat, bool resetTFRaw)
54{
55 data.clear();
56 lastPageSize = 0;
57 nTriggers = 0;
58 lanes = 0;
60 packetCounter = -1;
61 errorBits = 0;
62 irHBF.clear();
63 if (resetTFRaw) {
64 rawData.clear();
65 dataOffset = 0;
66 gbtErrStatUpadated = false;
67 rofJumpWasSeen = false;
69 ir.clear();
70 }
71 // lastRDH = nullptr;
72 if (resetStat) {
74 }
75 hbfEntry = 0;
76 extTrigVec = nullptr;
77 status = None;
78}
79
81void GBTLink::printTrigger(const GBTTrigger* gbtTrg, int offs)
82{
83 std::bitset<12> trb(gbtTrg->triggerType);
84 LOG(info) << "Offs: " << offs << " Trigger : Orbit " << gbtTrg->orbit << " BC: " << gbtTrg->bc << " Trigger: " << trb << " noData:"
85 << gbtTrg->noData << " internal:" << gbtTrg->internal << " continuation:" << gbtTrg->continuation << " on " << describe();
86 gbtTrg->printX(expectPadding);
87}
88
90void GBTLink::printCalibrationWord(const GBTCalibration* gbtCal, int offs)
91{
92 LOGP(info, "Offs: {} Calibration word {:5} | user_data {:#08x} on {}", offs, gbtCal->calibCounter, gbtCal->calibUserField, describe());
93 gbtCal->printX(expectPadding);
94}
95
97void GBTLink::printHeader(const GBTDataHeader* gbtH, int offs)
98{
99 std::bitset<28> LA(gbtH->activeLanes);
100 LOG(info) << "Offs: " << offs << " Header : Active Lanes " << LA << " on " << describe();
101 gbtH->printX(expectPadding);
102}
103
105void GBTLink::printHeader(const GBTDataHeaderL* gbtH, int offs)
106{
107 std::bitset<28> LA(gbtH->activeLanesL);
108 LOG(info) << "Offs: " << offs << " HeaderL : Active Lanes " << LA << " on " << describe();
109 gbtH->printX(expectPadding);
110}
111
113void GBTLink::printTrailer(const GBTDataTrailer* gbtT, int offs)
114{
115 std::bitset<28> LT(gbtT->lanesTimeout), LS(gbtT->lanesStops); // RSTODO
116 LOG(info) << "Offs: " << offs << " Trailer: Done=" << gbtT->packetDone << " Lanes TO: " << LT << " | Lanes ST: " << LS << " on " << describe();
117 gbtT->printX(expectPadding);
118}
119
121void GBTLink::printDiagnostic(const GBTDiagnostic* gbtD, int offs)
122{
123 LOG(info) << "Offs: " << offs << " Diagnostic word on " << describe();
124 gbtD->printX(expectPadding);
125}
126
128void GBTLink::printCableDiagnostic(const GBTCableDiagnostic* gbtD)
129{
130 LOGP(info, "Diagnostic for {} Lane {} | errorID: {} data {:#018x} on {}", gbtD->isIB() ? "IB" : "OB", gbtD->getCableID(), gbtD->laneErrorID, gbtD->diagnosticData, describe());
131 gbtD->printX(expectPadding);
132}
133
135void GBTLink::printCableStatus(const GBTCableStatus* gbtS)
136{
137 LOGP(info, "Status data, not processed at the moment, on {}", describe());
138 gbtS->printX(expectPadding);
139}
140
142
143#ifdef _RAW_READER_ERROR_CHECKS_
144
147uint8_t GBTLink::checkErrorsRDH(const RDH& rdh)
148{
149 uint8_t err = uint8_t(NoError);
150 if (!RDHUtils::checkRDH(rdh, true)) {
152 gbtErrStatUpadated = true;
154 err |= uint8_t(ErrorPrinted);
156 }
158 err |= uint8_t(Abort);
159 return err; // fatal error
160 }
161 /*
162 // Note that an identical check is executed by default in the RawParser, currently disabled for ITS in the constructor of RawPixelDecoder
163 if (expectPadding && (RDHUtils::getPacketCounter(rdh) > packetCounter + 1) && packetCounter >= 0) { // packet counter check makes sense only for data with padding (no UL)
164 if (irHBF.isDummy()) {
165 irHBF = RDHUtils::getHeartBeatIR(rdh);
166 }
167 statistics.errorCounts[GBTLinkDecodingStat::ErrPacketCounterJump]++;
168 gbtErrStatUpadated = true;
169 if (needToPrintError(statistics.errorCounts[GBTLinkDecodingStat::ErrPacketCounterJump])) {
170 LOG(info) << describe() << ' ' << irHBF << ". " << statistics.ErrNames[GBTLinkDecodingStat::ErrPacketCounterJump]
171 << " : jump from " << int(packetCounter) << " to " << int(RDHUtils::getPacketCounter(rdh));
172 err |= uint8_t(ErrorPrinted);
173 }
174 errorBits |= 0x1 << int(GBTLinkDecodingStat::ErrPacketCounterJump);
175 err |= uint8_t(Warning);
176 }
177 packetCounter = RDHUtils::getPacketCounter(rdh);
178 */
179 return err;
180}
181
183uint8_t GBTLink::checkErrorsAlignmentPadding()
184{
185 uint8_t err = uint8_t(NoError);
188 gbtErrStatUpadated = true;
190 err |= uint8_t(ErrorPrinted);
191 LOG(info) << describe() << ". " << statistics.ErrNames[GBTLinkDecodingStat::ErrWrongAlignmentWord] << " at offset " << dataOffset << " for page size " << lastPageSize;
192 }
194 err |= uint8_t(Warning);
195 return err; // fatal error
196 }
197 return err;
198}
199
202uint8_t GBTLink::checkErrorsRDHStop(const RDH& rdh)
203{
204 uint8_t err = uint8_t(NoError);
205 if (lastRDH && RDHUtils::getHeartBeatOrbit(*lastRDH) != RDHUtils::getHeartBeatOrbit(rdh) // new HB starts
206 && !RDHUtils::getStop(*lastRDH)) {
208 gbtErrStatUpadated = true;
213 err |= uint8_t(ErrorPrinted);
214 }
216 err |= uint8_t(Warning);
217 }
218 return err;
219}
220
223uint8_t GBTLink::checkErrorsRDHStopPageEmpty(const RDH& rdh)
224{
225 uint8_t err = uint8_t(NoError);
226 if (RDHUtils::getStop(rdh) && RDHUtils::getMemorySize(rdh) != sizeof(RDH) + wordLength) { // there could be only 1 diagnostic GBTWord after stop
228 gbtErrStatUpadated = true;
232 err |= uint8_t(ErrorPrinted);
233 }
235 err |= uint8_t(Warning);
236 }
237 return err;
238}
239
242uint8_t GBTLink::checkErrorsTriggerWord(const GBTTrigger* gbtTrg)
243{
244 uint8_t err = uint8_t(NoError);
245 if (!gbtTrg->isTriggerWord()) { // check trigger word
247 gbtErrStatUpadated = true;
249 gbtTrg->printX(expectPadding);
251 err |= uint8_t(ErrorPrinted);
252 }
254 err |= uint8_t(Abort);
255 }
256 return err;
257}
258
261uint8_t GBTLink::checkErrorsCalibrationWord(const GBTCalibration* gbtCal)
262{
263 // at the moment do nothing
264 return uint8_t(NoError);
265}
266
269uint8_t GBTLink::checkErrorsHeaderWord(const GBTDataHeader* gbtH)
270{
271 uint8_t err = uint8_t(NoError);
272 if (!gbtH->isDataHeader()) { // check header word
274 gbtErrStatUpadated = true;
276 gbtH->printX(expectPadding);
278 err |= uint8_t(ErrorPrinted);
279 }
281 err |= uint8_t(Abort);
282 }
283 return err;
284}
285
288uint8_t GBTLink::checkErrorsHeaderWord(const GBTDataHeaderL* gbtH)
289{
290 uint8_t err = uint8_t(NoError);
291 if (!gbtH->isDataHeader()) { // check header word
293 gbtErrStatUpadated = true;
294 if (verbosity >= VerboseErrors) {
295 gbtH->printX(expectPadding);
297 err |= uint8_t(ErrorPrinted);
298 }
300 err |= uint8_t(Abort);
301 return err;
302 }
303 int cnt = RDHUtils::getPageCounter(*lastRDH);
304 // RSTODO: this makes sense only for old format, where every trigger has its RDH
305 if (gbtH->packetIdx != cnt) {
307 gbtErrStatUpadated = true;
309 LOG(info) << describe() << ' ' << irHBF << ". " << statistics.ErrNames[GBTLinkDecodingStat::ErrRDHvsGBTHPageCnt] << ": diff in GBT header "
310 << gbtH->packetIdx << " and RDH page " << cnt << " counters";
311 err |= uint8_t(ErrorPrinted);
312 }
314 err |= uint8_t(Warning);
315 return err;
316 }
317 // RSTODO CHECK
318 if (lanesActive == lanesStop) { // all lanes received their stop, new page 0 expected
319 //if (cnt) { // makes sens for old format only
320 if (gbtH->packetIdx) {
322 gbtErrStatUpadated = true;
325 << ": Non-0 page counter (" << cnt << ") while all lanes were stopped";
326 err |= uint8_t(ErrorPrinted);
327 }
329 err |= uint8_t(Warning);
330 }
331 }
332 return err;
333}
334
337uint8_t GBTLink::checkErrorsActiveLanes(int cbl)
338{
339 uint8_t err = uint8_t(NoError);
340 if (~cbl & lanesActive) { // are there wrong lanes?
342 gbtErrStatUpadated = true;
344 std::bitset<32> expectL(cbl), gotL(lanesActive);
346 << gotL << " vs " << expectL << " skip page";
347 err |= uint8_t(ErrorPrinted);
348 }
350 err |= uint8_t(Warning);
351 }
352 return err;
353}
354
357uint8_t GBTLink::checkErrorsGBTData(int cablePos)
358{
359 uint8_t err = uint8_t(NoError);
360 lanesWithData |= 0x1 << cablePos; // flag that the data was seen on this lane
361 if (lanesStop & (0x1 << cablePos)) { // make sure stopped lanes do not transmit the data
363 gbtErrStatUpadated = true;
365 LOG(info) << describe() << ' ' << irHBF << ". " << statistics.ErrNames[GBTLinkDecodingStat::ErrDataForStoppedLane] << cablePos;
366 err |= uint8_t(ErrorPrinted);
367 }
369 err |= uint8_t(Warning);
370 }
371
372 return err;
373}
374
377uint8_t GBTLink::checkErrorsGBTDataID(const GBTData* gbtD)
378{
379 if (gbtD->isData()) {
380 return uint8_t(NoError);
381 }
382 uint8_t err = uint8_t(NoError);
384 gbtErrStatUpadated = true;
386 if (gbtD->isCableDiagnostic()) {
387 printCableDiagnostic((GBTCableDiagnostic*)gbtD);
388 } else if (gbtD->isStatus()) {
389 printCableStatus((GBTCableStatus*)gbtD);
390 }
391 gbtD->printX(expectPadding);
393 err |= uint8_t(ErrorPrinted);
394 }
395 err |= uint8_t(Skip);
396 return err;
397}
398
401uint8_t GBTLink::checkErrorsTrailerWord(const GBTDataTrailer* gbtT)
402{
403 uint8_t err = uint8_t(NoError);
404 if (!gbtT->isDataTrailer()) {
405 gbtT->printX(expectPadding);
407 gbtErrStatUpadated = true;
410 err |= uint8_t(ErrorPrinted);
411 }
413 err |= uint8_t(Abort);
414 return err;
415 }
416 lanesTimeOut |= gbtT->lanesTimeout; // register timeouts
417 lanesStop |= gbtT->lanesStops; // register stops
418 return err;
419}
420
423uint8_t GBTLink::checkErrorsPacketDoneMissing(const GBTDataTrailer* gbtT, bool notEnd)
424{
425 uint8_t err = uint8_t(NoError);
426 if (!gbtT || (!gbtT->packetDone && notEnd)) { // Done may be missing only in case of carry-over to new CRU page
428 gbtErrStatUpadated = true;
431 err |= uint8_t(ErrorPrinted);
432 }
434 err |= uint8_t(Warning);
435 }
436 return err;
437}
438
441uint8_t GBTLink::checkErrorsLanesStops()
442{
443 // make sure all lane stops for finished page are received
444 uint8_t err = uint8_t(NoError);
445 if ((lanesActive & ~lanesStop)) {
446 if (RDHUtils::getTriggerType(*lastRDH) != o2::trigger::SOT) { // only SOT trigger allows unstopped lanes?
448 gbtErrStatUpadated = true;
450 std::bitset<32> active(lanesActive), stopped(lanesStop);
452 << " | active: " << active << " stopped: " << stopped;
453 err |= uint8_t(ErrorPrinted);
454 }
456 }
457 err |= uint8_t(Warning);
458 }
459 // make sure all active lanes (except those in time-out) have sent some data
462 gbtErrStatUpadated = true;
464 std::bitset<32> withData(lanesWithData), active(lanesActive), timeOut(lanesTimeOut);
466 << " | with data: " << withData << " active: " << active << " timeOut: " << timeOut;
467 err |= uint8_t(ErrorPrinted);
468 }
470 err |= uint8_t(Warning);
471 }
472 return err;
473}
474
477uint8_t GBTLink::checkErrorsDiagnosticWord(const GBTDiagnostic* gbtD)
478{
479 uint8_t err = uint8_t(NoError);
480 if (!gbtD->isDiagnosticWord() || (lastPageSize > sizeof(RDH) + CRUPageAlignment)) {
482 gbtErrStatUpadated = true;
484 gbtD->printX(expectPadding);
486 err |= uint8_t(ErrorPrinted);
487 }
489 err |= uint8_t(Abort);
490 }
491 return err;
492}
493
496uint8_t GBTLink::checkErrorsCableID(const GBTData* gbtD, uint8_t cableSW)
497{
498 uint8_t err = uint8_t(NoError);
499 if (cableSW == 0xff) {
501 gbtErrStatUpadated = true;
503 gbtD->printX(expectPadding);
504 LOG(info) << describe() << ' ' << irHBF << ". " << statistics.ErrNames[GBTLinkDecodingStat::ErrWrongeCableID] << ' ' << gbtD->getCableID();
505 err |= uint8_t(ErrorPrinted);
506 }
508 err |= uint8_t(Skip);
509 }
510 return err;
511}
512
515uint8_t GBTLink::checkErrorsIRNotExtracted()
516{
517 uint8_t err = uint8_t(NoError);
518 if (ir.isDummy()) {
520 gbtErrStatUpadated = true;
522 LOG(info) << describe() << " IR_RDH " << irHBF << " IR_ROF " << ir << ". " << statistics.ErrNames[GBTLinkDecodingStat::ErrMissingGBTTrigger];
523 }
525 err |= uint8_t(Abort);
526 }
527 return err;
528}
529
533{
535 gbtErrStatUpadated = true;
538 }
540}
541
542#endif
class for the ALPIDE data decoding/encoding
Definition of the 32 Central Trigger System (CTS) Trigger Types defined in https://twiki....
uint8_t channelID
Definition RawEventData.h:8
GLboolean * data
Definition glcorearb.h:298
uint8_t itsSharedClusterMap uint8_t
RAWDataHeaderV7 RAWDataHeader
constexpr uint32_t SOT
Definition Triggers.h:33
static int getCableID(uint8_t v)
Definition GBTWord.h:288
static constexpr std::array< std::string_view, NErrorsDefined > ErrNames
std::array< uint32_t, NErrorsDefined > errorCounts
uint64_t continuation
13 No data expected (too close to previous trigger or error)
Definition GBTWord.h:94
uint64_t activeLanesL
0:15 Index of Data Packet within trigger
Definition GBTWord.h:71
uint64_t lanesTimeout
0:27 Bit map of “Valid Lane stops received”, 1 bit per lane, NOT USED
Definition GBTWord.h:79
uint64_t noData
12 Used in Continuous Mode for internally generated trigger
Definition GBTWord.h:93
uint64_t internal
0:11 12 lowest bits of trigger type received from CTP
Definition GBTWord.h:92
uint64_t lanesStops
Definition GBTWord.h:78
uint64_t orbit
28:31 reserved
Definition GBTWord.h:98
bool isTriggerWord() const
check if the GBT Header corresponds to GBT trigger word
Definition GBTWord.h:133
uint64_t triggerType
Definition GBTWord.h:91
uint64_t activeLanes
Definition GBTWord.h:63
void printX(bool padded=true, std::string com="") const
Definition GBTWord.cxx:21
bool isDataHeader() const
check if the GBT Header corresponds to GBT payload header
Definition GBTWord.h:127
bool isDataTrailer() const
check if the GBT Header corresponds to GBT payload trailer
Definition GBTWord.h:130
bool isDiagnosticWord() const
check if the GBT Header corresponds to Diagnostic data
Definition GBTWord.h:136
uint64_t bc
15 reserved
Definition GBTWord.h:96
bool isCableDiagnostic() const
Definition GBTWord.h:159
bool isStatus() const
Definition GBTWord.h:161
uint64_t packetIdx
Definition GBTWord.h:70
bool isData() const
check if the GBT Header corresponds to ITS IB or OB data (header is combined with lanes/connector inf...
Definition GBTWord.h:157
uint64_t packetDone
56:63 reserved
Definition GBTWord.h:81
static void printRDH(const RDHv4 &rdh)
Definition RDHUtils.cxx:26
static bool checkRDH(const RDHv4 &rdh, bool verbose=true, bool checkZeros=false)
Definition RDHUtils.cxx:133
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"
o2::InteractionRecord ir(0, 0)