Finished the third tutorial from from the Toni T800 YouTube channel. This one gave me some trouble for a bit because PuTTY was acting a little strange, so I switched to Windows and used the RealTerm serial program that he demonstrates in his video. In RealTerm you can send a single character by just typing it, while in PuTTY you have to hit Enter; I think hitting Enter sends more info to the board, which was messing up my receiving display. I probably could have messed with PuTTY more, but just went with the software that Toni used.
Anyway, for this one use RealTerm to make it easy: 9600 baud rate, no parity, 1 stop bit. I also used a USB to RS232 cable to connect to my pc because the DE2 UART output is via RS232 only.
Link to the video:
Here’s a pic of the RealTerm output: I sent an ‘a’, ‘b’, and ‘c’. All of those sends are from one press of KEY0 each.
A picture of my DE2 board with the red LEDs showing the ascii code for a ‘d’ that was received.
// Christopher Hays // 12/31/2016 // tutorial 3, uart on the de2 development board // using verilog // set parity to none, no flow control, 9600 baud module uart(CLOCK_50, KEY, SW, LEDG, LEDR, UART_TXD, UART_RXD); input CLOCK_50; input [17:0] SW; input [3:0] KEY; output [7:0] LEDG; output [17:0] LEDR; output UART_TXD; input UART_RXD; reg [7:0] tx_data, ledg_out, ledr_out; reg tx_start = 0; wire tx_busy, rx_busy; wire [7:0] rx_data; // connect the modules tx T0 (.CLK(CLOCK_50), .START(tx_start), .BUSY(tx_busy), .DATA(tx_data), .TX_LINE(UART_TXD)); rx R0 (.CLK(CLOCK_50), .RX_LINE(UART_RXD), .DATA(rx_data), .BUSY(rx_busy)); always@(posedge CLOCK_50) begin if (KEY == 0 && tx_busy == 0) begin // when key0 is pressed and not busy tx_data = SW[7:0]; // set the data and start tx tx_start = 1; ledg_out = tx_data; end else tx_start = 0; end // end always always@(negedge rx_busy) begin // as soon as receiver is not busy ledr_out = rx_data; // write the data to leds end // end always assign LEDR = ledr_out; assign LEDG = ledg_out; endmodule
// UART receiver module rx(CLK, RX_LINE, DATA, BUSY); input CLK, RX_LINE; output [7:0] DATA; output BUSY; reg [9:0] datafll; reg rx_flag = 0; reg busy_out = 0; reg [12:0] prescalar = 0; reg [3:0] index = 0; reg [7:0] data_out; always@(posedge CLK) begin if (rx_flag == 0 && RX_LINE == 0) begin // if we are not receiving index = 0; // and there is a start bit on RX prescalar = 0; busy_out = 1; rx_flag = 1; end if (rx_flag == 1) begin // begin receiving datafll[index] = RX_LINE; // fill one data bit if (prescalar < 5207) prescalar = prescalar + 1; else prescalar = 0; if (prescalar == 2600) begin // roughly every half cycle if (index < 9) index = index + 1; else begin if (datafll == 0 && datafll == 1) // verify a correct frame data_out = datafll[8:1]; // write data else datafll = 0; // all zeros if the frame is bad rx_flag = 0; busy_out = 0; end end end end // end always assign BUSY = busy_out; assign DATA = data_out; endmodule
// UART transmitter module tx (CLK, START, BUSY, DATA, TX_LINE); input CLK, START; input [7:0] DATA; output BUSY, TX_LINE; reg [12:0] prescalar = 0; // roughly 8k reg [3:0] index = 0; // need room for 0-9 reg [9:0] datafll = 0; // 8 bits of data plus start/stop bits reg tx_flag = 0; // 1 if we are transmitting reg busy_out = 0; reg tx_out = 1; // idle is data high always@(posedge CLK) begin if (tx_flag == 0 && START == 1) begin tx_flag = 1; busy_out = 1; datafll = 0; // place data in datafll inbetween the control bits datafll = 1; datafll[8:1] = DATA; end if (tx_flag == 1) begin // data is ready to transmit if (prescalar < 5207) // 50MHz/9600 baud = 5207 prescalar = prescalar + 1; else prescalar = 0; if (prescalar == 2600) begin // every half of a cycle, roughly tx_out = datafll[index]; // place a bit on the data line if (index < 9) index = index + 1; else begin // until the data is full tx_flag = 0; index = 0; busy_out = 0; end end end end // end always assign BUSY = busy_out; assign TX_LINE = tx_out; endmodule