tb: uart add framing error test

- Adds option to test invalid stop bit
- Adds a test that simulates an always low rx line
This commit is contained in:
Daniel Jobson 2025-10-24 23:08:50 +02:00
parent 395d241ed3
commit 6104356892

View file

@ -238,9 +238,10 @@ module tb_uart ();
//---------------------------------------------------------------- //----------------------------------------------------------------
// transmit_byte // transmit_byte
// //
// Transmit a byte of data to the DUT receive port. // Transmit a byte of data to the DUT receive port. With or without a valid
// stop bit.
//---------------------------------------------------------------- //----------------------------------------------------------------
task transmit_byte(input [7 : 0] data); task transmit_byte(input [7 : 0] data, input invalid_stop_bit);
integer i; integer i;
begin begin
$display("*** Transmitting byte 0x%02x to the dut.", data); $display("*** Transmitting byte 0x%02x to the dut.", data);
@ -260,8 +261,13 @@ module tb_uart ();
end end
// Send two stop bits. I.e. two bit times high (mark) value. // Send two stop bits. I.e. two bit times high (mark) value.
$display("*** Transmitting two stop bits."); if (invalid_stop_bit) begin
$display("*** Transmitting INVALID stop bits.");
tb_rxd = 0;
end else begin
$display("*** Transmitting stop bits.");
tb_rxd = 1; tb_rxd = 1;
end
#(2 * CLK_PERIOD * dut.DEFAULT_BIT_RATE * dut.DEFAULT_STOP_BITS); #(2 * CLK_PERIOD * dut.DEFAULT_BIT_RATE * dut.DEFAULT_STOP_BITS);
$display("*** End of transmission."); $display("*** End of transmission.");
end end
@ -272,25 +278,45 @@ module tb_uart ();
// check_transmit // check_transmit
// //
// Transmits a byte and checks that it was captured internally // Transmits a byte and checks that it was captured internally
// by the dut. // by the dut. Include option to set stop bit to invalid.
//---------------------------------------------------------------- //----------------------------------------------------------------
task check_transmit(input [7 : 0] data); task check_transmit(input [7 : 0] data, input invalid_stop_bit);
begin begin
tc_ctr = tc_ctr + 1; tc_ctr = tc_ctr + 1;
transmit_byte(data); transmit_byte(data, invalid_stop_bit);
if (!invalid_stop_bit) begin // Valid stop bit
if (dut.core.rxd_byte_reg == data & dut.core.erx_ctrl_reg == 0 ) begin
// Data OK, ctrl state idle OK.
if (dut.core.rxd_byte_reg == data) begin
$display("*** Correct data: 0x%01x captured by the dut.", dut.core.rxd_byte_reg); $display("*** Correct data: 0x%01x captured by the dut.", dut.core.rxd_byte_reg);
$display("*** Correct state after transmission: 0x%01x (IDLE) .", dut.core.erx_ctrl_reg);
end end
else begin else begin
$display("*** Incorrect data: 0x%01x captured by the dut Should be: 0x%01x.", $display("*** Incorrect:");
dut.core.rxd_byte_reg, data); $display("*** Data: 0x%01x captured by the dut. Expected: 0x%01x.",dut.core.rxd_byte_reg, data);
$display("*** State after transmission: 0x%01x.", dut.core.erx_ctrl_reg);
error_ctr = error_ctr + 1;
end
end else begin
if ( dut.core.erx_ctrl_reg == 5) begin
$display("*** Correct state after transmission: 0x%01x (ERR).", dut.core.erx_ctrl_reg);
end else begin
$display("*** Incorrect state: 0x%01x. Expected: 0x%01x.", dut.core.erx_ctrl_reg, 5);
error_ctr = error_ctr + 1; error_ctr = error_ctr + 1;
end end
end end
endtask // check_transmit
// Reset to a valid rx line
tb_rxd = 1;
#(CLK_PERIOD * dut.DEFAULT_BIT_RATE);
end
endtask // check_transmit
//---------------------------------------------------------------- //----------------------------------------------------------------
// test_transmit // test_transmit
@ -299,14 +325,71 @@ module tb_uart ();
//---------------------------------------------------------------- //----------------------------------------------------------------
task test_transmit; task test_transmit;
begin begin
check_transmit(8'h55); check_transmit(8'h55, 0);
check_transmit(8'h42); check_transmit(8'h42, 0);
check_transmit(8'hde); check_transmit(8'hde, 0);
check_transmit(8'had); check_transmit(8'h55, 1);
check_transmit(8'had, 0);
end end
endtask // test_transmit endtask // test_transmit
//----------------------------------------------------------------
// send_framing_error
//
// Sets the rx line low, and clocks an entire frame, checks the
// UARTs core ctrl state. Sets rx line to idle again, and checks
// that the core returns to idle state.
//----------------------------------------------------------------
task send_framing_error();
integer i;
begin
tc_ctr = tc_ctr + 1;
$display("*** Simulating a constant low rx-line.");
tb_rxd = 0;
// Clock start bit
#(CLK_PERIOD * dut.DEFAULT_BIT_RATE);
// Clock data bits
for (i = 0; i < 8; i = i + 1) begin
tb_rxd = 0;
#(CLK_PERIOD * dut.DEFAULT_BIT_RATE);
end
// Clock stop bit
#(CLK_PERIOD * dut.DEFAULT_BIT_RATE);
// Clock extra to be outside of frame
#(CLK_PERIOD * dut.DEFAULT_BIT_RATE * 3);
if ( dut.core.erx_ctrl_reg == 5) begin
$display("*** Correct state after frame: 0x%01x (ERR).", dut.core.erx_ctrl_reg);
end
else begin
$display("*** Incorrect state: 0x%01x. Expected: 0x%01x.", dut.core.erx_ctrl_reg, 5);
error_ctr = error_ctr + 1;
end
$display("*** Simulate rx-line return to a valid idle state.");
tb_rxd = 1;
#(CLK_PERIOD * dut.DEFAULT_BIT_RATE);
if ( dut.core.erx_ctrl_reg == 0) begin
$display("*** Correct state after rx line returns to valid: 0x%01x (IDLE).", dut.core.erx_ctrl_reg);
end
else begin
$display("*** Incorrect state: 0x%01x. Expected: 0x%01x.", dut.core.erx_ctrl_reg, 0);
error_ctr = error_ctr + 1;
end
end
endtask
//---------------------------------------------------------------- //----------------------------------------------------------------
// display_test_result() // display_test_result()
// //
@ -355,6 +438,8 @@ module tb_uart ();
test_transmit(); test_transmit();
send_framing_error();
display_test_result(); display_test_result();
$display("*** Simulation done."); $display("*** Simulation done.");
exit_with_error_code(); exit_with_error_code();