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
|