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 25 to Rev 29
    Reverse comparison

Rev 25 → Rev 29

/sc_pkt_generator.h
58,6 → 58,8
 
int crc_interval;
int fragment_interval;
int lenght_err_interval;
int lenght_err_size;
int coding_interval;
int local_fault_interval;
int remote_fault_interval;
79,6 → 81,7
 
void set_crc_errors(int interval);
void set_fragment_errors(int interval);
void set_lenght_errors(int interval, int size);
void set_coding_errors(int interval);
void set_local_fault(int interval);
void set_remote_fault(int interval);
/sc_cpu_if.h
43,6 → 43,15
#include "sc_scoreboard.h"
#include "sc_cpu_if.h"
 
struct rmonStats_t {
int tx_pkt_cnt;
int rx_pkt_cnt;
 
int tx_octets_cnt;
int rx_octets_cnt;
};
 
 
SC_MODULE(cpu_if) {
 
public:
81,6 → 90,7
INT_PAUSE_FRAME = 6,
INT_CRC_ERROR = 7,
INT_FRAGMENT_ERROR = 8,
INT_LENGHT_ERROR = 9,
};
 
enum regId {
89,6 → 99,12
CPUREG_INT_PENDING = 0x8,
CPUREG_INT_STATUS = 0xc,
CPUREG_INT_MASK = 0x10,
 
CPUREG_STATSTXOCTETS = 0x80,
CPUREG_STATSTXPKTS = 0x84,
 
CPUREG_STATSRXOCTETS = 0x90,
CPUREG_STATSRXPKTS = 0x94,
};
 
private:
121,6 → 137,7
void set_interrupt(cpu_if::intId intr);
void set_interrupt_mask(cpu_if::intId intr, bool value);
void enable_all_interrupts(void);
void get_rmon_stats(rmonStats_t *rmon_stats);
 
uint read(uint addr);
void write(uint addr, uint data);
/sc_packet.h
48,6 → 48,7
#define PKT_FLAG_ERR_CODING 0x0010
#define PKT_FLAG_LOCAL_FAULT 0x0020
#define PKT_FLAG_REMOTE_FAULT 0x0040
#define PKT_FLAG_ERR_LENGHT 0x0080
 
 
struct packet_t {
58,7 → 59,7
 
sc_uint<48> dest_addr;
sc_uint<48> src_addr;
sc_uint<8> payload [12000];
sc_uint<8> payload [18000];
sc_uint<32> crc;
 
sc_uint<32> crc_rx;
68,7 → 69,7
sc_uint<32> ifg;
sc_uint<32> start_lane;
 
sc_uint<8> data [10000];
sc_uint<8> data [20000];
};
 
ostream& operator<<(ostream& os, const packet_t& p);
/sc_pkt_if.cpp
54,6 → 54,7
 
void pkt_if::init(void) {
disable_rx = false;
flush_rx = false;
allow_rx_sop_err = false;
}
 
116,9 → 117,9
sb->notify_packet_tx(sb_id, pkt);
 
//---
// Enforce minimum spacing between SOP's
// Wait for room in the FIFO before processing next packet
 
for (int i = (pkt->length+7)/8; i < 8; i++) {
while (pkt_tx_full) {
wait();
}
}
132,6 → 133,8
 
sc_uint<64> data;
 
bool flush;
 
wait();
 
while (true) {
140,6 → 143,8
 
pkt = new(packet_t);
pkt->length = 0;
pkt->err_flags = 0;
flush = false;
 
// If reading already selected just keep going,
// if not we must enable ren
183,7 → 188,7
 
pkt->data[pkt->length++] = (data >> (8 * (7-lane))) & 0xff;
 
if (pkt->length >= 10000) {
if (pkt->length >= 17000) {
cout << "ERROR: Packet too long" << endl;
sc_stop();
}
200,6 → 205,10
}
}
 
if (flush_rx && pkt->err_flags) {
flush = true;
}
 
//---
// Store packet
 
211,7 → 220,9
//---
// Pass packet to scoreboard
 
