URL
https://opencores.org/ocsvn/xge_mac/xge_mac/trunk
Subversion Repositories xge_mac
Compare Revisions
- This comparison shows the changes necessary to convert path
/xge_mac/trunk/tbench/systemc
- from Rev 6 to Rev 7
- ↔ Reverse comparison
Rev 6 → Rev 7
/sc_pkt_if.cpp
0,0 → 1,222
////////////////////////////////////////////////////////////////////// |
//// //// |
//// File name "sc_pkt_if.cpp" //// |
//// //// |
//// This file is part of the "10GE MAC" project //// |
//// http://www.opencores.org/cores/xge_mac/ //// |
//// //// |
//// Author(s): //// |
//// - A. Tanguay (antanguay@opencores.org) //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2008 AUTHORS. All rights reserved. //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from http://www.opencores.org/lgpl.shtml //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
|
#include <stdio.h> |
#include <iostream> |
#include <sys/times.h> |
#include <sys/stat.h> |
|
#include "systemc.h" |
|
#include "sc_pkt_if.h" |
|
sc_fifo<packet_t*> * pkt_if::get_tx_fifo_ptr() { |
return &tx_fifo; |
} |
|
sc_fifo<packet_t*> * pkt_if::get_rx_fifo_ptr() { |
return &rx_fifo; |
} |
|
void pkt_if::init(void) { |
disable_rx = false; |
allow_rx_sop_err = false; |
} |
|
void pkt_if::connect_scoreboard(scoreboard *sbptr, scoreboard::sbSourceId sid) { |
sb = sbptr; |
sb_id = sid; |
} |
|
void pkt_if::transmit() { |
|
packet_t* pkt; |
|
while (true) { |
|
wait(); |
|
if (tx_fifo.nb_read(pkt)) { |
|
pack(pkt); |
|
//cout << "Transmit PKT_IF packet:\n" << * pkt << endl; |
|
pkt_tx_val = 1; |
|
for (int i = 0; i < pkt->length; i += 8) { |
|
pkt_tx_data = pkt->data[i+7] << 56 | |
pkt->data[i+6] << 48 | |
pkt->data[i+5] << 40 | |
pkt->data[i+4] << 32 | |
pkt->data[i+3] << 24 | |
pkt->data[i+2] << 16 | |
pkt->data[i+1] << 8 | |
pkt->data[i]; |
|
if (i == 0) { |
pkt_tx_sop = 1; |
} |
else { |
pkt_tx_sop = 0; |
} |
|
if (i + 8 >= pkt->length) { |
pkt_tx_eop = 1; |
pkt_tx_mod = pkt->length % 8; |
} |
else { |
pkt_tx_eop = 0; |
} |
|
wait(); |
} |
|
pkt_tx_val = 0; |
|
|
//--- |
// Pass packet to scoreboard |
|
sb->notify_packet_tx(sb_id, pkt); |
|
//--- |
// Enforce minimum spacing between SOP's |
|
for (int i = (pkt->length+7)/8; i < 8; i++) { |
wait(); |
} |
} |
} |
}; |
|
|
void pkt_if::receive() { |
|
packet_t* pkt; |
|
sc_uint<64> data; |
|
wait(); |
|
while (true) { |
|
if (pkt_rx_avail && !disable_rx) { |
|
pkt = new(packet_t); |
pkt->length = 0; |
|
// If reading already selected just keep going, |
// if not we must enable ren |
if (!pkt_rx_ren) { |
pkt_rx_ren = 1; |
wait(); |
}; |
|
while (true) { |
|
wait(); |
|
if (!pkt_rx_val) { |
continue; |
} |
|
// Check SOP |
|
if (pkt->length != 0 && pkt_rx_sop) { |
if (allow_rx_sop_err) { |
cout << "INFO: SOP errors allowed" << endl; |
pkt->length = 0; |
pkt->err_flags = 0; |
} |
else { |
pkt->err_flags |= PKT_FLAG_ERR_SOP; |
} |
} |
|
// Check error line |
|
if (pkt_rx_err) { |
pkt->err_flags |= PKT_FLAG_ERR_SIG; |
} |
|
// Capture data |
|
data = pkt_rx_data; |
|
for (int lane = 0; lane < 8; lane++) { |
|
pkt->data[pkt->length++] = (data >> (8 * lane)) & 0xff; |
|
if (pkt->length >= 10000) { |
cout << "ERROR: Packet too long" << endl; |
sc_stop(); |
} |
|
if (pkt_rx_eop && (pkt_rx_mod == ((lane+1) % 8))) { |
break; |
} |
} |
|
// Stop on EOP |
|
if (pkt_rx_eop) { |
break; |
} |
} |
|
//--- |
// Store packet |
|
unpack(pkt); |
//rx_fifo.write(pkt); |
|
//cout << "Receive PKT_IF packet:\n" << * pkt << endl; |
|
//--- |
// Pass packet to scoreboard |
|
sb->notify_packet_rx(sb_id, pkt); |
|
} |
else { |
pkt_rx_ren = 0; |
wait(); |
} |
} |
}; |
sc_pkt_if.cpp
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: sc_pkt_if.h
===================================================================
--- sc_pkt_if.h (nonexistent)
+++ sc_pkt_if.h (revision 7)
@@ -0,0 +1,121 @@
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// File name "sc_pkt_if.h" ////
+//// ////
+//// This file is part of the "10GE MAC" project ////
+//// http://www.opencores.org/cores/xge_mac/ ////
+//// ////
+//// Author(s): ////
+//// - A. Tanguay (antanguay@opencores.org) ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2008 AUTHORS. All rights reserved. ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer. ////
+//// ////
+//// This source file is free software; you can redistribute it ////
+//// and/or modify it under the terms of the GNU Lesser General ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any ////
+//// later version. ////
+//// ////
+//// This source is distributed in the hope that it will be ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
+//// PURPOSE. See the GNU Lesser General Public License for more ////
+//// details. ////
+//// ////
+//// You should have received a copy of the GNU Lesser General ////
+//// Public License along with this source; if not, download it ////
+//// from http://www.opencores.org/lgpl.shtml ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+
+#ifndef PKT_IF_H
+#define PKT_IF_H
+
+#include "systemc.h"
+
+#include "sc_packet.h"
+#include "sc_scoreboard.h"
+
+SC_MODULE(pkt_if) {
+
+ public:
+
+ //---
+ // Ports
+
+ sc_in clk_156m25;
+
+ sc_in reset_156m25_n;
+
+ sc_out > pkt_tx_data;
+ sc_out pkt_tx_eop;
+ sc_out pkt_tx_mod;
+ sc_out pkt_tx_sop;
+ sc_out pkt_tx_val;
+
+ sc_in pkt_tx_full;
+
+ sc_in pkt_rx_avail;
+ sc_in > pkt_rx_data;
+ sc_in pkt_rx_eop;
+ sc_in pkt_rx_mod;
+ sc_in pkt_rx_err;
+ sc_in pkt_rx_sop;
+ sc_in pkt_rx_val;
+
+ sc_out pkt_rx_ren;
+
+ private:
+
+ //---
+ // Variables
+
+ sc_fifo tx_fifo;
+ sc_fifo rx_fifo;
+
+ scoreboard *sb;
+ scoreboard::sbSourceId sb_id;
+
+ public:
+
+ //---
+ // Variables
+
+ bool disable_rx;
+ bool allow_rx_sop_err;
+
+ //---
+ // Functions
+
+ sc_fifo * get_tx_fifo_ptr();
+ sc_fifo * get_rx_fifo_ptr();
+
+ void init(void);
+ void connect_scoreboard(scoreboard *sbptr, scoreboard::sbSourceId sid);
+
+ //---
+ // Threads
+
+ void transmit();
+ void receive();
+
+ SC_CTOR(pkt_if) :
+ tx_fifo (2),
+ rx_fifo (2) {
+
+ SC_CTHREAD (transmit, clk_156m25.pos());
+
+ SC_CTHREAD (receive, clk_156m25.pos());
+
+ }
+
+};
+
+#endif
sc_pkt_if.h
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: sc_main.cpp
===================================================================
--- sc_main.cpp (nonexistent)
+++ sc_main.cpp (revision 7)
@@ -0,0 +1,263 @@
+// $Id: sc_main.cpp,v 1.3 2008-06-07 02:59:55 antanguay Exp $ -*- SystemC -*-
+// DESCRIPTION: Verilator Example: Top level main for invoking SystemC model
+//
+// Copyright 2003-2008 by Wilson Snyder. This program is free software; you can
+// redistribute it and/or modify it under the terms of either the GNU
+// General Public License or the Perl Artistic License.
+//====================================================================
+
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// File name "sc_main.cpp" ////
+//// ////
+//// This file is part of the "10GE MAC" project ////
+//// http://www.opencores.org/cores/xge_mac/ ////
+//// ////
+//// Author(s): ////
+//// - A. Tanguay (antanguay@opencores.org) ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2008 AUTHORS. All rights reserved. ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer. ////
+//// ////
+//// This source file is free software; you can redistribute it ////
+//// and/or modify it under the terms of the GNU Lesser General ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any ////
+//// later version. ////
+//// ////
+//// This source is distributed in the hope that it will be ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
+//// PURPOSE. See the GNU Lesser General Public License for more ////
+//// details. ////
+//// ////
+//// You should have received a copy of the GNU Lesser General ////
+//// Public License along with this source; if not, download it ////
+//// from http://www.opencores.org/lgpl.shtml ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+
+#include
+#include
+#include
+#include
+
+#include "systemc.h" // SystemC global header
+#include "SpTraceVcd.h"
+
+#include "crc.h"
+
+#include "Vxge_mac.h" // Top level header, generated from verilog
+
+#include "sc_testbench.h"
+#include "sc_testcases.h"
+
+
+int sc_main(int argc, char* argv[]) {
+
+ chksum_crc32gentab();
+
+ Verilated::randReset(2);
+ Verilated::debug(0); // We compiled with it on for testing, turn it back off
+
+ // General logfile
+ ios::sync_with_stdio();
+
+ cout << ("Defining Clocks\n");
+
+ sc_clock clk_156m25 ("clk_156m25", 10, 0.5, 3, true);
+ sc_clock clk_wb ("clk_wb", 29, 0.5, 3, true);
+ sc_clock clk_xgmii ("clk_xgmii", 10, 0.5, 3, true);
+
+ sc_signal pkt_rx_ren;
+ sc_signal > pkt_tx_data;
+ sc_signal pkt_tx_eop;
+ sc_signal pkt_tx_mod;
+ sc_signal pkt_tx_sop;
+ sc_signal pkt_tx_val;
+ sc_signal reset_156m25_n;
+ sc_signal reset_xgmii_n;
+ sc_signal wb_adr_i;
+ sc_signal wb_cyc_i;
+ sc_signal wb_dat_i;
+ sc_signal wb_rst_i;
+ sc_signal wb_stb_i;
+ sc_signal wb_we_i;
+ sc_signal xgmii_rxc;
+ sc_signal > xgmii_rxd;
+
+ sc_signal pkt_rx_avail;
+ sc_signal > pkt_rx_data;
+ sc_signal pkt_rx_eop;
+ sc_signal pkt_rx_mod;
+ sc_signal pkt_rx_sop;
+ sc_signal pkt_rx_val;
+ sc_signal pkt_rx_err;
+ sc_signal pkt_tx_full;
+ sc_signal wb_ack_o;
+ sc_signal wb_dat_o;
+ sc_signal wb_int_o;
+ sc_signal xgmii_txc;
+ sc_signal > xgmii_txd;
+
+ //==========
+ // Part under test
+
+ Vxge_mac* top = new Vxge_mac("top");
+
+ top->clk_156m25 (clk_156m25);
+ top->clk_xgmii_rx (clk_xgmii);
+ top->clk_xgmii_tx (clk_xgmii);
+
+ top->pkt_rx_ren (pkt_rx_ren);
+ top->pkt_tx_data (pkt_tx_data);
+ top->pkt_tx_eop (pkt_tx_eop);
+ top->pkt_tx_mod (pkt_tx_mod);
+ top->pkt_tx_sop (pkt_tx_sop);
+ top->pkt_tx_val (pkt_tx_val);
+ top->reset_156m25_n (reset_156m25_n);
+ top->reset_xgmii_rx_n (reset_xgmii_n);
+ top->reset_xgmii_tx_n (reset_xgmii_n);
+ top->wb_adr_i (wb_adr_i);
+ top->wb_clk_i (clk_wb);
+ top->wb_cyc_i (wb_cyc_i);
+ top->wb_dat_i (wb_dat_i);
+ top->wb_rst_i (wb_rst_i);
+ top->wb_stb_i (wb_stb_i);
+ top->wb_we_i (wb_we_i);
+ top->xgmii_rxc (xgmii_rxc);
+ top->xgmii_rxd (xgmii_rxd);
+
+ top->pkt_rx_avail (pkt_rx_avail);
+ top->pkt_rx_data (pkt_rx_data);
+ top->pkt_rx_eop (pkt_rx_eop);
+ top->pkt_rx_mod (pkt_rx_mod);
+ top->pkt_rx_err (pkt_rx_err);
+ top->pkt_rx_sop (pkt_rx_sop);
+ top->pkt_rx_val (pkt_rx_val);
+ top->pkt_tx_full (pkt_tx_full);
+ top->wb_ack_o (wb_ack_o);
+ top->wb_dat_o (wb_dat_o);
+ top->wb_int_o (wb_int_o);
+ top->xgmii_txc (xgmii_txc);
+ top->xgmii_txd (xgmii_txd);
+
+ //==========
+ // Testbench
+
+ testbench* tb = new testbench("tb");
+
+ tb->clk_156m25 (clk_156m25);
+ tb->clk_xgmii (clk_xgmii);
+ tb->wb_clk_i (clk_wb);
+
+ tb->reset_156m25_n (reset_156m25_n);
+ tb->reset_xgmii_n (reset_xgmii_n);
+ tb->wb_rst_i (wb_rst_i);
+
+ tb->wb_ack_o (wb_ack_o);
+ tb->wb_dat_o (wb_dat_o);
+ tb->wb_int_o (wb_int_o);
+
+ tb->wb_adr_i (wb_adr_i);
+ tb->wb_cyc_i (wb_cyc_i);
+ tb->wb_dat_i (wb_dat_i);
+ tb->wb_stb_i (wb_stb_i);
+ tb->wb_we_i (wb_we_i);
+
+ tb->xgmii_rxc (xgmii_rxc);
+ tb->xgmii_rxd (xgmii_rxd);
+
+ tb->xgmii_txc (xgmii_txc);
+ tb->xgmii_txd (xgmii_txd);
+
+ tb->pkt_tx_data (pkt_tx_data);
+ tb->pkt_tx_eop (pkt_tx_eop);
+ tb->pkt_tx_mod (pkt_tx_mod);
+ tb->pkt_tx_sop (pkt_tx_sop);
+ tb->pkt_tx_val (pkt_tx_val);
+
+ tb->pkt_tx_full (pkt_tx_full);
+
+ tb->pkt_rx_avail (pkt_rx_avail);
+ tb->pkt_rx_data (pkt_rx_data);
+ tb->pkt_rx_eop (pkt_rx_eop);
+ tb->pkt_rx_mod (pkt_rx_mod);
+ tb->pkt_rx_err (pkt_rx_err);
+ tb->pkt_rx_sop (pkt_rx_sop);
+ tb->pkt_rx_val (pkt_rx_val);
+
+ tb->pkt_rx_ren (pkt_rx_ren);
+
+ //==========
+ // Testcases
+ testcases* tc = new testcases("tc");
+
+ tc->connect_testbench(tb);
+
+
+#if WAVES
+ // Before any evaluation, need to know to calculate those signals only used for tracing
+ Verilated::traceEverOn(true);
+#endif
+
+ // You must do one evaluation before enabling waves, in order to allow
+ // SystemC to interconnect everything for testing.
+ cout <<("Test initialization...\n");
+
+ sc_start(1);
+
+ reset_156m25_n = 0;
+ wb_rst_i = 1;
+ reset_xgmii_n = 0;
+
+ sc_start(1);
+
+#if WAVES
+ cout << "Enabling waves...\n";
+ SpTraceFile* tfp = new SpTraceFile;
+ top->trace (tfp, 99);
+ tfp->open ("vl_dump.vcd");
+#endif
+
+ //==========
+ // Start of Test
+
+ cout <<("Test beginning...\n");
+
+ reset_156m25_n = 0;
+ wb_rst_i = 1;
+ reset_xgmii_n = 0;
+
+ while (!tc->done) {
+
+#if WAVES
+ tfp->flush();
+#endif
+ if (VL_TIME_Q() > 10) {
+ reset_156m25_n = 1;
+ wb_rst_i = 0;
+ reset_xgmii_n = 1;
+ }
+
+ sc_start(1);
+ }
+
+ top->final();
+
+#if WAVES
+ tfp->close();
+#endif
+
+ cout << "*-* All Finished *-*\n";
+
+ return(0);
+}
+
+
sc_main.cpp
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: sc_testbench.h
===================================================================
--- sc_testbench.h (nonexistent)
+++ sc_testbench.h (revision 7)
@@ -0,0 +1,194 @@
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// File name "sc_testbench.h" ////
+//// ////
+//// This file is part of the "10GE MAC" project ////
+//// http://www.opencores.org/cores/xge_mac/ ////
+//// ////
+//// Author(s): ////
+//// - A. Tanguay (antanguay@opencores.org) ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2008 AUTHORS. All rights reserved. ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer. ////
+//// ////
+//// This source file is free software; you can redistribute it ////
+//// and/or modify it under the terms of the GNU Lesser General ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any ////
+//// later version. ////
+//// ////
+//// This source is distributed in the hope that it will be ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
+//// PURPOSE. See the GNU Lesser General Public License for more ////
+//// details. ////
+//// ////
+//// You should have received a copy of the GNU Lesser General ////
+//// Public License along with this source; if not, download it ////
+//// from http://www.opencores.org/lgpl.shtml ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+
+#ifndef TESTBENCH_H
+#define TESTBENCH_H
+
+#include "systemc.h" // SystemC global header
+
+#include "sc_cpu_if.h"
+#include "sc_pkt_if.h"
+#include "sc_xgmii_if.h"
+#include "sc_pkt_generator.h"
+#include "sc_scoreboard.h"
+
+SC_MODULE(testbench) {
+
+ public:
+
+ //---
+ // Ports
+
+ sc_in clk_156m25;
+ sc_in clk_xgmii;
+ sc_in wb_clk_i;
+
+ sc_in reset_156m25_n;
+ sc_in reset_xgmii_n;
+ sc_in wb_rst_i;
+
+ sc_in wb_ack_o;
+ sc_in wb_dat_o;
+ sc_in wb_int_o;
+
+ sc_out wb_adr_i;
+ sc_out wb_cyc_i;
+ sc_out wb_dat_i;
+ sc_out wb_stb_i;
+ sc_out wb_we_i;
+
+ sc_out xgmii_rxc;
+ sc_out > xgmii_rxd;
+
+ sc_in xgmii_txc;
+ sc_in > xgmii_txd;
+
+ sc_out > pkt_tx_data;
+ sc_out pkt_tx_eop;
+ sc_out pkt_tx_mod;
+ sc_out pkt_tx_sop;
+ sc_out pkt_tx_val;
+
+ sc_in pkt_tx_full;
+
+ sc_in pkt_rx_avail;
+ sc_in > pkt_rx_data;
+ sc_in pkt_rx_eop;
+ sc_in pkt_rx_mod;
+ sc_in pkt_rx_err;
+ sc_in pkt_rx_sop;
+ sc_in pkt_rx_val;
+
+ sc_out pkt_rx_ren;
+
+ //---
+ // Instances
+
+ cpu_if cpu_if0;
+
+ pkt_if pkt_if0;
+ xgmii_if xgm_if0;
+
+ pkt_generator pif_gen0;
+ pkt_generator xgm_gen0;
+
+ scoreboard sb;
+
+ //---
+ // Functions
+
+ SC_CTOR(testbench) :
+ cpu_if0("cpu_if0"),
+ pkt_if0("pkt_if0"),
+ xgm_if0("xgm_if0"),
+ pif_gen0("pif_gen0"),
+ xgm_gen0("xgm_gen0"),
+ sb("sb") {
+
+ //--
+ // CPU Interface
+
+ cpu_if0.wb_clk_i (wb_clk_i);
+
+ cpu_if0.wb_rst_i (wb_rst_i);
+
+ cpu_if0.wb_ack_o (wb_ack_o);
+ cpu_if0.wb_dat_o (wb_dat_o);
+ cpu_if0.wb_int_o (wb_int_o);
+
+ cpu_if0.wb_adr_i (wb_adr_i);
+ cpu_if0.wb_cyc_i (wb_cyc_i);
+ cpu_if0.wb_dat_i (wb_dat_i);
+ cpu_if0.wb_stb_i (wb_stb_i);
+ cpu_if0.wb_we_i (wb_we_i);
+
+ //---
+ // Packet Interface
+
+ pkt_if0.clk_156m25 (clk_156m25);
+
+ pkt_if0.reset_156m25_n (reset_156m25_n);
+
+ pkt_if0.pkt_tx_data (pkt_tx_data);
+ pkt_if0.pkt_tx_eop (pkt_tx_eop);
+ pkt_if0.pkt_tx_mod (pkt_tx_mod);
+ pkt_if0.pkt_tx_sop (pkt_tx_sop);
+ pkt_if0.pkt_tx_val (pkt_tx_val);
+
+ pkt_if0.pkt_tx_full (pkt_tx_full);
+
+ pkt_if0.pkt_rx_avail (pkt_rx_avail);
+ pkt_if0.pkt_rx_data (pkt_rx_data);
+ pkt_if0.pkt_rx_eop (pkt_rx_eop);
+ pkt_if0.pkt_rx_mod (pkt_rx_mod);
+ pkt_if0.pkt_rx_err (pkt_rx_err);
+ pkt_if0.pkt_rx_sop (pkt_rx_sop);
+ pkt_if0.pkt_rx_val (pkt_rx_val);
+
+ pkt_if0.pkt_rx_ren (pkt_rx_ren);
+
+ //---
+ // XGMII Interface
+
+ xgm_if0.clk_xgmii (clk_xgmii);
+
+ xgm_if0.reset_xgmii_n (reset_xgmii_n);
+
+ xgm_if0.xgmii_rxc (xgmii_rxc);
+ xgm_if0.xgmii_rxd (xgmii_rxd);
+
+ xgm_if0.xgmii_txc (xgmii_txc);
+ xgm_if0.xgmii_txd (xgmii_txd);
+
+ //---
+ // Connect packet generators to physical interfaces
+
+ pif_gen0.connect_fifo(pkt_if0.get_tx_fifo_ptr());
+ xgm_gen0.connect_fifo(xgm_if0.get_tx_fifo_ptr());
+
+ //---
+ // Connector scoreboard to components
+
+ pkt_if0.connect_scoreboard(&sb, scoreboard::SB_PIF_ID);
+ xgm_if0.connect_scoreboard(&sb, scoreboard::SB_XGM_ID);
+ cpu_if0.connect_scoreboard(&sb, scoreboard::SB_CPU_ID);
+
+ }
+
+};
+
+#endif
sc_testbench.h
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: sc_testcases.cpp
===================================================================
--- sc_testcases.cpp (nonexistent)
+++ sc_testcases.cpp (revision 7)
@@ -0,0 +1,748 @@
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// File name "sc_testcases.cpp" ////
+//// ////
+//// This file is part of the "10GE MAC" project ////
+//// http://www.opencores.org/cores/xge_mac/ ////
+//// ////
+//// Author(s): ////
+//// - A. Tanguay (antanguay@opencores.org) ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2008 AUTHORS. All rights reserved. ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer. ////
+//// ////
+//// This source file is free software; you can redistribute it ////
+//// and/or modify it under the terms of the GNU Lesser General ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any ////
+//// later version. ////
+//// ////
+//// This source is distributed in the hope that it will be ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
+//// PURPOSE. See the GNU Lesser General Public License for more ////
+//// details. ////
+//// ////
+//// You should have received a copy of the GNU Lesser General ////
+//// Public License along with this source; if not, download it ////
+//// from http://www.opencores.org/lgpl.shtml ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+
+#include "sc_testcases.h"
+
+
+void testcases::connect_testbench(testbench* tbptr) {
+ tb = tbptr;
+}
+
+void testcases::run_tests(void) {
+
+ //---
+ // Init
+
+ tb->pkt_if0.init();
+ tb->xgm_if0.init();
+ tb->cpu_if0.init();
+ tb->pif_gen0.init();
+ tb->xgm_gen0.init();
+ tb->sb.init();
+
+ wait(300, SC_NS);
+
+ tb->cpu_if0.enable_all_interrupts();
+
+
+
+
+// done = true;
+// return;
+ //---
+ // Testcases
+
+ test_packet_size(50, 90, 50);
+ test_packet_size(9000, 9020, 20);
+
+ test_deficit_idle_count();
+
+ test_crc_errors(50, 90, 300, 2);
+ test_crc_errors(9000, 9020, 20, 1);
+
+ test_txdfifo_ovflow();
+ test_rxdfifo_ovflow();
+
+ test_rx_fragments(55, 90, 300, 2);
+ test_rx_coding_err(400, 4);
+
+ test_rx_local_fault(55, 90, 600, 15);
+ test_rx_remote_fault(55, 90, 600, 15);
+
+ test_rx_pause(64, 70, 600, 5);
+
+ test_interrupt_mask();
+
+ done = true;
+
+}
+
+
+void testcases::test_deficit_idle_count(void) {
+
+ int range;
+ int size;
+
+ cout << "-----------------------" << endl;
+ cout << "Deficit IDLE count" << endl;
+ cout << "-----------------------" << endl;
+
+ for (range = 0; range < 8; range++) {
+ for (size = 60; size < 68; size++) {
+ packet_dic(size, size + range);
+ }
+ }
+
+}
+
+
+void testcases::packet_dic(int minsize, int maxsize) {
+
+ sbStats_t* pif_stats;
+ sbStats_t* xgm_stats;
+
+ int cnt = 6;
+ float delta;
+ float cycletime = 6.4;
+ float rate;
+
+ //---
+ // Setup parameters
+
+ tb->sb.clear_stats();
+
+ tb->pif_gen0.set_pkt_size(minsize, maxsize);
+ tb->xgm_gen0.set_pkt_size(minsize, maxsize);
+
+ //---
+ // Enable traffic
+
+ tb->pif_gen0.set_tx_bucket(cnt);
+ tb->xgm_gen0.set_tx_bucket(cnt);
+
+ //---
+ // Wait for test to complete
+
+ while (tb->pif_gen0.get_tx_bucket() != 0) {
+ wait(10, SC_NS);
+ }
+
+ //---
+ // Check traffic
+
+ wait(1000, SC_NS);
+
+ pif_stats = tb->sb.get_pif_stats();
+ xgm_stats = tb->sb.get_xgm_stats();
+
+ if (pif_stats->rx_pkt_cnt != cnt || xgm_stats->rx_pkt_cnt != cnt) {
+ cout << "ERROR: Not all packets received." << endl;
+ sc_stop();
+ }
+
+}
+
+
+void testcases::test_packet_size(int min, int max, int cnt) {
+
+ sbStats_t* pif_stats;
+ sbStats_t* xgm_stats;
+
+ cout << "-----------------------" << endl;
+ cout << "Packet size" << endl;
+ cout << "-----------------------" << endl;
+
+ //---
+ // Setup parameters
+
+ tb->sb.clear_stats();
+
+ tb->pif_gen0.set_pkt_size(min, max);
+ tb->xgm_gen0.set_pkt_size(min, max);
+
+ //---
+ // Enable traffic
+
+ tb->pif_gen0.set_tx_bucket(cnt);
+ tb->xgm_gen0.set_tx_bucket(cnt);
+
+ //---
+ // Wait for test to complete
+
+ while (tb->pif_gen0.get_tx_bucket() != 0) {
+ wait(10, SC_NS);
+ }
+
+ //---
+ // Check traffic
+
+ wait(30000, SC_NS);
+
+ pif_stats = tb->sb.get_pif_stats();
+ xgm_stats = tb->sb.get_xgm_stats();
+
+ if (pif_stats->rx_pkt_cnt != cnt) {
+ cout << "ERROR: Not all packets received by PIF." << endl;
+ cout << pif_stats->rx_pkt_cnt << " " << cnt << endl;
+ sc_stop();
+ }
+
+ if (xgm_stats->rx_pkt_cnt != cnt) {
+ cout << "ERROR: Not all packets received by XGM." << endl;
+ cout << xgm_stats->rx_pkt_cnt << " " << cnt << endl;
+ sc_stop();
+ }
+}
+
+void testcases::test_crc_errors(int min, int max, int cnt, int interval) {
+
+ sbStats_t* pif_stats;
+ sbCpuStats_t* cpu_stats;
+
+ cout << "-----------------------" << endl;
+ cout << "CRC errors" << endl;
+ cout << "-----------------------" << endl;
+
+ //---
+ // Setup parameters
+
+ tb->sb.clear_stats();
+
+ tb->xgm_gen0.set_pkt_size(min, max);
+ tb->xgm_gen0.set_crc_errors(interval);
+ tb->sb.disable_signal_check = true;
+
+ //---
+ // Enable traffic
+
+ tb->xgm_gen0.set_tx_bucket(cnt);
+
+ //---
+ // Wait for test to complete
+
+ while (tb->xgm_gen0.get_tx_bucket() != 0) {
+ wait(10, SC_NS);
+ }
+
+ //---
+ // Check traffic
+
+ wait(30000, SC_NS);
+
+ pif_stats = tb->sb.get_pif_stats();
+ cpu_stats = tb->sb.get_cpu_stats();
+
+ if (pif_stats->rx_pkt_cnt != cnt) {
+ cout << "ERROR: Not all packets received by PIF." << endl;
+ cout << pif_stats->rx_pkt_cnt << " " << cnt << endl;
+ sc_stop();
+ }
+
+ if (cpu_stats->crc_error_cnt != pif_stats->crc_error_cnt) {
+ cout << "ERROR: Not all CRC errors reported to cpu" << endl;
+ sc_stop();
+ }
+
+ //---
+ // Return parameters to default state
+
+ tb->xgm_gen0.set_crc_errors(0);
+ tb->sb.disable_signal_check = false;
+}
+
+void testcases::test_txdfifo_ovflow() {
+
+ sbStats_t* xgm_stats;
+ sbCpuStats_t* cpu_stats;
+
+ cout << "-----------------------" << endl;
+ cout << "TXD FIFO overflow" << endl;
+ cout << "-----------------------" << endl;
+
+ //---
+ // Setup parameters
+
+ tb->sb.clear_stats();
+
+ tb->pif_gen0.set_pkt_size(1000, 1000);
+
+ tb->cpu_if0.set_param(cpu_if::TX_ENABLE, 0);
+ tb->sb.disable_signal_check = true;
+
+ //---
+ // Enable traffic
+
+ tb->pif_gen0.set_tx_bucket(2);
+
+ //---
+ // Wait for packets to be sent
+
+ while (tb->pif_gen0.get_tx_bucket() != 0) {
+ wait(10, SC_NS);
+ }
+
+ wait(30000, SC_NS);
+
+ //---
+ // Check errors reported
+
+ cpu_stats = tb->sb.get_cpu_stats();
+ cout << "Count: " << cpu_stats->txd_fifo_ovflow_cnt << endl;
+ sc_assert(cpu_stats->txd_fifo_ovflow_cnt == 1);
+
+ //---
+ // Flush out bad packets
+
+ tb->xgm_if0.allow_idle_errors = true;
+ tb->sb.disable_packet_check = true;
+ tb->cpu_if0.set_param(cpu_if::TX_ENABLE, 1);
+
+ wait(30000, SC_NS);
+ tb->xgm_if0.allow_idle_errors = false;
+ tb->sb.disable_packet_check = false;
+
+ //---
+ // Check errors reported
+
+ cpu_stats = tb->sb.get_cpu_stats();
+
+ //---
+ // Enable traffic
+
+ tb->pif_gen0.set_tx_bucket(2);
+
+ //---
+ // Wait for packets to be sent
+
+ while (tb->pif_gen0.get_tx_bucket() != 0) {
+ wait(10, SC_NS);
+ }
+
+ wait(30000, SC_NS);
+
+ xgm_stats = tb->sb.get_xgm_stats();
+ sc_assert(xgm_stats->rx_pkt_cnt == 4);
+
+ //---
+ // Return parameters to default state
+
+ tb->cpu_if0.set_param(cpu_if::TX_ENABLE, 1);
+ tb->sb.disable_signal_check = false;
+}
+
+void testcases::test_rxdfifo_ovflow() {
+
+ sbStats_t* pif_stats;
+ sbCpuStats_t* cpu_stats;
+
+ cout << "-----------------------" << endl;
+ cout << "RXD FIFO overflow" << endl;
+ cout << "-----------------------" << endl;
+
+ //---
+ // Setup parameters
+
+ tb->sb.clear_stats();
+
+ tb->xgm_gen0.set_pkt_size(1000, 1000);
+
+ tb->pkt_if0.disable_rx = true;
+ tb->pkt_if0.allow_rx_sop_err = true;
+ tb->sb.disable_flags_check = true;
+ tb->sb.disable_packet_check = true;
+ tb->sb.disable_signal_check = true;
+
+ //---
+ // Enable traffic
+
+ tb->xgm_gen0.set_tx_bucket(3);
+
+ //---
+ // Wait for packets to be sent
+
+ while (tb->xgm_gen0.get_tx_bucket() != 0) {
+ wait(10, SC_NS);
+ }
+
+ wait(30000, SC_NS);
+
+ //---
+ // Check errors reported
+
+ cpu_stats = tb->sb.get_cpu_stats();
+ sc_assert(cpu_stats->rxd_fifo_ovflow_cnt == 2);
+
+ //---
+ // Flush out bad packets
+
+ tb->pkt_if0.disable_rx = false;
+
+ wait(30000, SC_NS);
+
+ //---
+ // Check errors reported
+
+ cpu_stats = tb->sb.get_cpu_stats();
+ tb->sb.clear_stats();
+ tb->sb.disable_flags_check = false;
+ tb->sb.disable_packet_check = false;
+
+ //---
+ // Enable traffic
+
+ tb->xgm_gen0.set_tx_bucket(2);
+
+ //---
+ // Wait for packets to be sent
+
+ while (tb->xgm_gen0.get_tx_bucket() != 0) {
+ wait(10, SC_NS);
+ }
+
+ wait(30000, SC_NS);
+
+ pif_stats = tb->sb.get_pif_stats();
+ sc_assert(pif_stats->rx_pkt_cnt == 2);
+
+ //---
+ // Return parameters to default state
+
+ tb->pkt_if0.allow_rx_sop_err = false;
+ tb->sb.disable_signal_check = false;
+}
+
+void testcases::test_rx_fragments(int min, int max, int cnt, int interval) {
+
+ sbStats_t* pif_stats;
+ sbCpuStats_t* cpu_stats;
+
+ cout << "-----------------------" << endl;
+ cout << "Fragments errors" << endl;
+ cout << "-----------------------" << endl;
+
+ //---
+ // Setup parameters
+
+ tb->sb.clear_stats();
+
+ tb->xgm_gen0.set_pkt_size(min, max);
+ tb->xgm_gen0.set_fragment_errors(interval);
+ tb->sb.disable_signal_check = true;
+
+ //---
+ // Enable traffic
+
+ tb->xgm_gen0.set_tx_bucket(cnt);
+
+ //---
+ // Wait for test to complete
+
+ while (tb->xgm_gen0.get_tx_bucket() != 0) {
+ wait(10, SC_NS);
+ }
+
+ //---
+ // Check traffic
+
+ wait(30000, SC_NS);
+
+ pif_stats = tb->sb.get_pif_stats();
+ cpu_stats = tb->sb.get_cpu_stats();
+
+ if (pif_stats->rx_pkt_cnt != cnt) {
+ cout << "ERROR: Not all packets received by PIF." << endl;
+ cout << pif_stats->rx_pkt_cnt << " " << cnt << endl;
+ sc_stop();
+ }
+
+ if ((cpu_stats->fragment_error_cnt + cpu_stats->crc_error_cnt)
+ != pif_stats->fragment_error_cnt) {
+ cout << "ERROR: Not all fragment errors reported to cpu" << endl;
+ sc_stop();
+ }
+
+ //---
+ // Return parameters to default state
+
+ tb->xgm_gen0.set_fragment_errors(0);
+ tb->sb.disable_signal_check = false;
+}
+
+void testcases::test_rx_coding_err(int cnt, int interval) {
+
+ sbStats_t* pif_stats;
+ sbStats_t* xgm_stats;
+ sbCpuStats_t* cpu_stats;
+
+ cout << "-----------------------" << endl;
+ cout << "Coding errors" << endl;
+ cout << "-----------------------" << endl;
+
+ //---
+ // Setup parameters
+
+ tb->sb.clear_stats();
+
+ tb->xgm_gen0.set_pkt_size(64, 69);
+ tb->xgm_gen0.set_coding_errors(interval);
+ tb->sb.disable_signal_check = true;
+
+ //---
+ // Enable traffic
+
+ tb->xgm_gen0.set_tx_bucket(cnt);
+
+ //---
+ // Wait for test to complete
+
+ while (tb->xgm_gen0.get_tx_bucket() != 0) {
+ wait(10, SC_NS);
+ }
+
+ //---
+ // Check traffic
+
+ wait(30000, SC_NS);
+
+ pif_stats = tb->sb.get_pif_stats();
+ xgm_stats = tb->sb.get_xgm_stats();
+ cpu_stats = tb->sb.get_cpu_stats();
+
+ if (pif_stats->rx_pkt_cnt != xgm_stats->tx_pkt_cnt) {
+ cout << "ERROR: Not all packets received by PIF." << endl;
+ cout << pif_stats->rx_pkt_cnt << " " << xgm_stats->tx_pkt_cnt << endl;
+ sc_stop();
+ }
+
+ if (cpu_stats->crc_error_cnt != xgm_stats->crc_error_cnt) {
+ cout << "ERROR: Not all coding errors reported to cpu" << endl;
+ sc_stop();
+ }
+
+ //---
+ // Return parameters to default state
+
+ tb->xgm_gen0.set_coding_errors(0);
+ tb->sb.disable_signal_check = false;
+}
+
+void testcases::test_rx_local_fault(int min, int max, int cnt, int interval) {
+
+ sbStats_t* pif_stats;
+
+ cout << "-----------------------" << endl;
+ cout << "Local fault" << endl;
+ cout << "-----------------------" << endl;
+
+ //---
+ // Setup parameters
+
+ tb->sb.clear_stats();
+
+ tb->pif_gen0.set_pkt_size(min, max);
+ tb->xgm_gen0.set_pkt_size(min, max);
+
+ tb->xgm_gen0.set_local_fault(interval);
+ tb->sb.disable_signal_check = true;
+ tb->xgm_if0.allow_idle_errors = true;
+ tb->xgm_if0.disable_receive = true;
+
+ //---
+ // Enable traffic
+
+ tb->pif_gen0.set_tx_bucket(cnt);
+ tb->xgm_gen0.set_tx_bucket(cnt);
+
+ //---
+ // Wait for test to complete
+
+ while (tb->xgm_gen0.get_tx_bucket() != 0) {
+ wait(10, SC_NS);
+ }
+
+ //---
+ // Check traffic
+
+ wait(30000, SC_NS);
+
+ pif_stats = tb->sb.get_pif_stats();
+
+ if (pif_stats->rx_pkt_cnt != cnt) {
+ cout << "ERROR: Not all packets received by PIF." << endl;
+ cout << pif_stats->rx_pkt_cnt << " " << cnt << endl;
+ sc_stop();
+ }
+
+ //---
+ // Return parameters to default state
+
+ tb->xgm_gen0.set_local_fault(0);
+ tb->sb.disable_signal_check = false;
+ tb->xgm_if0.allow_idle_errors = false;
+ tb->xgm_if0.disable_receive = false;
+}
+
+void testcases::test_rx_remote_fault(int min, int max, int cnt, int interval) {
+
+ sbStats_t* pif_stats;
+
+ cout << "-----------------------" << endl;
+ cout << "Remote fault" << endl;
+ cout << "-----------------------" << endl;
+
+ //---
+ // Setup parameters
+
+ tb->sb.clear_stats();
+
+ tb->pif_gen0.set_pkt_size(min, max);
+ tb->xgm_gen0.set_pkt_size(min, max);
+
+ tb->xgm_gen0.set_remote_fault(interval);
+ tb->sb.disable_signal_check = true;
+ tb->xgm_if0.allow_idle_errors = true;
+ tb->xgm_if0.disable_receive = true;
+
+ //---
+ // Enable traffic
+
+ tb->pif_gen0.set_tx_bucket(cnt);
+ tb->xgm_gen0.set_tx_bucket(cnt);
+
+ //---
+ // Wait for test to complete
+
+ while (tb->xgm_gen0.get_tx_bucket() != 0) {
+ wait(10, SC_NS);
+ }
+
+ //---
+ // Check traffic
+
+ wait(30000, SC_NS);
+
+ pif_stats = tb->sb.get_pif_stats();
+
+ if (pif_stats->rx_pkt_cnt != cnt) {
+ cout << "ERROR: Not all packets received by PIF." << endl;
+ cout << pif_stats->rx_pkt_cnt << " " << cnt << endl;
+ sc_stop();
+ }
+
+ //---
+ // Return parameters to default state
+
+ tb->xgm_gen0.set_remote_fault(0);
+ tb->sb.disable_signal_check = false;
+ tb->xgm_if0.allow_idle_errors = false;
+ tb->xgm_if0.disable_receive = false;
+}
+
+void testcases::test_rx_pause(int min, int max, int cnt, int interval) {
+
+ sbCpuStats_t* cpu_stats;
+
+ cout << "-----------------------" << endl;
+ cout << "Receive Pause" << endl;
+ cout << "-----------------------" << endl;
+
+ //---
+ // Setup parameters
+
+ tb->sb.clear_stats();
+
+ tb->xgm_gen0.set_pkt_size(min, max);
+
+ tb->xgm_gen0.set_inject_pause(interval);
+ tb->sb.disable_signal_check = true;
+
+ //---
+ // Enable traffic
+
+ tb->xgm_gen0.set_tx_bucket(cnt);
+
+ //---
+ // Wait for test to complete
+
+ while (tb->xgm_gen0.get_tx_bucket() != 0) {
+ wait(10, SC_NS);
+ }
+
+ //---
+ // Check traffic
+
+ wait(30000, SC_NS);
+
+ cpu_stats = tb->sb.get_cpu_stats();
+
+ if (cpu_stats->rx_pause_frame_cnt == 0) {
+ cout << "ERROR: No pause frames received." << endl;
+ sc_stop();
+ }
+
+ //---
+ // Return parameters to default state
+
+ tb->xgm_gen0.set_inject_pause(0);
+ tb->sb.disable_signal_check = false;
+}
+
+void testcases::test_interrupt_mask() {
+
+ sbCpuStats_t* cpu_stats;
+
+ cout << "-----------------------" << endl;
+ cout << "Interrupt Mask" << endl;
+ cout << "-----------------------" << endl;
+
+ //---
+ // Setup parameters
+
+ tb->sb.clear_stats();
+ tb->sb.disable_signal_check = true;
+
+
+ //---
+ // Test unmasked
+
+ tb->cpu_if0.set_interrupt(cpu_if::INT_CRC_ERROR);
+
+ wait(300, SC_NS);
+
+ cpu_stats = tb->sb.get_cpu_stats();
+ sc_assert(cpu_stats->crc_error_cnt == 1);
+
+
+ //---
+ // Test masked
+
+ tb->cpu_if0.set_interrupt_mask(cpu_if::INT_CRC_ERROR, 0);
+ tb->cpu_if0.set_interrupt(cpu_if::INT_CRC_ERROR);
+
+ wait(300, SC_NS);
+
+ cpu_stats = tb->sb.get_cpu_stats();
+ sc_assert(cpu_stats->crc_error_cnt == 1);
+
+
+ //---
+ // Return parameters to default state
+
+ tb->sb.disable_signal_check = false;
+ tb->cpu_if0.set_interrupt_mask(cpu_if::INT_CRC_ERROR, 1);
+}
+
sc_testcases.cpp
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: sc_pkt_generator.h
===================================================================
--- sc_pkt_generator.h (nonexistent)
+++ sc_pkt_generator.h (revision 7)
@@ -0,0 +1,105 @@
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// File name "sc_pkt_generator.h" ////
+//// ////
+//// This file is part of the "10GE MAC" project ////
+//// http://www.opencores.org/cores/xge_mac/ ////
+//// ////
+//// Author(s): ////
+//// - A. Tanguay (antanguay@opencores.org) ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2008 AUTHORS. All rights reserved. ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer. ////
+//// ////
+//// This source file is free software; you can redistribute it ////
+//// and/or modify it under the terms of the GNU Lesser General ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any ////
+//// later version. ////
+//// ////
+//// This source is distributed in the hope that it will be ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
+//// PURPOSE. See the GNU Lesser General Public License for more ////
+//// details. ////
+//// ////
+//// You should have received a copy of the GNU Lesser General ////
+//// Public License along with this source; if not, download it ////
+//// from http://www.opencores.org/lgpl.shtml ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+
+#ifndef GENERATOR_H
+#define GENERATOR_H
+
+#include "systemc.h"
+
+#include "sc_packet.h"
+
+SC_MODULE(pkt_generator) {
+
+ private:
+
+ //---
+ // Variables
+
+ sc_fifo * tx_fifo;
+
+ int tx_bucket;
+
+ int min_pkt_size;
+ int max_pkt_size;
+
+ int crc_interval;
+ int fragment_interval;
+ int coding_interval;
+ int local_fault_interval;
+ int remote_fault_interval;
+ int inject_pause_interval;
+
+ public:
+
+ //---
+ // Functions
+
+ void init(void);
+
+ void connect_fifo(sc_fifo * fifo);
+
+ void set_tx_bucket(int cnt);
+ int get_tx_bucket(void);
+
+ void set_pkt_size(int min, int max);
+
+ void set_crc_errors(int interval);
+ void set_fragment_errors(int interval);
+ void set_coding_errors(int interval);
+ void set_local_fault(int interval);
+ void set_remote_fault(int interval);
+ void set_inject_pause(int interval);
+
+ //---
+ // Threads
+
+ void gen_packet();
+
+ SC_CTOR(pkt_generator) {
+
+ tx_bucket = 0;
+
+ min_pkt_size = 64;
+ max_pkt_size = 72;
+
+ SC_THREAD (gen_packet);
+
+ }
+
+};
+
+#endif
sc_pkt_generator.h
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: sc_cpu_if.h
===================================================================
--- sc_cpu_if.h (nonexistent)
+++ sc_cpu_if.h (revision 7)
@@ -0,0 +1,144 @@
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// File name "sc_cpu_if.h" ////
+//// ////
+//// This file is part of the "10GE MAC" project ////
+//// http://www.opencores.org/cores/xge_mac/ ////
+//// ////
+//// Author(s): ////
+//// - A. Tanguay (antanguay@opencores.org) ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2008 AUTHORS. All rights reserved. ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer. ////
+//// ////
+//// This source file is free software; you can redistribute it ////
+//// and/or modify it under the terms of the GNU Lesser General ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any ////
+//// later version. ////
+//// ////
+//// This source is distributed in the hope that it will be ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
+//// PURPOSE. See the GNU Lesser General Public License for more ////
+//// details. ////
+//// ////
+//// You should have received a copy of the GNU Lesser General ////
+//// Public License along with this source; if not, download it ////
+//// from http://www.opencores.org/lgpl.shtml ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+
+#ifndef CPU_IF_H
+#define CPU_IF_H
+
+#include "systemc.h"
+
+#include "sc_scoreboard.h"
+#include "sc_cpu_if.h"
+
+SC_MODULE(cpu_if) {
+
+ public:
+
+ //---
+ // Ports
+
+ sc_in wb_clk_i;
+
+ sc_in wb_rst_i;
+
+ sc_in wb_ack_o;
+ sc_in wb_dat_o;
+ sc_in wb_int_o;
+
+ sc_out wb_adr_i;
+ sc_out wb_cyc_i;
+ sc_out wb_dat_i;
+ sc_out wb_stb_i;
+ sc_out wb_we_i;
+
+ //---
+ // Types
+
+ enum paramId {
+ TX_ENABLE,
+ };
+
+ enum intId {
+ INT_TXD_FIFO_OVFLOW = 0,
+ INT_TXD_FIFO_UDFLOW = 1,
+ INT_RXD_FIFO_OVFLOW = 2,
+ INT_RXD_FIFO_UDFLOW = 3,
+ INT_LOCAL_FAULT = 4,
+ INT_REMOTE_FAULT = 5,
+ INT_PAUSE_FRAME = 6,
+ INT_CRC_ERROR = 7,
+ INT_FRAGMENT_ERROR = 8,
+ };
+
+ enum regId {
+ CPUREG_CONFIG0 = 0x0,
+
+ CPUREG_INT_PENDING = 0x8,
+ CPUREG_INT_STATUS = 0xc,
+ CPUREG_INT_MASK = 0x10,
+ };
+
+ private:
+
+ //---
+ // Variables
+
+ scoreboard *sb;
+ scoreboard::sbSourceId sb_id;
+
+ sc_mutex bus_lock;
+ sc_event bus_start;
+ sc_semaphore bus_done;
+
+ uint bus_addr;
+ uint bus_data;
+ bool bus_write;
+
+ public:
+
+ //---
+ // Variables
+
+ //---
+ // Functions
+
+ void init();
+ void connect_scoreboard(scoreboard *sbptr, scoreboard::sbSourceId sid);
+ void set_param(cpu_if::paramId param, int value);
+ void set_interrupt(cpu_if::intId intr);
+ void set_interrupt_mask(cpu_if::intId intr, bool value);
+ void enable_all_interrupts(void);
+
+ uint read(uint addr);
+ void write(uint addr, uint data);
+ void writebits(uint addr, uint hbit, uint lbit, uint value);
+
+ //---
+ // Threads
+
+ void transactor();
+ void monitor();
+
+ SC_CTOR(cpu_if): bus_done(0) {
+
+ SC_CTHREAD (monitor, wb_clk_i.pos());
+ SC_CTHREAD (transactor, wb_clk_i.pos());
+
+ }
+
+};
+
+#endif
sc_cpu_if.h
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: sc_packet.h
===================================================================
--- sc_packet.h (nonexistent)
+++ sc_packet.h (revision 7)
@@ -0,0 +1,88 @@
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// File name "sc_packet.h" ////
+//// ////
+//// This file is part of the "10GE MAC" project ////
+//// http://www.opencores.org/cores/xge_mac/ ////
+//// ////
+//// Author(s): ////
+//// - A. Tanguay (antanguay@opencores.org) ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2008 AUTHORS. All rights reserved. ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer. ////
+//// ////
+//// This source file is free software; you can redistribute it ////
+//// and/or modify it under the terms of the GNU Lesser General ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any ////
+//// later version. ////
+//// ////
+//// This source is distributed in the hope that it will be ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
+//// PURPOSE. See the GNU Lesser General Public License for more ////
+//// details. ////
+//// ////
+//// You should have received a copy of the GNU Lesser General ////
+//// Public License along with this source; if not, download it ////
+//// from http://www.opencores.org/lgpl.shtml ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+
+#ifndef PACKET_H
+#define PACKET_H
+
+#include "systemc.h"
+
+
+#define PKT_FLAG_ERR_SIG 0x0001
+#define PKT_FLAG_ERR_SOP 0x0002
+#define PKT_FLAG_ERR_CRC 0x0004
+#define PKT_FLAG_ERR_FRG 0x0008
+#define PKT_FLAG_ERR_CODING 0x0010
+#define PKT_FLAG_LOCAL_FAULT 0x0020
+#define PKT_FLAG_REMOTE_FAULT 0x0040
+
+
+struct packet_t {
+
+ int length;
+
+ // Packet fields
+
+ sc_uint<48> dest_addr;
+ sc_uint<48> src_addr;
+ sc_uint<8> payload [12000];
+ sc_uint<32> crc;
+
+ sc_uint<32> crc_rx;
+ sc_uint<32> err_flags;
+ sc_uint<32> err_info;
+
+ sc_uint<32> ifg;
+ sc_uint<32> start_lane;
+
+ sc_uint<8> data [10000];
+};
+
+ostream& operator<<(ostream& os, const packet_t& p);
+
+void pack(packet_t* p);
+void unpack(packet_t* p);
+
+void add_crc(packet_t* p);
+void strip_crc(packet_t* p);
+
+void calc_crc(packet_t* p);
+
+void pad(packet_t* p, int len);
+
+bool compare(packet_t* pkta, packet_t* pktb);
+
+#endif
sc_packet.h
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: sc_testbench.cpp
===================================================================
--- sc_testbench.cpp (nonexistent)
+++ sc_testbench.cpp (revision 7)
@@ -0,0 +1,46 @@
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// File name "sc_testbench.cpp" ////
+//// ////
+//// This file is part of the "10GE MAC" project ////
+//// http://www.opencores.org/cores/xge_mac/ ////
+//// ////
+//// Author(s): ////
+//// - A. Tanguay (antanguay@opencores.org) ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2008 AUTHORS. All rights reserved. ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer. ////
+//// ////
+//// This source file is free software; you can redistribute it ////
+//// and/or modify it under the terms of the GNU Lesser General ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any ////
+//// later version. ////
+//// ////
+//// This source is distributed in the hope that it will be ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
+//// PURPOSE. See the GNU Lesser General Public License for more ////
+//// details. ////
+//// ////
+//// You should have received a copy of the GNU Lesser General ////
+//// Public License along with this source; if not, download it ////
+//// from http://www.opencores.org/lgpl.shtml ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+
+#include
+#include
+#include
+#include
+
+#include "systemc.h"
+
+
+
sc_testbench.cpp
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: crc.cpp
===================================================================
--- crc.cpp (nonexistent)
+++ crc.cpp (revision 7)
@@ -0,0 +1,72 @@
+/*
+ * efone - Distributed internet phone system.
+ *
+ * (c) 1999,2000 Krzysztof Dabrowski
+ * (c) 1999,2000 ElysiuM deeZine
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ */
+
+/* based on implementation by Finn Yannick Jacobs */
+
+#include
+#include
+
+#include
+
+/* crc_tab[] -- this crcTable is being build by chksum_crc32GenTab().
+ * so make sure, you call it before using the other
+ * functions!
+ */
+u_int32_t crc_tab[256];
+
+/* chksum_crc() -- to a given block, this one calculates the
+ * crc32-checksum until the length is
+ * reached. the crc32-checksum will be
+ * the result.
+ */
+u_int32_t chksum_crc32 (sc_uint<8> *block, unsigned int length)
+{
+ register unsigned long crc;
+ unsigned long i;
+
+ crc = 0xFFFFFFFF;
+ for (i = 0; i < length; i++)
+ {
+ crc = ((crc >> 8) & 0x00FFFFFF) ^ crc_tab[(crc ^ *block++) & 0xFF];
+ }
+ return (crc ^ 0xFFFFFFFF);
+}
+
+/* chksum_crc32gentab() -- to a global crc_tab[256], this one will
+ * calculate the crcTable for crc32-checksums.
+ * it is generated to the polynom [..]
+ */
+
+void chksum_crc32gentab ()
+{
+ unsigned long crc, poly;
+ int i, j;
+
+ poly = 0xEDB88320L;
+ for (i = 0; i < 256; i++)
+ {
+ crc = i;
+ for (j = 8; j > 0; j--)
+ {
+ if (crc & 1)
+ {
+ crc = (crc >> 1) ^ poly;
+ }
+ else
+ {
+ crc >>= 1;
+ }
+ }
+ crc_tab[i] = crc;
+ }
+}
crc.cpp
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: sc_scoreboard.cpp
===================================================================
--- sc_scoreboard.cpp (nonexistent)
+++ sc_scoreboard.cpp (revision 7)
@@ -0,0 +1,511 @@
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// File name "sc_scoreboard.cpp" ////
+//// ////
+//// This file is part of the "10GE MAC" project ////
+//// http://www.opencores.org/cores/xge_mac/ ////
+//// ////
+//// Author(s): ////
+//// - A. Tanguay (antanguay@opencores.org) ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2008 AUTHORS. All rights reserved. ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer. ////
+//// ////
+//// This source file is free software; you can redistribute it ////
+//// and/or modify it under the terms of the GNU Lesser General ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any ////
+//// later version. ////
+//// ////
+//// This source is distributed in the hope that it will be ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
+//// PURPOSE. See the GNU Lesser General Public License for more ////
+//// details. ////
+//// ////
+//// You should have received a copy of the GNU Lesser General ////
+//// Public License along with this source; if not, download it ////
+//// from http://www.opencores.org/lgpl.shtml ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+
+#include
+#include
+#include
+#include
+
+#include "systemc.h"
+
+#include "sc_scoreboard.h"
+
+
+void scoreboard::init(void) {
+ disable_padding = false;
+ disable_crc_check = false;
+ disable_packet_check = false;
+ disable_flags_check = false;
+ disable_signal_check = false;
+}
+
+void scoreboard::notify_packet_tx(sbSourceId sid, packet_t* pkt) {
+
+ //---
+ // Save packet to a fifo
+
+ if (sid == SB_PIF_ID) {
+ cout << "SCOREBOARD PACKET INTERFACE TX ("
+ << pkt->length << ")" << endl;
+
+ //---
+ // Store packet in scoreboard
+
+ pif_fifo.write(pkt);
+ pif_stats.tx_pkt_cnt++;
+
+ }
+
+ if (sid == SB_XGM_ID) {
+
+ cout << "SCOREBOARD XGMII INTERFACE TX ("
+ << pkt->length << ")" << endl;
+
+ //---
+ // Store packet in scoreboard
+
+ if (sid == SB_XGM_ID && (pkt->dest_addr & 0xffff) == 0x000001 &&
+ ((pkt->dest_addr >> 24) & 0xffffff) == 0x0180c2) {
+
+ // Pause frames will be dropped
+ cout << "SCOREBOARD PAUSE INJECTED" << endl;
+ xgm_stats.inject_pause_frame_cnt++;
+
+ }
+ else {
+
+ xgm_fifo.write(pkt);
+ xgm_stats.tx_pkt_cnt++;
+
+ }
+
+ }
+
+ //---
+ // Update stats
+
+ if (sid == SB_XGM_ID && pkt->err_flags & PKT_FLAG_ERR_CODING) {
+ xgm_stats.crc_error_cnt++;
+ }
+
+ if (sid == SB_XGM_ID && pkt->err_flags & PKT_FLAG_LOCAL_FAULT) {
+ // If less than 4 faults in 128 columns, it will not be detected
+ if (pkt->err_info <= (128 - 4)) {
+ xgm_stats.inject_local_fault_cnt++;
+ }
+ }
+
+ if (sid == SB_XGM_ID && pkt->err_flags & PKT_FLAG_REMOTE_FAULT) {
+ // If less than 4 faults in 128 columns, it will not be detected
+ if (pkt->err_info <= (128 - 4)) {
+ xgm_stats.inject_remote_fault_cnt++;
+ }
+ }
+
+ //cout << *pkt << endl;
+}
+
+void scoreboard::notify_packet_rx(sbSourceId sid, packet_t* pkt) {
+
+ sbStats_t* stats;
+
+ packet_t* pkt_tx;
+ bool status;
+
+ //---
+ // Read matching packet from fifo
+
+ if (sid == SB_PIF_ID) {
+ status = xgm_fifo.nb_read(pkt_tx);
+ if (status) {
+ cout << "SCOREBOARD PACKET INTERFACE RX (TX SIZE="
+ << pkt_tx->length << " RX SIZE="
+ << pkt->length << ")" << endl;
+ }
+ }
+
+ if (sid == SB_XGM_ID) {
+ status = pif_fifo.nb_read(pkt_tx);
+ if (status) {
+ cout << "SCOREBOARD XGMII INTERFACE RX (TX SIZE="
+ << pkt_tx->length << " RX SIZE="
+ << pkt->length << ")" << endl;
+ }
+ }
+
+ if (!status) {
+ cout << "ERROR: FIFO EMPTY" << endl;
+ sc_stop();
+ }
+
+ //---
+ // Update stats
+
+ if (sid == SB_PIF_ID) {
+ stats = &pif_stats;
+ }
+
+ if (sid == SB_XGM_ID) {
+ stats = &xgm_stats;
+ }
+
+ stats->rx_pkt_cnt++;
+
+ if (stats->timestamp_first_pkt == 0) {
+ stats->timestamp_first_pkt = sc_simulation_time();
+ }
+
+ stats->timestamp_last_pkt = sc_simulation_time();
+
+ //---
+ // Pad packet if it expected to be padded by MAC
+
+ if (sid == SB_XGM_ID && !disable_padding) {
+ pad(pkt_tx, 60);
+ }
+
+ //---
+ // Calculate CRC
+
+ calc_crc(pkt_tx);
+ calc_crc(pkt);
+
+ //cout << *pkt_tx << *pkt << endl;
+
+ //---
+ // Compare TX and RX packets
+
+ if (disable_packet_check) {
+
+ cout << "INFO: Packet check disabled" << endl;
+
+ }
+ else if ((pkt_tx->err_flags & PKT_FLAG_ERR_FRG) &&
+ (pkt->err_flags |= PKT_FLAG_ERR_SIG)) {
+
+ cout << "INFO: Fragment detected" << endl;
+
+ }
+ else if ((pkt_tx->err_flags & PKT_FLAG_ERR_CODING) &&
+ (pkt->err_flags |= PKT_FLAG_ERR_SIG)) {
+
+ cout << "INFO: Coding error detected:" << pkt_tx->err_info << endl;
+
+ }
+ else if ((sid == SB_PIF_ID || pkt->crc == pkt->crc_rx || disable_crc_check) &&
+ compare(pkt_tx, pkt)) {
+
+ //cout << "GOOD: Packets are matching" << endl;
+
+ }
+ else {
+
+ cout << "ERROR: Packets don't match or bad CRC" << endl;
+
+ cout << "<<<" << endl;
+ cout << *pkt_tx << endl;
+ cout << *pkt << endl;
+ cout << ">>>" << endl;
+
+ sc_stop();
+
+ }
+
+ //---
+ // Check IFG against predicted IFG
+
+ if (sid == SB_XGM_ID) {
+
+ cout << "PKTMOD " << pkt->length % 4 \
+ << " LANE " << pkt->start_lane \
+ << " DIC " << stats->deficit_idle_count \
+ << " IFGLEN " << stats->next_ifg_length << endl;
+
+ if (pkt->ifg < 1000 && stats->next_ifg_length != 1000) {
+ if (pkt->ifg != stats->next_ifg_length) {
+ cout << "ERROR: DIC IFG " << pkt->ifg \
+ << " Predicted: " << stats->next_ifg_length << endl;
+ sc_stop();
+ }
+ }
+
+ }
+
+ //---
+ // Update deficit idle count and predict IFG
+
+ if (sid == SB_XGM_ID) {
+
+ stats->next_ifg_length = 12 - (pkt->length % 4);
+ stats->deficit_idle_count += (pkt->length % 4);
+ if (stats->deficit_idle_count > 3) {
+ stats->next_ifg_length += 4;
+ stats->deficit_idle_count = stats->deficit_idle_count % 4;
+ }
+ }
+
+ //---
+ // Check error flags
+
+ // CRC ERRORS
+
+ if (sid == SB_PIF_ID && (pkt_tx->err_flags & PKT_FLAG_ERR_CRC)) {
+
+ if (pkt->err_flags & PKT_FLAG_ERR_SIG) {
+
+ cout << "SCOREBOARD CRC ERROR CHECKED" << endl;
+ pif_stats.crc_error_cnt++;
+
+ if (cpu_stats.crc_error_cnt+1 < pif_stats.crc_error_cnt) {
+ cout << "ERROR: CRC error not reported to cpu" << endl;
+ sc_stop();
+ }
+ }
+ else {
+ cout << "ERROR: CRC error not detected: " << hex << pkt->err_flags << dec << endl;
+ sc_stop();
+ }
+
+ pkt->err_flags &= ~PKT_FLAG_ERR_SIG;
+ }
+
+
+ // FRAGMENT ERRORS
+
+ if (sid == SB_PIF_ID && (pkt_tx->err_flags & PKT_FLAG_ERR_FRG)) {
+
+ if (pkt->err_flags & PKT_FLAG_ERR_SIG) {
+
+ cout << "SCOREBOARD FRAGMENT ERROR CHECKED" << endl;
+ pif_stats.fragment_error_cnt++;
+
+ if ((cpu_stats.fragment_error_cnt + cpu_stats.crc_error_cnt + 1)
+ < pif_stats.fragment_error_cnt) {
+ cout << "ERROR: FRAGMENT error not reported to cpu" << endl;
+ sc_stop();
+ }
+ }
+ else {
+ cout << "ERROR: FRAGMENT error not detected: "
+ << hex << pkt->err_flags << dec << endl;
+ sc_stop();
+ }
+
+ pkt->err_flags &= ~PKT_FLAG_ERR_SIG;
+ }
+
+
+ // CODING ERRORS
+
+ if (sid == SB_PIF_ID && (pkt_tx->err_flags & PKT_FLAG_ERR_CODING)) {
+
+ if (pkt->err_flags & PKT_FLAG_ERR_SIG) {
+
+ cout << "SCOREBOARD CODING ERROR CHECKED" << endl;
+
+ if (cpu_stats.crc_error_cnt+1 < xgm_stats.crc_error_cnt) {
+ cout << "CPU Count: " << cpu_stats.crc_error_cnt <<
+ " XGM Count: " << xgm_stats.crc_error_cnt << endl;
+ cout << "ERROR: CODING error not reported to cpu" << endl;
+ sc_stop();
+ }
+ }
+ else {
+ cout << "ERROR: CODING error not detected: "
+ << hex << pkt->err_flags << dec << endl;
+ sc_stop();
+ }
+
+ pkt->err_flags &= ~PKT_FLAG_ERR_SIG;
+ }
+
+
+ if (pkt->err_flags != 0) {
+ stats->flags_error_cnt++;
+ if (!disable_flags_check) {
+ cout << "ERROR: Error flags set: " << hex << pkt->err_flags << dec << endl;
+ sc_stop();
+ }
+ else {
+ cout << "INFO: Error flags set: " << hex << pkt->err_flags << dec << endl;
+ }
+ }
+
+ //---
+ // Delete packets
+
+ delete(pkt_tx);
+ delete(pkt);
+}
+
+void scoreboard::notify_status(sbSourceId sid, sbStatusId statusId) {
+
+ //---
+ // Detect errors
+
+ if (sid == SB_CPU_ID && statusId == CRC_ERROR) {
+ cout << "SCOREBOARD CRC_ERROR SIGNAL" << endl;
+ cpu_stats.crc_error_cnt++;
+ }
+
+ if (sid == SB_CPU_ID && statusId == FRAGMENT_ERROR) {
+ cout << "SCOREBOARD FRAGMENT_ERROR SIGNAL" << endl;
+ cpu_stats.fragment_error_cnt++;
+ }
+
+ if (sid == SB_CPU_ID && statusId == LOCAL_FAULT) {
+ cout << "SCOREBOARD LOCAL_FAULT SIGNAL" << endl;
+ cpu_stats.local_fault_cnt++;
+
+ if (cpu_stats.local_fault_cnt != xgm_stats.inject_local_fault_cnt) {
+ cout << "ERROR: Local fault not reported to cpu "
+ << cpu_stats.local_fault_cnt << " "
+ << xgm_stats.inject_local_fault_cnt << endl;
+ sc_stop();
+ }
+
+ if (cpu_stats.local_fault_cnt != xgm_stats.detect_remote_fault_cnt) {
+ cout << "ERROR: Remote fault not detected "
+ << cpu_stats.local_fault_cnt << " "
+ << xgm_stats.detect_remote_fault_cnt << endl;
+ sc_stop();
+ }
+ }
+
+ if (sid == SB_CPU_ID && statusId == REMOTE_FAULT) {
+ cout << "SCOREBOARD REMOTE_FAULT SIGNAL" << endl;
+ cpu_stats.remote_fault_cnt++;
+
+ if (cpu_stats.remote_fault_cnt != xgm_stats.inject_remote_fault_cnt) {
+ cout << "ERROR: Remote fault not reported to cpu "
+ << cpu_stats.remote_fault_cnt << " "
+ << xgm_stats.inject_remote_fault_cnt << endl;
+ sc_stop();
+ }
+
+ }
+
+ if (sid == SB_CPU_ID && statusId == RXD_FIFO_OVFLOW) {
+ cout << "SCOREBOARD RXD_FIFO_OVFLOW SIGNAL" << endl;
+ cpu_stats.rxd_fifo_ovflow_cnt++;
+ }
+
+ if (sid == SB_CPU_ID && statusId == RXD_FIFO_UDFLOW) {
+ cout << "SCOREBOARD RXD_FIFO_UDFLOW SIGNAL" << endl;
+ cpu_stats.rxd_fifo_udflow_cnt++;
+ }
+
+ if (sid == SB_CPU_ID && statusId == TXD_FIFO_OVFLOW) {
+ cout << "SCOREBOARD TXD_FIFO_OVFLOW SIGNAL" << endl;
+ cpu_stats.txd_fifo_ovflow_cnt++;
+ }
+
+ if (sid == SB_CPU_ID && statusId == TXD_FIFO_UDFLOW) {
+ cout << "SCOREBOARD TXD_FIFO_UDFLOW SIGNAL" << endl;
+ cpu_stats.txd_fifo_udflow_cnt++;
+ }
+
+ //---
+ // Detect XGMII local/remote faults
+
+ if (sid == SB_XGM_ID && statusId == LOCAL_FAULT) {
+ cout << "SCOREBOARD RX LOCAL FAULT" << endl;
+ xgm_stats.detect_local_fault_cnt++;
+ sc_stop();
+ }
+
+ if (sid == SB_XGM_ID && statusId == REMOTE_FAULT) {
+ cout << "SCOREBOARD RX REMOTE FAULT" << endl;
+ xgm_stats.detect_remote_fault_cnt++;
+ }
+
+ //---
+ // Packet receive indication
+
+ if (sid == SB_CPU_ID && statusId == RX_GOOD_PAUSE_FRAME) {
+ cout << "SCOREBOARD RX GOOD PAUSE FRAME SIGNAL" << endl;
+ cpu_stats.rx_pause_frame_cnt++;
+
+ if (cpu_stats.rx_pause_frame_cnt != xgm_stats.inject_pause_frame_cnt) {
+ cout << "ERROR: Pause frame not reported "
+ << cpu_stats.rx_pause_frame_cnt << " "
+ << xgm_stats.inject_pause_frame_cnt << endl;
+ sc_stop();
+ }
+ }
+
+
+ if (!disable_signal_check) {
+ cout << "ERROR: Signal Active" << endl;
+ sc_stop();
+ }
+}
+
+sbStats_t* scoreboard::get_pif_stats(void) {
+ return &pif_stats;
+}
+
+sbStats_t* scoreboard::get_xgm_stats(void) {
+ return &xgm_stats;
+}
+
+sbCpuStats_t* scoreboard::get_cpu_stats(void) {
+ return &cpu_stats;
+}
+
+void scoreboard::clear_stats(void) {
+
+ //---
+ // Clear FIFOs
+
+ while (pif_fifo.num_available() != 0) {
+ delete(pif_fifo.read());
+ }
+
+ while (xgm_fifo.num_available() != 0) {
+ delete(xgm_fifo.read());
+ }
+
+ //---
+ // Clear stats
+
+ pif_stats.tx_pkt_cnt = 0;
+ pif_stats.rx_pkt_cnt = 0;
+ pif_stats.crc_error_cnt = 0;
+ pif_stats.flags_error_cnt = 0;
+
+ xgm_stats.tx_pkt_cnt = 0;
+ xgm_stats.rx_pkt_cnt = 0;
+ xgm_stats.crc_error_cnt = 0;
+ xgm_stats.flags_error_cnt = 0;
+
+ pif_stats.timestamp_first_pkt = 0;
+ pif_stats.timestamp_last_pkt = 0;
+
+ xgm_stats.timestamp_first_pkt = 0;
+ xgm_stats.timestamp_last_pkt = 0;
+
+ xgm_stats.next_ifg_length = 1000;
+ xgm_stats.deficit_idle_count = 0;
+
+ cpu_stats.crc_error_cnt = 0;
+ cpu_stats.fragment_error_cnt = 0;
+ cpu_stats.rxd_fifo_ovflow_cnt = 0;
+ cpu_stats.rxd_fifo_udflow_cnt = 0;
+ cpu_stats.txd_fifo_ovflow_cnt = 0;
+ cpu_stats.txd_fifo_udflow_cnt = 0;
+}
sc_scoreboard.cpp
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: crc.h
===================================================================
--- crc.h (nonexistent)
+++ crc.h (revision 7)
@@ -0,0 +1,18 @@
+/*
+ * efone - Distributed internet phone system.
+ *
+ * (c) 1999,2000 Krzysztof Dabrowski
+ * (c) 1999,2000 ElysiuM deeZine
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ */
+
+/* based on implementation by Finn Yannick Jacobs. */
+
+void chksum_crc32gentab ();
+u_int32_t chksum_crc32 (sc_uint<8> *block, unsigned int length);
+//extern u_int32_t crc_tab[256];
crc.h
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: sc_scoreboard.h
===================================================================
--- sc_scoreboard.h (nonexistent)
+++ sc_scoreboard.h (revision 7)
@@ -0,0 +1,157 @@
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// File name "sc_scoreboard.h" ////
+//// ////
+//// This file is part of the "10GE MAC" project ////
+//// http://www.opencores.org/cores/xge_mac/ ////
+//// ////
+//// Author(s): ////
+//// - A. Tanguay (antanguay@opencores.org) ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2008 AUTHORS. All rights reserved. ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer. ////
+//// ////
+//// This source file is free software; you can redistribute it ////
+//// and/or modify it under the terms of the GNU Lesser General ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any ////
+//// later version. ////
+//// ////
+//// This source is distributed in the hope that it will be ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
+//// PURPOSE. See the GNU Lesser General Public License for more ////
+//// details. ////
+//// ////
+//// You should have received a copy of the GNU Lesser General ////
+//// Public License along with this source; if not, download it ////
+//// from http://www.opencores.org/lgpl.shtml ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+
+#ifndef SCOREBOARD_H
+#define SCOREBOARD_H
+
+#include "systemc.h"
+
+#include "sc_packet.h"
+
+
+struct sbStats_t {
+ int tx_pkt_cnt;
+ int rx_pkt_cnt;
+
+ int crc_error_cnt;
+ int fragment_error_cnt;
+ int coding_error_cnt;
+ int flags_error_cnt;
+
+ int inject_local_fault_cnt;
+ int inject_remote_fault_cnt;
+
+ int inject_pause_frame_cnt;
+
+ int detect_local_fault_cnt;
+ int detect_remote_fault_cnt;
+
+ double timestamp_first_pkt;
+ double timestamp_last_pkt;
+
+ int next_ifg_length;
+ int deficit_idle_count;
+};
+
+struct sbCpuStats_t {
+ int crc_error_cnt;
+ int fragment_error_cnt;
+
+ int rxd_fifo_ovflow_cnt;
+ int rxd_fifo_udflow_cnt;
+ int txd_fifo_ovflow_cnt;
+ int txd_fifo_udflow_cnt;
+
+ int rx_pause_frame_cnt;
+
+ int local_fault_cnt;
+ int remote_fault_cnt;
+};
+
+SC_MODULE(scoreboard) {
+
+ public:
+
+ //---
+ // Types
+
+ enum sbSourceId {
+ SB_PIF_ID,
+ SB_XGM_ID,
+ SB_CPU_ID,
+ };
+
+ enum sbStatusId {
+ CRC_ERROR,
+ FRAGMENT_ERROR,
+ LOCAL_FAULT,
+ REMOTE_FAULT,
+ RXD_FIFO_OVFLOW,
+ RXD_FIFO_UDFLOW,
+ TXD_FIFO_OVFLOW,
+ TXD_FIFO_UDFLOW,
+ RX_GOOD_PAUSE_FRAME,
+ };
+
+ private:
+
+ //---
+ // Variables
+
+ sc_fifo pif_fifo;
+ sc_fifo xgm_fifo;
+
+ sbStats_t pif_stats;
+ sbStats_t xgm_stats;
+ sbCpuStats_t cpu_stats;
+
+ public:
+
+ //---
+ // Variables
+
+ bool disable_padding;
+ bool disable_crc_check;
+ bool disable_packet_check;
+ bool disable_flags_check;
+ bool disable_signal_check;
+
+ //---
+ // Functions
+
+ void init(void);
+
+ void notify_packet_tx(sbSourceId sid, packet_t* pkt);
+ void notify_packet_rx(sbSourceId sid, packet_t* pkt);
+ void notify_status(sbSourceId sid, sbStatusId statusId);
+
+ sbStats_t* get_pif_stats(void);
+ sbStats_t* get_xgm_stats(void);
+ sbCpuStats_t* get_cpu_stats(void);
+
+ void clear_stats(void);
+
+ SC_CTOR(scoreboard):
+ pif_fifo (2000),
+ xgm_fifo (2000) {
+
+ }
+
+};
+
+
+#endif
sc_scoreboard.h
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: sc_xgmii_if.cpp
===================================================================
--- sc_xgmii_if.cpp (nonexistent)
+++ sc_xgmii_if.cpp (revision 7)
@@ -0,0 +1,504 @@
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// File name "sc_xgmii_if.cpp" ////
+//// ////
+//// This file is part of the "10GE MAC" project ////
+//// http://www.opencores.org/cores/xge_mac/ ////
+//// ////
+//// Author(s): ////
+//// - A. Tanguay (antanguay@opencores.org) ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2008 AUTHORS. All rights reserved. ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer. ////
+//// ////
+//// This source file is free software; you can redistribute it ////
+//// and/or modify it under the terms of the GNU Lesser General ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any ////
+//// later version. ////
+//// ////
+//// This source is distributed in the hope that it will be ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
+//// PURPOSE. See the GNU Lesser General Public License for more ////
+//// details. ////
+//// ////
+//// You should have received a copy of the GNU Lesser General ////
+//// Public License along with this source; if not, download it ////
+//// from http://www.opencores.org/lgpl.shtml ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+
+#include
+#include
+#include
+#include
+
+#include "systemc.h"
+
+#include "sc_xgmii_if.h"
+
+sc_fifo * xgmii_if::get_tx_fifo_ptr() {
+ return &tx_fifo;
+}
+
+sc_fifo * xgmii_if::get_rx_fifo_ptr() {
+ return &rx_fifo;
+}
+
+void xgmii_if::init(void) {
+ allow_idle_errors = false;
+ disable_padding = false;
+}
+
+void xgmii_if::connect_scoreboard(scoreboard *sbptr, scoreboard::sbSourceId sid) {
+ sb = sbptr;
+ sb_id = sid;
+}
+
+void xgmii_if::transmit() {
+
+ packet_t* pkt;
+
+ sc_uint<64> txd = 0;
+ sc_uint<8> txc = 0;
+
+ int lane = 0;
+ int bytecnt = 0;
+ int length = 0;
+ int preamblecnt = 0;
+ int ifg = 0;
+ int fragment_size = 8;
+ int coding_offset = 0;
+ int fault_cnt = 0;
+ int fault_byte = 0;
+ int fault_spacing;
+ int fault_spacing_cnt = 0;
+
+ while (true) {
+
+ if (length == 0 && tx_fifo.nb_read(pkt)) {
+
+ if (!disable_padding) {
+ pad(pkt, 60);
+ }
+ pack(pkt);
+
+ calc_crc(pkt);
+
+ //---
+ // Inject errors
+
+ if (pkt->err_flags & PKT_FLAG_ERR_CRC) {
+ pkt->crc++;
+ }
+
+ if (pkt->err_flags & PKT_FLAG_ERR_FRG) {
+ pkt->length = fragment_size;
+ fragment_size++;
+ if (fragment_size > 64) {
+ fragment_size = 8;
+ }
+ }
+
+ if (pkt->err_flags & PKT_FLAG_ERR_CODING) {
+ if (coding_offset >= pkt->length) {
+ pkt->err_info = pkt->length-1;
+ }
+ else {
+ pkt->err_info = coding_offset;
+ }
+ coding_offset++;
+ if (coding_offset >= 70) {
+ coding_offset = 0;
+ }
+ }
+
+ //---
+ // Inject local / remote faults
+
+ if (pkt->err_flags & PKT_FLAG_LOCAL_FAULT ||
+ pkt->err_flags & PKT_FLAG_REMOTE_FAULT) {
+ fault_cnt = 4;
+ fault_byte = 4;
+ fault_spacing_cnt = 0;
+
+ fault_spacing = pkt->err_info;
+ cout << "INFO: Fault insert, spacing: " << fault_spacing << endl;
+ }
+
+ //---
+ // Pass packet to scoreboard
+
+ sb->notify_packet_tx(sb_id, pkt);
+
+ add_crc(pkt);
+ strip_crc(pkt);
+ length = pkt->length + 4;
+
+ //cout << "Transmit XGMII packet:\n" << * pkt << endl;
+
+ }
+
+
+ if (ifg != 0) {
+ txd |= ((sc_uint<64>)0x07) << (8 * lane);
+ txc |= 0x01 << lane;
+ ifg--;
+
+ }
+ else if (fault_spacing_cnt != 0) {
+
+ txd |= ((sc_uint<64>)0x07) << (8 * lane);
+ txc |= 0x01 << lane;
+
+ fault_spacing_cnt--;
+
+ }
+ else if ((lane == 0 || lane == 4) && fault_byte == 4) {
+
+ txd |= ((sc_uint<64>)0x9c) << (8 * lane);
+ txc |= 0x01 << lane;
+
+ fault_byte--;
+
+ }
+ else if (fault_byte == 3 || fault_byte == 2) {
+
+ fault_byte--;
+
+ }
+ else if (fault_byte == 1) {
+
+ if (pkt->err_flags & PKT_FLAG_LOCAL_FAULT) {
+ txd |= ((sc_uint<64>)0x01) << (8 * lane);
+ }
+ else {
+ txd |= ((sc_uint<64>)0x02) << (8 * lane);
+ }
+ fault_byte--;
+
+ fault_cnt--;
+ if (fault_cnt > 0) {
+ fault_byte = 4;
+ }
+
+ if (fault_cnt == 1) {
+ fault_spacing_cnt = 4 * fault_spacing;
+ }
+ }
+ else if ((lane == 0 || lane == 4) && bytecnt != length && preamblecnt == 0) {
+
+ txd |= ((sc_uint<64>)0xfb) << (8 * lane);
+ txc |= 0x01 << lane;
+
+ preamblecnt++;
+
+ }
+ else if (preamblecnt > 0 && preamblecnt < 7) {
+
+ txd |= ((sc_uint<64>)0x55) << (8 * lane);
+
+ preamblecnt++;
+
+ }
+ else if (preamblecnt == 7) {
+
+ txd |= ((sc_uint<64>)0xd5) << (8 * lane);
+
+ preamblecnt++;
+
+ }
+ else if (preamblecnt > 7 && (bytecnt == (length-4)) &&
+ (pkt->err_flags & PKT_FLAG_ERR_FRG)) {
+
+ //---
+ // Fragment insertion
+
+ bytecnt = 0;
+ length = 0;
+ preamblecnt = 0;
+ ifg = 0;
+
+ }
+ else if (preamblecnt >7 && bytecnt == pkt->err_info &&
+ (pkt->err_flags & PKT_FLAG_ERR_CODING)) {
+
+ //---
+ // Coding error insertion
+
+ txc |= 0x01 << lane;
+ txd |= ((sc_uint<64>)pkt->data[bytecnt]) << (8 * lane);
+ bytecnt++;
+
+ }
+ else if (preamblecnt > 7 && bytecnt < length) {
+
+ txd |= ((sc_uint<64>)pkt->data[bytecnt]) << (8 * lane);
+ bytecnt++;
+
+ }
+ else if (preamblecnt > 7 && bytecnt == length) {
+
+ //---
+ // End of frame TERMINATE
+
+ txd |= ((sc_uint<64>)0xfd) << (8 * lane);
+ txc |= 0x01 << lane;
+
+ bytecnt = 0;
+ length = 0;
+ preamblecnt = 0;
+
+ // Minimum IFG is 5 including TERMINATE
+ ifg = 4;
+
+ }
+ else {
+ txd |= ((sc_uint<64>)0x07) << (8 * lane);
+ txc |= 0x01 << lane;
+ }
+ if (lane == 7) {
+ xgmii_rxd = txd;
+ xgmii_rxc = txc;
+ txd = 0;
+ txc = 0;
+ wait();
+ }
+ lane = (lane + 1) % 8;
+
+ }
+};
+
+
+void xgmii_if::receive() {
+
+ packet_t* pkt;
+
+ sc_uint<64> rxd;
+ sc_uint<8> rxc;
+
+ int lane, bytecnt, ifgcnt;
+
+ lane = 0;
+
+ wait();
+
+ while (true) {
+
+ ifgcnt = 1;
+
+ rxd = xgmii_txd;
+ rxc = xgmii_txc;
+
+
+ //---
+ // Wait for START code in lane0 or lane4
+
+ while (true) {
+
+ // Check for START character
+ if (((rxd >> (8*lane)) & 0xff) == 0xfb && ((rxc >> lane) & 0x1) == 1) {
+ if (disable_receive) {
+ cout << "INFO: XGMII Receive Disabled" << endl;
+ }
+ else {
+ break;
+ }
+ };
+
+ // Check IDLE character and control lines
+ if (((rxd >> (8*lane)) & 0xff) != 0x07 || ((rxc >> lane) & 0x1) != 1) {
+ if (allow_idle_errors) {
+ cout << "INFO: IDLE check disabled" << endl;
+ }
+ else {
+ cout << "ERROR: IDLE character " << hex << rxd << " " << rxc << dec << lane << endl;
+ sc_stop();
+ }
+ };
+
+ ifgcnt++;
+
+ lane = (lane + 1) % 8;
+ if (lane == 0) {
+ wait();
+ rxd = xgmii_txd;
+ rxc = xgmii_txc;
+ }
+ }
+
+ //cout << "START in lane " << lane << " IFG " << ifgcnt << endl;
+
+ // Check starting lane
+ if (lane != 0 && lane != 4) {
+ cout << "ERROR: Lane aligment" << endl;
+ sc_stop();
+ }
+
+ // Check for minimum inter frame gap
+ if (ifgcnt < 9) {
+ cout << "ERROR: MINIMUM IFG " << ifgcnt << endl;
+ sc_stop();
+ }
+
+ //---
+ // Capture data until end of frame is detected (TERMINATE)
+
+ pkt = new(packet_t);
+ pkt->ifg = ifgcnt;
+ pkt->start_lane = lane;
+ pkt->length = 0;
+
+ bytecnt = 0;
+ while (true) {
+
+ // Look for end of frame delimiter in any lane
+ if (((rxd >> (8*lane)) & 0xff) == 0xfd && ((rxc >> lane) & 0x1) == 1) {
+ break;
+ };
+
+ // Stop if packet is too long
+ if (bytecnt >= 10000) {
+ break;
+ }
+
+ // Validate preamble bytes
+ if (bytecnt > 0 && bytecnt <= 6 && ((rxd >> (8*lane)) & 0xff) != 0x55) {
+ cout << "ERROR: Invalid preamble byte: " << bytecnt << endl;
+ sc_stop();
+ }
+
+ // Validate SFD code in preamble
+ if (bytecnt == 7 && ((rxd >> (8*lane)) & 0xff) != 0xd5) {
+ cout << "ERROR: Invalid preamble byte: " << bytecnt << endl;
+ sc_stop();
+ }
+
+ // Store all bytes after preamble
+ if (bytecnt > 7) {
+ if (((rxc >> lane) & 0x1) == 0) {
+ pkt->data[pkt->length] = ((rxd >> (8*lane)) & 0xff);
+ pkt->length++;
+ }
+ else {
+ cout << "ERROR: RXC high during data cycle" << endl;
+ sc_stop();
+ }
+ }
+ else if (bytecnt > 0) {
+ if (((rxc >> lane) & 0x1) == 1) {
+ cout << "ERROR: RXC high during preamble" << endl;
+ sc_stop();
+ }
+ }
+
+ bytecnt++;
+ lane = (lane + 1) % 8;
+ if (lane == 0) {
+ wait();
+ rxd = xgmii_txd;
+ rxc = xgmii_txc;
+ }
+ }
+
+
+ lane = (lane + 1) % 8;
+ if (lane == 0) {
+ wait();
+ rxd = xgmii_txd;
+ rxc = xgmii_txc;
+ }
+
+ //---
+ // Store packet
+
+ strip_crc(pkt);
+
+ unpack(pkt);
+ //rx_fifo.write(pkt);
+ //cout << "Received XGMII packet:" << * pkt << endl;
+
+ //---
+ // Pass packet to scoreboard
+
+ sb->notify_packet_rx(sb_id, pkt);
+
+ }
+};
+
+
+void xgmii_if::monitor() {
+
+ sc_uint<64> rxd;
+ sc_uint<8> rxc;
+
+ wait();
+
+ while (true) {
+
+ rxd = xgmii_txd;
+ rxc = xgmii_txc;
+
+ //---
+ // Check for local/remote fault
+
+ if (((rxd & 0xffffffff) == 0x0100009c && (rxc & 0xf) == 0x1) &&
+ (((rxd >> 32) & 0xffffffff) == 0x0100009c && ((rxc > 4) & 0xf) == 0x1)) {
+
+ //--
+ // Local fault detection
+
+ if (!rx_local_fault) {
+ cout << "XGMII Local Fault Asserted" << endl;
+
+ // Notify Scoreboard
+ sb->notify_status(sb_id, scoreboard::LOCAL_FAULT);
+ }
+ rx_local_fault = true;
+
+ }
+ else {
+
+ if (rx_local_fault) {
+ cout << "XGMII Local Fault De-Asserted" << endl;
+ }
+ rx_local_fault = false;
+
+ }
+
+ if (((rxd & 0xffffffff) == 0x0200009c && (rxc & 0xf) == 0x1) &&
+ (((rxd >> 32) & 0xffffffff) == 0x0200009c && ((rxc > 4) & 0xf) == 0x1)) {
+
+ //--
+ // Remote fault detection
+
+ if (!rx_remote_fault) {
+ cout << "XGMII Remote Fault Asserted" << endl;
+
+ // Notify Scoreboard
+ sb->notify_status(sb_id, scoreboard::REMOTE_FAULT);
+ }
+ rx_remote_fault = true;
+
+ }
+ else {
+
+ if (rx_remote_fault) {
+ cout << "XGMII Remote Fault De-Asserted" << endl;
+ }
+ rx_remote_fault = false;
+
+ }
+
+ wait();
+ }
+};
+
+
sc_xgmii_if.cpp
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: sc_xgmii_if.h
===================================================================
--- sc_xgmii_if.h (nonexistent)
+++ sc_xgmii_if.h (revision 7)
@@ -0,0 +1,115 @@
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// File name "sc_xgmii_if.h" ////
+//// ////
+//// This file is part of the "10GE MAC" project ////
+//// http://www.opencores.org/cores/xge_mac/ ////
+//// ////
+//// Author(s): ////
+//// - A. Tanguay (antanguay@opencores.org) ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2008 AUTHORS. All rights reserved. ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer. ////
+//// ////
+//// This source file is free software; you can redistribute it ////
+//// and/or modify it under the terms of the GNU Lesser General ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any ////
+//// later version. ////
+//// ////
+//// This source is distributed in the hope that it will be ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
+//// PURPOSE. See the GNU Lesser General Public License for more ////
+//// details. ////
+//// ////
+//// You should have received a copy of the GNU Lesser General ////
+//// Public License along with this source; if not, download it ////
+//// from http://www.opencores.org/lgpl.shtml ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+
+#ifndef XGMII_IF_H
+#define XGMII_IF_H
+
+#include "systemc.h"
+
+#include "sc_packet.h"
+#include "sc_scoreboard.h"
+
+SC_MODULE(xgmii_if) {
+
+ public:
+
+ //---
+ // Ports
+
+ sc_in clk_xgmii;
+
+ sc_in reset_xgmii_n;
+
+ sc_out xgmii_rxc;
+ sc_out > xgmii_rxd;
+
+ sc_in xgmii_txc;
+ sc_in > xgmii_txd;
+
+ private:
+
+ //---
+ // Variables
+
+ sc_fifo tx_fifo;
+ sc_fifo rx_fifo;
+
+ scoreboard *sb;
+ scoreboard::sbSourceId sb_id;
+
+ public:
+
+ //---
+ // Variables
+
+ bool allow_idle_errors;
+ bool disable_receive;
+ bool disable_padding;
+
+ bool rx_local_fault;
+ bool rx_remote_fault;
+
+ //---
+ // Functions
+
+ sc_fifo * get_tx_fifo_ptr();
+ sc_fifo * get_rx_fifo_ptr();
+
+ void init(void);
+ void connect_scoreboard(scoreboard *sbptr, scoreboard::sbSourceId sid);
+
+ //---
+ // Threads
+
+ void transmit();
+ void receive();
+ void monitor();
+
+ SC_CTOR(xgmii_if) :
+ tx_fifo (2),
+ rx_fifo (2) {
+
+ SC_CTHREAD (transmit, clk_xgmii.pos());
+
+ SC_CTHREAD (receive, clk_xgmii.pos());
+
+ SC_CTHREAD (monitor, clk_xgmii.pos());
+ }
+
+};
+
+#endif
sc_xgmii_if.h
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: sc_testcases.h
===================================================================
--- sc_testcases.h (nonexistent)
+++ sc_testcases.h (revision 7)
@@ -0,0 +1,96 @@
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// File name "sc_testcases.h" ////
+//// ////
+//// This file is part of the "10GE MAC" project ////
+//// http://www.opencores.org/cores/xge_mac/ ////
+//// ////
+//// Author(s): ////
+//// - A. Tanguay (antanguay@opencores.org) ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2008 AUTHORS. All rights reserved. ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer. ////
+//// ////
+//// This source file is free software; you can redistribute it ////
+//// and/or modify it under the terms of the GNU Lesser General ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any ////
+//// later version. ////
+//// ////
+//// This source is distributed in the hope that it will be ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
+//// PURPOSE. See the GNU Lesser General Public License for more ////
+//// details. ////
+//// ////
+//// You should have received a copy of the GNU Lesser General ////
+//// Public License along with this source; if not, download it ////
+//// from http://www.opencores.org/lgpl.shtml ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+
+#include "systemc.h"
+
+#include "sc_testbench.h"
+
+
+
+SC_MODULE(testcases) {
+
+ public:
+
+ //---
+ // Variables
+
+ bool done;
+
+ private:
+
+ testbench* tb;
+
+ public:
+
+ //---
+ // Functions
+
+ void connect_testbench(testbench* tbptr);
+
+ void test_deficit_idle_count(void);
+ void packet_dic(int minsize, int maxsize);
+
+ void test_packet_size(int min, int max, int cnt);
+
+ void test_crc_errors(int min, int max, int cnt, int interval);
+
+ void test_txdfifo_ovflow();
+ void test_rxdfifo_ovflow();
+
+ void test_rx_fragments(int min, int max, int cnt, int interval);
+ void test_rx_coding_err(int cnt, int interval);
+ void test_rx_local_fault(int min, int max, int cnt, int interval);
+ void test_rx_remote_fault(int min, int max, int cnt, int interval);
+
+ void test_rx_pause(int min, int max, int cnt, int interval);
+
+ void test_interrupt_mask();
+
+ //---
+ // Threads
+
+ void run_tests(void);
+
+ SC_CTOR(testcases) {
+
+ done = false;
+
+ SC_THREAD (run_tests);
+
+ }
+
+};
sc_testcases.h
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: sc_pkt_generator.cpp
===================================================================
--- sc_pkt_generator.cpp (nonexistent)
+++ sc_pkt_generator.cpp (revision 7)
@@ -0,0 +1,265 @@
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// File name "sc_pkt_generator.cpp" ////
+//// ////
+//// This file is part of the "10GE MAC" project ////
+//// http://www.opencores.org/cores/xge_mac/ ////
+//// ////
+//// Author(s): ////
+//// - A. Tanguay (antanguay@opencores.org) ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2008 AUTHORS. All rights reserved. ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer. ////
+//// ////
+//// This source file is free software; you can redistribute it ////
+//// and/or modify it under the terms of the GNU Lesser General ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any ////
+//// later version. ////
+//// ////
+//// This source is distributed in the hope that it will be ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
+//// PURPOSE. See the GNU Lesser General Public License for more ////
+//// details. ////
+//// ////
+//// You should have received a copy of the GNU Lesser General ////
+//// Public License along with this source; if not, download it ////
+//// from http://www.opencores.org/lgpl.shtml ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+
+#include
+#include
+#include
+#include
+
+#include "systemc.h"
+
+#include "sc_pkt_generator.h"
+
+
+void pkt_generator::init(void) {
+ crc_interval = 0;
+ fragment_interval = 0;
+ coding_interval = 0;
+ local_fault_interval = 0;
+ remote_fault_interval = 0;
+}
+
+void pkt_generator::connect_fifo(sc_fifo * fifo) {
+ tx_fifo = fifo;
+}
+
+
+void pkt_generator::gen_packet() {
+
+ int len = 0;
+ int crc_int = 0;
+ int fragment_int = 0;
+ int coding_int = 0;
+ int local_fault_int = 0;
+ int remote_fault_int = 0;
+ int fault_spacing = 120;
+ int pause_int = 0;
+ char running_cnt = 0;
+
+ while (true) {
+
+ wait(5, SC_NS);
+
+ if (tx_bucket != 0 && tx_fifo->num_available() == 0) {
+
+ //--
+ // Check fifo
+
+ if (tx_fifo == NULL || tx_fifo->num_free() == 0) {
+ cout << "ERROR: FIFO not defined or full" << endl;
+ sc_stop();
+ }
+
+ //---
+ // Update constraints
+
+ if (len < min_pkt_size) {
+ len = min_pkt_size;
+ }
+
+ if (len > max_pkt_size) {
+ len = min_pkt_size;
+ }
+
+ //--
+ // Generate packet
+
+ packet_t* pkt = new(packet_t);
+
+ for (int i = 0; i < len+8; i++) {
+ pkt->payload[i] = len+i;
+ }
+ pkt->payload[0] = running_cnt;
+ running_cnt++;
+
+ pkt->length = len;
+
+ //---
+ // Inject errors
+
+ if (crc_interval != 0) {
+ if (crc_int >= crc_interval) {
+ pkt->err_flags |= PKT_FLAG_ERR_CRC;
+ crc_int = 0;
+ }
+ else {
+ crc_int++;
+ }
+ }
+ else {
+ crc_int = 0;
+ }
+
+ if (fragment_interval != 0) {
+ if (fragment_int >= fragment_interval) {
+ pkt->err_flags |= PKT_FLAG_ERR_FRG;
+ fragment_int = 0;
+ }
+ else {
+ fragment_int++;
+ }
+ }
+ else {
+ fragment_int = 0;
+ }
+
+ if (coding_interval != 0) {
+ if (coding_int >= coding_interval) {
+ pkt->err_flags |= PKT_FLAG_ERR_CODING;
+ coding_int = 0;
+ }
+ else {
+ coding_int++;
+ }
+ }
+ else {
+ coding_int = 0;
+ }
+
+ //--
+ // Inject local / remote faults
+
+ if (local_fault_interval != 0) {
+ if (local_fault_int >= local_fault_interval) {
+
+ pkt->err_flags |= PKT_FLAG_LOCAL_FAULT;
+ local_fault_int = 0;
+
+ fault_spacing++;
+ if (fault_spacing > (132 - 4)) {
+ fault_spacing = 120;
+ }
+ pkt->err_info = fault_spacing;
+ }
+ else {
+ local_fault_int++;
+ }
+ }
+ else {
+ local_fault_int = 0;
+ }
+
+ if (remote_fault_interval != 0) {
+ if (remote_fault_int >= remote_fault_interval) {
+
+ pkt->err_flags |= PKT_FLAG_REMOTE_FAULT;
+ remote_fault_int = 0;
+
+ fault_spacing++;
+ if (fault_spacing > (132 - 4)) {
+ fault_spacing = 120;
+ }
+ pkt->err_info = fault_spacing;
+ }
+ else {
+ remote_fault_int++;
+ }
+ }
+ else {
+ remote_fault_int = 0;
+ }
+
+ //--
+ // Inject PAUSE frames
+
+ if (inject_pause_interval != 0) {
+ if (pause_int >= inject_pause_interval) {
+
+ pkt->dest_addr = 0x0180c2;
+ pkt->dest_addr = (pkt->dest_addr << 24) | 0x000001;
+ pause_int = 0;
+
+ }
+ else {
+ pause_int++;
+ }
+ }
+
+ //--
+ // Send packet
+
+ tx_fifo->write(pkt);
+
+ tx_bucket--;
+ len++;
+
+ }
+ else {
+ wait(50, SC_NS);
+ }
+
+ }
+}
+
+void pkt_generator::set_tx_bucket(int cnt) {
+ tx_bucket = cnt;
+}
+
+int pkt_generator::get_tx_bucket(void) {
+ return tx_bucket;
+}
+
+void pkt_generator::set_pkt_size(int min, int max) {
+
+ min_pkt_size = min;
+ max_pkt_size = max;
+
+}
+
+void pkt_generator::set_crc_errors(int interval) {
+ crc_interval = interval;
+}
+
+void pkt_generator::set_fragment_errors(int interval) {
+ fragment_interval = interval;
+}
+
+void pkt_generator::set_coding_errors(int interval) {
+ coding_interval = interval;
+}
+
+void pkt_generator::set_local_fault(int interval) {
+ local_fault_interval = interval;
+}
+
+void pkt_generator::set_remote_fault(int interval) {
+ remote_fault_interval = interval;
+}
+
+void pkt_generator::set_inject_pause(int interval) {
+ inject_pause_interval = interval;
+}
sc_pkt_generator.cpp
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: sc_cpu_if.cpp
===================================================================
--- sc_cpu_if.cpp (nonexistent)
+++ sc_cpu_if.cpp (revision 7)
@@ -0,0 +1,287 @@
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// File name "sc_cpu_if.h" ////
+//// ////
+//// This file is part of the "10GE MAC" project ////
+//// http://www.opencores.org/cores/xge_mac/ ////
+//// ////
+//// Author(s): ////
+//// - A. Tanguay (antanguay@opencores.org) ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2008 AUTHORS. All rights reserved. ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer. ////
+//// ////
+//// This source file is free software; you can redistribute it ////
+//// and/or modify it under the terms of the GNU Lesser General ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any ////
+//// later version. ////
+//// ////
+//// This source is distributed in the hope that it will be ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
+//// PURPOSE. See the GNU Lesser General Public License for more ////
+//// details. ////
+//// ////
+//// You should have received a copy of the GNU Lesser General ////
+//// Public License along with this source; if not, download it ////
+//// from http://www.opencores.org/lgpl.shtml ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+
+#include
+#include
+#include
+#include
+
+#include "systemc.h"
+
+#include "sc_cpu_if.h"
+
+void cpu_if::init() {
+};
+
+void cpu_if::connect_scoreboard(scoreboard *sbptr, scoreboard::sbSourceId sid) {
+ sb = sbptr;
+ sb_id = sid;
+}
+
+void cpu_if::set_param(cpu_if::paramId param, int value) {
+
+ switch (param) {
+
+ case TX_ENABLE:
+ writebits(cpu_if::CPUREG_CONFIG0, 0, 0, value);
+ break;
+
+ }
+
+};
+
+void cpu_if::set_interrupt(cpu_if::intId intr) {
+
+ writebits(cpu_if::CPUREG_INT_PENDING, intr, intr, 1);
+};
+
+void cpu_if::set_interrupt_mask(cpu_if::intId intr, bool value) {
+
+ writebits(cpu_if::CPUREG_INT_MASK, intr, intr, value);
+};
+
+void cpu_if::enable_all_interrupts(void) {
+
+ write(cpu_if::CPUREG_INT_MASK, 0xffffffff);
+};
+
+uint cpu_if::read(uint addr) {
+
+ uint data;
+
+ //--
+ // Wait for bus to be free, lock it, start transaction
+
+ bus_lock.lock();
+ bus_addr = addr;
+ bus_write = false;
+ bus_start.notify();
+
+ //--
+ // Wait for transaction to complete
+
+ while (bus_done.trywait()) {
+ wait(10, SC_NS);
+ };
+
+ //--
+ // Get the data, free the bus
+
+ data = bus_data;
+ cout << hex << "READ ADDR 0x" << addr << ": 0x" << data << dec << endl;
+ bus_lock.unlock();
+
+ return data;
+};
+
+void cpu_if::write(uint addr, uint data) {
+
+ //--
+ // Wait for bus to be free, lock it, start transaction
+
+ bus_lock.lock();
+ bus_addr = addr;
+ bus_data = data;
+ bus_write = true;
+ bus_start.notify();
+
+ //--
+ // Wait for transaction to complete
+
+ while (bus_done.trywait()) {
+ wait(10, SC_NS);
+ };
+
+ //--
+ // Free the bus
+
+ cout << hex << "WRITE ADDR 0x" << addr << ": 0x" << data << dec << endl;
+ bus_lock.unlock();
+};
+
+void cpu_if::writebits(uint addr, uint hbit, uint lbit, uint value) {
+
+ uint data;
+ uint mask;
+
+ mask = ~((0xffffffff << lbit) & (0xffffffff >> (31-lbit)));
+
+ data = mask & read(addr);
+ data = data | ((value << lbit) & ~mask);
+
+ write(addr, data);
+};
+
+void cpu_if::transactor() {
+
+
+ while (true) {
+
+ // Wait for a transaction
+ wait(bus_start);
+
+ if (!bus_write) {
+
+ //---
+ // Read access
+
+ // Start of access
+ wb_adr_i = bus_addr;
+ wb_dat_i = 0;
+
+ wb_cyc_i = 1;
+ wb_stb_i = 1;
+ wb_we_i = 0;
+
+ // Wait for ack
+ while (wb_ack_o != 1) {
+ wait();
+ }
+
+ // Capture data
+ bus_data = wb_dat_o;
+
+ wb_adr_i = 0;
+ wb_dat_i = 0;
+
+ wb_cyc_i = 0;
+ wb_stb_i = 0;
+
+ }
+ else {
+
+ //---
+ // Write access
+
+ // Start of access
+ wb_adr_i = bus_addr;
+ wb_dat_i = bus_data;
+
+ wb_cyc_i = 1;
+ wb_stb_i = 1;
+ wb_we_i = 1;
+
+ // Wait for ack
+ while (wb_ack_o != 1) {
+ wait();
+ }
+
+ // End cycle
+ wb_adr_i = 0;
+ wb_dat_i = 0;
+
+ wb_cyc_i = 0;
+ wb_stb_i = 0;
+ wb_we_i = 0;
+
+ }
+
+ bus_done.post();
+ }
+};
+
+void cpu_if::monitor() {
+
+ uint data;
+
+ wait();
+
+ while (true) {
+
+ if (wb_int_o) {
+
+ //---
+ // Read interrupt register when interrupt signal is asserted
+
+ data = read(cpu_if::CPUREG_INT_PENDING);
+
+ cout << "READ INTERRUPTS: 0x" << hex << data << dec << endl;
+
+ //---
+ // Notify scoreboard
+
+ if ((data >> cpu_if::INT_CRC_ERROR) & 0x1) {
+ sb->notify_status(sb_id, scoreboard::CRC_ERROR);
+ }
+
+ if ((data >> cpu_if::INT_FRAGMENT_ERROR) & 0x1) {
+ sb->notify_status(sb_id, scoreboard::FRAGMENT_ERROR);
+ }
+
+ if ((data >> cpu_if::INT_LOCAL_FAULT) & 0x1) {
+
+ data = read(cpu_if::CPUREG_INT_STATUS);
+
+ if ((data >> cpu_if::INT_LOCAL_FAULT) & 0x1) {
+ sb->notify_status(sb_id, scoreboard::LOCAL_FAULT);
+ }
+ }
+
+ if ((data >> cpu_if::INT_REMOTE_FAULT) & 0x1) {
+
+ data = read(cpu_if::CPUREG_INT_STATUS);
+
+ if ((data >> cpu_if::INT_REMOTE_FAULT) & 0x1) {
+ sb->notify_status(sb_id, scoreboard::REMOTE_FAULT);
+ }
+ }
+
+ if ((data >> cpu_if::INT_RXD_FIFO_OVFLOW) & 0x1) {
+ sb->notify_status(sb_id, scoreboard::RXD_FIFO_OVFLOW);
+ }
+
+ if ((data >> cpu_if::INT_RXD_FIFO_UDFLOW) & 0x1) {
+ sb->notify_status(sb_id, scoreboard::RXD_FIFO_UDFLOW);
+ }
+
+ if ((data >> cpu_if::INT_TXD_FIFO_OVFLOW) & 0x1) {
+ sb->notify_status(sb_id, scoreboard::TXD_FIFO_OVFLOW);
+ }
+
+ if ((data >> cpu_if::INT_TXD_FIFO_UDFLOW) & 0x1) {
+ sb->notify_status(sb_id, scoreboard::TXD_FIFO_UDFLOW);
+ }
+
+ if ((data >> cpu_if::INT_PAUSE_FRAME) & 0x1) {
+ sb->notify_status(sb_id, scoreboard::RX_GOOD_PAUSE_FRAME);
+ }
+
+ }
+
+ wait();
+ }
+};
sc_cpu_if.cpp
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: sc_packet.cpp
===================================================================
--- sc_packet.cpp (nonexistent)
+++ sc_packet.cpp (revision 7)
@@ -0,0 +1,151 @@
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// File name "sc_packet.cpp" ////
+//// ////
+//// This file is part of the "10GE MAC" project ////
+//// http://www.opencores.org/cores/xge_mac/ ////
+//// ////
+//// Author(s): ////
+//// - A. Tanguay (antanguay@opencores.org) ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2008 AUTHORS. All rights reserved. ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer. ////
+//// ////
+//// This source file is free software; you can redistribute it ////
+//// and/or modify it under the terms of the GNU Lesser General ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any ////
+//// later version. ////
+//// ////
+//// This source is distributed in the hope that it will be ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
+//// PURPOSE. See the GNU Lesser General Public License for more ////
+//// details. ////
+//// ////
+//// You should have received a copy of the GNU Lesser General ////
+//// Public License along with this source; if not, download it ////
+//// from http://www.opencores.org/lgpl.shtml ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+
+#include
+#include
+#include
+#include
+
+#include "systemc.h"
+
+#include "crc.h"
+#include "sc_packet.h"
+
+ostream& operator<<(ostream& os, const packet_t& p) {
+ os << "\n=====================\n"
+ << dec
+ << " length : " << p.length << "\n"
+ << hex
+ << " src_addr : 0x" << p.src_addr << "\n"
+ << " dest_addr: 0x" << p.dest_addr << "\n"
+ << " crc : 0x" << p.crc << "\n"
+ << " crc_rx : 0x" << p.crc_rx << "\n"
+ << " err_flags: 0x" << p.err_flags << "\n"
+ << " payload : " << "\n";
+
+ for (int i = 0; i < p.length; i++) {
+ os << p.payload[i] << " ";
+ }
+
+ cout << "\n--\n";
+
+ for (int i = 0; i < p.length; i++) {
+ os << p.data[i] << " ";
+ }
+
+ os << dec << "\n" << endl;
+
+ return os;
+}
+
+void pack(packet_t* p) {
+ if (p->dest_addr != 0) {
+ for (int i = 0; i < 6; i++) {
+ p->payload[i] = p->dest_addr >> ((5-i)*8);
+ }
+ }
+ for (int i = 0; i < p->length; i++) {
+ p->data[i] = p->payload[i];
+ }
+}
+
+
+void unpack(packet_t* p) {
+ for (int i = 0; i < p->length; i++) {
+ p->payload[i] = p->data[i];
+ }
+}
+
+void add_crc(packet_t* p) {
+ for (int i = p->length; i < p->length + 4; i++) {
+ p->data[i] = p->crc >> (8 * (i - p->length));
+ }
+ p->length += 4;
+}
+
+void strip_crc(packet_t* p) {
+ if (p->length >= 4) {
+ p->crc_rx = 0;
+ for (int i = p->length - 4; i < p->length; i++) {
+ p->crc_rx |= p->data[i] << (8 * (i - p->length - 4));
+ }
+ p->length -= 4;
+ }
+}
+
+void calc_crc(packet_t* p) {
+
+ u_int32_t crc;
+
+ p->crc = chksum_crc32(p->data, p->length);
+}
+
+void pad(packet_t* p, int len) {
+ if (p->length < len) {
+ for (int i = p->length; i < len; i++) {
+ p->payload[i] = 0;
+ }
+ p->length = len;
+ };
+}
+
+bool compare(packet_t* pkta, packet_t* pktb) {
+
+ bool good = true;
+
+ if (pkta->length != pktb->length) {
+
+ good = false;
+
+ }
+ else {
+
+ if (pkta->crc != pktb->crc) {
+ good = false;
+ }
+
+ for (int i = 0; i < pkta->length; i++) {
+ if (pkta->payload[i] != pktb->payload[i]) {
+ good = false;
+ }
+ }
+
+ }
+
+ return good;
+}
+
sc_packet.cpp
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property