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 28

Go to most recent revision | 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
        cout << "SCOREBOARD PACKET INTERFACE TX ("
63
             << pkt->length << ")" << endl;
64
 
65
        //---
66
        // Store packet in scoreboard
67
 
68
        pif_fifo.write(pkt);
69
        pif_stats.tx_pkt_cnt++;
70
 
71
    }
72
 
73
    if (sid == SB_XGM_ID) {
74
 
75
        cout << "SCOREBOARD XGMII INTERFACE TX ("
76
             << pkt->length << ")" << endl;
77
 
78
        //---
79
        // Store packet in scoreboard
80
 
81
        if (sid == SB_XGM_ID && (pkt->dest_addr & 0xffff) == 0x000001 &&
82
            ((pkt->dest_addr >> 24) & 0xffffff) == 0x0180c2) {
83
 
84
            // Pause frames will be dropped
85
            cout << "SCOREBOARD PAUSE INJECTED" << endl;
86
            xgm_stats.inject_pause_frame_cnt++;
87
 
88
        }
89
        else {
90
 
91
            xgm_fifo.write(pkt);
92
            xgm_stats.tx_pkt_cnt++;
93
 
94
        }
95
 
96
    }
97
 
98
    //---
99
    // Update stats
100
 
101
    if (sid == SB_XGM_ID && pkt->err_flags & PKT_FLAG_ERR_CODING) {
102
        xgm_stats.crc_error_cnt++;
103
    }
104
 
105
    if (sid == SB_XGM_ID && pkt->err_flags & PKT_FLAG_LOCAL_FAULT) {
106
        // If less than 4 faults in 128 columns, it will not be detected
107
        if (pkt->err_info <= (128 - 4)) {
108
            xgm_stats.inject_local_fault_cnt++;
109
        }
110
    }
111
 
112
    if (sid == SB_XGM_ID && pkt->err_flags & PKT_FLAG_REMOTE_FAULT) {
113
        // If less than 4 faults in 128 columns, it will not be detected
114
        if (pkt->err_info <= (128 - 4)) {
115
            xgm_stats.inject_remote_fault_cnt++;
116
        }
117
    }
118
 
119
    //cout << *pkt << endl;
120
}
121
 
