Line 51... |
Line 51... |
wire eth_mdio;
|
wire eth_mdio;
|
|
|
//
|
//
|
// TASKS registers to communicate with interfaces
|
// TASKS registers to communicate with interfaces
|
//
|
//
|
|
reg design_ready;
|
|
reg uart_echo;
|
|
`ifdef UART
|
|
reg [40*8-1:0] line;
|
|
reg [12*8-1:0] hello;
|
|
reg new_line;
|
|
reg new_char;
|
|
`endif
|
`ifdef ETHERNET
|
`ifdef ETHERNET
|
reg [7:0] eth_rx_data [0:1535]; //receive buffer ETH (max packet 1536)
|
reg [7:0] eth_rx_data [0:1535]; //receive buffer ETH (max packet 1536)
|
reg [7:0] eth_tx_data [0:1535]; //send buffer ETH (max packet 1536)
|
reg [7:0] eth_tx_data [0:1535]; //send buffer ETH (max packet 1536)
|
localparam ETH_HDR = 14;
|
localparam ETH_HDR = 14;
|
localparam ETH_PAYLOAD_MAX_LENGTH = 1518;//only able to send up to 1536 bytes with header (14 bytes) and CRC (4 bytes)
|
localparam ETH_PAYLOAD_MAX_LENGTH = 1518;//only able to send up to 1536 bytes with header (14 bytes) and CRC (4 bytes)
|
Line 70... |
Line 78... |
reg load_file;
|
reg load_file;
|
|
|
initial begin
|
initial begin
|
reset = ~RESET_LEVEL;
|
reset = ~RESET_LEVEL;
|
clock = 1'b0;
|
clock = 1'b0;
|
|
design_ready = 1'b0;
|
|
uart_echo = 1'b1;
|
|
|
`ifndef NO_CLOCK_DIVISION
|
`ifndef NO_CLOCK_DIVISION
|
minsoc_top_0.clk_adjust.clk_int = 1'b0;
|
minsoc_top_0.clk_adjust.clk_int = 1'b0;
|
minsoc_top_0.clk_adjust.clock_divisor = 32'h0000_0000;
|
minsoc_top_0.clk_adjust.clock_divisor = 32'h0000_0000;
|
`endif
|
`endif
|
Line 154... |
Line 164... |
|
|
|
|
//
|
//
|
// Testbench START
|
// Testbench START
|
//
|
//
|
|
design_ready = 1'b1;
|
fork
|
fork
|
begin
|
begin
|
`ifdef ETHERNET
|
`ifdef TEST_UART
|
get_mac();
|
$display("Testing UART interface...");
|
|
@ (posedge new_line);
|
if ( { eth_rx_data[ETH_HDR] , eth_rx_data[ETH_HDR+1] , eth_rx_data[ETH_HDR+2] , eth_rx_data[ETH_HDR+3] } == 32'hFF2B4050 )
|
$display("UART data received.");
|
$display("eth-nocache firmware started.");
|
hello = line[12*8-1:0];
|
`endif
|
//sending character A to UART, B expected
|
end
|
$display("Testing UART interrupt...");
|
begin
|
uart_echo = 1'b0;
|
#2000000;
|
|
`ifdef UART
|
|
uart_send(8'h41); //Character A
|
uart_send(8'h41); //Character A
|
`endif
|
@ (posedge new_char);
|
`ifdef ETHERNET
|
if ( line[7:0] == "B" )
|
|
$display("UART interrupt working.");
|
|
else
|
|
$display("UART interrupt failed.");
|
|
uart_echo = 1'b1;
|
|
|
|
if ( hello == "Hello World." )
|
|
$display("UART interface test completed, firmware behaving correclty.");
|
|
else
|
|
$display("UART interface test completed, UART firmware failed.");
|
|
`ifdef TEST_ETHERNET
|
|
$display("Testing Ethernet interface...");
|
eth_tx_data[ETH_HDR+0] = 8'hBA;
|
eth_tx_data[ETH_HDR+0] = 8'hBA;
|
eth_tx_data[ETH_HDR+1] = 8'h87;
|
eth_tx_data[ETH_HDR+1] = 8'h87;
|
eth_tx_data[ETH_HDR+2] = 8'hAA;
|
eth_tx_data[ETH_HDR+2] = 8'hAA;
|
eth_tx_data[ETH_HDR+3] = 8'hBB;
|
eth_tx_data[ETH_HDR+3] = 8'hBB;
|
eth_tx_data[ETH_HDR+4] = 8'hCC;
|
eth_tx_data[ETH_HDR+4] = 8'hCC;
|
eth_tx_data[ETH_HDR+5] = 8'hDD;
|
eth_tx_data[ETH_HDR+5] = 8'hDD;
|
|
|
|
$display("Sending an Ethernet package to the system and waiting for the data to be output from UART...");
|
send_mac(6);
|
send_mac(6);
|
|
$display("This takes a long time, if you want to stop it, type ctrl+c and type in finish afterwards.");
|
|
repeat(3+40) @ (posedge new_line);
|
|
$display("Ethernet test completed.");
|
|
$display("Stopping simulation.");
|
|
$finish;
|
|
`endif
|
|
$display("Stopping simulation.");
|
|
$finish;
|
|
`endif
|
|
end
|
|
begin
|
|
`ifdef TEST_ETHERNET
|
|
get_mac();
|
|
|
|
if ( { eth_rx_data[ETH_HDR] , eth_rx_data[ETH_HDR+1] , eth_rx_data[ETH_HDR+2] , eth_rx_data[ETH_HDR+3] } == 32'hFF2B4050 )
|
|
$display("Ethernet firmware started correctly.");
|
`endif
|
`endif
|
end
|
end
|
join
|
join
|
|
|
end
|
end
|
Line 287... |
Line 323... |
`endif
|
`endif
|
//~SPI START_UP
|
//~SPI START_UP
|
|
|
//UART
|
//UART
|
`ifdef UART
|
`ifdef UART
|
localparam UART_TX_WAIT = (`FREQ_NUM_FOR_NS / `UART_BAUDRATE);
|
localparam UART_TX_WAIT = (`FREQ / `UART_BAUDRATE);
|
|
|
task uart_send;
|
task uart_send;
|
input [7:0] data;
|
input [7:0] data;
|
integer i;
|
integer i;
|
begin
|
begin
|
uart_srx = 1'b0;
|
uart_srx = 1'b0;
|
#UART_TX_WAIT;
|
repeat (UART_TX_WAIT) @ (posedge clock);
|
for ( i = 0; i < 8 ; i = i + 1 ) begin
|
for ( i = 0; i < 8 ; i = i + 1 ) begin
|
uart_srx = data[i];
|
uart_srx = data[i];
|
#UART_TX_WAIT;
|
repeat (UART_TX_WAIT) @ (posedge clock);
|
end
|
end
|
uart_srx = 1'b0;
|
uart_srx = 1'b0;
|
#UART_TX_WAIT;
|
repeat (UART_TX_WAIT) @ (posedge clock);
|
uart_srx = 1'b1;
|
uart_srx = 1'b1;
|
end
|
end
|
endtask
|
endtask
|
|
|
//UART Monitor (prints uart output on the terminal)
|
//UART Monitor (prints uart output on the terminal)
|
// Something to trigger the task
|
// Something to trigger the task
|
|
initial
|
|
begin
|
|
new_line = 1'b0;
|
|
new_char = 1'b0;
|
|
end
|
|
|
always @(posedge clock)
|
always @(posedge clock)
|
|
if ( design_ready )
|
uart_decoder;
|
uart_decoder;
|
|
|
task uart_decoder;
|
task uart_decoder;
|
integer i;
|
integer i;
|
reg [7:0] tx_byte;
|
reg [7:0] tx_byte;
|
begin
|
begin
|
|
new_char = 1'b0;
|
// Wait for start bit
|
// Wait for start bit
|
while (uart_stx == 1'b1)
|
while (uart_stx == 1'b1)
|
@(uart_stx);
|
@(uart_stx);
|
|
|
#(UART_TX_WAIT+(UART_TX_WAIT/2));
|
repeat (UART_TX_WAIT+(UART_TX_WAIT/2)) @ (posedge clock);
|
|
|
for ( i = 0; i < 8 ; i = i + 1 ) begin
|
for ( i = 0; i < 8 ; i = i + 1 ) begin
|
tx_byte[i] = uart_stx;
|
tx_byte[i] = uart_stx;
|
#UART_TX_WAIT;
|
repeat (UART_TX_WAIT) @ (posedge clock);
|
end
|
end
|
|
|
//Check for stop bit
|
//Check for stop bit
|
if (uart_stx == 1'b0) begin
|
if (uart_stx == 1'b0) begin
|
//$display("* WARNING: user stop bit not received when expected at time %d__", $time);
|
//$display("* WARNING: user stop bit not received when expected at time %d__", $time);
|
Line 335... |
Line 378... |
while (uart_stx == 1'b0)
|
while (uart_stx == 1'b0)
|
@(uart_stx);
|
@(uart_stx);
|
//$display("* USER UART returned to idle at time %d",$time);
|
//$display("* USER UART returned to idle at time %d",$time);
|
end
|
end
|
// display the char
|
// display the char
|
|
new_char = 1'b1;
|
|
if ( uart_echo )
|
$write("%c", tx_byte);
|
$write("%c", tx_byte);
|
|
if ( new_line )
|
|
line = "";
|
|
if ( tx_byte == "\n" )
|
|
new_line = 1'b1;
|
|
else begin
|
|
line = { line[39*8-1:0], tx_byte};
|
|
new_line = 1'b0;
|
|
end
|
end
|
end
|
endtask
|
endtask
|
//~UART Monitor
|
//~UART Monitor
|
`endif // !UART
|
`endif // !UART
|
//~UART
|
//~UART
|
Line 434... |
Line 487... |
integer rx_cnt;
|
integer rx_cnt;
|
reg [31:0] eth_tx_data_addr_in; // address for reading from RX memory
|
reg [31:0] eth_tx_data_addr_in; // address for reading from RX memory
|
reg [7:0] eth_tx_data_data_out; // data for reading from RX memory
|
reg [7:0] eth_tx_data_data_out; // data for reading from RX memory
|
begin
|
begin
|
@(posedge eth_rx_clk);
|
@(posedge eth_rx_clk);
|
#1 eth_rx_dv = 1;
|
eth_rx_dv = 1;
|
|
|
// set initial rx memory address
|
// set initial rx memory address
|
eth_tx_data_addr_in = start_addr;
|
eth_tx_data_addr_in = start_addr;
|
|
|
// send preamble
|
// send preamble
|
for (rx_cnt = 0; (rx_cnt < (preamble_len << 1)) && (rx_cnt < 16); rx_cnt = rx_cnt + 1)
|
for (rx_cnt = 0; (rx_cnt < (preamble_len << 1)) && (rx_cnt < 16); rx_cnt = rx_cnt + 1)
|
begin
|
begin
|
#1 eth_rxd = preamble_data[3:0];
|
eth_rxd = preamble_data[3:0];
|
#1 preamble_data = preamble_data >> 4;
|
preamble_data = preamble_data >> 4;
|
@(posedge eth_rx_clk);
|
@(posedge eth_rx_clk);
|
end
|
end
|
|
|
// send SFD
|
// send SFD
|
for (rx_cnt = 0; rx_cnt < 2; rx_cnt = rx_cnt + 1)
|
for (rx_cnt = 0; rx_cnt < 2; rx_cnt = rx_cnt + 1)
|
begin
|
begin
|
#1 eth_rxd = sfd_data[3:0];
|
eth_rxd = sfd_data[3:0];
|
#1 sfd_data = sfd_data >> 4;
|
sfd_data = sfd_data >> 4;
|
@(posedge eth_rx_clk);
|
@(posedge eth_rx_clk);
|
end
|
end
|
|
|
// send packet's addresses, type/length, data and FCS
|
// send packet's addresses, type/length, data and FCS
|
for (rx_cnt = 0; rx_cnt < len; rx_cnt = rx_cnt + 1)
|
for (rx_cnt = 0; rx_cnt < len; rx_cnt = rx_cnt + 1)
|
begin
|
begin
|
#1;
|
|
eth_tx_data_data_out = eth_tx_data[eth_tx_data_addr_in[21:0]];
|
eth_tx_data_data_out = eth_tx_data[eth_tx_data_addr_in[21:0]];
|
eth_rxd = eth_tx_data_data_out[3:0];
|
eth_rxd = eth_tx_data_data_out[3:0];
|
@(posedge eth_rx_clk);
|
@(posedge eth_rx_clk);
|
#1;
|
|
eth_rxd = eth_tx_data_data_out[7:4];
|
eth_rxd = eth_tx_data_data_out[7:4];
|
eth_tx_data_addr_in = eth_tx_data_addr_in + 1;
|
eth_tx_data_addr_in = eth_tx_data_addr_in + 1;
|
@(posedge eth_rx_clk);
|
@(posedge eth_rx_clk);
|
#1;
|
|
end
|
end
|
if (plus_drible_nibble)
|
if (plus_drible_nibble)
|
begin
|
begin
|
eth_tx_data_data_out = eth_tx_data[eth_tx_data_addr_in[21:0]];
|
eth_tx_data_data_out = eth_tx_data[eth_tx_data_addr_in[21:0]];
|
eth_rxd = eth_tx_data_data_out[3:0];
|
eth_rxd = eth_tx_data_data_out[3:0];
|
@(posedge eth_rx_clk);
|
@(posedge eth_rx_clk);
|
end
|
end
|
|
|
#1 eth_rx_dv = 0;
|
eth_rx_dv = 0;
|
@(posedge eth_rx_clk);
|
@(posedge eth_rx_clk);
|
|
|
end
|
end
|
endtask // send_rx_packet
|
endtask // send_rx_packet
|
|
|