OpenCores
URL https://opencores.org/ocsvn/xge_mac/xge_mac/trunk

Subversion Repositories xge_mac

[/] [xge_mac/] [trunk/] [tbench/] [systemc/] [sc_scoreboard.cpp] - Blame information for rev 29

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 antanguay
//////////////////////////////////////////////////////////////////////
2
////                                                              ////
3
////  File name "sc_scoreboard.cpp"                               ////
4
////                                                              ////
5
////  This file is part of the "10GE MAC" project                 ////
6
////  http://www.opencores.org/cores/xge_mac/                     ////
7
////                                                              ////
8
////  Author(s):                                                  ////
9
////      - A. Tanguay (antanguay@opencores.org)                  ////
10
////                                                              ////
11
//////////////////////////////////////////////////////////////////////
12
////                                                              ////
13
//// Copyright (C) 2008 AUTHORS. All rights reserved.             ////
14
////                                                              ////
15
//// This source file may be used and distributed without         ////
16
//// restriction provided that this copyright statement is not    ////
17
//// removed from the file and that any derivative work contains  ////
18
//// the original copyright notice and the associated disclaimer. ////
19
////                                                              ////
20
//// This source file is free software; you can redistribute it   ////
21
//// and/or modify it under the terms of the GNU Lesser General   ////
22
//// Public License as published by the Free Software Foundation; ////
23
//// either version 2.1 of the License, or (at your option) any   ////
24
//// later version.                                               ////
25
////                                                              ////
26
//// This source is distributed in the hope that it will be       ////
27
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
28
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
29
//// PURPOSE.  See the GNU Lesser General Public License for more ////
30
//// details.                                                     ////
31
////                                                              ////
32
//// You should have received a copy of the GNU Lesser General    ////
33
//// Public License along with this source; if not, download it   ////
34
//// from http://www.opencores.org/lgpl.shtml                     ////
35
////                                                              ////
36
//////////////////////////////////////////////////////////////////////
37
 
38
#include <stdio.h>
39
#include <iostream>
40
#include <sys/times.h>
41
#include <sys/stat.h>
42
 
43
#include "systemc.h"
44
 
45
#include "sc_scoreboard.h"
46
 
47
 
48
void scoreboard::init(void) {
49
    disable_padding = false;
50
    disable_crc_check = false;
51
    disable_packet_check = false;
52
    disable_flags_check = false;
53
    disable_signal_check = false;
54
}
55
 
56
void scoreboard::notify_packet_tx(sbSourceId sid, packet_t* pkt) {
57
 
58
    //---
59
    // Save packet to a fifo
60
 
61
    if (sid == SB_PIF_ID) {
62 29 antanguay
        cout << "SCOREBOARD PACKET INTERFACE TX ("
63 2 antanguay
             << pkt->length << ")" << endl;
64
 
65
        //---
66
        // Store packet in scoreboard
67
 
68
        pif_fifo.write(pkt);
69
        pif_stats.tx_pkt_cnt++;
70 29 antanguay
        pif_stats.tx_octets_cnt = pif_stats.tx_octets_cnt + pkt->length;
71 2 antanguay
 
72
    }
73
 
74
    if (sid == SB_XGM_ID) {
75
 
76 29 antanguay
        cout << "SCOREBOARD XGMII INTERFACE TX ("
77 2 antanguay
             << pkt->length << ")" << endl;
78
 
79
        //---
80
        // Store packet in scoreboard
81
 
82
        if (sid == SB_XGM_ID && (pkt->dest_addr & 0xffff) == 0x000001 &&
83
            ((pkt->dest_addr >> 24) & 0xffffff) == 0x0180c2) {
84
 
85
            // Pause frames will be dropped
86
            cout << "SCOREBOARD PAUSE INJECTED" << endl;
87
            xgm_stats.inject_pause_frame_cnt++;
88
 
89
        }
90
        else {
91
 
92
            xgm_fifo.write(pkt);
93
            xgm_stats.tx_pkt_cnt++;
94 29 antanguay
            xgm_stats.tx_octets_cnt = xgm_stats.tx_octets_cnt + pkt->length;
95 2 antanguay
 
96
        }
97
 
98
    }
99
 
100
    //---
101
    // Update stats
102
 
103
    if (sid == SB_XGM_ID && pkt->err_flags & PKT_FLAG_ERR_CODING) {
104
        xgm_stats.crc_error_cnt++;
105
    }
106
 
107
    if (sid == SB_XGM_ID && pkt->err_flags & PKT_FLAG_LOCAL_FAULT) {
108
        // If less than 4 faults in 128 columns, it will not be detected
109
        if (pkt->err_info <= (128 - 4)) {
110
            xgm_stats.inject_local_fault_cnt++;
111
        }
112
    }
113
 
114
    if (sid == SB_XGM_ID && pkt->err_flags & PKT_FLAG_REMOTE_FAULT) {
115
        // If less than 4 faults in 128 columns, it will not be detected
116
        if (pkt->err_info <= (128 - 4)) {
117
            xgm_stats.inject_remote_fault_cnt++;
118
        }
119
    }
120
 
121
    //cout << *pkt << endl;
122
}
123
 