122
void scoreboard::notify_packet_rx(sbSourceId sid, packet_t* pkt) {
123
 
124
    sbStats_t* stats;
125
 
126
    packet_t* pkt_tx;
127
    bool status;
128
 
129
    //---
130
    // Read matching packet from fifo
131
 
132
    if (sid == SB_PIF_ID) {
133
        status = xgm_fifo.nb_read(pkt_tx);
134
        if (status) {
135
            cout << "SCOREBOARD PACKET INTERFACE RX (TX SIZE="
136
                 << pkt_tx->length << "  RX SIZE="
137
                 << pkt->length << ")" << endl;
138
        }
139
    }
140
 
141
    if (sid == SB_XGM_ID) {
142
        status = pif_fifo.nb_read(pkt_tx);
143
        if (status) {
144
            cout << "SCOREBOARD XGMII INTERFACE RX (TX SIZE="
145
                 << pkt_tx->length << "  RX SIZE="
146
                 << pkt->length << ")" << endl;
147
        }
148
    }
149
 
150
    if (!status) {
151
        cout << "ERROR: FIFO EMPTY" << endl;
152
        sc_stop();
153
    }
154
 
155
    //---
156
    // Update stats
157
 
158
    if (sid == SB_PIF_ID) {
159
        stats = &pif_stats;
160
    }
161
 
162
    if (sid == SB_XGM_ID) {
163
        stats = &xgm_stats;
164
    }
165
 
166
    stats->rx_pkt_cnt++;
167
 
168
    if (stats->timestamp_first_pkt == 0) {
169
        stats->timestamp_first_pkt = sc_simulation_time();
170
    }
171
 
172
    stats->timestamp_last_pkt = sc_simulation_time();
173
 
174
    //---
175
    // Pad packet if it expected to be padded by MAC
176
 
177
    if (sid == SB_XGM_ID && !disable_padding) {
178
        pad(pkt_tx, 60);
179
    }
180
 
181
    //---
182
    // Calculate CRC
183
 
184
    calc_crc(pkt_tx);
185
    calc_crc(pkt);
186
 
187
    //cout << *pkt_tx << *pkt << endl;
188
 
189
    //---
190
    // Compare TX and RX packets
191
 
192
    if (disable_packet_check) {
193
 
194
        cout << "INFO: Packet check disabled" << endl;
195
 
196
    }
197
    else if ((pkt_tx->err_flags & PKT_FLAG_ERR_FRG) &&
198
             (pkt->err_flags |= PKT_FLAG_ERR_SIG)) {
199
 
200
        cout << "INFO: Fragment detected" << endl;
201
 
202
    }
203
    else if ((pkt_tx->err_flags & PKT_FLAG_ERR_CODING) &&
204
             (pkt->err_flags |= PKT_FLAG_ERR_SIG)) {
205
 
206
        cout << "INFO: Coding error detected:" << pkt_tx->err_info << endl;
207
 
208
    }
209
    else if ((sid == SB_PIF_ID || pkt->crc == pkt->crc_rx || disable_crc_check) &&
210
             compare(pkt_tx, pkt)) {
211
 
212
        //cout << "GOOD: Packets are matching" << endl;
213
 
214
    }
215
    else {
216
 
217
        cout << "ERROR: Packets don't match or bad CRC" << endl;
218
 
219
        cout << "<<<" << endl;
220
        cout << *pkt_tx << endl;
221
        cout << *pkt << endl;
222
        cout << ">>>" << endl;
223
 
224
        sc_stop();
225
 
226
    }
227
 
228
    //---
229
    // Check IFG against predicted IFG
230
 
231
    if (sid == SB_XGM_ID) {
232
 
233
        cout << "PKTMOD " << pkt->length % 4 \
234
             << " LANE " << pkt->start_lane \
235
             << " DIC " << stats->deficit_idle_count \
236
             << " IFGLEN " << stats->next_ifg_length  << endl;
237
 
238
        if (pkt->ifg < 1000 && stats->next_ifg_length != 1000) {
239
            if (pkt->ifg != stats->next_ifg_length) {
240
                cout << "ERROR: DIC IFG " << pkt->ifg                   \
241
                     << " Predicted: " << stats->next_ifg_length << endl;
242
                sc_stop();
243
            }
244
        }
245
 
246
    }
247
 
248
    //---
249
    // Update deficit idle count and predict IFG
250
 
251
    if (sid == SB_XGM_ID) {
252
 
253
        stats->next_ifg_length = 12 - (pkt->length % 4);
254
        stats->deficit_idle_count += (pkt->length % 4);
255
        if (stats->deficit_idle_count > 3) {
256
            stats->next_ifg_length += 4;
257
            stats->deficit_idle_count = stats->deficit_idle_count % 4;
258
        }
259
    }
260
 
261
    //---
262
    // Check error flags
263
 
264
    // CRC ERRORS
265
 
266
    if (sid == SB_PIF_ID && (pkt_tx->err_flags & PKT_FLAG_ERR_CRC)) {
267
 
268
        if (pkt->err_flags & PKT_FLAG_ERR_SIG) {
269
 
270
            cout << "SCOREBOARD CRC ERROR CHECKED" << endl;
271
            pif_stats.crc_error_cnt++;
272
 
273
            if (cpu_stats.crc_error_cnt+1 < pif_stats.crc_error_cnt) {
274
                cout << "ERROR: CRC error not reported to cpu" << endl;
275
                sc_stop();
276
            }
277
        }
278
        else {
279
            cout << "ERROR: CRC error not detected: " << hex << pkt->err_flags << dec << endl;
280
            sc_stop();
281
        }
282
 
283
        pkt->err_flags &= ~PKT_FLAG_ERR_SIG;
284
    }
285
 
286
 
287
    // FRAGMENT ERRORS
288
 
289
    if (sid == SB_PIF_ID && (pkt_tx->err_flags & PKT_FLAG_ERR_FRG)) {
290
 
291
        if (pkt->err_flags & PKT_FLAG_ERR_SIG) {
292
 
293
            cout << "SCOREBOARD FRAGMENT ERROR CHECKED" << endl;
294
            pif_stats.fragment_error_cnt++;
295
 
296
            if ((cpu_stats.fragment_error_cnt + cpu_stats.crc_error_cnt + 1)
297
                < pif_stats.fragment_error_cnt) {
298
                cout << "ERROR: FRAGMENT error not reported to cpu" << endl;
299
                sc_stop();
300
            }
301
        }
302
        else {
303
            cout << "ERROR: FRAGMENT error not detected: "
304
                 << hex << pkt->err_flags << dec << endl;
305
            sc_stop();
306
        }
307
 
308
        pkt->err_flags &= ~PKT_FLAG_ERR_SIG;
309
    }
310
 
311
 
312
    // CODING ERRORS
313
 
314
    if (sid == SB_PIF_ID && (pkt_tx->err_flags & PKT_FLAG_ERR_CODING)) {
315
 
316
        if (pkt->err_flags & PKT_FLAG_ERR_SIG) {
317
 
318
            cout << "SCOREBOARD CODING ERROR CHECKED" << endl;
319
 
320
            if (cpu_stats.crc_error_cnt+1 < xgm_stats.crc_error_cnt) {
321
                cout << "CPU Count: " << cpu_stats.crc_error_cnt <<
322
                    " XGM Count: " << xgm_stats.crc_error_cnt << endl;
323
                cout << "ERROR: CODING error not reported to cpu" << endl;
324
                sc_stop();
325
            }
326
        }
327
        else {
328
            cout << "ERROR: CODING error not detected: "
329
                 << hex << pkt->err_flags << dec << endl;
330
            sc_stop();
331
        }
332
 
333
        pkt->err_flags &= ~PKT_FLAG_ERR_SIG;
334
    }
335
 
336
 
337
    if (pkt->err_flags != 0) {
338
        stats->flags_error_cnt++;
339
        if (!disable_flags_check) {
340
            cout << "ERROR: Error flags set: " << hex << pkt->err_flags << dec << endl;
341
            sc_stop();
342
        }
343
        else {
344
            cout << "INFO: Error flags set: " << hex << pkt->err_flags << dec << endl;
345
        }
346
    }
347
 
348
    //---
349
    // Delete packets
350
 
351
    delete(pkt_tx);
352
    delete(pkt);
353
}
354
 
