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.
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 | |||
---|---|---|---|
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:
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.
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.
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.
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.
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
Exercise 2 Pass-off: Show a TA your tcl script and your testbench output.
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:
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:
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.
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.
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.
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.
Here are some ideas for personal exploration in this laboratory:
Describe your personal exploration activities