124
void scoreboard::notify_packet_rx(sbSourceId sid, packet_t* pkt) {
125
 
126
    sbStats_t* stats;
127
 
128
    packet_t* pkt_tx;
129
    bool status;
130
 
131
    //---
132
    // Read matching packet from fifo
133
 
134
    if (sid == SB_PIF_ID) {
135
        status = xgm_fifo.nb_read(pkt_tx);
136
        if (status) {
137 29 antanguay
            cout << "SCOREBOARD PACKET INTERFACE RX (TX SIZE="
138 2 antanguay
                 << pkt_tx->length << "  RX SIZE="
139
                 << pkt->length << ")" << endl;
140
        }
141
    }
142
 
143
    if (sid == SB_XGM_ID) {
144
        status = pif_fifo.nb_read(pkt_tx);
145
        if (status) {
146
            cout << "SCOREBOARD XGMII INTERFACE RX (TX SIZE="
147
                 << pkt_tx->length << "  RX SIZE="
148
                 << pkt->length << ")" << endl;
149
        }
150
    }
151
 
152
    if (!status) {
153
        cout << "ERROR: FIFO EMPTY" << endl;
154
        sc_stop();
155
    }
156
 
157
    //---
158
    // Update stats
159
 
160
    if (sid == SB_PIF_ID) {
161
        stats = &pif_stats;
162
    }
163
 
164
    if (sid == SB_XGM_ID) {
165
        stats = &xgm_stats;
166
    }
167
 
168
    stats->rx_pkt_cnt++;
169
 
170
    if (stats->timestamp_first_pkt == 0) {
171
        stats->timestamp_first_pkt = sc_simulation_time();
172
    }
173
 
174
    stats->timestamp_last_pkt = sc_simulation_time();
175
 
176
    //---
177
    // Pad packet if it expected to be padded by MAC
178
 
179
    if (sid == SB_XGM_ID && !disable_padding) {
180
        pad(pkt_tx, 60);
181
    }
182
 
183
    //---
184
    // Calculate CRC
185
 
186
    calc_crc(pkt_tx);
187
    calc_crc(pkt);
188
 
189 29 antanguay
    //---
190
    // Update byte count after padding
191
 
192
    stats->rx_octets_cnt = stats->rx_octets_cnt + pkt_tx->length + 4;
193
 
194 2 antanguay
    //cout << *pkt_tx << *pkt << endl;
195
 
196
    //---
197
    // Compare TX and RX packets
198
 
199
    if (disable_packet_check) {
200
 
201
        cout << "INFO: Packet check disabled" << endl;
202
 
203
    }
204
    else if ((pkt_tx->err_flags & PKT_FLAG_ERR_FRG) &&
205 29 antanguay
             (pkt->err_flags & PKT_FLAG_ERR_SIG)) {
206 2 antanguay
 
207
        cout << "INFO: Fragment detected" << endl;
208
 
209
    }
210 29 antanguay
    else if ((pkt_tx->err_flags & PKT_FLAG_ERR_LENGHT) &&
211
             (pkt->err_flags & PKT_FLAG_ERR_SIG)) {
212
 
213
        cout << "INFO: Lenght error detected" << endl;
214
 
215
    }
216 2 antanguay
    else if ((pkt_tx->err_flags & PKT_FLAG_ERR_CODING) &&
217 29 antanguay
             (pkt->err_flags & PKT_FLAG_ERR_SIG)) {
218 2 antanguay
 
219
        cout << "INFO: Coding error detected:" << pkt_tx->err_info << endl;
220
 
221
    }
222
    else if ((sid == SB_PIF_ID || pkt->crc == pkt->crc_rx || disable_crc_check) &&
223
             compare(pkt_tx, pkt)) {
224 29 antanguay
 
225 2 antanguay
        //cout << "GOOD: Packets are matching" << endl;
226
 
227
    }
228
    else {
229
 
230
        cout << "ERROR: Packets don't match or bad CRC" << endl;
231
 
232
        cout << "<<<" << endl;
233
        cout << *pkt_tx << endl;
234
        cout << *pkt << endl;
235
        cout << ">>>" << endl;
236
 
237
        sc_stop();
238
 
239
    }
240
 
241
    //---
242
    // Check IFG against predicted IFG
243
 
244
    if (sid == SB_XGM_ID) {
245
 
246
        cout << "PKTMOD " << pkt->length % 4 \
247
             << " LANE " << pkt->start_lane \
248
             << " DIC " << stats->deficit_idle_count \
249
             << " IFGLEN " << stats->next_ifg_length  << endl;
250
 
251
        if (pkt->ifg < 1000 && stats->next_ifg_length != 1000) {
252
            if (pkt->ifg != stats->next_ifg_length) {
253
                cout << "ERROR: DIC IFG " << pkt->ifg                   \
254
                     << " Predicted: " << stats->next_ifg_length << endl;
255
                sc_stop();
256
            }
257
        }
258
 
259
    }
260
 
261
    //---
262
    // Update deficit idle count and predict IFG
263
 
264
    if (sid == SB_XGM_ID) {
265
 
266
        stats->next_ifg_length = 12 - (pkt->length % 4);
267
        stats->deficit_idle_count += (pkt->length % 4);
268
        if (stats->deficit_idle_count > 3) {
269
            stats->next_ifg_length += 4;
270
            stats->deficit_idle_count = stats->deficit_idle_count % 4;
271
        }
272
    }
273
 
274
    //---
275
    // Check error flags
276
 
277
    // CRC ERRORS
278
 
279
    if (sid == SB_PIF_ID && (pkt_tx->err_flags & PKT_FLAG_ERR_CRC)) {
280
 
281
        if (pkt->err_flags & PKT_FLAG_ERR_SIG) {
282 29 antanguay
 
283 2 antanguay
            cout << "SCOREBOARD CRC ERROR CHECKED" << endl;
284
            pif_stats.crc_error_cnt++;
285 29 antanguay
 
286 2 antanguay
            if (cpu_stats.crc_error_cnt+1 < pif_stats.crc_error_cnt) {
287
                cout << "ERROR: CRC error not reported to cpu" << endl;
288
                sc_stop();
289
            }
290
        }
291
        else {
292
            cout << "ERROR: CRC error not detected: " << hex << pkt->err_flags << dec << endl;
293
            sc_stop();
294
        }
295 29 antanguay
 
296 2 antanguay
        pkt->err_flags &= ~PKT_FLAG_ERR_SIG;
297
    }
298
 
299
 
300
    // FRAGMENT ERRORS
301
 
302
    if (sid == SB_PIF_ID && (pkt_tx->err_flags & PKT_FLAG_ERR_FRG)) {
303
 
304
        if (pkt->err_flags & PKT_FLAG_ERR_SIG) {
305 29 antanguay
 
306 2 antanguay
            cout << "SCOREBOARD FRAGMENT ERROR CHECKED" << endl;
307
            pif_stats.fragment_error_cnt++;
308 29 antanguay
 
309 2 antanguay
            if ((cpu_stats.fragment_error_cnt + cpu_stats.crc_error_cnt + 1)
310
                < pif_stats.fragment_error_cnt) {
311
                cout << "ERROR: FRAGMENT error not reported to cpu" << endl;
312
                sc_stop();
313
            }
314
        }
315
        else {
316
            cout << "ERROR: FRAGMENT error not detected: "
317
                 << hex << pkt->err_flags << dec << endl;
318
            sc_stop();
319
        }
320 29 antanguay
 
321 2 antanguay
        pkt->err_flags &= ~PKT_FLAG_ERR_SIG;
322
    }
323
 
324
 
325 29 antanguay
    // LENGHT ERRORS
326
 
327
    if (sid == SB_PIF_ID && (pkt_tx->err_flags & PKT_FLAG_ERR_LENGHT)) {
328
 
329
        if (pkt->err_flags & PKT_FLAG_ERR_SIG) {
330
 
331
            cout << "SCOREBOARD LENGHT ERROR CHECKED" << endl;
332
            pif_stats.lenght_error_cnt++;
333
 
334
            if (cpu_stats.lenght_error_cnt + 1 < pif_stats.lenght_error_cnt) {
335
                cout << "ERROR: LENGHT error not reported to cpu" << endl;
336
                sc_stop();
337
            }
338
        }
339
        else {
340
            cout << "ERROR: LENGHT error not detected: "
341
                 << hex << pkt->err_flags << dec << endl;
342
            sc_stop();
343
        }
344
 
345
        pkt->err_flags &= ~PKT_FLAG_ERR_SIG;
346
    }
347
 
348
 
349 2 antanguay
    // CODING ERRORS
350
 
351
    if (sid == SB_PIF_ID && (pkt_tx->err_flags & PKT_FLAG_ERR_CODING)) {
352
 
353
        if (pkt->err_flags & PKT_FLAG_ERR_SIG) {
354 29 antanguay
 
355 2 antanguay
            cout << "SCOREBOARD CODING ERROR CHECKED" << endl;
356 29 antanguay
 
357 2 antanguay
            if (cpu_stats.crc_error_cnt+1 < xgm_stats.crc_error_cnt) {
358
                cout << "CPU Count: " << cpu_stats.crc_error_cnt <<
359
                    " XGM Count: " << xgm_stats.crc_error_cnt << endl;
360
                cout << "ERROR: CODING error not reported to cpu" << endl;
361
                sc_stop();
362
            }
363
        }
364
        else {
365
            cout << "ERROR: CODING error not detected: "
366
                 << hex << pkt->err_flags << dec << endl;
367
            sc_stop();
368
        }
369 29 antanguay
 
370 2 antanguay
        pkt->err_flags &= ~PKT_FLAG_ERR_SIG;
371
    }
372
 
373
 
374
    if (pkt->err_flags != 0) {
375
        stats->flags_error_cnt++;
376
        if (!disable_flags_check) {
377
            cout << "ERROR: Error flags set: " << hex << pkt->err_flags << dec << endl;
378
            sc_stop();
379
        }
380
        else {
381
            cout << "INFO: Error flags set: " << hex << pkt->err_flags << dec << endl;
382
        }
383
    }
384
 
385
    //---
386
    // Delete packets
387
 
388
    delete(pkt_tx);
389
    delete(pkt);
390
}
391
 
