Line 53... |
Line 53... |
|
|
import std_defs::*;
|
import std_defs::*;
|
|
|
interface uart_if ();
|
interface uart_if ();
|
logic txd = 0; //from testbench driver
|
logic txd = 0; //from testbench driver
|
logic rxd = 0; //to testbench monitor
|
logic rxd; //to testbench monitor
|
endinterface : uart_if
|
endinterface : uart_if
|
|
|
typedef logic[11:0] cpu_addr_t;
|
typedef logic[11:0] cpu_addr_t;
|
typedef logic[7:0] cpu_data_t;
|
typedef logic[7:0] cpu_data_t;
|
|
|
Line 115... |
Line 115... |
forever begin
|
forever begin
|
mbx.get( data ); //block if no transactions waiting.
|
mbx.get( data ); //block if no transactions waiting.
|
data_bits = data;
|
data_bits = data;
|
//start bit
|
//start bit
|
uart_.txd = 0;
|
uart_.txd = 0;
|
#(1/baud_rate)s;
|
#(1s/baud_rate);
|
//8 bits of data
|
//8 bits of data
|
for(uint8 i=0; i<8; i++) begin
|
for(uint8 i=0; i<8; i++) begin
|
uart_.txd = data_bits[i]; //least significant bit first.
|
uart_.txd = data_bits[i]; //least significant bit first.
|
#(1/baud_rate)s;
|
#(1s/baud_rate);
|
end
|
end
|
//1 stop bit
|
//1 stop bit
|
uart_.txd = 1;
|
uart_.txd = 1;
|
#(1/baud_rate)s;
|
#(1s/baud_rate);
|
end
|
end
|
end
|
end
|
join_none
|
join_none
|
endtask
|
endtask
|
endclass
|
endclass
|
Line 149... |
Line 149... |
task automatic run();
|
task automatic run();
|
fork begin
|
fork begin
|
forever begin
|
forever begin
|
//Look for a valid start bit. Must be at least 1/2 bit period duration.
|
//Look for a valid start bit. Must be at least 1/2 bit period duration.
|
@(negedge uart_.rxd);
|
@(negedge uart_.rxd);
|
#(0.5 * 1/baud_rate)s;
|
#(0.5 * 1s/baud_rate);
|
if ( uart_.rxd == 0 ) begin
|
if ( uart_.rxd == 0 ) begin
|
logic[7:0] data_bits;
|
logic[7:0] data_bits;
|
//read in 8 data bits, LSBit first, sampling in the center of the bit period.
|
//read in 8 data bits, LSBit first, sampling in the center of the bit period.
|
for(uint8 i=0; i<8; i++) begin
|
for(uint8 i=0; i<8; i++) begin
|
#( 1/baud_rate )s;
|
#(1s/baud_rate);
|
data_bits[i] = uart_.rxd;
|
data_bits[i] = uart_.rxd;
|
end
|
end
|
//check stop bit.
|
//check stop bit.
|
#( 1/baud_rate )s;
|
#(1s/baud_rate);
|
if ( uart_.rxd != 1 ) begin
|
if ( uart_.rxd != 1 ) begin
|
$display("Monitor: Invalid stop bit.");
|
$display("Monitor: Invalid stop bit.");
|
end
|
end
|
else begin
|
else begin
|
//valid stop bit so generate transaction.
|
//valid stop bit so generate transaction.
|
Line 221... |
Line 221... |
|
|
//ok, now run some tests.
|
//ok, now run some tests.
|
test_cpu_interface();
|
test_cpu_interface();
|
test_serial_facing_loopback(); //This one is also a good test for the testbench UART monitor/driver classes.
|
test_serial_facing_loopback(); //This one is also a good test for the testbench UART monitor/driver classes.
|
test_cpu_to_txd();
|
test_cpu_to_txd();
|
test_rxd_to_cpu();
|
//test_rxd_to_cpu();
|
|
|
$display("%m: %t << Simulation ran to completion >>", $time);
|
$display("%m: %t << Simulation ran to completion >>", $time);
|
// $stop(0); //stop the simulation
|
// $stop(0); //stop the simulation
|
end
|
end
|
|
|
Line 284... |
Line 284... |
uart_driver_mbx.put( data );
|
uart_driver_mbx.put( data );
|
sent_data_mbx.put( data );
|
sent_data_mbx.put( data );
|
end
|
end
|
|
|
//Gives some time for any remaining transactions to propagate through the DUT.
|
//Gives some time for any remaining transactions to propagate through the DUT.
|
#( `UART_FIFO_SIZE * (12 * 1/`BAUD_RATE))s; //10 bits/ baud, but allow for 12.
|
#( `UART_FIFO_SIZE * (12 * 1s/`BAUD_RATE)); //10 bits/ baud, but allow for 12.
|
|
|
//Check the sent data comes back error free.
|
//Check the sent data comes back error free.
|
compare_mailbox_data( sent_data_mbx, uart_monitor_mbx );
|
compare_mailbox_data( sent_data_mbx, uart_monitor_mbx );
|
endtask
|
endtask
|
|
|
Line 316... |
Line 316... |
sent_data_mbx.put(data);
|
sent_data_mbx.put(data);
|
end
|
end
|
end
|
end
|
|
|
//Gives some time for any remaining transactions to propagate through the DUT.
|
//Gives some time for any remaining transactions to propagate through the DUT.
|
#( `UART_FIFO_SIZE * (12 * 1/`BAUD_RATE))s; //10 bits/ baud, but allow for 12.
|
#( `UART_FIFO_SIZE * (12 * 1s/`BAUD_RATE)); //10 bits/ baud, but allow for 12.
|
|
|
//Check the sent and received data is the same.
|
//Check the sent and received data is the same.
|
compare_mailbox_data( sent_data_mbx, uart_monitor_mbx );
|
compare_mailbox_data( sent_data_mbx, uart_monitor_mbx );
|
endtask
|
endtask
|
|
|
//Check all reference mailbox items against dut mailbox items. Expected to be identical, report differences.
|
//Check all reference mailbox items against dut mailbox items. Expected to be identical, report differences.
|
function automatic void compare_mailbox_data( mailbox #(uint8) ref_mbx, mailbox #(uint8) dut_mbx );
|
function automatic void compare_mailbox_data( mailbox #(uint8) ref_mbx, mailbox #(uint8) dut_mbx );
|
uint32 error = 0;
|
uint32 error = 0;
|
uint32 good = 0;
|
uint32 good = 0;
|
repeat( ref_mbx.size() ) begin
|
uint32 ref_mbx_num;
|
|
uint32 dut_mbx_num;
|
|
|
|
ref_mbx_num = ref_mbx.num();
|
|
dut_mbx_num = dut_mbx.num();
|
|
|
|
repeat( ref_mbx_num ) begin
|
uint8 dut_data;
|
uint8 dut_data;
|
uint8 ref_data;
|
uint8 ref_data;
|
uint32 tryget_result;
|
uint32 tryget_result;
|
|
|
ref_mbx.get( ref_data );
|
ref_mbx.try_get( ref_data );
|
//try to get dut data, may not be there if dut swallowed it.
|
//try to get dut data, may not be there if dut swallowed it.
|
tryget_result = dut_mbx.try_get( dut_data );
|
tryget_result = dut_mbx.try_get( dut_data );
|
if (tryget_result) begin
|
if (tryget_result) begin
|
if (ref_data != dut_data) begin
|
if (ref_data != dut_data) begin
|
error++;
|
error++;
|
Line 345... |
Line 351... |
end
|
end
|
break; //no more DUT data
|
break; //no more DUT data
|
end
|
end
|
end
|
end
|
$display("Good: %2d, Errored: %2d, Excess reference %2d, Excess DUT %2d",
|
$display("Good: %2d, Errored: %2d, Excess reference %2d, Excess DUT %2d",
|
good, error, ref_mbx.size(), dut_mbx.size());
|
good, error, ref_mbx_num, dut_mbx_num);
|
endfunction
|
endfunction
|
|
|
endmodule
|
endmodule
|
|
|
|
|