`default_nettype none module uart_tx #(parameter CLOCKS_PER_BAUD=16'd868)( input wire clk, input wire rst_n, input wire en_i, input wire [7:0] data_i, output reg tx_o, output reg tx_done_o ); localparam s_idle = 5'b00001, s_start = 5'b00010, s_wr = 5'b00100, s_stop = 5'b01000, s_done = 5'b10000; reg en_cnt; reg [15:0] cnt; reg [4:0] state; reg [7:0] data_r; reg [2:0] tx_bits; always @(posedge clk or negedge rst_n) begin if (!rst_n) cnt <= 16'd0; else if ((en_cnt == 0) || (cnt == CLOCKS_PER_BAUD)) cnt <= 16'd0; else cnt <= cnt + 1; end always @(posedge clk or negedge rst_n) begin if (~rst_n) begin state <= s_idle; tx_o <= 1; en_cnt <= 0; data_r <= 0; tx_bits <= 0; tx_done_o <= 0; end else begin case (state) s_idle: begin data_r <= data_i; tx_bits <= 0; tx_done_o <= 0; if (en_i == 1) begin en_cnt <= 1; state <= s_start; end else begin en_cnt <= 0; state <= s_idle; end end s_start: begin if (cnt == CLOCKS_PER_BAUD) state <= s_wr; else begin tx_o <= 0; state <= s_start; end end s_wr: begin if (cnt == CLOCKS_PER_BAUD) begin if (tx_bits == 3'd7) state <= s_stop; else begin tx_bits <= tx_bits + 1; state <= s_wr; end end else begin tx_o <= data_r[tx_bits]; state <= s_wr; end end s_stop: begin if (cnt == CLOCKS_PER_BAUD) state <= s_done; else begin tx_o <= 1; state <= s_stop; end end s_done: begin en_cnt <= 0; tx_done_o <= 1; state <= s_idle; end default : begin state <= s_idle; end endcase end end endmodule // Local Variables: // verilog-library-directories:(".." "../rtl" ".") // End: