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_enable, output reg tx_ready, output wire tx ); 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 tx_reg; reg [2:0] bit_cnt; reg [7:0] tx_data_latch = 0; 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_enable == 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_ready block if(rst_p == 1'b1) tx_ready <= 1'b0; // Reset else if(state == IDLE && tx_enable == 1'b1) tx_ready <= 1'b0; // Pas prêt tant que les données sont valides else if(state == IDLE) tx_ready <= 1'b1; else if(state == STOP && cycle_cnt == CYCLE - 1) tx_ready <= 1'b1; // Prêt une fois le bit STOP envoyé else tx_ready <= tx_ready; // Reste inchangé dans d'autres cas 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_enable == 1'b1) begin tx_data_latch <= data; // Charger les données de data dans tx_data_latch end 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