CMS 3D CMS Logo

AMC13Spec.cc
Go to the documentation of this file.
1 #include <iomanip>
2 #include <map>
3 
7 
9 
10 #define EDM_ML_DEBUG 1
11 
12 namespace amc13 {
13  Header::Header(unsigned int namc, unsigned int orbit) {
14  data_ = (static_cast<uint64_t>(namc & nAMC_mask) << nAMC_shift) |
15  (static_cast<uint64_t>(orbit & OrN_mask) << OrN_shift) |
16  (static_cast<uint64_t>(fov & uFOV_mask) << uFOV_shift);
17  }
18 
19  bool Header::check() const { return (getNumberOfAMCs() <= max_amc) && (getFormatVersion() == fov); }
20 
21  Trailer::Trailer(unsigned int blk, unsigned int lv1, unsigned int bx) {
22  data_ = (static_cast<uint64_t>(blk & BlkNo_mask) << BlkNo_shift) |
23  (static_cast<uint64_t>(lv1 & LV1_mask) << LV1_shift) | (static_cast<uint64_t>(bx & BX_mask) << BX_shift);
24  }
25 
26  bool Trailer::check(unsigned int crc, unsigned int block, unsigned int lv1_id, unsigned int bx) const {
27  if ((crc != 0 && crc != getCRC()) || block != getBlock() || (lv1_id & LV1_mask) != getLV1ID() ||
28  (bx & BX_mask) != getBX()) {
29  edm::LogWarning("L1T") << "Found AMC13 trailer with:"
30  << "\n\tBX " << getBX() << ", LV1 ID " << getLV1ID() << ", block # " << getBlock()
31  << ", CRC " << std::hex << std::setw(8) << std::setfill('0') << getCRC() << std::dec
32  << "\nBut expected:"
33  << "\n\tBX " << (bx & BX_mask) << ", LV1 ID " << (lv1_id & LV1_mask) << ", block # "
34  << block << ", CRC " << std::hex << std::setw(8) << std::setfill('0') << crc;
35  return false;
36  }
37  return true;
38  }
39 
41  std::string dstring(reinterpret_cast<const char*>(start), reinterpret_cast<const char*>(end) + 4);
42  auto crc = cms::CRC32Calculator(dstring).checksum();
43 
44  *end = ((*end) & ~(uint64_t(CRC_mask) << CRC_shift)) | (static_cast<uint64_t>(crc & CRC_mask) << CRC_shift);
45  }
46 
47  void Packet::add(unsigned int amc_no,
48  unsigned int board,
49  unsigned int lv1id,
50  unsigned int orbit,
51  unsigned int bx,
52  const std::vector<uint64_t>& load,
53  unsigned int user) {
54  edm::LogInfo("AMC") << "Adding board " << board << " with payload size " << load.size() << " as payload #"
55  << amc_no;
56  // Start by indexing with 1
57  payload_.push_back(amc::Packet(amc_no, board, lv1id, orbit, bx, load, user));
58  }
59 
61  const uint64_t* data,
62  unsigned int size,
63  unsigned int lv1,
64  unsigned int bx,
65  bool legacy_mc,
66  bool mtf7_mode) {
67  // Need at least a header and trailer
68  // TODO check if this can be removed
69  if (size < 2) {
70  edm::LogError("AMC") << "AMC13 packet size too small";
71  return false;
72  }
73 
74  std::map<int, int> amc_index;
75 
76  header_ = Header(data++);
77 
78  if (!header_.check()) {
79  edm::LogError("AMC") << "Invalid header for AMC13 packet: "
80  << "format version " << header_.getFormatVersion() << ", " << header_.getNumberOfAMCs()
81  << " AMC packets";
82  return false;
83  }
84 
85  if (size < 2 + header_.getNumberOfAMCs())
86  return false;
87 
88  // Initial filling of AMC payloads. First, get the headers. The
89  // first payload follows afterwards.
90  for (unsigned int i = 0; i < header_.getNumberOfAMCs(); ++i) {
91  payload_.push_back(amc::Packet(data++));
92  amc_index[payload_.back().blockHeader().getAMCNumber()] = i;
93  }
94 
95  unsigned int tot_size = 0; // total payload size
96  unsigned int tot_nblocks = 0; // total blocks of payload
97  unsigned int maxblocks = 0; // counting the # of amc13 header/trailers (1 ea per block)
98 
99  bool check_crc = false;
100  for (const auto& amc : payload_) {
101  tot_size += amc.blockHeader().getSize();
102  tot_nblocks += amc.blockHeader().getBlocks();
103  maxblocks = std::max(maxblocks, amc.blockHeader().getBlocks());
104 
105  if (amc.blockHeader().validCRC())
106  check_crc = true;
107  }
108 
109  unsigned int words = tot_size + // payload size
110  tot_nblocks + // AMC headers
111  2 * maxblocks; // AMC13 headers
112 
113  if (size < words) {
114  edm::LogError("L1T") << "Encountered AMC 13 packet with " << size << " words, "
115  << "but expected " << words << " words: " << tot_size << " payload words, " << tot_nblocks
116  << " AMC header words, and 2 AMC 13 header words.";
117  return false;
118  }
119 
120  // Read in the first AMC block and append the payload to the
121  // corresponding AMC packet.
122  for (auto& amc : payload_) {
123  amc.addPayload(data, amc.blockHeader().getBlockSize());
124  data += amc.blockHeader().getBlockSize();
125  }
126 
127  Trailer t(data++);
128 
129  int crc = 0;
130  if (check_crc) {
131  std::string check(reinterpret_cast<const char*>(start), reinterpret_cast<const char*>(data) - 4);
133 
134  LogDebug("L1T") << "checking data checksum of " << std::hex << crc << std::dec;
135  }
136 
137  t.check(crc, 0, lv1, bx);
138 
139  // Read in remaining AMC blocks
140  for (unsigned int b = 1; b < maxblocks; ++b) {
141  Header block_h(data++);
142  std::vector<amc::BlockHeader> headers;
143 
144  for (unsigned int i = 0; i < block_h.getNumberOfAMCs(); ++i)
145  headers.push_back(amc::BlockHeader(data++));
146 
147  check_crc = false;
148  for (const auto& amc : headers) {
149  payload_[amc_index[amc.getAMCNumber()]].addPayload(data, amc.getBlockSize());
150  data += amc.getBlockSize();
151 
152  if (amc.validCRC())
153  check_crc = true;
154  }
155 
156  t = Trailer(data++);
157 
158  if (check_crc) {
159  std::string check(reinterpret_cast<const char*>(start), reinterpret_cast<const char*>(data) - 4);
161 
162  LogDebug("L1T") << "checking data checksum of " << std::hex << crc << std::dec;
163  } else {
164  crc = 0;
165  }
166 
167  t.check(crc, b, lv1, bx);
168  }
169 
170  for (auto& amc : payload_) {
171  amc.finalize(lv1, bx, legacy_mc, mtf7_mode);
172  }
173 
174  return true;
175  }
176 
177  unsigned int Packet::blocks() const {
178  unsigned int maxblocks = 0;
179 
180  for (const auto& amc : payload_)
181  maxblocks = std::max(maxblocks, amc.blocks());
182 
183  return maxblocks;
184  }
185 
186  unsigned int Packet::size() const {
187  unsigned int words = 0;
188  unsigned int blocks = 0;
189  unsigned int maxblocks = 0;
190 
191  for (const auto& amc : payload_) {
192  words += amc.header().getSize();
193  blocks += amc.blocks();
194  maxblocks = std::max(maxblocks, amc.blocks());
195  }
196 
197  // Size is total amount of words + # of blocks for AMC headers + # of
198  // maxblocks for AMC13 block header, trailer
199  return words + blocks + maxblocks * 2;
200  }
201 
202  bool Packet::write(const edm::Event& ev, unsigned char* ptr, unsigned int skip, unsigned int size) const {
203  if (size < this->size() * 8)
204  return false;
205 
206  if (size % 8 != 0)
207  return false;
208 
209  uint64_t* data = reinterpret_cast<uint64_t*>(ptr + skip);
210 
211  for (unsigned int b = 0; b < blocks(); ++b) {
212  // uint64_t * block_start = data;
213 
214  std::vector<uint64_t> block_headers;
215  std::vector<uint64_t> block_load;
216  for (const auto& amc : payload_) {
217  edm::LogInfo("AMC") << "Considering block " << b << " for payload " << amc.blockHeader().getBoardID()
218  << " with size " << amc.size() << " and " << amc.blocks() << " blocks";
219  if (amc.blocks() < b + 1)
220  continue;
221 
222  block_headers.push_back(amc.blockHeader(b));
223  auto words = amc.block(b);
224  block_load.insert(block_load.end(), words.begin(), words.end());
225  }
226 
227  if (b == 0) {
228  amc13::Header h(block_headers.size(), ev.orbitNumber());
229  edm::LogInfo("AMC") << "Writing header for AMC13 packet: "
230  << "format version " << h.getFormatVersion() << ", " << h.getNumberOfAMCs()
231  << " AMC packets, orbit " << h.getOrbitNumber();
232  }
233 
234  *(data++) = amc13::Header(block_headers.size(), ev.orbitNumber()).raw();
235 
236  block_headers.insert(block_headers.end(), block_load.begin(), block_load.end());
237  for (const auto& word : block_headers)
238  *(data++) = word;
239 
240  *data = Trailer(b, ev.id().event(), ev.bunchCrossing()).raw();
241  Trailer::writeCRC(reinterpret_cast<uint64_t*>(ptr), data);
242  }
243 
244  return true;
245  }
246 } // namespace amc13
size
Write out results.
Definition: start.py:1
Header header_
Definition: AMC13Spec.h:92
static const unsigned int OrN_shift
Definition: AMC13Spec.h:33
static const unsigned int LV1_mask
Definition: AMC13Spec.h:62
static void writeCRC(const uint64_t *start, uint64_t *end)
Definition: AMC13Spec.cc:40
bool check() const
Definition: AMC13Spec.cc:19
static const unsigned int fov
Definition: AMC13Spec.h:36
static const unsigned int nAMC_mask
Definition: AMC13Spec.h:32
static const unsigned int CRC_mask
Definition: AMC13Spec.h:58
static const unsigned int BlkNo_mask
Definition: AMC13Spec.h:60
unsigned int getLV1ID() const
Definition: AMC13Spec.h:49
static const unsigned int BX_mask
Definition: AMC13Spec.h:64
void add(unsigned int amc_no, unsigned int board, unsigned int lv1id, unsigned int orbit, unsigned int bx, const std::vector< uint64_t > &load, unsigned int user=0)
Definition: AMC13Spec.cc:47
unsigned int getBX() const
Definition: AMC13Spec.h:50
Log< level::Error, false > LogError
uint64_t data_
Definition: AMC13Spec.h:39
bool write(const edm::Event &ev, unsigned char *ptr, unsigned int skip, unsigned int size) const
Definition: AMC13Spec.cc:202
Trailer(const uint64_t *data)
Definition: AMC13Spec.h:44
unsigned int size() const
Definition: AMC13Spec.cc:186
std::vector< amc::Packet > payload_
Definition: AMC13Spec.h:96
uint64_t word
uint64_t data_
Definition: AMC13Spec.h:66
static const unsigned int uFOV_shift
Definition: AMC13Spec.h:29
static const unsigned int BX_shift
Definition: AMC13Spec.h:63
static const unsigned int uFOV_mask
Definition: AMC13Spec.h:30
bool check(unsigned int crc, unsigned int block, unsigned int lv1_id, unsigned int bx) const
Definition: AMC13Spec.cc:26
unsigned int getBlock() const
Definition: AMC13Spec.h:48
Log< level::Info, false > LogInfo
static const unsigned int max_amc
Definition: AMC13Spec.h:37
unsigned long long uint64_t
Definition: Time.h:13
unsigned int getFormatVersion() const
Definition: AMC13Spec.h:24
def load(fileName)
Definition: svgfig.py:547
bool parse(const uint64_t *start, const uint64_t *data, unsigned int size, unsigned int lv1, unsigned int bx, bool legacy_mc=false, bool mtf7_mode=false)
Definition: AMC13Spec.cc:60
double b
Definition: hdecay.h:120
static const unsigned int nAMC_shift
Definition: AMC13Spec.h:31
static const unsigned int LV1_shift
Definition: AMC13Spec.h:61
static const unsigned int BlkNo_shift
Definition: AMC13Spec.h:59
char data[epos_bytes_allocation]
Definition: EPOS_Wrapper.h:80
unsigned int blocks() const
Definition: AMC13Spec.cc:177
static const unsigned int CRC_shift
Definition: AMC13Spec.h:57
Log< level::Warning, false > LogWarning
std::uint32_t checksum()
Definition: AMCSpec.h:8
The Signals That Services Can Subscribe To This is based on ActivityRegistry h
Helper function to determine trigger accepts.
Definition: Activities.doc:4
unsigned int getNumberOfAMCs() const
Definition: AMC13Spec.h:25
unsigned int getCRC() const
Definition: AMC13Spec.h:47
static const unsigned int OrN_mask
Definition: AMC13Spec.h:34
#define LogDebug(id)