In this laboratory you will create an asynchronous serial transmitter that will allow you to send ASCII characters from the NEXYS4 board to your computer.
Chapter 28 discusses the asynchronous transmitter in detail. You will want to review this chapter before beginning this lab and refer back to it when you have questions. Note that we will be using the method described in Section 28.3 (note there are at least two methods described in this section, we are doing the one reflected in Figures 28.8, 28.9, 28.11, 28.12, and programs 28.3.1).
In this lab we will operate the transmitter at a baud rate of 19,200 bits per second. We will transmit using odd parity and 8 bits of data.
How many clock cycles of the 100 MHz clock used on the FPGA board does it take to provide one bit of data using this baud rate?
How many bits are needed to count the clock cycles for each bit of data?
What is the maximum number of 8-bit ASCII characters that can be transmitted per second using your transmitter at a baud rate of 19,200? (make sure you consider the presence of the start bit, parity bit, and stop bit).
Begin your laboratory assignment by creating a module that has the following parameters and ports:
Module Name = tx | |||
---|---|---|---|
Parameter | Type (Default) | Function | |
Port Name | Direction | Width | Function |
clk | Input | 1 | 100 MHz System Clock |
Reset | Input | 1 | Reset signal to reset state machine (at a minimum) |
Send | Input | 1 | Control signal to request a data transmission (corresponds to the 'req' signal in Figure 28.7) |
Din | Input | 8 | 8-bit data in to send over transmitter |
Sent | Output | 1 | Acknowledge that transmitter is done with the transmission (corresponds to the 'ack' signal in Figure 28.7) |
Sout | Output | 1 | Transmitter serial output signal |
The transmitter consists of a control section and a data path section as shown in Figure 28.9 of the text. The code for the data path is given in Program 28.3.1.
The control section is outlined in Figure 28.11. As you can see, it requires two counters - one to time each bit period and one to count the bits.
Baud Rate Timer
Your transmitter will need a counter that counts the number of clock cycles needed for a single baud period. Create a counter using behavioral SystemVerilog with the following specifications:
The counter has an output signal that indicates when the counter has reached the last clock cycle of the baud period ('timerDone' in the system diagram). This signal is used as an input in the FSM. When the timer reaches this point, it must roll over to 0; the state machine design relies upon this.
Parity Generator
The parity calculation is actually embedded in the code of Program 28.3.1 - can you see where it is being done and how it is being done? Make sure you understand this.
Bit Counter
Create the Bit Counter which is responsible for counting the number of bits that have been transmitted. You can see in Figure 28.11 what signals the state machine uses to interact with the bit counter.
Datapath
Note that the data path outputs the correct bits needed in response to state machine outputs. Note that it is an always_ff block to ensure that the final output signal (sout) is registered to avoid glitching. The datapath code is outlined in Program 28.3.1.
FSM
Create the FSM as outlined in the following figure. Note, this is slightly different that the figure in the textbook, which as a small error in the BITS state.
Use the following TCL script to simulate your tx
module:
restart # Start clock add_force clk {0} {1 5} -repeat_every 10 run 10ns # Reset design add_force Reset 1 add_force Send 0 run 10ns add_force Reset 0 run 10ns # Run for some time run 50us # Send a byte add_force -radix hex Din 47 add_force Send 1 run 10ns add_force Send 0 run 1ms # Send another byte add_force -radix hex Din 4F add_force Send 1 run 10ns add_force Send 0 run 1ms
Look at the waveform and make sure your module is operating correctly. Check the simulation that:
Exercise 1 Pass-off: Show a TA your waveform and discuss how the waveform demonstrates the above points.
When it looks like your tx module is working properly use the following testbench file to test it.
Include a copy of the simulation console in your laboratory report when your simulation passes the testbench with no errors
Exercise 2 Pass-off: You don't need a TA to pass of this exercise, but make sure the testbench is working before moving on.
After simulating your module and verifying it operates, download the following top-level module (just click the link below to download the file, then add it to your project.):
////////////////////////////////////////////////////////////////////////////////// // // Filename: tx_top.sv // // Author: Jeff Goeders // // Description: UART Transmitter top-level design // // ////////////////////////////////////////////////////////////////////////////////// module tx_top( input wire logic clk, input wire logic CPU_RESETN, input wire logic [7:0] sw, input wire logic btnc, output logic [7:0] anode, output logic [7:0] segment, output logic tx_out, output logic tx_debug); logic reset; assign reset = ~CPU_RESETN; assign tx_debug = tx_out; logic btnc_r; logic btnc_r2; logic send_character; // Button synchronizaer always_ff@(posedge clk) begin btnc_r <= btnc; btnc_r2 <= btnc_r; end // Debounce the start button debounce debounce_inst( .clk(clk), .reset(reset), .noisy(btnc_r2), .debounced(send_character) ); // Transmitter tx tx_inst( .clk (clk), .Reset (reset), .Send (send_character), .Din (sw), .Sent (), .Sout (tx_out) ); // Seven Segment Display SevenSegmentControl SSC ( .clk(clk), .reset(reset), .dataIn({24'h0, sw}), .digitDisplay(8'h03), .digitPoint(8'h00), .anode(anode), .segment(segment) ); endmodule
Look over the top-level file. You will see that it uses your debounce circuit from a previous lab, which ensures that when you hit the send button, only a single character is sent. The seven segment controller displays the current value of the switches to help quickly determine the hexadecimal value and compare it to an ASCII table.
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 transciever 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 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]
After completing your .xdc file, proceed to generate your bitstream.
Attach a copy of and then explain in word any ERRORS or CRITICAL WARNINGS that are in either the synthesis report from above. For each one, explain the following: What does this ERROR or CRITICAL WARNING refer to and do you understand why was it flagged? Is it OK or not for you to ignore it and assume the design will work in hardware (and if so, why)? Please explain.
Exercise 3 Pass-off: There is no pass-off for this exercise.
Once the bitstream has been generated, download your bitstream to the FPGA. To test the transmitter, you will need to run a program called “PuTTY”. Follow the PuTTY tutorial to set it up if you are running on your own machine. If you are running on a lab machine it should already be installed.
After installing, specifically, follow the testing procedures outlined to ensure that PuTTY is working on your machine. That way, if your downloaded circuit design doesn't work you will know that PuTTY is not the reason.
Once your PuTTY terminal is configured properly you should be able to send characters to the terminal by selecting the ASCII value of the character to send on the switches and pressing the center button.
Interesting control commands:
The above are called “control characters” since they control the screen rather than draw characters. They are typically reached on normal keyboards using the “Control” key like a shift key (press concurrently with another key). Thus, when you hit Control-C to kill a program on a computer you are sending (or at least with older computers were sending) the ASCII character 8'h03.
Attach a video link to LearningSuite, demonstrating that transmitter circuit works. Test it against a variety of characters from the ASCII table at the end of your textbook - digits, punctuation, and both upper and lowercase letters. Show what happens when you send some of the special characters mentioned above - do you get interesting or meaningful stuff? How about for characters with values 8'h80 and above?
How many hours did you work on the lab?
Please provide any suggestions for improving this lab in the future.
Upload your tx.sv SystemVerilog module to Learning Suite. (Make sure your SystemVerilog conforms to the lab SystemVerilog coding standards).