DUNE-DAQ
DUNE Trigger and Data Acquisition software
Loading...
Searching...
No Matches
emu_confgen.cxx File Reference
#include "logging/Logging.hpp"
#include <cstdint>
#include <cstdlib>
#include <fstream>
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
Include dependency graph for emu_confgen.cxx:

Go to the source code of this file.

Functions

uint64_t crc20 (uint64_t *data, uint64_t length, bool crc_new)
 
bool generateFm (uint64_t *emudata, uint64_t emusize, uint32_t req_chunksize, uint32_t pattern_id, uint32_t idle_chars, bool random_sz, bool crc_new, bool use_streamid, bool add_busy, bool omit_one_soc, bool omit_one_eoc, bool add_crc_err)
 
int main (int argc, char *argv[])
 

Variables

const constexpr uint64_t FM_KCHAR_IDLE = (((uint64_t)1 << 32) | 0xBC)
 
const constexpr uint64_t FM_KCHAR_SOP = (((uint64_t)1 << 32) | 0x3C)
 
const constexpr uint64_t FM_KCHAR_EOP = (((uint64_t)1 << 32) | 0xDC)
 
const constexpr uint64_t FM_KCHAR_SOB = (((uint64_t)1 << 32) | 0x5C)
 
const constexpr uint64_t FM_KCHAR_EOB = (((uint64_t)1 << 32) | 0x7C)
 
const constexpr uint64_t CRC_WIDTH = 20
 
const constexpr uint64_t CRC_MASK = ((1 << CRC_WIDTH) - 1)
 
const constexpr uint64_t CRC_POLYNOM_1 = 0xC1ACF
 
const constexpr uint64_t CRC_POLYNOM_2 = 0x8359F
 
const constexpr uint64_t CRC_INITVAL = 0xFFFFF
 
const constexpr uint64_t CHUNKHDR_SIZE = 8
 
const constexpr size_t EMU_SIZE = 8192
 

Detailed Description

Generates files tad can be loaded by flx-config

This is part of the DUNE DAQ , copyright 2020. Licensing/copyright details are in the COPYING file that you should have received with this code.

Definition in file emu_confgen.cxx.

Function Documentation

◆ crc20()

uint64_t crc20 ( uint64_t * data,
uint64_t length,
bool crc_new )

Definition at line 39 of file emu_confgen.cxx.

40{
41 // Initialize
42 uint64_t crc = CRC_INITVAL; // NOLINT
43 uint64_t polynomial; // NOLINT
44 if (crc_new) {
45 polynomial = CRC_POLYNOM_2;
46 } else {
47 polynomial = CRC_POLYNOM_1;
48 }
49
50 unsigned int i, k; // NOLINT
51 for (k = 0; k < CRC_WIDTH; ++k) {
52 if ((crc & 1)) {
53 crc = (crc >> 1) ^ ((1 << (CRC_WIDTH - 1)) | (polynomial >> 1));
54 } else {
55 crc = (crc >> 1);
56 }
57 }
58
59 // Calculate CRC
60 for (i = 0; i < length; i++) {
61 for (k = 1; k <= 32; k++) {
62 if (crc & (1 << (CRC_WIDTH - 1))) {
63 crc = ((crc << 1) | ((data[i] >> (32 - k)) & 1)) ^ polynomial;
64 } else {
65 crc = ((crc << 1) | ((data[i] >> (32 - k)) & 1));
66 }
67 }
68 crc &= CRC_MASK;
69 }
70
71 // One more loop
72 for (k = 0; k < CRC_WIDTH; k++) {
73 if (crc & (1 << (CRC_WIDTH - 1))) {
74 crc = (crc << 1) ^ polynomial;
75 } else {
76 crc = (crc << 1);
77 }
78 }
79 crc &= CRC_MASK;
80
81 return crc;
82}
const constexpr uint64_t CRC_POLYNOM_1
const constexpr uint64_t CRC_INITVAL
const constexpr uint64_t CRC_WIDTH
const constexpr uint64_t CRC_MASK
const constexpr uint64_t CRC_POLYNOM_2

◆ generateFm()

bool generateFm ( uint64_t * emudata,
uint64_t emusize,
uint32_t req_chunksize,
uint32_t pattern_id,
uint32_t idle_chars,
bool random_sz,
bool crc_new,
bool use_streamid,
bool add_busy,
bool omit_one_soc,
bool omit_one_eoc,
bool add_crc_err )

Definition at line 85 of file emu_confgen.cxx.

