This shows you the differences between two versions of the page.
Both sides previous revision Previous revision Next revision | Previous revision | ||
labs:uart_rx [2019/04/02 15:44] nelson [UART Receiver] |
labs:uart_rx [2019/04/09 11:47] (current) djlee |
||
---|---|---|---|
Line 1: | Line 1: | ||
====== UART Receiver ====== | ====== UART Receiver ====== | ||
- | 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. | + | 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 ===== | ===== Learning Outcomes ===== | ||
Line 11: | Line 11: | ||
- | A class lecture has been prepared to talk about the asynchronous transmitter and a proposed design approach. Review the slides of this lecture that have been posted on learning suite. | + | 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. | In this lab we will operate the receiver at a baud rate of 19,200. | ||
Line 24: | Line 24: | ||
^ Module Name = rx ^^^^ | ^ 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 ^ | ^ Port Name ^ Direction ^ Width ^ Function ^ | ||
| clk | Input | 1 | 100 MHz System Clock | | | clk | Input | 1 | 100 MHz System Clock | | ||
- | | rx_in | Input | 1 | Receiver input signal | | + | | Reset | Input | 1 | The system reset signal | |
- | | odd | Input | 1 | Apply odd parity when odd=1 or even parity when odd=0 | | + | | Sin | Input | 1 | Receiver serial input signal | |
- | | dout | Output | 8 | 8-bit data received by the receiver | | + | | Receive | Output | 1 | Indicates that the receiver now has a byte it is asking to hand off on the Dout pins | |
- | | busy | Output | 1 | Indicates that the receiver is busy | | + | | 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. | |
- | | error | Output | 1 | Indicates that there was an error on the last transaction | | + | | Dout | Output | 8 | 8-bit data received by the receiver which is then output on pins | |
- | | data_strobe | Output | 1 | Control signal indicating that new data is available | | + | | parityErr | Output | 1 | Indicates that there was a parity error on the last byte reception.| |
- | Next, complete the full design of the receiver as described in the lecture notes. As described in the notes, you will need: | + | Next, complete the full design of the receiver. See the textbook for more information. You will need: |
* Baud timer | * Baud timer | ||
* Bit counter | * Bit counter | ||
- | * Shift Register | + | * Shift register |
- | * Error Checker | + | * Parity checker |
- | * Finite State Machine | + | |
- | **Data_strobe:** | + | ===Baud Timer=== |
- | 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. | + | 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 ==== | ==== Exercise #2 - Simulation ==== | ||
Line 50: | Line 61: | ||
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: | 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: | ||
- | {{ :labs:tb_rx.v |}} | + | {{ :labs:tb_rx.sv |}} |
<color red>Provide a copy of the console output from the testbench simulation in your lab report</color> | <color red>Provide a copy of the console output from the testbench simulation in your lab report</color> | ||
<color red>Include your 'rx' SystemVerilog module in your report</color> | <color red>Include your 'rx' SystemVerilog module in your report</color> | ||
+ | |||
+ | **Exercise 2 Pass-off:** Show a TA your tcl script and your testbench output.\\ \\ | ||
==== Exercise #3 - Top-Level Circuit ==== | ==== Exercise #3 - Top-Level Circuit ==== | ||
Line 65: | Line 78: | ||
| sw | Input | 8 | Slide switches to specify character to send | | | sw | Input | 8 | Slide switches to specify character to send | | ||
| btnc | Input | 1 | Send character control signal | | | btnc | Input | 1 | Send character control signal | | ||
+ | | btnd | Input | 1 | Reset signal | | ||
| rx_in | Input | 1 | Receive signal | | | rx_in | Input | 1 | Receive signal | | ||
| tx_out | Output | 1 | Transmit signal | | | tx_out | Output | 1 | Transmit signal | | ||
Line 76: | Line 90: | ||
* 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 your top-level tx_out output | ||
* Connect the tx_out output of your tx module to the top_level tx_debug output | * Connect the tx_out output of your tx module to the top_level tx_debug output | ||
- | * Assign the value '0' to the “odd” parity input (for even parity) | + | * Connect an unused signal to the 'Sent' signal of your tx module ('Sent' will not be used in this circuit) |
- | * Connect an unused signal to the 'busy' signal of your tx module (busy will not be used in this circuit) | + | * Connect the 8 switches to the 'Din' input of your tx module |
- | * 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 | * 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 "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 make the following connections to your rx module: | + | After instancing your tx circuit, instance your rx circuit and connect it to your rx module. |
- | * Connect the rx_in input of your top-level rx_in to the rx_input of your receiver 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. |
- | * Connect the rx_in input to rx_debug | + | |
- | * Connect the top-level clock to the clk input of your rx module | + | 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. |
- | * Assign the value of '0' to the "odd" parity input (for even parity) | + | |
- | * Connect an unused signal to the 'busy' signal of the rx module (busy will not be used in this circuit) | + | |
- | * Connect an unused signal to the data_strobe signal of the rx module (it was important for the testbench but will not be used in the top-level module) | + | |
- | * Create a signal named "rx_data" and attach it to the dout port | + | |
- | * Attach the top-level rx_error output port to the error port of your rx module. This should be attached to LED[0] on the board. | + | |
Instance your seven segment display controller and connect the inputs to your controller as follows: | 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 switches to the lower 8-bits of the data in of the seven-segment controller (bottom two digits) | ||
- | * Attach the 8-bit signal "rx_data" to bits 23-16 of the data going to the seven segment controller (digits 5 and 4) | + | * 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 | * Only display the bottom two digits and digits 5 and 4 of the seven segment display | ||
* Do not use any of the digit points | * 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 | * 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. | ||
+ | |||
+ | {{ :labs:UART_tx_rx.png |}} | ||
<color red>Include a copy of your top-level module in your laboratory report</color> | <color red>Include a copy of your top-level module in your laboratory report</color> | ||
+ | |||
+ | **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.\\ \\ | ||
Line 122: | Line 137: | ||
<color red>Indicate the number of Look-up Tables (LUT) and Input/Output (I/O) pins for your design.</color> | <color red>Indicate the number of Look-up Tables (LUT) and Input/Output (I/O) pins for your design.</color> | ||
+ | **Exercise 4 Pass-off:** There is no pass-off for this exercise.\\ \\ | ||
==== Exercise #5 - Download and Putty ==== | ==== 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 [[tutorials:putty|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. | Once the bitstream has been generated, download your bitstream to the FPGA and test both your transmitter and receiver. Follow the [[tutorials:putty|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 | ||
+ | |||
+ | <color red>How many hours did you work on the lab?</color> | ||
+ | |||
+ | <color red>Please provide any suggestions for improving this lab in the future.</color> | ||
===== Personal Exploration ===== | ===== Personal Exploration ===== | ||
Line 136: | Line 164: | ||
<color red>Describe your personal exploration activities</color> | <color red>Describe your personal exploration activities</color> | ||
- | ===== Pass Off ===== | ||
- | |||
- | To pass off this laboratory, demonstrate to the TA the following: | ||
- | * Your testbench passing with 0 errors | ||
- | * Your working top-level uart transmitter/receiver circuit | ||
- | |||
- | |||
- | <color red>How many hours did you work on the lab?</color> | ||
- | |||
- | <color red>Please provide any suggestions for improving this lab in the future.</color> | ||
Line 248: | Line 266: | ||
characters). | characters). | ||
*/ | */ | ||
- |