Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2025-02-26 04:25:13

0001 #ifndef EventFilter_Utilities_DTHHeaders_h
0002 #define EventFilter_Utilities_DTHHeaders_h
0003 
0004 #include <array>
0005 #include <cstddef>
0006 #include <cstdint>
0007 
0008 /*
0009  * DTH Orbit header, event fragment trailer and SlinkRocket Header and Trailer accompanying
0010  * slink payload. Format that is sent is is low-endian for multi-byte fields
0011  *
0012  * Version 1 DTH and Version 3 SLinkRocket
0013  *
0014  * */
0015 
0016 namespace evf {
0017   constexpr uint32_t SLR_MAX_EVENT_LEN = (1 << 20) - 1;
0018   constexpr std::array<uint8_t, 2> DTHOrbitMarker{{0x48, 0x4f}};            //HO
0019   constexpr std::array<uint8_t, 2> DTHFragmentTrailerMarker{{0x54, 0x46}};  //TF
0020   constexpr uint32_t DTH_WORD_NUM_BYTES_SHIFT = 4;
0021   constexpr uint32_t SLR_WORD_NUM_BYTES_SHIFT = 4;
0022 
0023   class DTHOrbitHeader_v1 {
0024   public:
0025     DTHOrbitHeader_v1(uint32_t source_id,
0026                       uint32_t run_number,
0027                       uint32_t orbit_number,
0028                       uint16_t event_count,
0029                       uint32_t packed_word_count,
0030                       uint32_t flags,
0031                       uint32_t crc)
0032         : source_id_(source_id),
0033           run_number_(run_number),
0034           orbit_number_(orbit_number),
0035           event_count_(event_count),
0036           packed_word_count_(packed_word_count),
0037           crc32c_(crc) {
0038       flags_.all_ = flags;
0039     }
0040 
0041     uint16_t version() const { return version_; }
0042     uint32_t sourceID() const { return source_id_; }
0043     uint32_t runNumber() const { return run_number_; }
0044     uint32_t orbitNumber() const { return orbit_number_; }
0045     uint16_t eventCount() const { return event_count_; }
0046     uint32_t packed_word_count() const { return packed_word_count_; }
0047     uint32_t flags() const { return flags_.all_; }
0048     uint32_t crc() const { return crc32c_; }
0049 
0050     uint64_t totalSize() const { return uint64_t(packed_word_count_) << DTH_WORD_NUM_BYTES_SHIFT; }
0051     uint64_t payloadSizeBytes() const { return totalSize() - sizeof(DTHOrbitHeader_v1); }
0052     uint64_t headerSize() const { return sizeof(DTHOrbitHeader_v1); }
0053     const void* payload() const { return (uint8_t*)this + sizeof(DTHOrbitHeader_v1); }
0054     bool verifyMarker() const {
0055       for (size_t i = 0; i < DTHOrbitMarker.size(); i++) {
0056         if (marker_[i] != DTHOrbitMarker[i])
0057           return false;
0058       }
0059       return true;
0060     }
0061 
0062     bool verifyChecksum() const;
0063 
0064   private:
0065     std::array<uint8_t, 2> marker_ = DTHOrbitMarker;
0066     uint16_t version_ = 1;  //bytes: 01 00
0067     uint32_t source_id_;
0068     uint32_t run_number_;
0069     uint32_t orbit_number_;
0070     uint32_t event_count_ : 12, res_ : 20;
0071     uint32_t packed_word_count_;  //Total size encoded in multiples of 128 bits (16 bytes)
0072     union {
0073       struct {
0074         uint32_t error_flag_ : 1, res_flags_ : 31;
0075       } bits_;
0076       uint32_t all_;
0077     } flags_;
0078     uint32_t crc32c_;
0079   };
0080 
0081   class DTHFragmentTrailer_v1 {
0082   public:
0083     DTHFragmentTrailer_v1(uint16_t flags, uint32_t payload_word_count, uint64_t event_id, uint16_t crc)
0084         : payload_word_count_(payload_word_count), event_id_(event_id), crc_(crc) {
0085       flags_.all_ = flags;
0086     }
0087 
0088     uint64_t eventID() const { return event_id_; }
0089     uint32_t payloadWordCount() const { return payload_word_count_; }
0090     uint64_t payloadSizeBytes() const { return uint64_t(payload_word_count_) << DTH_WORD_NUM_BYTES_SHIFT; }
0091     uint16_t flags() const { return flags_.all_; }
0092     uint16_t crc() const { return crc_; }
0093     const void* payload() const { return (uint8_t*)this - payloadSizeBytes(); }
0094     bool verifyMarker() const {
0095       for (size_t i = 0; i < DTHFragmentTrailerMarker.size(); i++) {
0096         if (marker_[i] != DTHFragmentTrailerMarker[i])
0097           return false;
0098       }
0099       return true;
0100     }
0101 
0102   private:
0103     std::array<uint8_t, 2> marker_ = DTHFragmentTrailerMarker;
0104     union {
0105       struct {
0106         uint16_t fed_crc_error_ : 1, slink_crc_error_ : 1, source_id_error_ : 1, fragment_cut_ : 1,
0107             event_id_sync_error_ : 1, fragment_timout_ : 1, fragment_length_error_ : 1, res_ : 9;
0108       } bits_;
0109       uint16_t all_;
0110     } flags_;
0111     uint32_t
0112         payload_word_count_;  // Fragment size is encoded in multiples of 128 bits (16 bytes). I.e needs to be shifted by 4
0113     uint64_t event_id_ : 44, res_ : 4, crc_ : 16;
0114   };
0115 
0116   //SLinkExpress classes
0117 
0118   //begin and end event markers
0119   constexpr uint8_t SLR_BOE = 0x55;
0120   constexpr uint8_t SLR_EOE = 0xaa;
0121 
0122   //minimal SLinkRocket version overlay
0123   class SLinkRocketHeader_version {
0124   public:
0125     SLinkRocketHeader_version(uint8_t version, uint8_t res = 0) : res_(res), version_(version) {}
0126     uint8_t version() const { return version_; }
0127     bool verifyMarker() const { return boe_ == SLR_BOE; }
0128 
0129   private:
0130     uint8_t res_ : 4, version_ : 4;
0131     uint8_t boe_ = SLR_BOE;
0132   };
0133 
0134   class SLinkRocketHeader_v3 {
0135   public:
0136     SLinkRocketHeader_v3(uint32_t source_id, uint16_t l1a_types, uint8_t l1a_phys, uint8_t emu_status, uint64_t event_id)
0137         : source_id_(source_id),
0138           l1a_types_(l1a_types),
0139           phys_type_(l1a_phys),
0140           emu_status_(emu_status),
0141           event_id_(event_id) {}
0142 
0143     uint32_t sourceID() const { return source_id_; }
0144     uint16_t l1aTypes() const { return l1a_types_; }
0145     uint8_t l1aPhysType() const { return phys_type_; }
0146     uint8_t emuStatus() const { return emu_status_; }
0147     uint64_t globalEventID() const { return event_id_; }
0148     uint8_t version() const { return version_; }
0149     bool verifyMarker() const { return boe_ == SLR_BOE; }
0150 
0151   private:
0152     uint32_t source_id_;
0153     uint16_t l1a_types_;
0154     uint8_t phys_type_;
0155     uint8_t emu_status_ : 2, res1_ : 6;
0156     uint64_t event_id_ : 44, res2_ : 8, version_ : 4 = 3, boe_ : 8 = SLR_BOE;
0157   };
0158 
0159   class SLinkRocketTrailer_v3 {
0160   public:
0161     SLinkRocketTrailer_v3(
0162         uint16_t status, uint16_t crc, uint32_t orbit_id, uint16_t bx_id, uint32_t evtlen_word_count, uint16_t daq_crc)
0163         : crc_(crc), orbit_id_(orbit_id), bx_id_(bx_id), event_length_wcount_(evtlen_word_count), daq_crc_(daq_crc) {
0164       status_.all_ = status;
0165     }
0166 
0167     uint16_t status() const { return status_.all_; }
0168     uint16_t crc() const { return crc_; }
0169     uint32_t orbitID() const { return orbit_id_; }
0170     uint16_t bxID() const { return bx_id_; }
0171     uint32_t eventLenBytes() const { return uint32_t(event_length_wcount_) << SLR_WORD_NUM_BYTES_SHIFT; }
0172     uint16_t daqCRC() const { return daq_crc_; }
0173     bool verifyMarker() const { return eoe_ == SLR_EOE; }
0174 
0175   private:
0176     union {
0177       struct {
0178         uint16_t fed_crc_error_ : 1, /* FED CRC error was detected by DTH and corrected */
0179             slink_crc_error_ : 1, /* Set when the slink receviver finds a mistmatch between calculated crc and daq_crc. It should never happen */
0180             source_id_error_ : 1, /* SOURCE_ID is not expected */
0181             sync_lost_error_ : 1, /* Sync lost detected by DTH */
0182             fragment_cut_ : 1,    /* Fragment was cut */
0183             res_ : 11;
0184       } bits_;
0185       uint16_t all_;
0186     } status_;
0187     uint16_t crc_; /* CRC filled by the FED */
0188     uint32_t orbit_id_;
0189     uint32_t bx_id_ : 12,
0190         event_length_wcount_ : 20; /* Length is encoded in multiples of 128 bits (16 bytes). I.e needs to be shifter by 4 */
0191     uint32_t reserved_ : 8, daq_crc_ : 16, /* CRC filled by the slink sender */
0192         eoe_ : 8 = SLR_EOE;
0193   };
0194 
0195 }  // namespace evf
0196 
0197 #endif