355
void scoreboard::notify_status(sbSourceId sid, sbStatusId statusId) {
356
 
357
    //---
358
    // Detect errors
359
 
360
    if (sid == SB_CPU_ID && statusId == CRC_ERROR) {
361
        cout << "SCOREBOARD CRC_ERROR SIGNAL" << endl;
362
        cpu_stats.crc_error_cnt++;
363
    }
364
 
365
    if (sid == SB_CPU_ID && statusId == FRAGMENT_ERROR) {
366
        cout << "SCOREBOARD FRAGMENT_ERROR SIGNAL" << endl;
367
        cpu_stats.fragment_error_cnt++;
368
    }
369
 
370
    if (sid == SB_CPU_ID && statusId == LOCAL_FAULT) {
371
        cout << "SCOREBOARD LOCAL_FAULT SIGNAL" << endl;
372
        cpu_stats.local_fault_cnt++;
373
 
374
        if (cpu_stats.local_fault_cnt != xgm_stats.inject_local_fault_cnt) {
375
            cout << "ERROR: Local fault not reported to cpu "
376
                 << cpu_stats.local_fault_cnt << " "
377
                 << xgm_stats.inject_local_fault_cnt << endl;
378
            sc_stop();
379
        }
380
 
381
        if (cpu_stats.local_fault_cnt != xgm_stats.detect_remote_fault_cnt) {
382
            cout << "ERROR: Remote fault not detected "
383
                 << cpu_stats.local_fault_cnt << " "
384
                 << xgm_stats.detect_remote_fault_cnt << endl;
385
            sc_stop();
386
        }
387
    }
388
 
389
    if (sid == SB_CPU_ID && statusId == REMOTE_FAULT) {
390
        cout << "SCOREBOARD REMOTE_FAULT SIGNAL" << endl;
391
        cpu_stats.remote_fault_cnt++;
392
 
393
        if (cpu_stats.remote_fault_cnt != xgm_stats.inject_remote_fault_cnt) {
394
            cout << "ERROR: Remote fault not reported to cpu "
395
                 << cpu_stats.remote_fault_cnt << " "
396
                 << xgm_stats.inject_remote_fault_cnt << endl;
397
            sc_stop();
398
        }
399
 
400
    }
401
 
402
    if (sid == SB_CPU_ID && statusId == RXD_FIFO_OVFLOW) {
403
        cout << "SCOREBOARD RXD_FIFO_OVFLOW SIGNAL" << endl;
404
        cpu_stats.rxd_fifo_ovflow_cnt++;
405
    }
406
 
407
    if (sid == SB_CPU_ID && statusId == RXD_FIFO_UDFLOW) {
408
        cout << "SCOREBOARD RXD_FIFO_UDFLOW SIGNAL" << endl;
409
        cpu_stats.rxd_fifo_udflow_cnt++;
410
    }
411
 
412
    if (sid == SB_CPU_ID && statusId == TXD_FIFO_OVFLOW) {
413
        cout << "SCOREBOARD TXD_FIFO_OVFLOW SIGNAL" << endl;
414
        cpu_stats.txd_fifo_ovflow_cnt++;
415
    }
416
 
417
    if (sid == SB_CPU_ID && statusId == TXD_FIFO_UDFLOW) {
418
        cout << "SCOREBOARD TXD_FIFO_UDFLOW SIGNAL" << endl;
419
        cpu_stats.txd_fifo_udflow_cnt++;
420
    }
421
 
422
    //---
423
    // Detect XGMII local/remote faults
424
 
425
    if (sid == SB_XGM_ID && statusId == LOCAL_FAULT) {
426
        cout << "SCOREBOARD RX LOCAL FAULT" << endl;
427
        xgm_stats.detect_local_fault_cnt++;
428
        sc_stop();
429
    }
430
 
431
    if (sid == SB_XGM_ID && statusId == REMOTE_FAULT) {
432
        cout << "SCOREBOARD RX REMOTE FAULT" << endl;
433
        xgm_stats.detect_remote_fault_cnt++;
434
    }
435
 
436
    //---
437
    // Packet receive indication
438
 
439
    if (sid == SB_CPU_ID && statusId == RX_GOOD_PAUSE_FRAME) {
440
        cout << "SCOREBOARD RX GOOD PAUSE FRAME SIGNAL" << endl;
441
        cpu_stats.rx_pause_frame_cnt++;
442
 
443
        if (cpu_stats.rx_pause_frame_cnt != xgm_stats.inject_pause_frame_cnt) {
444
            cout << "ERROR: Pause frame not reported "
445
                 << cpu_stats.rx_pause_frame_cnt << " "
446
                 << xgm_stats.inject_pause_frame_cnt << endl;
447
            sc_stop();
448
        }
449
    }
450
 
451
 
452
    if (!disable_signal_check) {
453
        cout << "ERROR: Signal Active" << endl;
454
        sc_stop();
455
    }
456
}
457
 