97{
98 // Initialize emudata to all zeroes
99 unsigned i; // NOLINT
100 for (i = 0; i < emusize; ++i) {
101 emudata[i] = 0;
102 }
103
104 // Determine the number of chunks that will fit
105 // (chunk size includes 8-byte header): 2 IDLEs, SOP, chunk, EOP
106 uint32_t max_chunkcnt = (emusize - 2) / (1 + req_chunksize / 4 + 1 + idle_chars); // NOLINT
107 uint32_t index = 0; // NOLINT
108 bool success = true;
109 // g_chunk_count = max_chunkcnt;
110
111 // Start with some IDLE symbols
112 emudata[index++] = FM_KCHAR_IDLE; // NOLINT(runtime/increment_decrement)
113 emudata[index++] = FM_KCHAR_IDLE; // NOLINT(runtime/increment_decrement)
114
115 // Multiple chunks
116 uint32_t next_index, chunkcntr = 0, chunksz, chunk_datasz; // NOLINT
117 while (index < emusize && chunkcntr < max_chunkcnt) {
118 if (random_sz && req_chunksize > 8) { // Size not less than 8
119 // Determine a random (data) size to use for the next chunk
120 // (here: size between req_chunksize/2 and req_chunksize,
121 // but rounded up to a multiple of 4 bytes)
122 uint32_t sz = (req_chunksize + 1) / 2; // NOLINT
123 double r = static_cast<double>(rand()) / RAND_MAX; // NOLINT
124 double d = 0.5 * static_cast<double>(1 - (req_chunksize & 1));
125 chunksz = ((sz + static_cast<uint32_t>(static_cast<double>(sz) * r + d) + 3) / 4) * 4; // NOLINT
126
127 } else {
128 chunksz = req_chunksize;
129 }
130
131 // Check if the next chunk will fit
132 // (chunksz includes header)
133 next_index = index + (1 + chunksz / 4 + 1);
134 if (next_index >= emusize) {
135 // It won't fit, so forget it: from here onwards fill with IDLEs
136 for (; index < emusize; ++index) {
137 emudata[index] = FM_KCHAR_IDLE;
138 }
139 // Should exit the while-loop on the basis of the chunk counter
140 // so we consider this an error...
141 success = false;
142 continue; // Jump to start of while-loop
143 }
144
145 // SOP
146 emudata[index++] = FM_KCHAR_SOP; // NOLINT
147 if (omit_one_soc && chunkcntr == 2) {
148 --index; // For testing
149 }
150
151 // Add chunk header
152 chunk_datasz = chunksz - CHUNKHDR_SIZE;
153 if (use_streamid) {
154 emudata[index++] = ((chunkcntr & 0xFF) | // Chunk counter = StreamID // NOLINT
155 (chunk_datasz & 0xF00) | ((chunk_datasz & 0x0FF) << 16) | ((chunkcntr & 0xFF) << 24));
156 } else {
157 emudata[index++] = // NOLINT
158 (0xAA | (chunk_datasz & 0xF00) | ((chunk_datasz & 0x0FF) << 16) | ((chunkcntr & 0xFF) << 24));
159 }
160
161 emudata[index++] = 0x10AABB00; // ewidth=0x10=16 bits // NOLINT
162
163 // Add chunk data according to 'pattern_id'
164 if (pattern_id == 1) {
165 for (i = 0; i < chunk_datasz / 4; ++i) {
166 emudata[index++] = 0xAA55AA55; // NOLINT
167 }
168 } else if (pattern_id == 2) {
169 for (i = 0; i < chunk_datasz / 4; ++i) {
170 emudata[index++] = 0xFFFFFFFF; // NOLINT
171 }
172 } else if (pattern_id == 3) {
173 for (i = 0; i < chunk_datasz / 4; ++i) {
174 emudata[index++] = 0x00000000; // NOLINT
175 }
176 } else {
177 unsigned int cntr = 0; // NOLINT
178 for (i = 0; i < chunk_datasz / 4; ++i, cntr += 4) {
179 emudata[index++] = // NOLINT
180 ((((cntr + 3) & 0xFF) << 24) | (((cntr + 2) & 0xFF) << 16) | (((cntr + 1) & 0xFF) << 8) |
181 (((cntr + 0) & 0xFF) << 0));
182 }
183 }
184
185 // EOP (+ 20-bits CRC)
186 uint64_t crc = crc20(&emudata[index - chunksz / 4], chunksz / 4, crc_new); // NOLINT
187
188 if (add_crc_err && chunkcntr == 3) {
189 ++crc; // For testing
190 }
191
192 emudata[index++] = FM_KCHAR_EOP | (crc << 8); // NOLINT
193
194 if (omit_one_eoc && chunkcntr == 2) {
195 --index; // For testing
196 }
197
198 if (add_busy && chunkcntr == 0) {
199 emudata[index++] = FM_KCHAR_SOB; // NOLINT
200 }
201
202 // A configurable number of comma symbols in between chunks
203 for (i = 0; i < idle_chars; ++i) {
204 emudata[index++] = FM_KCHAR_IDLE; // NOLINT
205 }
206
207 if (add_busy && chunkcntr == 0) {
208 emudata[index++] = FM_KCHAR_EOB; // NOLINT
209 }
210
211 ++chunkcntr;
212 }
213
214 // Fill any remaining uninitialised array locations with IDLE symbols
215 for (; index < emusize; ++index) {
216 emudata[index] = FM_KCHAR_IDLE;
217 }
218
219 // We expect to have generated max_chunkcnt chunks!
220 if (chunkcntr < max_chunkcnt) {
221 success = false;
222 }
223
224 return success;
225} // NOLINT(readability/fn_size)
uint64_t crc20(uint64_t *data, uint64_t length, bool crc_new)
const constexpr uint64_t CHUNKHDR_SIZE
const constexpr uint64_t FM_KCHAR_SOP
const constexpr uint64_t FM_KCHAR_IDLE
const constexpr uint64_t FM_KCHAR_EOB
const constexpr uint64_t FM_KCHAR_SOB
const constexpr uint64_t FM_KCHAR_EOP