sb->notify_packet_rx(sb_id, pkt);
if (!flush) {
sb->notify_packet_rx(sb_id, pkt);
}
 
}
else {
/sc_pkt_if.h
91,6 → 91,7
// Variables
 
bool disable_rx;
bool flush_rx;
bool allow_rx_sop_err;
 
//---
/sc_scoreboard.cpp
59,7 → 59,7
// Save packet to a fifo
 
if (sid == SB_PIF_ID) {
cout << "SCOREBOARD PACKET INTERFACE TX ("
cout << "SCOREBOARD PACKET INTERFACE TX ("
<< pkt->length << ")" << endl;
 
//---
67,12 → 67,13
 
pif_fifo.write(pkt);
pif_stats.tx_pkt_cnt++;
pif_stats.tx_octets_cnt = pif_stats.tx_octets_cnt + pkt->length;
 
}
 
if (sid == SB_XGM_ID) {
 
cout << "SCOREBOARD XGMII INTERFACE TX ("
cout << "SCOREBOARD XGMII INTERFACE TX ("
<< pkt->length << ")" << endl;
 
//---
90,6 → 91,7
 
xgm_fifo.write(pkt);
xgm_stats.tx_pkt_cnt++;
xgm_stats.tx_octets_cnt = xgm_stats.tx_octets_cnt + pkt->length;
 
}
 
132,7 → 134,7
if (sid == SB_PIF_ID) {
status = xgm_fifo.nb_read(pkt_tx);
if (status) {
cout << "SCOREBOARD PACKET INTERFACE RX (TX SIZE="
cout << "SCOREBOARD PACKET INTERFACE RX (TX SIZE="
<< pkt_tx->length << " RX SIZE="
<< pkt->length << ")" << endl;
}
184,6 → 186,11
calc_crc(pkt_tx);
calc_crc(pkt);
 
//---
// Update byte count after padding
 
stats->rx_octets_cnt = stats->rx_octets_cnt + pkt_tx->length + 4;
 
//cout << *pkt_tx << *pkt << endl;
 
//---
195,13 → 202,19
 
}
else if ((pkt_tx->err_flags & PKT_FLAG_ERR_FRG) &&
(pkt->err_flags |= PKT_FLAG_ERR_SIG)) {
(pkt->err_flags & PKT_FLAG_ERR_SIG)) {
 
cout << "INFO: Fragment detected" << endl;
 
}
else if ((pkt_tx->err_flags & PKT_FLAG_ERR_LENGHT) &&
(pkt->err_flags & PKT_FLAG_ERR_SIG)) {
 
cout << "INFO: Lenght error detected" << endl;
 
}
else if ((pkt_tx->err_flags & PKT_FLAG_ERR_CODING) &&
(pkt->err_flags |= PKT_FLAG_ERR_SIG)) {
(pkt->err_flags & PKT_FLAG_ERR_SIG)) {
 
cout << "INFO: Coding error detected:" << pkt_tx->err_info << endl;
 
208,7 → 221,7
}
else if ((sid == SB_PIF_ID || pkt->crc == pkt->crc_rx || disable_crc_check) &&
compare(pkt_tx, pkt)) {
 
//cout << "GOOD: Packets are matching" << endl;
 
}
266,10 → 279,10
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();
279,7 → 292,7
cout << "ERROR: CRC error not detected: " << hex << pkt->err_flags << dec << endl;
sc_stop();
}
 
pkt->err_flags &= ~PKT_FLAG_ERR_SIG;
}
 
289,10 → 302,10
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;
304,19 → 317,43
<< hex << pkt->err_flags << dec << endl;
sc_stop();
}
 
pkt->err_flags &= ~PKT_FLAG_ERR_SIG;
}
 
 
// LENGHT ERRORS
 
if (sid == SB_PIF_ID && (pkt_tx->err_flags & PKT_FLAG_ERR_LENGHT)) {
 
if (pkt->err_flags & PKT_FLAG_ERR_SIG) {
 
cout << "SCOREBOARD LENGHT ERROR CHECKED" << endl;
pif_stats.lenght_error_cnt++;
 
if (cpu_stats.lenght_error_cnt + 1 < pif_stats.lenght_error_cnt) {
cout << "ERROR: LENGHT error not reported to cpu" << endl;
sc_stop();
}
}
else {
cout << "ERROR: LENGHT 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;
329,7 → 366,7
<< hex << pkt->err_flags << dec << endl;
sc_stop();
}
 
pkt->err_flags &= ~PKT_FLAG_ERR_SIG;
}
 
