File indexing completed on 2025-01-09 23:33:30
0001 #include <iomanip>
0002
0003 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0004 #include "FWCore/Utilities/interface/calculateCRC32.h"
0005
0006 #include "EventFilter/L1TRawToDigi/interface/AMCSpec.h"
0007
0008
0009
0010 namespace amc {
0011 BlockHeader::BlockHeader(unsigned int amc_no, unsigned int board_id, unsigned int size, unsigned int block) {
0012
0013 unsigned int max_block_no = 0;
0014 if (size >= 0x13ff)
0015 max_block_no = (size - 1023) / 4096;
0016
0017 if (block != max_block_no)
0018 size = split_block_size;
0019 else if (block != 0)
0020 size -= split_block_size * max_block_no;
0021
0022 data_ = (static_cast<uint64_t>(size & Size_mask) << Size_shift) |
0023 (static_cast<uint64_t>(block & BlkNo_mask) << BlkNo_shift) |
0024 (static_cast<uint64_t>(amc_no & AmcNo_mask) << AmcNo_shift) |
0025 (static_cast<uint64_t>(board_id & BoardID_mask) << BoardID_shift) | (1llu << Enabled_bit_shift) |
0026 (1llu << Present_bit_shift);
0027
0028 if (block == getBlocks() - 1) {
0029
0030 data_ |= (1llu << CRC_bit_shift) | (1llu << Valid_bit_shift) | (1llu << Length_bit_shift);
0031 }
0032
0033 if (block == 0 && getBlocks() == 1) {
0034
0035 } else if (block == 0) {
0036
0037 data_ |= 1llu << More_bit_shift;
0038 } else if (block == getBlocks() - 1) {
0039
0040 data_ |= 1llu << Segmented_bit_shift;
0041 } else {
0042
0043 data_ |= (1llu << More_bit_shift) | (1llu << Segmented_bit_shift);
0044 }
0045 }
0046
0047 unsigned int BlockHeader::getBlocks() const {
0048
0049
0050
0051 unsigned int size = getSize();
0052 if (size >= 0x13ff)
0053 return (size - 1023) / 4096 + 1;
0054 return 1;
0055 }
0056
0057 unsigned int BlockHeader::getBlockSize() const {
0058
0059
0060
0061 if (getMore() && !getSegmented())
0062 return split_block_size;
0063 return getSize();
0064 }
0065
0066 Header::Header(unsigned int amc_no,
0067 unsigned int lv1_id,
0068 unsigned int bx_id,
0069 unsigned int size,
0070 unsigned int or_n,
0071 unsigned int board_id,
0072 unsigned int user)
0073 : data0_((uint64_t(amc_no & AmcNo_mask) << AmcNo_shift) | (uint64_t(lv1_id & LV1ID_mask) << LV1ID_shift) |
0074 (uint64_t(bx_id & BX_mask) << BX_shift) | (uint64_t(size & Size_mask) << Size_shift)),
0075 data1_((uint64_t(or_n & OrN_mask) << OrN_shift) | (uint64_t(board_id & BoardID_mask) << BoardID_shift) |
0076 (uint64_t(user & User_mask) << User_shift)) {}
0077
0078 Trailer::Trailer(unsigned int crc, unsigned int lv1_id, unsigned int size)
0079 : data_((uint64_t(crc & CRC_mask) << CRC_shift) | (uint64_t(lv1_id & LV1ID_mask) << LV1ID_shift) |
0080 (uint64_t(size & Size_mask) << Size_shift)) {}
0081
0082 bool Trailer::check(unsigned int crc, unsigned int lv1_id, unsigned int size, bool mtf7_mode) const {
0083 if ((crc != getCRC() || size != getSize() || (lv1_id & LV1ID_mask) != getLV1ID()) && !mtf7_mode) {
0084 edm::LogWarning("L1T") << "Found AMC trailer with:"
0085 << "\n\tLV1 ID " << getLV1ID() << ", size " << getSize() << ", CRC " << std::hex
0086 << std::setw(8) << std::setfill('0') << getCRC() << std::dec << "\nBut expected:"
0087 << "\n\tLV1 ID " << (lv1_id & LV1ID_mask) << ", size " << size << ", CRC " << std::hex
0088 << std::setw(8) << std::setfill('0') << crc;
0089 return false;
0090 }
0091 return true;
0092 }
0093
0094 void Trailer::writeCRC(const uint64_t *start, uint64_t *end) {
0095 std::string_view dstring(reinterpret_cast<const char *>(start), reinterpret_cast<const char *>(end) + 4);
0096 auto crc = cms::calculateCRC32(dstring);
0097
0098 *end = ((*end) & ~(uint64_t(CRC_mask) << CRC_shift)) | (static_cast<uint64_t>(crc & CRC_mask) << CRC_shift);
0099 }
0100
0101 Packet::Packet(unsigned int amc,
0102 unsigned int board,
0103 unsigned int lv1id,
0104 unsigned int orbit,
0105 unsigned int bx,
0106 const std::vector<uint64_t> &load,
0107 unsigned int user)
0108 : block_header_(amc, board, load.size() + 3),
0109 header_(amc, lv1id, bx, load.size() + 3, orbit, board, user),
0110 trailer_(0, lv1id, load.size() + 3) {
0111 auto hdata = header_.raw();
0112 payload_.reserve(load.size() + 3);
0113 payload_.insert(payload_.end(), hdata.begin(), hdata.end());
0114 payload_.insert(payload_.end(), load.begin(), load.end());
0115 payload_.insert(payload_.end(), trailer_.raw());
0116
0117 auto ptr = payload_.data();
0118 Trailer::writeCRC(ptr, ptr + payload_.size() - 1);
0119 }
0120
0121 void Packet::addPayload(const uint64_t *data, unsigned int size) {
0122 payload_.insert(payload_.end(), data, data + size);
0123 }
0124
0125 void Packet::finalize(unsigned int lv1, unsigned int bx, bool legacy_mc, bool mtf7_mode) {
0126 if (legacy_mc) {
0127 header_ =
0128 Header(block_header_.getAMCNumber(), lv1, bx, block_header_.getSize(), 0, block_header_.getBoardID(), 0);
0129
0130 payload_.insert(payload_.begin(), {0, 0});
0131 payload_.insert(payload_.end(), {0});
0132 } else {
0133 header_ = Header(payload_.data());
0134 trailer_ = Trailer(&payload_.back());
0135
0136 std::string_view check(reinterpret_cast<const char *>(payload_.data()), payload_.size() * 8 - 4);
0137 auto crc = cms::calculateCRC32(check);
0138
0139 trailer_.check(crc, lv1, header_.getSize(), mtf7_mode);
0140 }
0141 }
0142
0143 std::span<const uint64_t> Packet::block(unsigned int id) const {
0144 if (id == 0 and id == block_header_.getBlocks() - 1) {
0145 return std::span<const uint64_t>(payload_);
0146 } else if (id == block_header_.getBlocks() - 1) {
0147 return std::span<const uint64_t>(payload_.begin() + id * split_block_size, payload_.end());
0148 } else {
0149 return std::span<const uint64_t>(payload_.begin() + id * split_block_size,
0150 payload_.begin() + (id + 1) * split_block_size);
0151 }
0152 }
0153 }