17 #include "CLHEP/Random/RandFlat.h" 27 os <<
"Dump of the '" <<
name <<
"' words:\n";
28 for (
size_t i = 0;
i < vec.size(); ++
i)
29 os <<
std::dec << std::setfill(
' ') << std::setw(4) <<
i <<
": 0x" << std::hex << std::setfill(
'0')
30 << std::setw(
sizeof(
T) * 2) << vec.at(
i) <<
"\n";
33 static std::vector<uint64_t>
to64bit(
const std::vector<uint32_t>&
in) {
34 std::vector<uint64_t>
out;
35 for (
size_t i = 0;
i <
in.size();
i += 2) {
36 uint64_t word1 = (
i <
in.size()) ?
in.at(
i) : 0ul, word2 = (
i + 1 <
in.size()) ?
in.at(
i + 1) : 0ul;
37 out.emplace_back(((word2 & 0xffffffff) << 32) | (word1 & 0xffffffff));
42 static std::vector<uint64_t>
to128bit(
const std::vector<uint64_t>&
in) {
43 std::vector<uint64_t>
out;
44 for (
size_t i = 0;
i <
in.size();
i += 2) {
45 out.emplace_back(
in.at(
i));
46 out.emplace_back((
i + 1 <
in.size()) ?
in.at(
i + 1) : 0u);
55 std::vector<unsigned int> active_econds;
56 for (
const auto& econd : slink_config.getParameter<std::vector<edm::ParameterSet> >(
"ECONDs")) {
58 if (slink_config.getParameter<
bool>(
"checkECONDsLimits")) {
61 <<
"Too many active ECON-D set: " << active_econds.size() <<
" > " <<
kMaxNumECONDs <<
".";
64 <<
"Invalid ECON-D identifier: " << econd_id <<
" >= " <<
kMaxNumECONDs <<
".";
66 if (econd.getParameter<
bool>(
"active"))
67 active_econds.emplace_back(econd_id);
74 .boe_marker = slink_config.getParameter<
unsigned int>(
"boeMarker"),
75 .eoe_marker = slink_config.getParameter<
unsigned int>(
"eoeMarker"),
76 .format_version = slink_config.getParameter<
unsigned int>(
"formatVersion"),
77 .num_capture_blocks = slink_config.getParameter<
unsigned int>(
"numCaptureBlocks"),
78 .store_header_trailer = slink_config.getParameter<
bool>(
"storeHeaderTrailer")};
84 std::vector<edm::ParameterSet> econds_psets;
85 for (
size_t i = 0;
i < 7; ++
i)
86 econds_psets.emplace_back();
90 ->
setComment(
"list of active ECON-Ds in S-link");
91 slink_desc.
add<
unsigned int>(
"boeMarker", 0x55);
92 slink_desc.
add<
unsigned int>(
"eoeMarker", 0xaa);
93 slink_desc.
add<
unsigned int>(
"formatVersion", 3);
94 slink_desc.
add<
unsigned int>(
"numCaptureBlocks", 1)
95 ->setComment(
"number of capture blocks to emulate per S-link payload");
96 slink_desc.
add<
bool>(
"checkECONDsLimits",
true)->setComment(
"check the maximal number of ECON-Ds per S-link");
97 slink_desc.
add<
bool>(
"storeHeaderTrailer",
true)->setComment(
"also store the S-link header and trailer words");
113 throw cms::Exception(
"HGCalFrameGenerator") <<
"Random number generator not initialised.";
117 .
bitO = CLHEP::RandFlat::shoot(
rng_) < econd_params.error_prob.bitO,
118 .bitB = CLHEP::RandFlat::shoot(
rng_) < econd_params.error_prob.bitB,
119 .bitE = CLHEP::RandFlat::shoot(
rng_) < econd_params.error_prob.bitE,
120 .bitT = CLHEP::RandFlat::shoot(
rng_) < econd_params.error_prob.bitT,
121 .bitH = CLHEP::RandFlat::shoot(
rng_) < econd_params.error_prob.bitH,
122 .bitS = CLHEP::RandFlat::shoot(
rng_) < econd_params.error_prob.bitS,
129 for (
size_t i = 0;
i < chmap.size();
i++)
131 chmap[
i] = CLHEP::RandFlat::shoot(
rng_) <= econd_params.chan_surv_prob;
136 unsigned int econd_id,
138 std::vector<econd::ERxChannelEnable>& enabled_channels)
const {
140 std::vector<uint32_t> erx_data;
141 enabled_channels.clear();
142 for (
const auto& jt : input_event) {
147 uint8_t
stat = 0b111 , hamming_check = 0;
150 erx_data.insert(erx_data.end(), erx_header.begin(), erx_header.end());
151 if (jt.second.adc.size() < econd_params.num_channels_per_erx) {
153 <<
"Data multiplicity too low (" << jt.second.adc.size() <<
") to emulate " 154 << econd_params.num_channels_per_erx <<
" ECON-D channel(s).";
163 econd_params.characterisation_mode);
164 erx_data.insert(erx_data.end(), erx_chan_data.begin(), erx_chan_data.end());
165 enabled_channels.emplace_back(chmap);
172 uint32_t crc = 0x12345678;
183 <<
"ECON-D emulator was not properly set to the frame generator. Please ensure you are calling the " 184 "HGCalFrameGenerator::setEmulator method.";
186 std::vector<uint64_t> econd_event;
191 std::vector<econd::ERxChannelEnable> enabled_ch_per_erx;
195 const uint8_t hamming = 0,
rr = 0;
198 erx_payload.size() + 1 ,
199 econd_params.passthrough_mode,
200 econd_params.expected_mode,
202 (header_bits.bitH & 0x1) << 1 | (header_bits.bitT & 0x1),
203 (header_bits.bitE & 0x1) << 2 | (header_bits.bitB & 0x1) << 1 |
204 (header_bits.bitO & 0x1),
205 econd_params.matching_ebo_numbers,
206 econd_params.bo_truncated,
208 std::get<1>(
event.first),
209 std::get<0>(
event.first),
210 std::get<2>(
event.first),
213 LogDebug(
"HGCalFrameGenerator").log([&econd_header](
auto&
log) {
printWords(
log,
"econ-d header", econd_header); });
214 auto econd_header_64bit =
to64bit(econd_header);
215 econd_event.insert(econd_event.end(), econd_header_64bit.begin(), econd_header_64bit.end());
216 LogDebug(
"HGCalFrameGenerator") << econd_header.size()
217 <<
" word(s) of event packet header prepend. New size of ECON frame: " 218 << econd_event.size();
219 const auto erx_payload_64bit =
to64bit(erx_payload);
220 econd_event.insert(econd_event.end(), erx_payload_64bit.begin(), erx_payload_64bit.end());
221 LogDebug(
"HGCalFrameGenerator") << erx_payload.size() <<
" word(s) of eRx payloads inserted.";
223 std::vector<uint64_t> econd_footer;
224 if (econd_params.add_econd_crc)
225 econd_footer.emplace_back(
computeCRC(econd_header));
226 if (econd_params.add_idle_word) {
227 const uint8_t buffer_status = 0, error_status = 0, reset_request = 0;
228 econd_footer.emplace_back(
229 econd::buildIdleWord(buffer_status, error_status, reset_request, econd_params.programmable_pattern));
231 econd_event.insert(econd_event.end(), econd_footer.begin(), econd_footer.end());
241 enabled_ch_per_erx));
247 std::vector<uint64_t> cb_event;
251 const auto& econd_id = econd.first;
252 if (!econd.second.active)
254 econd_statuses[econd_id] =
257 cb_event.insert(cb_event.end(), econd_payload.begin(), econd_payload.end());
260 const uint64_t event_id = std::get<0>(
eid), bx_id = std::get<1>(
eid), orbit_id = std::get<2>(
eid);
264 cb_event.insert(cb_event.begin(), l1a_header.begin(), l1a_header.end());
271 std::vector<uint64_t> slink_event;
274 slink_event.insert(slink_event.end(),
283 const uint64_t event_id = std::get<0>(
eid), bx_id = std::get<1>(
eid), orbit_id = std::get<2>(
eid);
286 slink_event.insert(slink_event.begin(), slink_header.begin(), slink_header.end());
289 const bool fed_crc_err =
false, slinkrocket_crc_err =
false, source_id_err =
false, sync_lost =
false,
290 fragment_trunc =
false;
294 const uint16_t daq_crc = 0, crc = 0;
295 const uint32_t event_length = slink_event.size() - slink_header.size() - 1;
298 slink_event.insert(slink_event.end(), slink_trailer.begin(), slink_trailer.end());
300 LogDebug(
"HGCalFrameGenerator").log([&slink_header, &slink_trailer](
auto&
log) {
void setComment(std::string const &value)
T getParameter(std::string const &) const
econd::ECONDInput last_emul_event_
ParameterDescriptionBase * addVPSet(U const &iLabel, ParameterSetDescription const &validator, std::vector< ParameterSet > const &defaults)
unsigned int format_version
std::map< unsigned int, econd::EmulatorParameters > econd_params_
std::vector< uint64_t > produceECONEvent(unsigned int econd_id, unsigned int cb_id=0) const
void setEmulator(econd::Emulator &)
Set the emulation source for ECON-D frames.
std::vector< uint32_t > produceERxData(const ERxChannelEnable &, const ERxData &, bool passZS, bool passZSm1, bool hasToA, bool char_mode)
std::vector< uint32_t > buildCaptureBlockHeader(uint32_t bunch_crossing, uint32_t event_counter, uint32_t orbit_counter, const std::vector< ECONDPacketStatus > &econd_statuses)
std::vector< uint32_t > eRxSubPacketHeader(uint8_t stat, uint8_t ham, bool bitE, uint16_t common_mode0, uint16_t common_mode1, const ERxChannelEnable &channel_enable)
HeaderBits generateStatusBits(unsigned int) const
CLHEP::HepRandomEngine * rng_
std::vector< uint64_t > produceCaptureBlockEvent(unsigned int cb_id) const
std::map< ERxId_t, ERxData > ERxInput
eRx data maps
uint32_t buildSlinkContentId(SlinkEmulationFlag, uint8_t l1a_subtype, uint16_t l1a_fragment_cnt)
std::vector< uint32_t > generateERxData(unsigned int, const econd::ERxInput &, std::vector< econd::ERxChannelEnable > &) const
HGCalCaptureBlockEmulatorInfo & captureBlockEmulatedInfo(unsigned int)
Log< level::Error, false > LogError
econd::ERxChannelEnable generateEnabledChannels(unsigned int) const
std::vector< bool > ERxChannelEnable
list of channels enabled in eRx
std::vector< uint64_t > produceSlinkEvent(unsigned int fed_id) const
Produce a S-link event from an emulated event.
Pure virtual base class for a ECON-D event emulator implementation.
unsigned int num_capture_blocks
static std::vector< uint64_t > to128bit(const std::vector< uint64_t > &in)
static edm::ParameterSetDescription description()
List of S-link operational parameters for emulation.
std::vector< unsigned int > active_econds
ParameterDescriptionBase * add(U const &iLabel, T const &value)
std::vector< uint32_t > buildSlinkHeader(uint8_t boe, uint8_t v, uint64_t global_event_id, uint32_t content_id, uint32_t fed_id)
uint32_t computeCRC(const std::vector< uint32_t > &) const
32bit CRC
uint32_t buildIdleWord(uint8_t bufStat, uint8_t err, uint8_t rr, uint32_t progPattern)
HGCalSlinkEmulatorInfo last_slink_emul_info_
virtual ECONDInput next()=0
Fetch the next ECON-D event.
uint16_t buildSlinkRocketStatus(bool fed_crc_err, bool slinkrocket_crc_err, bool source_id_err, bool sync_lost, bool fragment_trunc)
static edm::ParameterSetDescription description()
unsigned long long uint64_t
void addECONDEmulatedInfo(unsigned int, const HGCalECONDEmulatorInfo &)
void setRandomEngine(CLHEP::HepRandomEngine &rng)
Set the random number generator engine.
std::vector< uint32_t > buildSlinkTrailer(uint8_t eoe, uint16_t daqcrc, uint32_t event_length, uint16_t bxid, uint32_t orbit_id, uint16_t crc, uint16_t status)
static std::vector< uint64_t > to64bit(const std::vector< uint32_t > &in)
HGCalFrameGenerator(const edm::ParameterSet &)
bool store_header_trailer
SlinkParameters slink_params_
void printWords(edm::MessageSender &os, const std::string &name, const std::vector< T > vec)
std::vector< uint32_t > eventPacketHeader(uint16_t header, uint16_t payload, bool bitP, bool bitE, uint8_t ht, uint8_t ebo, bool bitM, bool bitT, uint8_t hamming, uint16_t bx, uint16_t l1a, uint8_t orb, bool bitS, uint8_t RR)
static constexpr size_t kMaxNumECONDs