392
void scoreboard::notify_status(sbSourceId sid, sbStatusId statusId) {
393
 
394
    //---
395
    // Detect errors
396
 
397
    if (sid == SB_CPU_ID && statusId == CRC_ERROR) {
398
        cout << "SCOREBOARD CRC_ERROR SIGNAL" << endl;
399
        cpu_stats.crc_error_cnt++;
400
    }
401
 
402
    if (sid == SB_CPU_ID && statusId == FRAGMENT_ERROR) {
403
        cout << "SCOREBOARD FRAGMENT_ERROR SIGNAL" << endl;
404
        cpu_stats.fragment_error_cnt++;
405
    }
406
 
407 29 antanguay
    if (sid == SB_CPU_ID && statusId == LENGHT_ERROR) {
408
        cout << "SCOREBOARD LENGHT_ERROR SIGNAL" << endl;
409
        cpu_stats.lenght_error_cnt++;
410
    }
411
 
412 2 antanguay
    if (sid == SB_CPU_ID && statusId == LOCAL_FAULT) {
413
        cout << "SCOREBOARD LOCAL_FAULT SIGNAL" << endl;
414
        cpu_stats.local_fault_cnt++;
415
 
416
        if (cpu_stats.local_fault_cnt != xgm_stats.inject_local_fault_cnt) {
417
            cout << "ERROR: Local fault not reported to cpu "
418
                 << cpu_stats.local_fault_cnt << " "
419
                 << xgm_stats.inject_local_fault_cnt << endl;
420
            sc_stop();
421
        }
422
 
423
        if (cpu_stats.local_fault_cnt != xgm_stats.detect_remote_fault_cnt) {
424
            cout << "ERROR: Remote fault not detected "
425
                 << cpu_stats.local_fault_cnt << " "
426
                 << xgm_stats.detect_remote_fault_cnt << endl;
427
            sc_stop();
428
        }
429
    }
430
 
431
    if (sid == SB_CPU_ID && statusId == REMOTE_FAULT) {
432
        cout << "SCOREBOARD REMOTE_FAULT SIGNAL" << endl;
433
        cpu_stats.remote_fault_cnt++;
434
 
435
        if (cpu_stats.remote_fault_cnt != xgm_stats.inject_remote_fault_cnt) {
436
            cout << "ERROR: Remote fault not reported to cpu "
437
                 << cpu_stats.remote_fault_cnt << " "
438
                 << xgm_stats.inject_remote_fault_cnt << endl;
439
            sc_stop();
440
        }
441
 
442
    }
443
 
444
    if (sid == SB_CPU_ID && statusId == RXD_FIFO_OVFLOW) {
445
        cout << "SCOREBOARD RXD_FIFO_OVFLOW SIGNAL" << endl;
446
        cpu_stats.rxd_fifo_ovflow_cnt++;
447
    }
448
 
449
    if (sid == SB_CPU_ID && statusId == RXD_FIFO_UDFLOW) {
450
        cout << "SCOREBOARD RXD_FIFO_UDFLOW SIGNAL" << endl;
451
        cpu_stats.rxd_fifo_udflow_cnt++;
452
    }
453
 
454
    if (sid == SB_CPU_ID && statusId == TXD_FIFO_OVFLOW) {
455
        cout << "SCOREBOARD TXD_FIFO_OVFLOW SIGNAL" << endl;
456
        cpu_stats.txd_fifo_ovflow_cnt++;
457
    }
458
 
459
    if (sid == SB_CPU_ID && statusId == TXD_FIFO_UDFLOW) {
460
        cout << "SCOREBOARD TXD_FIFO_UDFLOW SIGNAL" << endl;
461
        cpu_stats.txd_fifo_udflow_cnt++;
462
    }
463
 
464
    //---
465
    // Detect XGMII local/remote faults
466
 
467
    if (sid == SB_XGM_ID && statusId == LOCAL_FAULT) {
468
        cout << "SCOREBOARD RX LOCAL FAULT" << endl;
469
        xgm_stats.detect_local_fault_cnt++;
470
        sc_stop();
471
    }
472
 
473
    if (sid == SB_XGM_ID && statusId == REMOTE_FAULT) {
474
        cout << "SCOREBOARD RX REMOTE FAULT" << endl;
475
        xgm_stats.detect_remote_fault_cnt++;
476
    }
477
 
478
    //---
479
    // Packet receive indication
480
 
481
    if (sid == SB_CPU_ID && statusId == RX_GOOD_PAUSE_FRAME) {
482
        cout << "SCOREBOARD RX GOOD PAUSE FRAME SIGNAL" << endl;
483
        cpu_stats.rx_pause_frame_cnt++;
484
 
485
        if (cpu_stats.rx_pause_frame_cnt != xgm_stats.inject_pause_frame_cnt) {
486
            cout << "ERROR: Pause frame not reported "
487
                 << cpu_stats.rx_pause_frame_cnt << " "
488
                 << xgm_stats.inject_pause_frame_cnt << endl;
489
            sc_stop();
490
        }
491
    }
492
 
493
 
494
    if (!disable_signal_check) {
495
        cout << "ERROR: Signal Active" << endl;
496
        sc_stop();
497
    }
498
}
499
 
