Forum Discussion
Well the verilog code tells me basically nothing.
What clock frequency are you using, what baud rate, how many data bits and stop bits have you configured?
The serial program needs to set the same parameters for the serial line as well (baud rate, number of data and stop bits).
You also will need to invert the data line, or not, to get the correct polarity based on your serial connection.
Configuring the UART code to send some fixed pattern (ie, like the letter 'A' or something) would be a start.
And viewing the serial line result on a simulator (like modelsim, etc) to validate the waveform.
Based on your experience you have jumped about five steps ahead when you need to take one step at a time.
As an example, here is a waveform output from a UART module I wrote years ago.
Once I validated the RXD and TXD waveform patterns and timing were right I could connect it up to a real serial interface.
And here is the testbench code I use to test my UART module ...
`timescale 1ns / 1ns module test; parameter SYSFREQ = 50000, // KHz BAUDRATE = 38400, // baud SYSPER = 1000000/SYSFREQ, // ns/clk BITPER = 1000000000/BAUDRATE, // ns/bit TPD = 1; // ns reg sysclk; reg reset; wire txd; reg rxd; reg rxdd; wire [7:0] rxdata; wire rxferr; wire rxoerr; wire rxperr; wire rxerr; wire rxrdy; wire rxrd; reg [7:0] txdata; wire txrdy; wire txwr; parameter START = 1'b0, STOP = 1'b1; initial rxdd = 1'b1; always @(rxd) rxdd <= #(10.5*BITPER+48*SYSPER) rxd; wire delta = rxdd ^ txd; initial begin sysclk = 1; forever #(500000.0/SYSFREQ) sysclk = ~sysclk; end initial begin $timeformat(-6, 3, "us", 15); $dumpfile("test.vcd"); $dumpvars(2,test); reset = 1'b1; #950; reset = 1'b0; end task rxchar; input [7:0] char; reg [9:0] bits; reg [3:0] i; begin rxd = 1'b1; bits = {STOP,char[7:0],START}; for (i = 0; i <= 9; i = i+1) #BITPER rxd = bits[i]; end endtask // rxchar initial begin rxd = 1'b1; #(2.0*BITPER); rxchar(8'b01111111); #(1.5*BITPER); rxchar(8'b10101010); #(2.5*BITPER); rxchar(8'b01010101); #(2.0*BITPER); rxchar(8'b10000000); #(1.5*BITPER); rxchar(8'b00000010); #(1.0*BITPER); rxchar(8'b00000000); rxchar(8'b01010101); rxchar(8'b01000101); rxchar(8'b01010101); rxchar(8'b01000101); rxchar(8'b01010101); rxchar(8'b00000000); #(3.0*BITPER); rxd = 1'b0; #(15.0*BITPER); rxd = 1'b1; #(2.0*BITPER); $write("\n\n"); $finish; end reg txrdyd, rxrdyd, txgo; wire rxrdy_rising = rxrdy & ~rxrdyd; wire txrdy_falling = ~txrdy & txrdyd; always @(posedge sysclk) begin if (reset) begin txgo <= #TPD 0; rxrdyd <= #TPD 0; txrdyd <= #TPD 0; txdata <= #TPD 0; end else begin rxrdyd <= #TPD rxrdy; txrdyd <= #TPD txrdy; if (rxrdy_rising) txdata <= #TPD rxdata; if (rxrdy_rising) txgo <= #TPD 1'b1; else if (txrdy_falling) txgo <= #TPD 1'b0; end end always @(posedge sysclk) begin if (!reset) begin if (rxrdy_rising) $write("\n%t rxdata=%o\n", $time, rxdata); if (txrdy_falling) $write("%t txdata=%o\n", $time, txdata); end end assign rxrd = txgo; assign txwr = txgo; assign rxerr = rxferr|rxoerr|rxperr; uart #(.TPD(TPD)) uart ( .clk (sysclk), .reset (reset), .bauddiv (16'd163), .stopbits (4'd1), .databits (4'd8), .rxd (rxd), .rxrd (rxrd), .rxrdy (rxrdy), .rxferr (rxferr), .rxoerr (rxoerr), .rxperr (rxperr), .rxdata (rxdata), .txd (txd), .txwr (txwr), .txrdy (txrdy), .txdata (txdata) ); endmodule // test
I am using the clock on the FPGA which is 50 MHz, and baud rate of 115200.
based on the code, there is one start bit and one stop bit. (start bit =0, start sending data, and stop bit=1, end of data).
Yes I need to test it in ModelSim first.
I thought it might be simple since it is only transmitter and I can test it on pga right away.