In this assignment, you will combine the uart_rx and uart_tx modules to create a bi-directional interface. You will demonstrate the interface using a PC terminal. Your design will record the most recent keystroke received from the PC, and repeat it back to the PC when a button is pressed.
uart_rx and uart_txCopy your transmitter and receiver modules into the src/ directory, and add them to the git repository.
top moduleNext, create a top module contining an instance of uart_tx and uart_rx, as well as a specialized debouncer and a data_register module with the I/O ports and connections as shown in the figure below.
Note that all modules have clk and rst_l inputs, although not shown in every case.
debouncerThe debouncer should take input from the send button and produce the start/done handshaking whenever the button is pressed.
data_registerCreate a module named data_register with these I/O ports:
clk and rst_ld_in (8 bits)d_out (8 bits)readyackInitialize d_out to the 68h.
Normally ack and ready are 0.
When ready rises to 1, d_out is assigned the value from d_in. At the same time, ack is set to 1.
After ack rises, ready should clear to 0, and then ack should clear back to 0.
A testbench is provided for this assignment. It does three things in parallel:
send button pressesrx signaltx signalThe button presses are modeled by a random number in this code segment:
reg [3:0] send_rnum;
initial begin
while (1) begin
#200000; // Wait for a while
send_rnum = $random(); // Get a random number between 0 and 15
// Probability 1/16:
if ((send_rnum == 0) && !DUT.start) begin
send = 1;
$write("SEND pressed\n");
$fwrite(fid,"SEND pressed\n");
tx_count = tx_count + 1;
end
else begin
send = 0;
end
end
endThis model uses a while loop to delay 200ns, then raise the send signal with probability 1/16 (there are 16 possible values of send_rnum and only one of those values is 0). The event is delayed if a transmission is alreay in progress, as indicated by DUT.start. The byte latency at 9600 baud is (1/9600)10 = 1ms. Combining these delays, on average, the button presses will occur every (200ns 16) + (1ms) = 4.2ms during the simulation.
To emulate a PC terminal, the testbench models UART TX/RX processes using #delay statements. The transmission model is shown in this segment:
// -----------------------------------------------
// Send UART byte
// -----------------------------------------------
integer rx_index = 0;
reg [2:0] rnum;
initial begin
rx = 1;
while (1) begin
#104170;
rnum = $random();
if (rnum == 0) begin
d_in = $random();
$display("Transmitting %xh ('%c') to module",d_in,d_in);
rx = 0; // START bit
for (rx_index=0;rx_index<8;rx_index=rx_index+1) begin
#104170;
rx = d_in[rx_index];
end
end
#104170;
rx = 1; // STOP bit
#104170;
end
endThe #delay statements use the 9600 baud clock period, 104170ns. As with the button-press simulator, a while loop is used with a random number. In this case, the possible values are 0 to 7, each with probability 1/8. A transmission will occur, on average, every (104170ns * 8) = 833us during the simulation. To simulate the actual transmission, rx is pulled to 0 to initiate the START bit. A for loop sends the individual data bits, one at a time, each time preceded by a period delay. Lastly the rx signal is set to 1 to send the STOP bit.
The testbench receiver model is shown in this code segment:
// -----------------------------------------------
// Receive UART byte task
// -----------------------------------------------
integer tx_index = 0;
initial begin
d_out = 0;
while (1) begin
#100;
if (!tx) begin
#1000; // Add margin for timing skew
for (tx_index=0;tx_index<8;tx_index=tx_index+1) begin
#104170;
$write(">%b ",tx);
d_out[tx_index] = tx;
end
#104170;
#104170;
if (!tx)
$display("BAD STOP BIT");
$display("Received %xh ('%c') from module",d_out,d_out);
end
end
end // initial beginThis process implements the transmitter in reverse. The message begins with a START bit when tx drops to 0. You may notice the extra delay of #1000 after the START bit. This is effectively the same as the sync delay specified in the UART RX assignment. The purpose is to allow the tx wire to stabilize before reading its value.
When the simulation runs, the output will look something like this:
SEND pressed
Received 68h ('h') from module
Transmitting 89h ('<89>') to module
SEND pressed
Received 89h ('<89>') from module
Transmitting 2ah ('*') to module
Transmitting 79h ('y') to module
Transmitting 2dh ('-') to module
SEND pressed
Received 2dh ('-') from module
It can be helpful to add more $display or $write statements in your modules. These statements are evaluated during simulation, but ignored for synthesis. For example, some $display lines can be added in the uart_tx state machine:
case (state)
WAIT:
begin
if (start) begin
bit_index <= 0; // start at LSB
tx <= 0; // start bit
state <= SEND;
$display("\tUART: transmitting %xh ('%c')", d_out, d_out);
end
else begin
tx <= 1; // idle signal
done <= 0; // not done, ready for data
end
end
SEND:
begin
tx <= d_out[bit_index];
if (bit_index == 7) begin
state <= STOP;
end
else begin
bit_index <= bit_index + 1;
end
end
STOP:
begin
tx <= 1;
if (start) begin
$display("\tUART: sending STOP bit");
done <= 1; // Signal that the transmission is complete
end
else begin
done <= 0;
state <= WAIT;
end
end
endcaseWith the inserted $display statements, the testbench output offers more detail:
SEND pressed
UART: transmitting 68h ('h')
Transmitting aah ('<AA>') to module
UART: sending STOP bit
Received 68h ('h') from module
Transmitting 89h ('<89>') to module
SEND pressed
UART: transmitting 89h ('<89>')
UART: sending STOP bit
Received 89h ('<89>') from module
Transmitting 2ah ('*') to module
Transmitting 79h ('y') to module
Transmitting 2dh ('-') to module
SEND pressed
UART: transmitting 2dh ('-')
UART: sending STOP bit
Received 2dh ('-') from module
You may freely add $display statements to uart_rx, debouncer, data_register in order to get a more detailed picture of your design’s internal activity.
Implement the design on the Basys3 board and test using a PC terminal. The procedure is essentially the same as for the UART TX assignment, with these additional steps:
send button and you should see the letter ‘h’send button again and the character should be repeated back in the terminal.Take a short video showing your test and upload it to Canvas.
Turn in your work using git:
git add src/*.v *.v *.rpt *.txt *.tcl *.bit *.xdc
git commit . -m "Complete"
git push origin master