500
sbStats_t* scoreboard::get_pif_stats(void) {
501
    return &pif_stats;
502
}
503
 
504
sbStats_t* scoreboard::get_xgm_stats(void) {
505
    return &xgm_stats;
506
}
507
 
508
sbCpuStats_t* scoreboard::get_cpu_stats(void) {
509
    return &cpu_stats;
510
}
511
 
512
void scoreboard::clear_stats(void) {
513
 
514
    //---
515
    // Clear FIFOs
516
 
517
    while (pif_fifo.num_available() != 0) {
518
        delete(pif_fifo.read());
519
    }
520
 
521
    while (xgm_fifo.num_available() != 0) {
522
        delete(xgm_fifo.read());
523
    }
524
 
525
    //---
526
    // Clear stats
527
 
528
    pif_stats.tx_pkt_cnt = 0;
529
    pif_stats.rx_pkt_cnt = 0;
530 29 antanguay
    pif_stats.tx_octets_cnt = 0;
531
    pif_stats.rx_octets_cnt = 0;
532 2 antanguay
    pif_stats.crc_error_cnt = 0;
533
    pif_stats.flags_error_cnt = 0;
534
 
535
    xgm_stats.tx_pkt_cnt = 0;
536
    xgm_stats.rx_pkt_cnt = 0;
537 29 antanguay
    xgm_stats.tx_octets_cnt = 0;
538
    xgm_stats.rx_octets_cnt = 0;
539 2 antanguay
    xgm_stats.crc_error_cnt = 0;
540
    xgm_stats.flags_error_cnt = 0;
541
 
542
    pif_stats.timestamp_first_pkt = 0;
543
    pif_stats.timestamp_last_pkt = 0;
544
 
545
    xgm_stats.timestamp_first_pkt = 0;
546
    xgm_stats.timestamp_last_pkt = 0;
547
 
548
    xgm_stats.next_ifg_length = 1000;
549
    xgm_stats.deficit_idle_count = 0;
550
 
551
    cpu_stats.crc_error_cnt = 0;
552
    cpu_stats.fragment_error_cnt = 0;
553 29 antanguay
    cpu_stats.lenght_error_cnt = 0;
554 2 antanguay
    cpu_stats.rxd_fifo_ovflow_cnt = 0;
555
    cpu_stats.rxd_fifo_udflow_cnt = 0;
556
    cpu_stats.txd_fifo_ovflow_cnt = 0;
557
    cpu_stats.txd_fifo_udflow_cnt = 0;
558
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.