Skip to content

Commit 6517ee7

Browse files
authored
Merge pull request #47276 from cramonal/CRCatUnpacker
HGCAL: ECON D CRC (trailer) computation in the Unpacker
2 parents 0308cd8 + 7ea089a commit 6517ee7

File tree

7 files changed

+83
-9
lines changed

7 files changed

+83
-9
lines changed

DataFormats/HGCalDigi/interface/HGCalECONDPacketInfoSoA.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,8 @@ namespace hgcaldigi {
4141
// 0b100: No ECOND packet. The event builder state machine timed-out.
4242
// 0b101: No ECOND packet due to BCID and/or OrbitID mismatch.
4343
// 0b110: No ECOND packet. Packet was detected but was discarded due to Main Buffer overflow.
44-
SOA_COLUMN(uint8_t, cbFlag), //cbflag
44+
// 0b111: ECOND CRC trailer error.
45+
SOA_COLUMN(uint16_t, cbFlag), //cbflag
4546
// ECON-D header information
4647
// bit 0: Truncation flag
4748
// bit 1: Match flag

DataFormats/HGCalDigi/interface/HGCalRawDataDefinitions.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@ namespace hgcal {
1313
namespace backend {
1414
namespace ECONDPacketStatus {
1515
constexpr uint8_t Normal = 0x0, PayloadTooLarge = 0x1, PayloadCRCError = 0x2, EventIDMismatch = 0x3,
16-
EBTimeout = 0x4, BCIDOrbitIDMismatch = 0x5, MainBufferOverflow = 0x6, InactiveECOND = 0x7;
16+
EBTimeout = 0x4, BCIDOrbitIDMismatch = 0x5, MainBufferOverflow = 0x6, InactiveECOND = 0x7,
17+
OfflinePayloadCRCError = 0x8;
1718
} // namespace ECONDPacketStatus
1819
} // namespace backend
1920

@@ -25,7 +26,8 @@ namespace hgcal {
2526
EHCRC_MASK = 0xff, EHCRC_POS = 0, ERXSTAT_POS = 29, ERXSTAT_MASK = 0x7, ERXHAM_POS = 26,
2627
ERXHAM_MASK = 0x7, ERXFORMAT_POS = 25, ERXFORMAT_MASK = 0x1, COMMONMODE0_POS = 15,
2728
COMMONMODE0_MASK = 0x3ff, COMMONMODE1_POS = 5, COMMONMODE1_MASK = 0x3ff, CHMAP32_POS = 0,
28-
CHMAP32_MASK = 0x1f, CHMAP0_POS = 0, CHMAP0_MASK = 0xffffffff, ERX_E_POS = 4, ERX_E_MASK = 1;
29+
CHMAP32_MASK = 0x1f, CHMAP0_POS = 0, CHMAP0_MASK = 0xffffffff, ERX_E_POS = 4, ERX_E_MASK = 1,
30+
CRC_POL = 0x4c11db7, CRC_INITREM = 0x0, CRC_FINALXOR = 0x0;
2931
} // namespace ECOND_FRAME
3032

3133
namespace BACKEND_FRAME {

EventFilter/HGCalRawToDigi/BuildFile.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
<use name="DataFormats/HGCalDigi"/>
55
<use name="FWCore/ParameterSet"/>
66
<use name="clhep"/>
7+
<use name="boost"/>
78
<export>
89
<lib name="1"/>
910
</export>

EventFilter/HGCalRawToDigi/interface/HGCalUnpacker.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include "CondFormats/HGCalObjects/interface/HGCalMappingModuleIndexer.h"
1919
#include "CondFormats/HGCalObjects/interface/HGCalConfiguration.h"
2020
#include "FWCore/Utilities/interface/Exception.h"
21+
#include "EventFilter/HGCalRawToDigi/interface/UnpackerTools.h"
2122

2223
#include <cstdint>
2324
#include <functional>
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#ifndef EventFilter_HGCalRawToDigi_interface_UnpackerTools_h
2+
#define EventFilter_HGCalRawToDigi_interface_UnpackerTools_h
3+
#include "DataFormats/HGCalDigi/interface/HGCalRawDataDefinitions.h"
4+
5+
#include <string>
6+
7+
namespace hgcal {
8+
9+
/**
10+
@short this function re-computes the CRC of the ECON-D packet and compares it with the trailer of the packet
11+
false is returned if there is a mismatch
12+
*/
13+
bool econdCRCAnalysis(const uint64_t *header, const uint32_t pos, const uint32_t payloadLength);
14+
15+
} // namespace hgcal
16+
17+
#endif

EventFilter/HGCalRawToDigi/src/HGCalUnpacker.cc

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
#include "CondFormats/HGCalObjects/interface/HGCalMappingCellIndexer.h"
88
#include "FWCore/MessageLogger/interface/MessageLogger.h"
99
#include "FWCore/Utilities/interface/Exception.h"
10-
10+
#include "EventFilter/HGCalRawToDigi/interface/UnpackerTools.h"
1111
#include <array>
1212

1313
using namespace hgcal;
@@ -152,12 +152,21 @@ uint8_t HGCalUnpacker::parseFEDData(unsigned fedId,
152152
<< "), got 0x" << econd_headers[0] << ".";
153153
return UNPACKER_STAT::WrongECONDHeader;
154154
}
155+
const auto econd_payload_length = ((econd_headers[0] >> ECOND_FRAME::PAYLOAD_POS) & ECOND_FRAME::PAYLOAD_MASK);
156+
// Compute ECON-D trailer CRC
157+
bool crcvalid = hgcal::econdCRCAnalysis(ptr, 0, econd_payload_length);
158+
LogDebug("[HGCalUnpacker]") << "crc value " << crcvalid;
155159
++ptr;
156160

157-
econdPacketInfo.view()[ECONDdenseIdx].cbFlag() = (uint8_t)(econd_pkt_status);
161+
if (!crcvalid) {
162+
econd_pkt_status |=
163+
backend::ECONDPacketStatus::OfflinePayloadCRCError; //If CRC errors in the trailer, update the pkt status
164+
}
165+
166+
econdPacketInfo.view()[ECONDdenseIdx].cbFlag() = (uint16_t)(econd_pkt_status);
167+
158168
// ECON-D payload length (num of 32b words)
159169
// NOTE: in the capture blocks, ECON-D packets do not have the trailing IDLE word
160-
const auto econd_payload_length = ((econd_headers[0] >> ECOND_FRAME::PAYLOAD_POS) & ECOND_FRAME::PAYLOAD_MASK);
161170
if (econd_payload_length > 469) {
162171
econdPacketInfo.view()[ECONDdenseIdx].exception() = 4;
163172
edm::LogWarning("[HGCalUnpacker]")
@@ -180,12 +189,13 @@ uint8_t HGCalUnpacker::parseFEDData(unsigned fedId,
180189
<< ", econdIdx = " << econdIdx << ", econd_headers = " << std::hex
181190
<< std::setfill('0') << std::setw(8) << econd_headers[0] << " " << econd_headers[1]
182191
<< std::dec << ", econd_payload_length = " << econd_payload_length;
183-
184-
//quality check for ECON-D (no need to check again econd_pkt_status here again)
192+
//quality check for ECON-D (check econd_pkt_status here for error in trailer CRC)
185193
if ((((econd_headers[0] >> ECOND_FRAME::HT_POS) & ECOND_FRAME::HT_MASK) >= 0b10) ||
186194
(((econd_headers[0] >> ECOND_FRAME::EBO_POS) & ECOND_FRAME::EBO_MASK) >= 0b10) ||
187195
(((econd_headers[0] >> ECOND_FRAME::BITM_POS) & 0b1) == 0) ||
188-
(((econd_headers[0] >> ECOND_FRAME::BITM_POS) & 0b1) == 0) || econd_payload_length == 0 || headerOnlyMode) {
196+
(((econd_headers[0] >> ECOND_FRAME::BITM_POS) & 0b1) == 0) || econd_payload_length == 0 ||
197+
econd_pkt_status == backend::ECONDPacketStatus::OfflinePayloadCRCError ||
198+
econd_pkt_status == backend::ECONDPacketStatus::InactiveECOND || headerOnlyMode) {
189199
continue;
190200
}
191201

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
#include "EventFilter/HGCalRawToDigi/interface/UnpackerTools.h"
2+
#include "DataFormats/HGCalDigi/interface/HGCalRawDataDefinitions.h"
3+
#include <boost/crc.hpp>
4+
#include <vector>
5+
#include <iostream>
6+
//
7+
//
8+
9+
bool hgcal::econdCRCAnalysis(const uint64_t *header, const uint32_t pos, const uint32_t payloadLength) {
10+
int index = 0;
11+
std::vector<uint32_t> data32b; // reading 32-bit words, input is 64b
12+
13+
while (data32b.size() < payloadLength + 2) {
14+
uint64_t word = *(header + pos + index); // move to ECOND header
15+
data32b.push_back(word >> 32); // Reading first 32b
16+
17+
if (data32b.size() == payloadLength + 2)
18+
break;
19+
data32b.push_back(word & 0xFFFFFFFF); //read second 32b
20+
++index;
21+
}
22+
23+
auto target = data32b.back(); // CRC in ECOND trailer
24+
25+
//Compute CRC using all eRx subpackets but not the event paket header (two first words)
26+
std::vector<uint32_t> crcvec(data32b.begin() + 2, data32b.end() - 1);
27+
std::transform(crcvec.begin(), crcvec.end(), crcvec.begin(), [](uint32_t w) {
28+
return ((w << 24) & 0xFF000000) | ((w << 8) & 0x00FF0000) | ((w >> 8) & 0x0000FF00) |
29+
((w >> 24) & 0x000000FF); //swapping endianness
30+
});
31+
32+
auto array = &(crcvec[0]);
33+
auto bytes = reinterpret_cast<const unsigned char *>(array);
34+
auto crc32 = boost::crc<32,
35+
hgcal::ECOND_FRAME::CRC_POL,
36+
hgcal::ECOND_FRAME::CRC_INITREM,
37+
hgcal::ECOND_FRAME::CRC_FINALXOR,
38+
false,
39+
false>(bytes, (payloadLength - 1) * 4); //32-bit words, hence need to parse 4 bytes
40+
41+
return crc32 == target;
42+
}

0 commit comments

Comments
 (0)