data/full_repos/permissive/430393260/rtl/uart_tx.v
data/verilator_xmls/d6921ee0-67ab-4577-9a8f-887415d6fa87.xml
module uart_tx #(
    parameter WIDTH = 8,
    parameter SAMPLE_RATE = 16
) (
    input               clk,
    input               rst,
    input [1:0]         cfg_parity,
    input [1:0]         cfg_stop_bits,
    input [15:0]        cfg_clk_div,
    input [WIDTH-1:0]   tx_din,
    input               tx_valid,
    output reg          tx_ready,
    output reg          uart_tx
);




    reg [2:0]       samples;
    reg             sample_tick;
    reg [15:0]      buad_count;


    parameter IDLE   = 0;
    parameter START  = 1;
    parameter DATA   = 2;
    parameter PARITY = 3;
    parameter STOP   = 4;


    reg [2:0] tx_state;
    reg [7:0] data;
    reg [3:0] data_cnt;
    reg [5:0] sample_cnt;
    reg       parity;
    reg [5:0] stop_cnt_static;

    wire      sampled_all;








    always @(posedge clk)
    begin
        if (rst)
        begin
            sample_tick <= 1'b0;
            buad_count  <= 'b0;
        end
        else
        begin
            if (buad_count == cfg_clk_div)
            begin
                sample_tick <= 1'b1;
                buad_count  <= 'b0;
            end
            else
            begin
                sample_tick <= 1'b0;
                buad_count  <= buad_count + 1;
            end
        end
    end









    assign sampled_all = (sample_cnt == SAMPLE_RATE);


    always @(posedge clk)
    begin
        if(rst)
        begin
            tx_state <= IDLE;
        end
        else
        begin
            case(tx_state)
                IDLE:
                begin
                    if (tx_valid)
                        tx_state <= START;
                end
                START:
                begin
                    if (sampled_all)
                        tx_state <= DATA;
                end
                DATA:
                begin
                    if (data_cnt == WIDTH)
                        tx_state <= (cfg_parity > 0) ? PARITY : STOP;
                end
                PARITY:
                begin
                    if (sampled_all)
                        tx_state <= STOP;
                end
                STOP:
                begin
                    if (sample_cnt == stop_cnt_static)
                        tx_state <= IDLE;
                end
            endcase
        end
    end

    always @(posedge clk)
    begin
        if(rst)
        begin
            data_cnt    <= 'b0;
            data        <= 'b0;
            sample_cnt  <= 'b0;
            parity      <= 'b0;
            uart_tx     <= 1'b1;
            tx_ready       <= 1'b1;
            stop_cnt_static <= 'b0;
        end
        else
        begin
            stop_cnt_static <= (cfg_stop_bits == 2'b00) ? 16 : (cfg_stop_bits == 2'b01) ? 24 : 32;
            case(tx_state)
                IDLE:
                begin
                    sample_cnt  <= 'b0;
                    data        <= tx_din;
                    data_cnt    <= 'b0;
                    tx_ready    <= ~tx_valid;
                    uart_tx     <= 1'b1;
                end
                START:
                begin
                    sample_cnt  <= sampled_all ? 'b0 : (sample_tick ? sample_cnt + 1 : sample_cnt);
                    uart_tx     <= 1'b0;
                    parity      <= ^data;
                end
                DATA:
                begin
                    sample_cnt  <= sampled_all ? 'b0 : (sample_tick ? sample_cnt + 1 : sample_cnt);
                    data_cnt    <= sampled_all ? data_cnt + 1 : data_cnt;
                    data        <= sampled_all ? data>>1 : data;
                    uart_tx     <= data[0];
                end
                PARITY:
                begin
                    sample_cnt  <= sampled_all ? 'b0 : (sample_tick ? sample_cnt + 1 : sample_cnt);
                    uart_tx     <= (cfg_parity == 1) ^ parity;
                end
                STOP:
                begin
                    sample_cnt  <= sample_tick ? sample_cnt + 1 : sample_cnt;
                    uart_tx     <= 1'b1;
                    tx_ready       <= (sample_cnt == stop_cnt_static) ? 1'b1 : 1'b0;
                end
            endcase
        end
    end

