User Tools


UART Receiver

In this laboratory you will create an asynchronous serial receiver that will allow you to send characters from your computer to the NEXYS4 board. Your design will closely follow last week's serial transmitter. That is, you will have handshaking with the receiver (but the signals are called Receive and Received). And, the receiver has similar components - a state machine, a bit counter, and a timer. A number of the details are different but it will have a similar organization.

Learning Outcomes

  • Implement an asynchronous receiver
  • Strengthen behavioral SystemVerilog skills

Preliminary

A class lecture was given discussing how the receiver should work. That and the textbook section on the receiver will form the basis for the lab. However, you will note that far less of the design is provided to you this week.

In this lab we will operate the receiver at a baud rate of 19,200.

Using a 100 MHz clock, how many clock cycles does it take to reach the middle of the bit period using this baud rate? (see Figure 28.15)

Exercises

Exercise #1 - Asynchronous Receiver Module

Begin your laboratory assignment by creating a receiver module that has the following parameters and ports:

Module Name = rx
Port Name Direction Width Function
clk Input 1 100 MHz System Clock
Reset Input 1 The system reset signal
Sin Input 1 Receiver serial input signal
Receive Output 1 Indicates that the receiver now has a byte it is asking to hand off on the Dout pins
Received Input 1 Indicates that the other circuitry has accepted the received byte on the Dout pins. Receive and Received serve as Req and Ack from Figure 28.7. However, the requestor who raises Receive is your rx module and the acknowledger who raises the Received signal is the testbench or other outside agent.
Dout Output 8 8-bit data received by the receiver which is then output on pins
parityErr Output 1 Indicates that there was a parity error on the last byte reception.

Next, complete the full design of the receiver. See the textbook for more information. You will need:

  • Baud timer
  • Bit counter
  • Shift register
  • Parity checker

Baud Timer

This is very similar to your timer from last time except it needs to be able to tell you when a whole bit time has passed as well as when a half bit time has passed. Both are needed at some point in your state machine's operation.

Shift Register

The purpose of this is to collect the serially received bits as they come in. It is recommended that you shift all 8 data bits plus the parity bit into the shift register. But, you will only output the 8 data bits on the Dout pins.

Parity Checker

Once you have shifted all 9 bits into the shift register, you should check that the parity bit is correct (odd parity). If this is not true, you should raise the parityErr signal.

The parityErr signal can be a combinational logic signal which is constantly reflecting the contents of the shift register. It will thus transition as things are shifted into the shift register and will only be an accurate error signal once you have shifted in the 9th bit (the parity bit). That is OK - the circuit that checks this will only look at the parityErr signal when Receive == 1.

You need to think carefully - given the order that bits arrive - do you want the register to shift right or shift left? The textbook explicitly states which bit arrives first. Given that, should you feed the bits in from the left of the shift register and right shift each time or the other way around? All you care about is that when you are done that you can assign the bits to Dout for output.

Finite State Machine

You get to design this yourself from scratch. However, we suggest you pattern it somewhat after the transmitter state machine. Note that you have to have your timer get you over into the middle of each bit period and so your timer may have additional output signals. And, your state machine will need to be designed to control when the shift register shifts so that you collect the 8 data bits and parity bits. Finally, your state machine will need to handshake using the Receive and Received signals at the end of each byte reception. You may safely assume that a new byte will not start to arrive on the Sin signal before the Receive/Received handshake has completed. You can simulate that way and that will surely be the case when you hook everything up in hardware.

Exercise 1 Pass-off: Show a TA a state graph of your state machine. Show how each of the components listed above are implemented in your rx module.

Exercise #2 - Simulation

After creating your rx module create a simple TCL file and simulate your module to make sure that there are no major errors. Then simulate your module with the following testbench file:

tb_rx.sv

Provide a copy of the console output from the testbench simulation in your lab report

Include your 'rx' SystemVerilog module in your report

Exercise 2 Pass-off: Show a TA your tcl script and your testbench output.

Exercise #3 - Top-Level Circuit

After simulating your receiver module and verifying it operates, begin a new top-level module with the following ports:

Module Name = uart_top
Port Name Direction Width Function
clk Input 1 100 MHz System Clock
sw Input 8 Slide switches to specify character to send
btnc Input 1 Send character control signal
btnd Input 1 Reset signal
rx_in Input 1 Receive signal
tx_out Output 1 Transmit signal
segment Output 8 Cathode signals for seven segment display
anode Output 8 Anode signals for each of the eight digits
rx_error Output 1 RX transfer error
tx_debug Output 1 TX Debug signal
rx_debug Output 1 RX Debug signal

