module uart_tx #( parameter CLK_FREQ = 27_000_000, parameter BAUD_RATE = 115200 )( input wire clk, input wire rst_p, input wire[7:0] data, input wire tx_data_valid, output wire tx, output reg tx_data_ready ); localparam CYCLE = CLK_FREQ / BAUD_RATE; localparam IDLE = 2'd0; localparam START = 2'd1; localparam DATA = 2'd2; localparam STOP = 2'd3; reg [1:0] state = IDLE; reg [1:0] next_state; reg [15:0] cycle_cnt; //baud counter reg [3:0] bit_index = 0; reg [15:0] clk_count = 0; reg [7:0] tx_data = 0; reg tx_reg; assign tx = tx_reg; always@(posedge clk or posedge rst_p)begin // Avance d'etat if(rst_p == 1'b1) state <= IDLE; else state <= next_state; end always@(*) begin case(state) IDLE: if(tx_data_valid == 1'b1) next_state = START; else next_state = IDLE; START: if(cycle_cnt == CYCLE - 1) next_state = DATA; else next_state = START; DATA: if(cycle_cnt == CYCLE - 1 && bit_cnt == 3'd7) next_state = STOP; else next_state = DATA; STOP: if(cycle_cnt == CYCLE - 1) next_state = IDLE; else next_state = STOP; default: next_state = IDLE; endcase end always@(posedge clk or posedge rst_p)begin // tx_data_ready block if(rst_p == 1'b1) begin tx_data_ready <= 1'b0; end else if(state == IDLE) if(tx_data_valid == 1'b1) tx_data_ready <= 1'b0; else tx_data_ready <= 1'b1; else if(state == STOP && cycle_cnt == CYCLE - 1) tx_data_ready <= 1'b1; end always@(posedge clk or posedge rst_p) begin // tx_data_latch block if(rst_p == 1'b1)begin tx_data_latch <= 8'd0; end else if(state == IDLE && tx_data_valid == 1'b1) tx_data_latch <= tx_data; end always@(posedge clk or posedge rst_p)begin // DATA bit_cnt block if(rst_p == 1'b1)begin bit_cnt <= 3'd0; end else if(state == DATA) if(cycle_cnt == CYCLE - 1) bit_cnt <= bit_cnt + 3'd1; else bit_cnt <= bit_cnt; else bit_cnt <= 3'd0; end always@(posedge clk or posedge rst_p)begin // Cycle counter if(rst_p == 1'b1) cycle_cnt <= 16'd0; else if((state == DATA && cycle_cnt == CYCLE - 1) || next_state != state) cycle_cnt <= 16'd0; else cycle_cnt <= cycle_cnt + 16'd1; end always@(posedge clk or posedge rst_p)begin // tx state managment if(rst_p == 1'b1) tx_reg <= 1'b1; else case(state) IDLE,STOP: tx_reg <= 1'b1; START: tx_reg <= 1'b0; DATA: tx_reg <= tx_data_latch[bit_cnt]; // SENDING BYTE HERE default: tx_reg <= 1'b1; endcase end endmodule