OpenCores
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

powered by: WebSVN 2.1.0

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