Skip to content

Instantly share code, notes, and snippets.

@the6p4c
Created October 1, 2019 13:08
Show Gist options
  • Select an option

  • Save the6p4c/890455c23725ac515b5bf557621cb436 to your computer and use it in GitHub Desktop.

Select an option

Save the6p4c/890455c23725ac515b5bf557621cb436 to your computer and use it in GitHub Desktop.

Revisions

  1. the6p4c created this gist Oct 1, 2019.
    44 changes: 44 additions & 0 deletions top.v
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,44 @@
    `default_nettype none

    module top(input CLK, output PIN_24);
    wire tx_buf_empty;
    reg tx_data_ready;
    reg [7:0] tx_data;

    uart_tx #(
    .BAUD_DIVISOR(16000000 / 115200)
    ) uart_tx_inst (
    .i_clk(CLK),
    .o_tx(PIN_24),

    .o_tx_buf_empty(tx_buf_empty),
    .i_tx_data_ready(tx_data_ready),
    .i_tx_data(tx_data)
    );

    reg [3:0] ctr = 0;

    always @(*) begin
    if (tx_buf_empty) begin
    if (ctr == 10) begin
    tx_data <= " ";
    end else begin
    tx_data <= "0" + ctr;
    end
    tx_data_ready <= 1;
    end else begin
    tx_data <= 'h00;
    tx_data_ready <= 0;
    end
    end

    always @(posedge CLK) begin
    if (tx_buf_empty) begin
    if (ctr == 10) begin
    ctr <= 0;
    end else begin
    ctr <= ctr + 1;
    end
    end
    end
    endmodule
    83 changes: 83 additions & 0 deletions uart_tx.v
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,83 @@
    `default_nettype none

    module uart_tx
    # (
    parameter BAUD_DIVISOR = 0,
    parameter N_START_BITS = 1,
    parameter N_DATA_BITS = 8,
    parameter N_STOP_BITS = 1
    ) (
    input i_clk,
    output o_tx,

    output o_tx_buf_empty,
    input i_tx_data_ready,
    input [N_DATA_BITS-1:0] i_tx_data
    );
    localparam SHREG_WIDTH = N_START_BITS + N_DATA_BITS + N_STOP_BITS;
    localparam START_BITS = {N_START_BITS{1'b0}};
    localparam STOP_BITS = {N_STOP_BITS{1'b1}};

    localparam STATE_IDLE = 0;
    localparam STATE_TX = 1;
    reg state = STATE_IDLE;
    reg next_state;

    reg tx;
    assign o_tx = tx;

    reg tx_buf_empty = 1;
    reg [N_DATA_BITS-1:0] tx_buf;

    assign o_tx_buf_empty = tx_buf_empty;

    reg [SHREG_WIDTH-1:0] shreg;
    reg [3:0] num_bits_sent;
    reg [10:0] ctr;

    always @(*) begin
    if (state == STATE_IDLE) begin
    tx <= 1'b1;

    if (!tx_buf_empty) begin
    next_state <= STATE_TX;
    end else begin
    next_state <= STATE_IDLE;
    end
    end else if (state == STATE_TX) begin
    tx <= shreg[0];
    if ((num_bits_sent == SHREG_WIDTH - 1) & (ctr == BAUD_DIVISOR)) begin
    next_state <= STATE_IDLE;
    end else begin
    next_state <= STATE_TX;
    end
    end
    end

    always @(posedge i_clk) begin
    if (i_tx_data_ready & tx_buf_empty) begin
    tx_buf_empty <= 0;
    tx_buf <= i_tx_data;
    end

    if (state == STATE_IDLE) begin
    if (!tx_buf_empty) begin
    tx_buf_empty <= 1;

    shreg <= {STOP_BITS, tx_buf, START_BITS};
    num_bits_sent <= 0;
    ctr <= 0;
    end
    end else if (state == STATE_TX) begin
    if (ctr == BAUD_DIVISOR) begin
    shreg <= {1'b0, shreg[SHREG_WIDTH-1:1]};
    num_bits_sent <= num_bits_sent + 1;
    ctr <= 0;
    end else begin
    ctr <= ctr + 1;
    end
    end

    state <= next_state;
    end
    endmodule