4 #include <netinet/in.h>
5 #include <sys/socket.h>
21 #define NW_SEND_HEADER 6
22 #define NW_SEND_TRAILER 2
23 #define NW_RAW_HEADER 12
24 #define NW_RAW_TRAILER 2
29 #define NW_COPPER_HEADER 0
30 #define NW_B2L_HEADER 2
31 #define NW_B2L_TRAILER 1
32 #define NW_COPPER_TRAILER 0
34 #define NW_COPPER_HEADER 13
35 #define NW_B2L_HEADER 6
36 #define NW_B2L_TRAILER 3
37 #define NW_COPPER_TRAILER 3
42 unsigned short CalcCRC16LittleEndian(
unsigned short crc16,
const int buf[],
int nwords)
47 sprintf(err_buf,
"nwords value(%d) is invalid. Cannot calculate CRC16. Exiting...\n %s %s %d\n",
48 nwords, __FILE__, __PRETTY_FUNCTION__, __LINE__);
49 printf(
"%s", err_buf); fflush(stdout);
50 string err_str = err_buf;
54 const unsigned short CRC16Table0x1021[ 256 ] = {
55 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7,
56 0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF,
57 0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6,
58 0x9339, 0x8318, 0xB37B, 0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE,
59 0x2462, 0x3443, 0x0420, 0x1401, 0x64E6, 0x74C7, 0x44A4, 0x5485,
60 0xA56A, 0xB54B, 0x8528, 0x9509, 0xE5EE, 0xF5CF, 0xC5AC, 0xD58D,
61 0x3653, 0x2672, 0x1611, 0x0630, 0x76D7, 0x66F6, 0x5695, 0x46B4,
62 0xB75B, 0xA77A, 0x9719, 0x8738, 0xF7DF, 0xE7FE, 0xD79D, 0xC7BC,
64 0x48C4, 0x58E5, 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823,
65 0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969, 0xA90A, 0xB92B,
66 0x5AF5, 0x4AD4, 0x7AB7, 0x6A96, 0x1A71, 0x0A50, 0x3A33, 0x2A12,
67 0xDBFD, 0xCBDC, 0xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A,
68 0x6CA6, 0x7C87, 0x4CE4, 0x5CC5, 0x2C22, 0x3C03, 0x0C60, 0x1C41,
69 0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD, 0xAD2A, 0xBD0B, 0x8D68, 0x9D49,
70 0x7E97, 0x6EB6, 0x5ED5, 0x4EF4, 0x3E13, 0x2E32, 0x1E51, 0x0E70,
71 0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A, 0x9F59, 0x8F78,
73 0x9188, 0x81A9, 0xB1CA, 0xA1EB, 0xD10C, 0xC12D, 0xF14E, 0xE16F,
74 0x1080, 0x00A1, 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046, 0x6067,
75 0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 0xF35E,
76 0x02B1, 0x1290, 0x22F3, 0x32D2, 0x4235, 0x5214, 0x6277, 0x7256,
77 0xB5EA, 0xA5CB, 0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D,
78 0x34E2, 0x24C3, 0x14A0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
79 0xA7DB, 0xB7FA, 0x8799, 0x97B8, 0xE75F, 0xF77E, 0xC71D, 0xD73C,
80 0x26D3, 0x36F2, 0x0691, 0x16B0, 0x6657, 0x7676, 0x4615, 0x5634,
82 0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9, 0xB98A, 0xA9AB,
83 0x5844, 0x4865, 0x7806, 0x6827, 0x18C0, 0x08E1, 0x3882, 0x28A3,
84 0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A,
85 0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1, 0x1AD0, 0x2AB3, 0x3A92,
86 0xFD2E, 0xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9,
87 0x7C26, 0x6C07, 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1,
88 0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8,
89 0x6E17, 0x7E36, 0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0
92 int cnt = 0, nints = 0;
96 unsigned char temp_buf = *((
unsigned char*)(buf + nints) + (-(cnt % 4) + 3));
97 crc16 = CRC16Table0x1021[(crc16 >> (16 - CHAR_BIT)) ^ temp_buf ] ^ (crc16 << CHAR_BIT);
117 gettimeofday(&t, NULL);
118 return (t.tv_sec + t.tv_usec * 1.e-6 - 1417570000.);
121 int fillDataContents(
int* buf,
int nwords_per_fee,
unsigned int node_id,
int ncpr,
int nhslb,
int run)
123 int nwords = NW_SEND_HEADER + NW_SEND_TRAILER +
124 ncpr * (NW_RAW_HEADER + NW_COPPER_HEADER +
125 (NW_B2L_HEADER + NW_B2L_TRAILER + nwords_per_fee) * nhslb
126 + NW_COPPER_TRAILER + NW_RAW_TRAILER);
131 buf[ offset + 0 ] = nwords;
132 buf[ offset + 1 ] = 6;
133 buf[ offset + 2 ] = (1 << 16) | ncpr;
134 unsigned int exp_run = run << 8;
135 buf[ offset + 3 ] = exp_run;
136 buf[ offset + 5 ] = node_id;
141 for (
int k = 0; k < ncpr; k++) {
142 int top_pos = offset;
146 int cpr_nwords = NW_RAW_HEADER + NW_COPPER_HEADER +
147 (NW_B2L_HEADER + NW_B2L_TRAILER + nwords_per_fee) * nhslb
148 + NW_COPPER_TRAILER + NW_RAW_TRAILER;
149 int finesse_nwords = nwords_per_fee + NW_B2L_HEADER + NW_B2L_TRAILER;
150 unsigned int ctime = 0x12345601;
151 unsigned int utime = 0x98765432;
154 buf[ offset + 0 ] = cpr_nwords;
156 buf[ offset + 1 ] = 0x7f7f020c;
158 buf[ offset + 1 ] = 0x7f7f820c;
160 buf[ offset + 2 ] = exp_run;
161 printf(
"run_no %d\n", exp_run); fflush(stdout);
162 buf[ offset + 4 ] = ctime;
163 buf[ offset + 5 ] = utime;
164 buf[ offset + 6 ] = node_id + k;
165 buf[ offset + 7 ] = 0x34567890;
166 buf[ offset + 8 ] = NW_RAW_HEADER + NW_COPPER_HEADER;
167 buf[ offset + 9 ] = buf[ offset + 8 ] + finesse_nwords;
169 buf[ offset + 10 ] = buf[ offset + 9 ] + finesse_nwords;
171 buf[ offset + 10 ] = buf[ offset + 9 ];
174 buf[ offset + 11 ] = buf[ offset + 10 ] + finesse_nwords;
176 buf[ offset + 11 ] = buf[ offset + 10 ];
182 int top_pos_cpr = offset;
185 buf[ offset + 0 ] = 0x7fff0008;
186 buf[ offset + 2 ] = 0;
187 buf[ offset + 3 ] = 0;
188 buf[ offset + 4 ] = 0;
189 buf[ offset + 5 ] = 0;
190 buf[ offset + 6 ] = 0;
191 buf[ offset + 7 ] = 0xfffffafa;
192 buf[ offset + 8 ] = cpr_nwords - (NW_RAW_HEADER + 7 + 2 + NW_RAW_TRAILER);
193 buf[ offset + 9 ] = finesse_nwords;
196 buf[ offset + 10 ] = finesse_nwords;
198 buf[ offset + 11 ] = finesse_nwords;
200 buf[ offset + 12 ] = finesse_nwords;
202 buf[ offset + 12 ] = 0;
205 buf[ offset + 11 ] = 0;
206 buf[ offset + 12 ] = 0;
209 buf[ offset + 10 ] = 0;
210 buf[ offset + 11 ] = 0;
211 buf[ offset + 12 ] = 0;
219 for (
int i = 0; i < nhslb ; i++) {
221 buf[ offset + 0 ] = 0xffaa0000;
222 buf[ offset + 1 ] = ctime;
225 buf[ offset + 0 ] = 0xffaa0000;
226 buf[ offset + 1 ] = ctime;
227 buf[ offset + 3 ] = utime;
228 buf[ offset + 4 ] = exp_run;
229 buf[ offset + 5 ] = ctime;
233 for (
int j = offset; j < offset + nwords_per_fee; j++) {
236 offset += nwords_per_fee;
241 buf[ offset ] = ctime;
242 buf[ offset + 1 ] = 0;
243 buf[ offset + 2 ] = 0xff550000;
251 buf[ offset ] = 0xfffff5f5;
252 buf[ offset + 1 ] = buf[ top_pos_cpr ];
253 for (
int j = top_pos_cpr + 1; j < offset + 1; j++) {
254 buf[ offset + 1 ] ^= buf[ j ];
256 buf[ offset + 2 ] = 0x7fff0009;
259 buf[ offset ] = buf[ top_pos ];
260 for (
int j = top_pos + 1; j < offset; j++) {
261 buf[ offset ] ^= buf[ j ];
263 buf[ offset + 1 ] = 0x7fff0006;
269 buf[ offset + 1 ] = 0x7fff0000;
279 inline void addEvent(
int* buf,
int nwords_per_fee,
unsigned int event,
int ncpr,
int nhslb)
284 buf[ offset + 4 ] = event;
285 offset += NW_SEND_HEADER;
287 for (
int k = 0; k < ncpr; k++) {
288 int nwords = buf[ offset ];
289 int posback_xorchksum = 2;
290 int pos_xorchksum = offset + nwords - posback_xorchksum;
291 prev_offset = offset;
292 if (buf[ offset + 4 ] != 0x12345601) {
293 printf(
"[FATAL] data-production error 2 0x%.x", buf[ offset + 4 ]);
298 buf[ pos_xorchksum ] ^= buf[ offset + 3];
299 buf[ offset + 3] = event;
300 buf[ pos_xorchksum ] ^= buf[ offset + 3];
303 offset += NW_RAW_HEADER + NW_COPPER_HEADER +
304 nhslb * (NW_B2L_HEADER + nwords_per_fee + NW_B2L_TRAILER)
305 + NW_COPPER_TRAILER + NW_RAW_TRAILER;
307 int pos_xorchksum_cpr = offset + nwords - 4;
308 buf[ pos_xorchksum ] ^= buf[ pos_xorchksum_cpr ];
311 offset += NW_RAW_HEADER;
313 buf[ pos_xorchksum ] ^= buf[ offset + 1];
314 buf[ pos_xorchksum_cpr ] ^= buf[ offset + 1];
315 buf[ offset + 1 ] = event;
316 buf[ pos_xorchksum ] ^= buf[ offset + 1];
317 buf[ pos_xorchksum_cpr ] ^= buf[ offset + 1];
318 offset += NW_COPPER_HEADER;
320 for (
int i = 0; i < nhslb ; i++) {
321 if ((buf[ offset ] & 0xffff0000) != 0xffaa0000) {
322 printf(
"[FATAL] data-production error 3 : 0x%.x hslb %d cpr %d\n", buf[ offset ], i, k);
327 buf[ pos_xorchksum ] ^= buf[ offset + 0];
328 buf[ pos_xorchksum_cpr ] ^= buf[ offset + 0];
329 buf[ offset + 0 ] = 0xffaa0000 + (
event & 0xffff);
330 buf[ pos_xorchksum ] ^= buf[ offset + 0];
331 buf[ pos_xorchksum_cpr ] ^= buf[ offset + 0];
333 buf[ pos_xorchksum ] ^= buf[ offset + 2];
334 buf[ pos_xorchksum_cpr ] ^= buf[ offset + 2];
335 buf[ offset + 2 ] = event;
336 buf[ pos_xorchksum ] ^= buf[ offset + 2];
337 buf[ pos_xorchksum_cpr ] ^= buf[ offset + 2];
340 int* crc_buf = buf + offset + 1;
341 int crc_nwords = nwords_per_fee + 5;
342 unsigned short temp_crc16 = CalcCRC16LittleEndian(0xffff, crc_buf, crc_nwords);
343 buf[ pos_xorchksum ] ^= buf[ offset + NW_B2L_HEADER + nwords_per_fee + 1 ];
344 buf[ pos_xorchksum_cpr ] ^= buf[ offset + NW_B2L_HEADER + nwords_per_fee + 1 ];
345 buf[ offset + NW_B2L_HEADER + nwords_per_fee + 1 ] = ((
event & 0x0000ffff) << 16) | temp_crc16;
347 buf[ pos_xorchksum ] ^= buf[ offset + NW_B2L_HEADER + nwords_per_fee + 1 ];
348 buf[ pos_xorchksum_cpr ] ^= buf[ offset + NW_B2L_HEADER + nwords_per_fee + 1 ];
352 offset += NW_B2L_HEADER + nwords_per_fee + NW_B2L_TRAILER;
355 offset += NW_COPPER_TRAILER + NW_RAW_TRAILER;
356 unsigned int xor_chksum = 0;
357 unsigned int xor_chksum2 = 0;
359 buf[ pos_xorchksum ] ^= buf[ pos_xorchksum_cpr ];
368 int main(
int argc,
char** argv)
371 printf(
"###################################################\n");
373 printf(
"# Data after reduction (#define REDUCED_DATA) #\n");
375 printf(
"# Data before reduction (//#define REDUCED_DATA) #\n");
377 printf(
"###################################################\n");
381 printf(
"Usage : %s <node ID> <run#> <nwords of det. buf per FEE> <# of CPR per COPPER> <# of HSLBs>\n", argv[ 0 ]);
386 printf(
"Usage : %s <node ID> <run#> <nwords of det. buf per FEE> <# of CPR per COPPER> <# of HSLBs> <ropc hostname> <ropc port> argc %d\n",
392 unsigned int node_id = 0;
393 sscanf(argv[1],
"0x%x", &node_id);
396 int run_no = atoi(argv[2]);
399 int nwords_per_fee = atoi(argv[3]);
400 int ncpr = atoi(argv[4]);
401 int nhslb = atoi(argv[5]);
403 int listenfd, connfd;
404 struct sockaddr_in servaddr;
405 int total_words = NW_SEND_HEADER + NW_SEND_TRAILER +
406 ncpr * (NW_RAW_HEADER + NW_COPPER_HEADER + (NW_B2L_HEADER + NW_B2L_TRAILER + nwords_per_fee) * nhslb + NW_COPPER_TRAILER +
408 printf(
"TET %d %d %d %d %d\n ", NW_SEND_HEADER + NW_SEND_TRAILER, ncpr,
409 NW_RAW_HEADER + NW_COPPER_HEADER, (NW_B2L_HEADER + NW_B2L_TRAILER + nwords_per_fee) * nhslb, NW_COPPER_TRAILER + NW_RAW_TRAILER);
411 int buff[total_words];
417 int temp_ret = fillDataContents(buff, nwords_per_fee, node_id, ncpr, nhslb, run_no);
418 if (temp_ret != total_words) {
419 printf(
"[FATAL] data-production error %d %d\n", total_words, temp_ret);
426 listenfd = socket(AF_INET, SOCK_STREAM, 0);
427 memset(&servaddr, 0,
sizeof(servaddr));
428 servaddr.sin_family = AF_INET;
429 servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
430 servaddr.sin_port = htons(30000);
433 int ret = setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &flags, (socklen_t)
sizeof(flags));
435 perror(
"Failed to set REUSEADDR");
438 bind(listenfd, (
struct sockaddr*)&servaddr,
sizeof(servaddr));
440 listen(listenfd, LISTENQ);
441 printf(
"Accepting..."); fflush(stdout);
442 connfd = accept(listenfd, (
struct sockaddr*) NULL, NULL);
443 printf(
"Done."); fflush(stdout);
451 if ((connfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
452 perror(
"[FATAL] socket error");
456 memset(&servaddr, 0,
sizeof(servaddr));
457 servaddr.sin_family = AF_INET;
458 servaddr.sin_port = htons(atoi(argv[7]));
459 if (inet_pton(AF_INET, argv[6], &servaddr.sin_addr) <= 0) {
460 perror(
"[FATAL] inetpton error");
465 if (connect(connfd, (
struct sockaddr*)&servaddr,
sizeof(servaddr)) < 0) {
466 perror(
"Failed to connect");
476 printf(
"Connection Accepted\n"); fflush(stdout);
478 double init_time = getTimeSec();
479 double prev_time = init_time;
481 unsigned long long int cnt = 0;
482 unsigned long long int prev_cnt = 0;
483 unsigned long long int start_cnt = 300000;
486 addEvent(buff, nwords_per_fee, cnt, ncpr, nhslb);
496 if ((ret = write(connfd, buff, total_words *
sizeof(
int))) <= 0) {
497 printf(
"[FATAL] Return value %d\n", ret);
504 if (cnt == start_cnt) init_time = getTimeSec();
505 if (cnt % 10000 == 1) {
506 if (cnt > start_cnt) {
507 double cur_time = getTimeSec();
508 printf(
"run %d evt %lld time %.1lf dataflow %.1lf MB/s rate %.2lf kHz : so far dataflow %.1lf MB/s rate %.2lf kHz size %d\n",
511 cur_time - init_time,
512 (cnt - prev_cnt)*total_words *
sizeof(
int) / 1000000. / (cur_time - prev_time),
513 (cnt - prev_cnt) / (cur_time - prev_time) / 1000. ,
514 (cnt - start_cnt)*total_words *
sizeof(
int) / 1000000. / (cur_time - init_time),
515 (cnt - start_cnt) / (cur_time - init_time) / 1000. , total_words);
518 prev_time = cur_time;