I'm trying to simulate a uart receiver in a testbench using Verilog. I forced all the input bits, the clock and the reset, and I forced RsRx
, the serial input of the receiver, in order to get the output rx_data
, but rx_data
is always
The baudgenerator worked well, but the receiver didn't. I think the problem is in the testbench because the code of the receiver is provided by ARM. Could anyone help me please?
module TEST_Uart() ;
reg HCLK=0 ;
reg HRESETn=0 ;
wire b_tick ;
wire rx_done ;
reg RsRx=1 ;
wire [7:0]rx_data ;
initial
forever #1 HCLK = ~HCLK;
initial
begin
@(posedge HCLK);
HRESETn=1 ;
end
BAUDGEN uBAUDGEN(
.clk(HCLK),
.resetn(HRESETn),
.baudtick(b_tick)
);
//UART receiver
UART_RX uUART_RX(
.clk(HCLK),
.resetn(HRESETn),
.b_tick(b_tick),
.rx(RsRx),
.rx_done(rx_done),
.dout(rx_data[7:0])
);
task UART_WRITE_BYTE;
input [7:0] i_Data;
integer ii;
begin
// Send Start Bit
RsRx <= 1'b0;
// Send Data Byte
for (ii=0; ii<8; ii=ii+1)
begin
RsRx <= i_Data[ii];
end
// Send Stop Bit
RsRx <= 1'b1;
end
endtask // UART_WRITE_BYTE
initial
begin
// Send a command to the UART (exercise Rx)
@(posedge HCLK);
UART_WRITE_BYTE(8'h3F);
@(posedge HCLK);
// Check that the correct command was received
if (rx_data == 8'h3F)
$display("Test Passed - Correct Byte Received");
else
$display("Test Failed - Incorrect Byte Received");
end
endendmodule
You need to add delays inside the UART_WRITE_BYTE
task
. Currently, RsRx
seems to always be 1 when you run a simulation and you look at waveforms. This is because all your assignments occur at the same simulation time.
You need to add delays between each assignment. For example, in the code below, I add a delay of 5 after each assignment:
task UART_WRITE_BYTE;
input [7:0] i_Data;
integer ii;
begin
// Send Start Bit
RsRx <= 1'b0;
#5;
// Send Data Byte
for (ii=0; ii<8; ii=ii+1)
begin
RsRx <= i_Data[ii];
#5;
end
// Send Stop Bit
RsRx <= 1'b1;
#5;
end
endtask // UART_WRITE_BYTE
I used 5 just to demonstrate the principle. The delay should really be related to the baud rate. You probably want to replace that fixed delay with code related to an edge of the b_tick
signal, for example:
@(posedge b_tick);