BlockHeader

Header

Packet

Trailer

Macros

Line Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169
#ifndef EventFilter_L1TRawToDigi_AMC_SPEC__h
#define EventFilter_L1TRawToDigi_AMC_SPEC__h

#include <memory>
#include <vector>
#include <cstdint>
#include <span>

namespace amc {
  static const unsigned int split_block_size = 0x1000;

  // The AMC header within an AMC13 payload block.  Should optimally only
  // be used when packing/unpacking AMC payloads into AMC13 blocks.
  class BlockHeader {
  public:
    BlockHeader() : data_(0) {}
    BlockHeader(const uint64_t *data) : data_(data[0]) {}
    // size is the total size of the AMC payload, not just of the
    // block
    BlockHeader(unsigned int amc_no, unsigned int board_id, unsigned int size, unsigned int block = 0);

    operator uint64_t() const { return data_; };

    inline uint64_t raw() const { return data_; };

    unsigned int getBlocks() const;
    unsigned int getBlockSize() const;

    inline unsigned int getAMCNumber() const { return (data_ >> AmcNo_shift) & AmcNo_mask; };
    inline unsigned int getBoardID() const { return (data_ >> BoardID_shift) & BoardID_mask; };
    inline unsigned int getSize() const { return (data_ >> Size_shift) & Size_mask; };
    inline unsigned int getMore() const { return (data_ >> More_bit_shift) & 1; };
    inline unsigned int getSegmented() const { return (data_ >> Segmented_bit_shift) & 1; };

    inline unsigned int validCRC() const { return (data_ >> CRC_bit_shift) & 1; };

  private:
    static const unsigned int Size_shift = 32;
    static const unsigned int Size_mask = 0xffffff;
    static const unsigned int BlkNo_shift = 20;
    static const unsigned int BlkNo_mask = 0xff;
    static const unsigned int AmcNo_shift = 16;
    static const unsigned int AmcNo_mask = 0xf;
    static const unsigned int BoardID_shift = 0;
    static const unsigned int BoardID_mask = 0xffff;

    static const unsigned int Length_bit_shift = 62;
    static const unsigned int More_bit_shift = 61;
    static const unsigned int Segmented_bit_shift = 60;
    static const unsigned int Enabled_bit_shift = 59;
    static const unsigned int Present_bit_shift = 58;
    static const unsigned int Valid_bit_shift = 57;
    static const unsigned int CRC_bit_shift = 56;

    uint64_t data_;
  };

  // The actual header attached to the AMC payload, also contained in the
  // AMC payload of an AMC13 packet/block.
  class Header {
  public:
    Header() : data0_(0), data1_(0) {}
    Header(const uint64_t *data) : data0_(data[0]), data1_(data[1]) {}
    Header(unsigned int amc_no,
           unsigned int lv1_id,
           unsigned int bx_id,
           unsigned int size,
           unsigned int or_n,
           unsigned int board_id,
           unsigned int user);

    inline unsigned int getAMCNumber() const { return (data0_ >> AmcNo_shift) & AmcNo_mask; };
    inline unsigned int getBoardID() const { return (data1_ >> BoardID_shift) & BoardID_mask; };
    inline unsigned int getLV1ID() const { return (data0_ >> LV1ID_shift) & LV1ID_mask; };
    inline unsigned int getBX() const { return (data0_ >> BX_shift) & BX_mask; };
    inline unsigned int getOrbitNumber() const { return (data1_ >> OrN_shift) & OrN_mask; };
    inline unsigned int getSize() const { return (data0_ >> Size_shift) & Size_mask; };
    inline unsigned int getUserData() const { return (data1_ >> User_shift) & User_mask; };

    std::vector<uint64_t> raw() const { return {data0_, data1_}; };

  private:
    static const unsigned int Size_shift = 0;
    static const unsigned int Size_mask = 0xfffff;
    static const unsigned int BX_shift = 20;
    static const unsigned int BX_mask = 0xfff;
    static const unsigned int LV1ID_shift = 32;
    static const unsigned int LV1ID_mask = 0xffffff;
    static const unsigned int AmcNo_shift = 56;
    static const unsigned int AmcNo_mask = 0xf;

    static const unsigned int BoardID_shift = 0;
    static const unsigned int BoardID_mask = 0xffff;
    static const unsigned int OrN_shift = 16;
    static const unsigned int OrN_mask = 0xffff;
    static const unsigned int User_shift = 32;
    static const unsigned int User_mask = 0xffffffff;

    uint64_t data0_;
    uint64_t data1_;
  };

  class Trailer {
  public:
    Trailer() : data_(0) {}
    Trailer(const uint64_t *data) : data_(data[0]) {}
    Trailer(unsigned int crc, unsigned int lv1_id, unsigned int size);

    inline unsigned int getCRC() const { return (data_ >> CRC_shift) & CRC_mask; };
    inline unsigned int getLV1ID() const { return (data_ >> LV1ID_shift) & LV1ID_mask; };
    inline unsigned int getSize() const { return (data_ >> Size_shift) & Size_mask; };

    uint64_t raw() const { return data_; }
    bool check(unsigned int crc, unsigned int lv1_id, unsigned int size, bool mtf7_mode = false) const;

    static void writeCRC(const uint64_t *start, uint64_t *end);

  private:
    static const unsigned int Size_shift = 0;
    static const unsigned int Size_mask = 0xfffff;
    static const unsigned int LV1ID_shift = 24;
    static const unsigned int LV1ID_mask = 0xff;
    static const unsigned int CRC_shift = 32;
    static const unsigned int CRC_mask = 0xffffffff;

    uint64_t data_;
  };

  class Packet {
  public:
    Packet(const uint64_t *d) : block_header_(d) {}
    Packet(unsigned int amc,
           unsigned int board,
           unsigned int lv1id,
           unsigned int orbit,
           unsigned int bx,
           const std::vector<uint64_t> &load,
           unsigned int user = 0);

    // Add payload fragment from an AMC13 block to the AMC packet
    void addPayload(const uint64_t *, unsigned int);
    // To be called after the last payload addition.  Removes header
    // and trailer from the actual paylod.  Also performs
    // cross-checks for data consistency.
    void finalize(unsigned int lv1, unsigned int bx, bool legacy_mc = false, bool mtf7_mode = false);

    std::span<const uint64_t> block(unsigned int id) const;
    std::span<const uint64_t> data() const {
      // Remove 3 words: 2 for the header, 1 for the trailer
      return payload_.empty() ? std::span<const uint64_t>() : std::span<const uint64_t>(payload_).subspan(2, size());
    };
    BlockHeader blockHeader(unsigned int block = 0) const { return block_header_; };
    Header header() const { return header_; };
    Trailer trailer() const { return trailer_; };

    inline unsigned int blocks() const { return block_header_.getBlocks(); };
    // Returns the size of the payload _without_ the headers
    inline unsigned int size() const { return payload_.size() - 3; };

  private:
    BlockHeader block_header_;
    Header header_;
    Trailer trailer_;

    std::vector<uint64_t> payload_;
  };
}  // namespace amc

#endif