This is an old revision of the document!
In this laboratory you will create an asynchronous serial receiver that will allow you to receive characters from your computer and onto 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.
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)
Begin your laboratory assignment by creating a receiver module that has the following parameters and ports:
Module Name = rx | |||
---|---|---|---|
Parameter | Type (Default) | Function | |
CLK_FREQUENCY | integer (100,000,000) | Specifies clock frequency in Hz | |
BAUD_RATE | integer (19200) | Determines the wait time, in micro seconds, for the debounce circuit | |
Port Name | Direction | Width | Function |
clk | Input | 1 | 100 MHz System Clock |
rx_in | Input | 1 | Receiver input signal |
odd | Input | 1 | Apply odd parity when odd=1 or even parity when odd=0 |
dout | Output | 8 | 8-bit data received by the receiver |
busy | Output | 1 | Indicates that the receiver is busy |
error | Output | 1 | Indicates that there was an error on the last transaction |
data_strobe | Output | 1 | Control signal indicating that new data is available |
Next, complete the full design of the receiver as described in the lecture notes. As described in the notes, you will need:
Data_strobe: While your state machine is running, dout changes each time you shift the shift register. The final value of dout is the only one that we care about, so we will create a signal that lets us know if our state machine has finished and the output is valid. The signal data_strobe should pulse once, after you have shifted the data the final time.
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:
Provide a copy of the console output from the testbench simulation in your lab report
Include your 'rx' SystemVerilog module in your report
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 |
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:
After instancing your tx circuit, instance your rx circuit and make the following connections to your rx module:
Instance your seven segment display controller and connect the inputs to your controller as follows:
Include a copy of your top-level module in your laboratory report
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.
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.
Here are some ideas for personal exploration in this laboratory:
Describe your personal exploration activities
To pass off this laboratory, demonstrate to the TA the following:
How many hours did you work on the lab?
Please provide any suggestions for improving this lab in the future.