458
sbStats_t* scoreboard::get_pif_stats(void) {
459
    return &pif_stats;
460
}
461
 
462
sbStats_t* scoreboard::get_xgm_stats(void) {
463
    return &xgm_stats;
464
}
465
 
466
sbCpuStats_t* scoreboard::get_cpu_stats(void) {
467
    return &cpu_stats;
468
}
469
 
470
void scoreboard::clear_stats(void) {
471
 
472
    //---
473
    // Clear FIFOs
474
 
475
    while (pif_fifo.num_available() != 0) {
476
        delete(pif_fifo.read());
477
    }
478
 
479
    while (xgm_fifo.num_available() != 0) {
480
        delete(xgm_fifo.read());
481
    }
482
 
483
    //---
484
    // Clear stats
485
 
486
    pif_stats.tx_pkt_cnt = 0;
487
    pif_stats.rx_pkt_cnt = 0;
488
    pif_stats.crc_error_cnt = 0;
489
    pif_stats.flags_error_cnt = 0;
490
 
491
    xgm_stats.tx_pkt_cnt = 0;
492
    xgm_stats.rx_pkt_cnt = 0;
493
    xgm_stats.crc_error_cnt = 0;
494
    xgm_stats.flags_error_cnt = 0;
495
 
496
    pif_stats.timestamp_first_pkt = 0;
497
    pif_stats.timestamp_last_pkt = 0;
498
 
499
    xgm_stats.timestamp_first_pkt = 0;
500
    xgm_stats.timestamp_last_pkt = 0;
501
 
502
    xgm_stats.next_ifg_length = 1000;
503
    xgm_stats.deficit_idle_count = 0;
504
 
505
    cpu_stats.crc_error_cnt = 0;
506
    cpu_stats.fragment_error_cnt = 0;
507
    cpu_stats.rxd_fifo_ovflow_cnt = 0;
508
    cpu_stats.rxd_fifo_udflow_cnt = 0;
509
    cpu_stats.txd_fifo_ovflow_cnt = 0;
510
    cpu_stats.txd_fifo_udflow_cnt = 0;
511
}

powered by: WebSVN 2.1.0

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