endmodule
module uart_tx #(
    parameter WIDTH = 8,
    parameter SAMPLE_RATE = 16
) (
    input               clk,
    input               rst,
    input [1:0]         cfg_parity,
    input [1:0]         cfg_stop_bits,
    input [15:0]        cfg_clk_div,
    input [WIDTH-1:0]   tx_din,
    input               tx_valid,
    output reg          tx_ready,
    output reg          uart_tx
);





    reg [2:0]       samples;
    reg             sample_tick;
    reg [15:0]      buad_count;


    parameter IDLE   = 0;
    parameter START  = 1;
    parameter DATA   = 2;
    parameter PARITY = 3;
    parameter STOP   = 4;


    reg [2:0] tx_state;
    reg [7:0] data;
    reg [3:0] data_cnt;
    reg [5:0] sample_cnt;
    reg       parity;
    reg [5:0] stop_cnt_static;

    wire      sampled_all;








    always @(posedge clk)
    begin
        if (rst)
        begin
            sample_tick <= 1'b0;
            buad_count  <= 'b0;
        end
        else
        begin
            if (buad_count == cfg_clk_div)
            begin
                sample_tick <= 1'b1;
                buad_count  <= 'b0;
            end
            else
            begin
                sample_tick <= 1'b0;
                buad_count  <= buad_count + 1;
            end
        end
    end









    assign sampled_all = (sample_cnt == SAMPLE_RATE);


    always @(posedge clk)
    begin
        if(rst)
        begin
            tx_state <= IDLE;
        end
        else
        begin
            case(tx_state)
                IDLE:
                begin
                    if (tx_valid)
                        tx_state <= START;
                end
                START:
                begin
                    if (sampled_all)
                        tx_state <= DATA;
                end
                DATA:
                begin
                    if (data_cnt == WIDTH)
                        tx_state <= (cfg_parity > 0) ? PARITY : STOP;
                end
                PARITY:
                begin
                    if (sampled_all)
                        tx_state <= STOP;
                end
                STOP:
                begin
                    if (sample_cnt == stop_cnt_static)
                        tx_state <= IDLE;
                end
            endcase
        end
    end

    always @(posedge clk)
    begin
        if(rst)
        begin
            data_cnt    <= 'b0;
            data        <= 'b0;
            sample_cnt  <= 'b0;
            parity      <= 'b0;
            uart_tx     <= 1'b1;
            tx_ready       <= 1'b1;
            stop_cnt_static <= 'b0;
        end
        else
        begin
            stop_cnt_static <= (cfg_stop_bits == 2'b00) ? 16 : (cfg_stop_bits == 2'b01) ? 24 : 32;
            case(tx_state)
                IDLE:
                begin
                    sample_cnt  <= 'b0;
                    data        <= tx_din;
                    data_cnt    <= 'b0;
                    tx_ready    <= ~tx_valid;
                    uart_tx     <= 1'b1;
                end
                START:
                begin
                    sample_cnt  <= sampled_all ? 'b0 : (sample_tick ? sample_cnt + 1 : sample_cnt);
                    uart_tx     <= 1'b0;
                    parity      <= ^data;
                end
                DATA:
                begin
                    sample_cnt  <= sampled_all ? 'b0 : (sample_tick ? sample_cnt + 1 : sample_cnt);
                    data_cnt    <= sampled_all ? data_cnt + 1 : data_cnt;
                    data        <= sampled_all ? data>>1 : data;
                    uart_tx     <= data[0];
                end
                PARITY:
                begin
                    sample_cnt  <= sampled_all ? 'b0 : (sample_tick ? sample_cnt + 1 : sample_cnt);
                    uart_tx     <= (cfg_parity == 1) ^ parity;
                end
                STOP:
                begin
                    sample_cnt  <= sample_tick ? sample_cnt + 1 : sample_cnt;
                    uart_tx     <= 1'b1;
                    tx_ready       <= (sample_cnt == stop_cnt_static) ? 1'b1 : 1'b0;
                end
            endcase
        end
    end

endmodule