◆ main()

int main ( int argc,
char * argv[] )

Definition at line 228 of file emu_confgen.cxx.

229{
230
231 // "-h", "--help", "--filename", "--emuSize", "--chunkSize", "--idles", "--pattern"
232
233 const std::vector<std::string> cmdArgs = { argv,
234 argv + argc }; // store arguments, options and flags from the command line
235
236 // set default values
237 uint32_t emusize = 8192; // NOLINT
238 uint32_t req_chunksize = 464; // NOLINT
239 uint32_t pattern_id = 0; // NOLINT
240 uint32_t idle_chars = 1; // NOLINT
241 bool random_sz = false;
242 bool crc_new = true;
243 bool use_streamid = false;
244 bool add_busy = false;
245 bool omit_one_soc = false;
246 bool omit_one_eoc = false;
247 bool add_crc_err = false;
248 std::string filename = "emuconfigreg";
249
250 // parse command line information
251 for (unsigned j = 0; j < cmdArgs.size(); j++) { // NOLINT
252 std::string arg = cmdArgs[j];
253 if (arg == "-h" || arg == "--help") {
254 std::ostringstream oss;
255 oss
256 << "\nThis app is used to create basic emulator configurations for the FELIX to use with flx-config. Usage: \n"
257 << " -h/--help : display help messege \n"
258 << " --filename : output configuration filename \n"
259 //<< " --emuSize : total number of lines of data \n"
260 << " --chunkSize : chunk sie of each block of data \n"
261 << " --idles : number of idle charachters between chunks \n"
262 << " --pattern : type of data to write \n"
263 << " 0 is incrimental \n"
264 << " 1 sets all to 0xAA55AA55 \n"
265 << " 2 sets all to 0xFFFFFFFF \n"
266 << " 3 sets all to 0x00000000";
267 TLOG() << oss.str();
268 exit(0);
269 } else if (arg == "--filename") {
270 // get input file name, then print it
271 if (j >= cmdArgs.size() - 1) // check if the arguement is at the end of the line without an input
272 {
273 TLOG() << "No file name was specified";
274 break;
275 }
276 filename = cmdArgs[j + 1];
277
278 //} else if (arg == "--emuSize") {
279 // if (j >= cmdArgs.size() - 1) {
280 // TLOG() << "No value was specified \n";
281 // break;
282 // }
283 // emusize = std::stoi(cmdArgs[j + 1]);
284
285 } else if (arg == "--chunkSize") {
286 if (j >= cmdArgs.size() - 1) {
287 TLOG() << "No value was specified";
288 break;
289 }
290 req_chunksize = std::stoi(cmdArgs[j + 1]);
291
292 } else if (arg == "--idles") {
293 if (j >= cmdArgs.size() - 1) {
294 TLOG() << "No value was specified";
295 break;
296 }
297 idle_chars = std::stoi(cmdArgs[j + 1]);
298
299 } else if (arg == "--pattern") {
300 if (j >= cmdArgs.size() - 1) {
301 TLOG() << "No value was specified";
302 break;
303 }
304 pattern_id = std::stoi(cmdArgs[j + 1]);
305 }
306 }
307 // TLOG() << "number of lines : " << emusize;
308 TLOG() << "chunk size : " << req_chunksize;
309 TLOG() << "idle characters : " << idle_chars;
310 TLOG() << "pattern type : " << pattern_id;
311
312 filename += "_" + std::to_string(req_chunksize) + "_" + std::to_string(idle_chars) + "_" + std::to_string(pattern_id);
313 TLOG() << "output file : " << filename;
314
315 uint64_t emudata[EMU_SIZE]; // NOLINT
316 std::ofstream output;
317 output.open(filename);
318
319 generateFm(emudata,
320 emusize,
321 req_chunksize,
322 pattern_id,
323 idle_chars,
324 random_sz,
325 crc_new,
326 use_streamid,
327 add_busy,
328 omit_one_soc,
329 omit_one_eoc,
330 add_crc_err);
331
332 for (unsigned i = 0; i < emusize; i++) { // NOLINT
333 output << "FE_EMU_CONFIG_WRADDR=0x" << std::hex << i << std::endl;
334 output << "FE_EMU_CONFIG_WRDATA=0x" << std::hex << emudata[i] << std::endl;
335 output << "FE_EMU_CONFIG_WE=1" << std::endl;
336 output << "FE_EMU_CONFIG_WE=0" << std::endl;
337 }
338
339 output.close();
340
341 TLOG() << "Config file written.";
342
343} // NOLINT(readability/fn_size)
bool generateFm(uint64_t *emudata, uint64_t emusize, uint32_t req_chunksize, uint32_t pattern_id, uint32_t idle_chars, bool random_sz, bool crc_new, bool use_streamid, bool add_busy, bool omit_one_soc, bool omit_one_eoc, bool add_crc_err)
const constexpr size_t EMU_SIZE
#define TLOG(...)
Definition macro.hpp:22

