Line 50... |
Line 50... |
`define ETH_TOP dut.ethmac0
|
`define ETH_TOP dut.ethmac0
|
`define ETH_BD_RAM_PATH `ETH_TOP.wishbone.bd_ram
|
`define ETH_BD_RAM_PATH `ETH_TOP.wishbone.bd_ram
|
`define ETH_MODER_PATH `ETH_TOP.ethreg1.MODER_0
|
`define ETH_MODER_PATH `ETH_TOP.ethreg1.MODER_0
|
|
|
`ifdef RTL_SIM
|
`ifdef RTL_SIM
|
`ifdef eth_IS_GATELEVEL
|
`ifdef ethmac_IS_GATELEVEL
|
`define ETH_MODER_TXEN_BIT `ETH_MODER_PATH.r_TxEn;
|
`define ETH_MODER_TXEN_BIT `ETH_MODER_PATH.r_TxEn;
|
`define ETH_MODER_RXEN_BIT `ETH_MODER_PATH.r_RxEn;
|
`define ETH_MODER_RXEN_BIT `ETH_MODER_PATH.r_RxEn;
|
`else
|
`else
|
`define ETH_MODER_TXEN_BIT `ETH_MODER_PATH.DataOut[1];
|
`define ETH_MODER_TXEN_BIT `ETH_MODER_PATH.DataOut[1];
|
`define ETH_MODER_RXEN_BIT `ETH_MODER_PATH.DataOut[0];
|
`define ETH_MODER_RXEN_BIT `ETH_MODER_PATH.DataOut[0];
|
Line 70... |
Line 70... |
reg [7:0] st_data;
|
reg [7:0] st_data;
|
reg [31:0] lfsr;
|
reg [31:0] lfsr;
|
integer lfsr_last_byte;
|
integer lfsr_last_byte;
|
|
|
// Is number of ethernet packets to send if doing the eth-rx test.
|
// Is number of ethernet packets to send if doing the eth-rx test.
|
parameter eth_stim_num_rx_only_tests = 256;
|
parameter eth_stim_num_rx_only_num_packets = 500; // Set to 0 for continuous RX
|
|
parameter eth_stim_num_rx_only_packet_size = 512;
|
|
parameter eth_stim_num_rx_only_packet_size_change = 2'b01; // 2'b01: Increment
|
|
parameter eth_stim_num_rx_only_packet_size_change_amount = 1;
|
|
parameter eth_stim_num_rx_only_IPG = 800000; // ns
|
|
|
|
// Do call/response test
|
|
reg eth_stim_do_rx_reponse_to_tx;
|
|
|
|
|
parameter num_tx_bds = 16;
|
parameter num_tx_bds = 16;
|
parameter num_tx_bds_mask = 4'hf;
|
parameter num_tx_bds_mask = 4'hf;
|
parameter num_rx_bds = 16;
|
parameter num_rx_bds = 16;
|
parameter num_rx_bds_mask = 4'hf;
|
parameter num_rx_bds_mask = 4'hf;
|
parameter max_eth_packet_size = 16'h0600;
|
parameter max_eth_packet_size = 16'h0600;
|
|
|
// If running eth-rxtxbig test (sending and receiving maximum packets), then
|
// If running eth-rxtxbig test (sending and receiving maximum packets), then
|
// set this parameter to the max packet size, otherwise min packet size
|
// set this parameter to the max packet size, otherwise min packet size
|
//parameter rx_while_tx_min_packet_size = max_eth_packet_size;
|
//parameter rx_while_tx_min_packet_size = max_eth_packet_size;
|
parameter rx_while_tx_min_packet_size = 32;
|
parameter rx_while_tx_min_packet_size = 32;
|
|
|
Line 138... |
Line 146... |
//lfsr = 32'h84218421; // Init pseudo lfsr
|
//lfsr = 32'h84218421; // Init pseudo lfsr
|
lfsr = 32'h00700001; // Init pseudo lfsr
|
lfsr = 32'h00700001; // Init pseudo lfsr
|
lfsr_last_byte = 0;
|
lfsr_last_byte = 0;
|
|
|
eth_stim_waiting = 1;
|
eth_stim_waiting = 1;
|
|
expected_rxbd = num_tx_bds; // init this here
|
|
|
|
eth_stim_do_rx_reponse_to_tx = 0;
|
|
|
|
|
while (eth_stim_waiting) // Loop, waiting for enabling of MAC by software
|
while (eth_stim_waiting) // Loop, waiting for enabling of MAC by software
|
begin
|
begin
|
#100;
|
#100;
|
// If RX enable and not TX enable...
|
// If RX enable and not TX enable...
|
if(ethmac_rxen === 1'b1 & !(ethmac_txen===1'b1))
|
if(ethmac_rxen === 1'b1 & !(ethmac_txen===1'b1))
|
begin
|
begin
|
if (eth_inject_errors)
|
if (eth_inject_errors)
|
begin
|
begin
|
do_rx_only_stim(16, 0, 0);
|
do_rx_only_stim(16, 64, 0, 0);
|
do_rx_only_stim(128, 1'b1, 8);
|
do_rx_only_stim(128, 64, 1'b1, 8);
|
do_rx_only_stim(256, 1'b1, 4);
|
do_rx_only_stim(256, 64, 1'b1, 4);
|
eth_stim_waiting = 0;
|
eth_stim_waiting = 0;
|
end
|
end
|
else
|
else
|
begin
|
begin
|
do_rx_only_stim(eth_stim_num_rx_only_tests, 0, 0);
|
//do_rx_only_stim(eth_stim_num_rx_only_num_packets,
|
|
//eth_stim_num_rx_only_packet_size, 0, 0);
|
|
|
|
// Call packet send loop directly. No error injection.
|
|
send_packet_loop(eth_stim_num_rx_only_num_packets,
|
|
eth_stim_num_rx_only_packet_size,
|
|
eth_stim_num_rx_only_packet_size_change,
|
|
eth_stim_num_rx_only_packet_size_change_amount,
|
|
eth_phy0.eth_speed, // Speed
|
|
eth_stim_num_rx_only_IPG, // IPG
|
|
48'h0012_3456_789a, 48'h0708_090A_0B0C, 1,
|
|
0, 0);
|
|
|
eth_stim_waiting = 0;
|
eth_stim_waiting = 0;
|
end
|
end
|
end // if (ethmac_rxen === 1'b1 & !(ethmac_txen===1'b1))
|
end // if (ethmac_rxen === 1'b1 & !(ethmac_txen===1'b1))
|
// If both RX and TX enabled
|
// If both RX and TX enabled
|
else if (ethmac_rxen === 1'b1 & ethmac_txen===1'b1)
|
else if (ethmac_rxen === 1'b1 & ethmac_txen===1'b1)
|
begin
|
begin
|
// If RX enable and TX enable
|
// Both enabled - let's wait for the first packet transmitted
|
|
// to see what stimulus we should provide
|
|
while (num_tx_packets==1)
|
|
#1000;
|
|
|
|
$display("* ethmac RX/TX test request: %x", eth_phy0.tx_mem[0]);
|
|
|
|
// Check the first received byte's value
|
|
case (eth_phy0.tx_mem[0])
|
|
0:
|
|
begin
|
|
// kickoff call/response here
|
|
eth_stim_do_rx_reponse_to_tx = 1;
|
|
end
|
|
default:
|
|
begin
|
do_rx_while_tx_stim(1400);
|
do_rx_while_tx_stim(1400);
|
|
end
|
|
endcase // case (eth_phy0.tx_mem[0])
|
|
|
eth_stim_waiting = 0;
|
eth_stim_waiting = 0;
|
end
|
end
|
end // while (eth_stim_waiting)
|
end // while (eth_stim_waiting)
|
|
|
end // initial begin
|
end // initial begin
|
|
|
// Main Ethernet RX testing stimulus task.
|
// Main Ethernet RX testing stimulus task.
|
// Sends a set of packets at both speeds
|
// Sends a set of packets at both speeds
|
task do_rx_only_stim;
|
task do_rx_only_stim;
|
input [31:0] num_packets;
|
input [31:0] num_packets;
|
|
input [31:0] start_packet_size;
|
input inject_errors;
|
input inject_errors;
|
input [31:0] inject_errors_mod;
|
input [31:0] inject_errors_mod;
|
|
|
begin
|
begin
|
expected_rxbd = num_tx_bds; // init this here
|
|
|
|
for(speed_loop=1;speed_loop<3;speed_loop=speed_loop+1)
|
for(speed_loop=1;speed_loop<3;speed_loop=speed_loop+1)
|
begin
|
begin
|
|
|
send_packet_loop(num_packets, 64, 2'b01, 1, speed_loop[0], 10000,
|
send_packet_loop(num_packets, start_packet_size, 2'b01, 1,
|
|
speed_loop[0], 10000,
|
48'h0012_3456_789a, 48'h0708_090A_0B0C, 1,
|
48'h0012_3456_789a, 48'h0708_090A_0B0C, 1,
|
inject_errors, inject_errors_mod);
|
inject_errors, inject_errors_mod);
|
|
|
end
|
end
|
|
|
Line 200... |
Line 243... |
reg [31:0] IPG; // Inter-packet gap
|
reg [31:0] IPG; // Inter-packet gap
|
reg [31:0] packet_size;
|
reg [31:0] packet_size;
|
|
|
integer j;
|
integer j;
|
begin
|
begin
|
expected_rxbd = num_tx_bds; // init this here
|
|
|
|
for(j=0;j<num_packets;j=j+1)
|
for(j=0;j<num_packets;j=j+1)
|
begin
|
begin
|
// Determine delay between RX packets:
|
// Determine delay between RX packets:
|
|
|
Line 267... |
Line 309... |
|
|
end // for (j=0;j<num_packets;j=j+1)
|
end // for (j=0;j<num_packets;j=j+1)
|
end
|
end
|
endtask // do_rx_stim
|
endtask // do_rx_stim
|
|
|
|
// Registers used in detecting transmitted packets
|
|
reg eth_stim_tx_loop_keep_polling;
|
|
reg [31:0] ethmac_txbd_lenstat, ethmac_last_txbd_lenstat;
|
|
reg eth_stim_detected_packet_tx;
|
|
|
|
// If in call-response mode, whenever we receive a TX packet, we generate
|
|
// one and send it back
|
|
always @(negedge eth_stim_detected_packet_tx)
|
|
begin
|
|
if (eth_stim_do_rx_reponse_to_tx & ethmac_rxen)
|
|
// Continue if we are enabled
|
|
do_rx_response_to_tx();
|
|
end
|
|
|
|
// Generate RX packet in rsponse to TX packet
|
|
task do_rx_response_to_tx;
|
|
//input unused;
|
|
|
|
reg [31:0] IPG; // Inter-packet gap
|
|
reg [31:0] packet_size;
|
|
|
|
integer j;
|
|
begin
|
|
|
|
// Get packet size test wants us to send
|
|
packet_size = {eth_phy0.tx_mem[0],eth_phy0.tx_mem[1],
|
|
eth_phy0.tx_mem[2],eth_phy0.tx_mem[3]};
|
|
|
|
|
|
IPG = {eth_phy0.tx_mem[4],eth_phy0.tx_mem[5],
|
|
eth_phy0.tx_mem[6],eth_phy0.tx_mem[7]};
|
|
|
|
|
|
$display("do_rx_response_to_tx IPG = %0d", IPG);
|
|
if (packet_size == 0)
|
|
begin
|
|
// Constrained random sized packets
|
|
packet_size = $random;
|
|
|
|
while (packet_size > (max_eth_packet_size-4))
|
|
packet_size = packet_size / 2;
|
|
|
|
if (packet_size < 60)
|
|
packet_size = packet_size + 60;
|
|
end
|
|
|
|
$display("do_rx_response_to_tx packet_size = %0d", packet_size);
|
|
send_packet_loop(1, packet_size, 2'b01, 1, eth_phy0.eth_speed,
|
|
IPG, 48'h0012_3456_789a,
|
|
48'h0708_090A_0B0C, 1, 1'b0, 0);
|
|
|
|
// If RX enable went low, wait for it go high again
|
|
if (ethmac_rxen===1'b0)
|
|
begin
|
|
|
|
while (ethmac_rxen===1'b0)
|
|
begin
|
|
@(posedge ethmac_rxen);
|
|
#10000;
|
|
end
|
|
|
|
// RX disabled and when re-enabled we reset the buffer
|
|
// descriptor number
|
|
expected_rxbd = num_tx_bds;
|
|
|
|
end
|
|
|
|
end
|
|
endtask // do_rx_response_to_tx
|
|
|
|
|
|
|
|
|
|
|
//
|
//
|
// always@() to check the TX buffer descriptors
|
// always@() to check the TX buffer descriptors
|
//
|
//
|
reg keep_polling;
|
|
reg [31:0] txbd_lenstat, last_txbd_lenstat;
|
|
reg detected_packet_tx;
|
|
always @(posedge ethmac_txen)
|
always @(posedge ethmac_txen)
|
begin
|
begin
|
last_txbd_lenstat = 0;
|
ethmac_last_txbd_lenstat = 0;
|
keep_polling=1;
|
eth_stim_tx_loop_keep_polling=1;
|
// Wait on the TxBD Ready bit
|
// Wait on the TxBD Ready bit
|
while(keep_polling)
|
while(eth_stim_tx_loop_keep_polling)
|
begin
|
begin
|
#10;
|
#10;
|
get_bd_lenstat(expected_txbd, txbd_lenstat);
|
get_bd_lenstat(expected_txbd, ethmac_txbd_lenstat);
|
// Check if we've finished transmitting this BD
|
// Check if we've finished transmitting this BD
|
if (!txbd_lenstat[15] & last_txbd_lenstat[15])
|
if (!ethmac_txbd_lenstat[15] & ethmac_last_txbd_lenstat[15])
|
// Falling edge of TX BD Ready
|
// Falling edge of TX BD Ready
|
detected_packet_tx = 1;
|
eth_stim_detected_packet_tx = 1;
|
|
|
last_txbd_lenstat = txbd_lenstat;
|
ethmac_last_txbd_lenstat = ethmac_txbd_lenstat;
|
|
|
// If TX en goes low then exit
|
// If TX en goes low then exit
|
if (!ethmac_txen)
|
if (!ethmac_txen)
|
keep_polling = 0;
|
eth_stim_tx_loop_keep_polling = 0;
|
else if (detected_packet_tx)
|
else if (eth_stim_detected_packet_tx)
|
begin
|
begin
|
// Wait until the eth_phy has finished receiving it
|
// Wait until the eth_phy has finished receiving it
|
while (eth_phy0.mtxen_i === 1'b1)
|
while (eth_phy0.mtxen_i === 1'b1)
|
#10;
|
#10;
|
|
|
$display("(%t) Check TX packet: bd %d: 0x%h",$time,
|
$display("(%t) Check TX packet: bd %d: 0x%h",$time,
|
expected_txbd, txbd_lenstat);
|
expected_txbd, ethmac_txbd_lenstat);
|
|
|
// Check the TXBD, see if the packet transmitted OK
|
// Check the TXBD, see if the packet transmitted OK
|
if (txbd_lenstat[8] | txbd_lenstat[3])
|
if (ethmac_txbd_lenstat[8] | ethmac_txbd_lenstat[3])
|
begin
|
begin
|
// Error occured
|
// Error occured
|
`TIME;
|
`TIME;
|
$display("*E TX Error of packet %0d detected.",
|
$display("*E TX Error of packet %0d detected.",
|
num_tx_packets);
|
num_tx_packets);
|
$display(" TX BD %0d = 0x%h", expected_txbd,
|
$display(" TX BD %0d = 0x%h", expected_txbd,
|
txbd_lenstat);
|
ethmac_txbd_lenstat);
|
if (txbd_lenstat[8])
|
if (ethmac_txbd_lenstat[8])
|
$display(" Underrun in MAC during TX");
|
$display(" Underrun in MAC during TX");
|
if (txbd_lenstat[3])
|
if (ethmac_txbd_lenstat[3])
|
$display(" Retransmission limit hit");
|
$display(" Retransmission limit hit");
|
|
|
$finish;
|
$finish;
|
end
|
end
|
else
|
else
|
begin
|
begin
|
// Packet was OK, let's compare the contents we received
|
// Packet was OK, let's compare the contents we
|
// with those that were meant to be transmitted
|
// received with those that were meant to be transmitted
|
if (eth_stim_check_tx_packet_contents)
|
if (eth_stim_check_tx_packet_contents)
|
begin
|
begin
|
check_tx_packet(expected_txbd);
|
check_tx_packet(expected_txbd);
|
expected_txbd = (expected_txbd + 1) &
|
expected_txbd = (expected_txbd + 1) &
|
num_tx_bds_mask;
|
num_tx_bds_mask;
|
num_tx_packets = num_tx_packets + 1;
|
num_tx_packets = num_tx_packets + 1;
|
detected_packet_tx = 0;
|
eth_stim_detected_packet_tx = 0;
|
end
|
end
|
end
|
end
|
end
|
end
|
end // while (keep_polling)
|
end // while (eth_stim_tx_loop_keep_polling)
|
end // always @ (posedge ethmac_txen)
|
end // always @ (posedge ethmac_txen)
|
|
|
|
|
|
|
//
|
//
|
Line 346... |
Line 459... |
|
|
reg [31:0] tx_bd_addr;
|
reg [31:0] tx_bd_addr;
|
reg [7:0] phy_byte;
|
reg [7:0] phy_byte;
|
|
|
reg [31:0] txpnt_wb; // Pointer in array to where data should be
|
reg [31:0] txpnt_wb; // Pointer in array to where data should be
|
reg [24:0] txpnt_sdram; // Index in array of shorts for data in SDRAM part
|
reg [24:0] txpnt_sdram; // Index in array of shorts for data in SDRAM
|
|
// part
|
reg [21:0] buffer;
|
reg [21:0] buffer;
|
reg [7:0] sdram_byte;
|
reg [7:0] sdram_byte;
|
reg [31:0] tx_len_bd;
|
reg [31:0] tx_len_bd;
|
|
|
integer i;
|
integer i;
|
Line 452... |
Line 566... |
reg [31:0] rx_bd_lenstat;
|
reg [31:0] rx_bd_lenstat;
|
begin
|
begin
|
error_type = 0;
|
error_type = 0;
|
error_this_time = 0;
|
error_this_time = 0;
|
|
|
|
if (num_packets == 0)
|
|
// Loop forever when num_packets is 0
|
|
num_packets = 32'h7fffffff;
|
|
|
|
|
if (speed & !(eth_phy0.control_bit14_10[13] === 1'b1))
|
if (speed & !(eth_phy0.control_bit14_10[13] === 1'b1))
|
begin
|
begin
|
// write to phy's control register for 100Mbps
|
// write to phy's control register for 100Mbps
|
eth_phy0.control_bit14_10 = 5'b01000; // bit 13 set - speed 100
|
eth_phy0.control_bit14_10 = 5'b01000; // bit 13 set - speed 100
|
// Swapping speeds, give some delay
|
// Swapping speeds, give some delay
|
Line 710... |
Line 829... |
delta_t = !delta_t;
|
delta_t = !delta_t;
|
end
|
end
|
endtask // set_rx_addr_type
|
endtask // set_rx_addr_type
|
|
|
|
|
`ifdef eth_IS_GATELEVEL // Check if we're using a synthesized version of eth module
|
// Check if we're using a synthesized version of eth module
|
|
`ifdef ethmac_IS_GATELEVEL
|
|
|
// Get the length/status register of the ethernet buffer descriptor
|
// Get the length/status register of the ethernet buffer descriptor
|
task get_bd_lenstat;
|
task get_bd_lenstat;
|
input [31:0] bd_num;// Number of ethernet BD to check
|
input [31:0] bd_num;// Number of ethernet BD to check
|
output [31:0] bd_lenstat;
|
output [31:0] bd_lenstat;
|
`ifdef ACTEL
|
`ifdef ACTEL
|
Line 776... |
Line 897... |
//$display("(%t) read eth bd%d addr %h",$time,bd_num, bd_addr);
|
//$display("(%t) read eth bd%d addr %h",$time,bd_num, bd_addr);
|
`endif
|
`endif
|
end
|
end
|
endtask // get_bd_addr
|
endtask // get_bd_addr
|
|
|
`else // !`ifdef eth_IS_GATELEVEL
|
`else // !`ifdef ethmac_IS_GATELEVEL
|
|
|
// Get the length/status register of the ethernet buffer descriptor
|
// Get the length/status register of the ethernet buffer descriptor
|
task get_bd_lenstat;
|
task get_bd_lenstat;
|
input [31:0] bd_num;// Number of ethernet BD to check
|
input [31:0] bd_num;// Number of ethernet BD to check
|
output [31:0] bd_lenstat;
|
output [31:0] bd_lenstat;
|
Line 804... |
Line 925... |
// send_packet_loop
|
// send_packet_loop
|
integer eth_rx_packet_length_to_check;
|
integer eth_rx_packet_length_to_check;
|
|
|
always @*
|
always @*
|
begin
|
begin
|
// Loop here waiting for a packet to be sent, or if we shouldn't
|
// Loop here until:
|
// check them at all.
|
// 1 - packets sent is not equal to packets checked (ie. some to check)
|
|
// 2 - we're explicitly disabled for some reason
|
|
// 3 - Receive has been disabled in the MAC
|
while((eth_rx_num_packets_sent == eth_rx_num_packets_checked) ||
|
while((eth_rx_num_packets_sent == eth_rx_num_packets_checked) ||
|
!eth_stim_check_rx_packet_contents)
|
!eth_stim_check_rx_packet_contents || !(ethmac_rxen===1'b1))
|
#1000;
|
#1000;
|
|
|
eth_rx_packet_length_to_check
|
eth_rx_packet_length_to_check
|
= rx_packet_lengths[(eth_rx_num_packets_checked & 12'h3ff)];
|
= rx_packet_lengths[(eth_rx_num_packets_checked & 12'h3ff)];
|
|
|
Line 897... |
Line 1020... |
|
|
phy_byte = eth_rx_sent_circbuf[eth_rx_sent_circbuf_read_ptr];//phy_rx_mem[buffer]; //eth_phy0.rx_mem[buffer];
|
phy_byte = eth_rx_sent_circbuf[eth_rx_sent_circbuf_read_ptr];//phy_rx_mem[buffer]; //eth_phy0.rx_mem[buffer];
|
|
|
if (phy_byte !== sdram_byte)
|
if (phy_byte !== sdram_byte)
|
begin
|
begin
|
`TIME;
|
// `TIME;
|
$display("*E Wrong byte (%d) of RX packet! phy = %h, ram = %h",
|
$display("*E Wrong byte (%5d) of RX packet %5d! phy = %h, ram = %h",
|
i, phy_byte, sdram_byte);
|
i, eth_rx_num_packets_checked, phy_byte, sdram_byte);
|
failure = 1;
|
failure = 1;
|
end
|
end
|
|
|
eth_rx_sent_circbuf_read_ptr = (eth_rx_sent_circbuf_read_ptr+1)&
|
eth_rx_sent_circbuf_read_ptr = (eth_rx_sent_circbuf_read_ptr+1)&
|
eth_rx_sent_circbuf_size_mask;
|
eth_rx_sent_circbuf_size_mask;
|