User Tools


Sp20 UART Transmitter

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.

Learning Outcomes

  • Learn how to implement state machines using behavioral SystemVerilog
  • Understand how asynchronous communication works

Preliminary

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).


Exercises

Exercise #1 - Asynchronous Transmitter Module

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 size of the counter (in bits) is based on the baud rate and your system's 100MHz clock rate. The counter must have enough bits to represent the largest count value as determined by your calculations above.

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:

  • For each byte sent, the 8 data bits are output correctly in the correct order.
  • Check that the parity output is correct.
  • Check that the start and stop output is correct.
  • Check that both of your timers are operating correctly; that they reset and increment in the correct conditions.

Exercise 1 Pass-off: Show a TA your waveform and discuss how the waveform demonstrates the above points.


Exercise #2 - Testbench Validation

When it looks like your tx module is working properly use the following testbench file to test it.

tb_tx.sv

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.


Exercise #3 - Top-Level TX Circuit

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.):

tx_top.sv
//////////////////////////////////////////////////////////////////////////////////
//
//  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.

Exercise #4 - Download and Putty

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:

  • 8'h07 - Bell (a sound, not a character)
  • 8'h09 - Tab
  • 8'h0C - Clear screen
  • 8'h0A - Move cursor down (Line Feed)
  • 8'h0D - Carriage Return

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.

Final Pass Off

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).

TA Notes and Feedback