In this exercise you will instance both your tx and rx modules. Begin by instancing your tx module just like the previous lab and make the following connections to your tx module:

  • Connect the tx_out output of your tx module to your top-level tx_out output
  • Connect the tx_out output of your tx module to the top_level tx_debug output
  • Connect an unused signal to the 'Sent' signal of your tx module ('Sent' will not be used in this circuit)
  • Connect the 8 switches to the 'Din' input of your tx module
  • Connect the top-level clock to the clk input of your tx module
  • Drive the tx “Send” signal with the same circuit you used in the top-level of your previous lab (attach to btnc, use a synchronizer and debouncer).
  • Drive the tx “Reset” signal the same way (attach to btnd, use a synchronizer and debouncer).

After instancing your tx circuit, instance your rx circuit and connect it to your rx module. The rx_error output port at the top level is the parityErr on your rx module and it should be attached to LED[0] on the board.

What to do with the Receive and Received handshaking signals? There is nothing on the board that can acknowledge each byte received. So, in your top level design create a signal called rxHandshake and use it to connect the Receive pin with the Received pin on your rx module. Now, when your rx module says it has a byte read (Receive=1) that will go right back in as Received to complete the handshake.

Instance your seven segment display controller and connect the inputs to your controller as follows:

  • Attach the 8 switches to the lower 8-bits of the data in of the seven-segment controller (bottom two digits)
  • Attach the 8-bit signal “rx_in” to bits 23-16 of the data going to the seven segment controller (digits 5 and 4)
  • Only display the bottom two digits and digits 5 and 4 of the seven segment display
  • Do not use any of the digit points
  • Attach the anode and segment signals of the controller to the top-level outputs of the top-level module

The following diagram illustrates the interconnections of different modules.

Include a copy of your top-level module in your laboratory report

Exercise 3 Pass-off: Show a TA your top level module and explain how we will know when the rx module has received a byte.

Exercise #4 - Implementation

Before synthesizing your design, you will need to create an .xdc file that contains the pin locations of each port in your design. Most of the pins used in this design are the same as pins used in previous designs (buttons, switches, seven-segment display, etc.). However, you will be using a new FPGA pin to connect to the UART/USB transceiver and the debug port.

The following example code demonstrates how these I/O pins can be attached to your top-level FPGA pins:

set_property -dict { PACKAGE_PIN C4    IOSTANDARD LVCMOS33 } [get_ports { rx_in }]; #IO_L7P_T1_AD6P_35 Sch=uart_txd_in
set_property -dict { PACKAGE_PIN D4    IOSTANDARD LVCMOS33 } [get_ports { tx_out }]; #IO_L11N_T1_SRCC_35 Sch=uart_rxd_out
set_property -dict { PACKAGE_PIN C17   IOSTANDARD LVCMOS33 } [get_ports { tx_debug }]; #IO_L20N_T3_A19_15 Sch=ja[1]
set_property -dict { PACKAGE_PIN D18   IOSTANDARD LVCMOS33 } [get_ports { rx_debug }]; #IO_L21N_T3_DQS_A18_15 Sch=ja[2]

Also, add an entry in your .xdc file for the led[0] which signals a receiver error. After completing your .xdc file, proceed with the synthesis of your design.

Provide a summary of your synthesis warnings.

After successfully synthesizing your design, proceed with the implementation and bitstream generation of your design. Indicate the number of Look-up Tables (LUT) and Input/Output (I/O) pins for your design.

Exercise 4 Pass-off: There is no pass-off for this exercise.

Exercise #5 - Download and Putty

Once the bitstream has been generated, download your bitstream to the FPGA and test both your transmitter and receiver. Follow the PuTTY tutorial to set it up. Once you have Putty setup properly, type characters on the computer keyboard while in the Putty window and check to see what HEX values show up on your NEXYS 4's seven segment display.

Then, using switches and buttons to transmit characters to Putty and see if they appear on the screen.

Final Pass Off

To pass off this laboratory, demonstrate to the TA the following:

  • Pass-offs for Exercises 1, 2, and 3
  • Your working top-level uart transmitter/receiver circuit

How many hours did you work on the lab?

Please provide any suggestions for improving this lab in the future.

Personal Exploration

Here are some ideas for personal exploration in this laboratory:

  • Experiment with different baud rates and see if you can communicate with the PC at a different baud rate.
  • Send a variety of interesting characters over the terminal and see how they respond.
  • Hook up the tx debug signal to the oscilliscope and view the transfer of an 8-bit character.

Describe your personal exploration activities

TA Notes and Feedback