Variable Documentation

◆ CHUNKHDR_SIZE

const constexpr uint64_t CHUNKHDR_SIZE = 8
constexpr

Definition at line 33 of file emu_confgen.cxx.

◆ CRC_INITVAL

const constexpr uint64_t CRC_INITVAL = 0xFFFFF
constexpr

Definition at line 30 of file emu_confgen.cxx.

◆ CRC_MASK

const constexpr uint64_t CRC_MASK = ((1 << CRC_WIDTH) - 1)
constexpr

Definition at line 27 of file emu_confgen.cxx.

◆ CRC_POLYNOM_1

const constexpr uint64_t CRC_POLYNOM_1 = 0xC1ACF
constexpr

Definition at line 28 of file emu_confgen.cxx.

◆ CRC_POLYNOM_2

const constexpr uint64_t CRC_POLYNOM_2 = 0x8359F
constexpr

Definition at line 29 of file emu_confgen.cxx.

◆ CRC_WIDTH

const constexpr uint64_t CRC_WIDTH = 20
constexpr

Definition at line 26 of file emu_confgen.cxx.

◆ EMU_SIZE

const constexpr size_t EMU_SIZE = 8192
constexpr

Definition at line 36 of file emu_confgen.cxx.

◆ FM_KCHAR_EOB

const constexpr uint64_t FM_KCHAR_EOB = (((uint64_t)1 << 32) | 0x7C)
constexpr

Definition at line 23 of file emu_confgen.cxx.

◆ FM_KCHAR_EOP

const constexpr uint64_t FM_KCHAR_EOP = (((uint64_t)1 << 32) | 0xDC)
constexpr

Definition at line 21 of file emu_confgen.cxx.

◆ FM_KCHAR_IDLE

const constexpr uint64_t FM_KCHAR_IDLE = (((uint64_t)1 << 32) | 0xBC)
constexpr

Definition at line 19 of file emu_confgen.cxx.

◆ FM_KCHAR_SOB

const constexpr uint64_t FM_KCHAR_SOB = (((uint64_t)1 << 32) | 0x5C)
constexpr

Definition at line 22 of file emu_confgen.cxx.

◆ FM_KCHAR_SOP

const constexpr uint64_t FM_KCHAR_SOP = (((uint64_t)1 << 32) | 0x3C)
constexpr

Definition at line 20 of file emu_confgen.cxx.