Search code examples
verilogfpgauart

Lattice iCE40-HX8K Board - UART


I have the following verilog code for my Lattice iCE40-HX8K Board:

uart.v:

module uart(input clk, output TXD);

reg [3:0] count;
reg [9:0] data;
reg z;

initial begin

data[9:0] = 10'b1000000000; // Startbit = 1, Stopbit = 0

z = 0;

end

always@(posedge clk)
begin

  if(count == 1250) //9600x per Second (1250) = Baudrate
    begin

      count <= 0;

      TXD = data[z];

      z = z + 1;
 if(z == 10)
        begin
        z = 0;
        end
      else
        begin
        end

    end
  else
    begin
      count <= count + 1;
    end


end

endmodule

For receiving the UART-Data I use gtkterm under Ubuntu 14.04. I have set the baudrate in gtkterm to 9600. If I now program my FPGA with the code I receive once per programming a hex "00" (irrespective of the 8 usage-bits).

enter image description here

Can anybody give me a hint what is wrong?

Thank you for your support.


Solution

  • There are at least two obvious problems with your design:

    1. Your count is only 4 bits wide, thus it cannot count to 1250. It must be at least 11 bits wide to be able to count to 1250.

    2. Also your z is only 1 bit wide, so it can only hold the values 0 and 1. It must be at least 4 bits wide to be able to count to 10.

    You should also read up on blocking vs. non-blocking assignments. The way you use blocking assignments in sequential logic can lead to race conditions in the verilog simulation model.

    You should always write testbenches for your HDL code and simulate it before trying to run it in hardware. A testbench for your design would be as easy as:

    module uart_testbench;
            reg clk = 1;
            always #5 clk = ~clk;
    
            uart uut (
                    .clk(clk)
            );
    
            initial begin
                    $dumpfile("uart.vcd");
                    $dumpvars(0, uut);
                    repeat (1000000) @(posedge clk);
                    $finish;
            end
    endmodule