367,6 → 404,11
cpu_stats.fragment_error_cnt++;
}
 
if (sid == SB_CPU_ID && statusId == LENGHT_ERROR) {
cout << "SCOREBOARD LENGHT_ERROR SIGNAL" << endl;
cpu_stats.lenght_error_cnt++;
}
 
if (sid == SB_CPU_ID && statusId == LOCAL_FAULT) {
cout << "SCOREBOARD LOCAL_FAULT SIGNAL" << endl;
cpu_stats.local_fault_cnt++;
485,11 → 527,15
 
pif_stats.tx_pkt_cnt = 0;
pif_stats.rx_pkt_cnt = 0;
pif_stats.tx_octets_cnt = 0;
pif_stats.rx_octets_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.tx_octets_cnt = 0;
xgm_stats.rx_octets_cnt = 0;
xgm_stats.crc_error_cnt = 0;
xgm_stats.flags_error_cnt = 0;
 
504,6 → 550,7
 
cpu_stats.crc_error_cnt = 0;
cpu_stats.fragment_error_cnt = 0;
cpu_stats.lenght_error_cnt = 0;
cpu_stats.rxd_fifo_ovflow_cnt = 0;
cpu_stats.rxd_fifo_udflow_cnt = 0;
cpu_stats.txd_fifo_ovflow_cnt = 0;
/sc_scoreboard.h
47,8 → 47,12
int tx_pkt_cnt;
int rx_pkt_cnt;
 
int tx_octets_cnt;
int rx_octets_cnt;
 
int crc_error_cnt;
int fragment_error_cnt;
int lenght_error_cnt;
int coding_error_cnt;
int flags_error_cnt;
 
70,6 → 74,7
struct sbCpuStats_t {
int crc_error_cnt;
int fragment_error_cnt;
int lenght_error_cnt;
 
int rxd_fifo_ovflow_cnt;
int rxd_fifo_udflow_cnt;
98,6 → 103,7
enum sbStatusId {
CRC_ERROR,
FRAGMENT_ERROR,
LENGHT_ERROR,
LOCAL_FAULT,
REMOTE_FAULT,
RXD_FIFO_OVFLOW,
145,7 → 151,7
 
void clear_stats(void);
 
SC_CTOR(scoreboard):
SC_CTOR(scoreboard):
pif_fifo (2000),
xgm_fifo (2000) {
 
/sc_xgmii_if.cpp
55,6 → 55,7
void xgmii_if::init(void) {
allow_idle_errors = false;
disable_padding = false;
inject_noise = false;
}
 
void xgmii_if::connect_scoreboard(scoreboard *sbptr, scoreboard::sbSourceId sid) {
69,6 → 70,15
sc_uint<64> txd = 0;
sc_uint<8> txc = 0;
 
int64_t noise [] = {0x1, 0xd5555555555555fb,
0x1, 0xd5555555555555fb,
0x1, 0xd5555555555555fc,
0x0, 0xd5555555555555fb,
0x1, 0xd5555555555555fb,
0x0, 0xd5555555555555fb,
0x1, 0x1111111111111111,
};
 
int lane = 0;
int bytecnt = 0;
int length = 0;
80,6 → 90,8
int fault_byte = 0;
int fault_spacing;
int fault_spacing_cnt = 0;
int count = 0;
int i = 0;
 
while (true) {
 
264,7 → 276,19
txd |= ((sc_uint<64>)0x07) << (8 * lane);
txc |= 0x01 << lane;
}
if (lane == 7) {
if (inject_noise) {
for (count = 0; count < 10000; count += 2) {
i = 2 * (random() % (sizeof(noise)/16));
cout << "NOISE: " << hex << noise[i] << " " << noise[i+1] << dec << endl;
xgmii_rxd = noise[i+1];
xgmii_rxc = noise[i];
txd = 0;
txc = 0;
wait();
}
inject_noise = false;
}
else if (lane == 7) {
xgmii_rxd = txd;
xgmii_rxc = txc;
txd = 0;
/sc_testcases.cpp
66,7 → 66,9
//---
// Testcases
 
test_packet_size(50, 90, 50);
test_noise();
 
test_packet_size(50, 90, 500);
test_packet_size(9000, 9020, 20);
test_packet_size(9599, 9601, 10);
 
79,6 → 81,7
test_rxdfifo_ovflow();
 
test_rx_fragments(55, 90, 300, 2);
test_rx_lenght(20, 3);
test_rx_coding_err(400, 4);
 
test_rx_local_fault(55, 90, 600, 15);
162,6 → 165,7
 
sbStats_t* pif_stats;
sbStats_t* xgm_stats;
rmonStats_t rmon_stats;
 
cout << "-----------------------" << endl;
cout << "Packet size" << endl;
207,6 → 211,35
cout << xgm_stats->rx_pkt_cnt << " " << cnt << endl;
sc_stop();
}
 
//---
// Check stats
 
tb->cpu_if0.get_rmon_stats(&rmon_stats);
 
if (rmon_stats.tx_pkt_cnt != cnt) {
cout << "ERROR: Not all TX packets counted by MAC." << endl;
cout << rmon_stats.tx_pkt_cnt << " " << cnt << endl;
sc_stop();
}
 
if (rmon_stats.rx_pkt_cnt != cnt) {
cout << "ERROR: Not all RX packets counted by MAC." << endl;
cout << rmon_stats.rx_pkt_cnt << " " << cnt << endl;
sc_stop();
}
 
if (rmon_stats.tx_octets_cnt != xgm_stats->rx_octets_cnt) {
cout << "ERROR: Not all TX octets counted by MAC." << endl;
cout << rmon_stats.tx_octets_cnt << " " << xgm_stats->rx_octets_cnt << endl;
sc_stop();
}
 
if (rmon_stats.rx_octets_cnt != pif_stats->rx_octets_cnt) {
cout << "ERROR: Not all RX octets counted by MAC." << endl;
cout << rmon_stats.rx_octets_cnt << " " << pif_stats->rx_octets_cnt << endl;
sc_stop();
}
}
 
void testcases::test_crc_errors(int min, int max, int cnt, int interval) {
483,6 → 516,65
tb->sb.disable_signal_check = false;
}
 
void testcases::test_rx_lenght(int cnt, int interval) {
 
sbStats_t* pif_stats;
sbCpuStats_t* cpu_stats;
 
cout << "-----------------------" << endl;
cout << "Lenght errors" << endl;
cout << "-----------------------" << endl;
 
//---
// Setup parameters
 
tb->sb.clear_stats();
 
tb->xgm_gen0.set_pkt_size(16000-4, 16000-4);
tb->xgm_gen0.set_lenght_errors(interval, 16000-3);
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(60000, 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->lenght_error_cnt + cpu_stats->crc_error_cnt
!= pif_stats->lenght_error_cnt) {
cout << "ERROR: Not all lenght errors reported to cpu" << endl;
cout << cpu_stats->lenght_error_cnt << endl;
cout << pif_stats->lenght_error_cnt << endl;
sc_stop();
}
 
//---
// Return parameters to default state
 
tb->sb.disable_signal_check = false;
tb->xgm_gen0.set_lenght_errors(0, 16000-3);
}
 
void testcases::test_rx_coding_err(int cnt, int interval) {
 
sbStats_t* pif_stats;
746,3 → 838,35
tb->sb.disable_signal_check = false;
tb->cpu_if0.set_interrupt_mask(cpu_if::INT_CRC_ERROR, 1);
}
 
void testcases::test_noise() {
 
cout << "-----------------------" << endl;
cout << "XGMII Noise" << endl;
cout << "-----------------------" << endl;
 
//---
// Setup parameters
 
tb->sb.disable_signal_check = true;
tb->pkt_if0.flush_rx = true;
 
//---
// Inject noise
 
tb->xgm_if0.inject_noise = true;
 
while (tb->xgm_if0.inject_noise) {
wait(100, SC_NS);
}
 
wait(30000, SC_NS);
 
//---
// Return parameters to default state
 
tb->sb.disable_signal_check = true;
tb->pkt_if0.flush_rx = false;
 
wait(30000, SC_NS);
}
/sc_xgmii_if.h
81,6 → 81,7
bool allow_idle_errors;
bool disable_receive;
bool disable_padding;
bool inject_noise;
 
bool rx_local_fault;
bool rx_remote_fault;
/sc_testcases.h
55,7 → 55,7
testbench* tb;
 
public:
 
//---
// Functions
 
65,13 → 65,14
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_lenght(int cnt, int interva);
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);
80,6 → 81,8
 
void test_interrupt_mask();
 
void test_noise();
 
//---
// Threads
 
/sc_pkt_generator.cpp
48,6 → 48,8
void pkt_generator::init(void) {
crc_interval = 0;
fragment_interval = 0;
lenght_err_interval = 0;
lenght_err_size = 10000;
coding_interval = 0;
local_fault_interval = 0;
remote_fault_interval = 0;
63,6 → 65,7
int len = 0;
int crc_int = 0;
int fragment_int = 0;
int lenght_err_int = 0;
int coding_int = 0;
int local_fault_int = 0;
int remote_fault_int = 0;
71,7 → 74,7
char running_cnt = 0;
 
while (true) {
 
wait(5, SC_NS);
 
if (tx_bucket != 0 && tx_fifo->num_available() == 0) {
86,7 → 89,7
 
//---
// Update constraints
 
if (len < min_pkt_size) {
len = min_pkt_size;
}
137,6 → 140,20
fragment_int = 0;
}
 
if (lenght_err_interval != 0) {
if (lenght_err_int >= lenght_err_interval) {
pkt->err_flags |= PKT_FLAG_ERR_LENGHT;
lenght_err_int = 0;
pkt->length = lenght_err_size;
}
else {
lenght_err_int++;
}
}
else {
lenght_err_int = 0;
}
 
if (coding_interval != 0) {
if (coding_int >= coding_interval) {
pkt->err_flags |= PKT_FLAG_ERR_CODING;
158,7 → 175,7
 
pkt->err_flags |= PKT_FLAG_LOCAL_FAULT;
local_fault_int = 0;
 
fault_spacing++;
if (fault_spacing > (132 - 4)) {
fault_spacing = 120;
178,7 → 195,7
 
pkt->err_flags |= PKT_FLAG_REMOTE_FAULT;
remote_fault_int = 0;
 
fault_spacing++;
if (fault_spacing > (132 - 4)) {
fault_spacing = 120;
202,7 → 219,7
pkt->dest_addr = 0x0180c2;
pkt->dest_addr = (pkt->dest_addr << 24) | 0x000001;
pause_int = 0;
 
}
else {
pause_int++;
216,7 → 233,7
 
tx_bucket--;
len++;
 
}
else {
wait(50, SC_NS);
248,6 → 265,11
fragment_interval = interval;
}
 
void pkt_generator::set_lenght_errors(int interval, int size) {
lenght_err_interval = interval;
lenght_err_size = size;
}
 
void pkt_generator::set_coding_errors(int interval) {
coding_interval = interval;
}
/sc_cpu_if.cpp
79,6 → 79,15
write(cpu_if::CPUREG_INT_MASK, 0xffffffff);
};
 
void cpu_if::get_rmon_stats(rmonStats_t *rmon_stats) {
 
rmon_stats->tx_octets_cnt = read(cpu_if::CPUREG_STATSTXOCTETS);
rmon_stats->tx_pkt_cnt = read(cpu_if::CPUREG_STATSTXPKTS);
 
rmon_stats->rx_octets_cnt = read(cpu_if::CPUREG_STATSRXOCTETS);
rmon_stats->rx_pkt_cnt = read(cpu_if::CPUREG_STATSRXPKTS);
};
 
uint cpu_if::read(uint addr) {
 
uint data;
240,6 → 249,10
sb->notify_status(sb_id, scoreboard::FRAGMENT_ERROR);
}
 
if ((data >> cpu_if::INT_LENGHT_ERROR) & 0x1) {
sb->notify_status(sb_id, scoreboard::LENGHT_ERROR);
}
 
if ((data >> cpu_if::INT_LOCAL_FAULT) & 0x1) {
 
data = read(cpu_if::CPUREG_INT_STATUS);

powered by: WebSVN 2.1.0

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