module top_uart_ultrasonic ( input wire clk, input wire rst_p, input wire start, // Démarrage de la mesure inout wire sig, // Signal vers le capteur ultrason output wire uart_tx // TX vers le PC ); wire [15:0] distance; wire [2:0] state; reg [7:0] tx_data_in; reg tx_data_valid; wire tx_data_ready; wire fifo_empty; wire fifo_full; wire uart_ready; reg uart_start; reg [7:0] uart_data; reg [1:0] send_state; localparam IDLE = 2'd0, SEND_HIGH = 2'd1, SEND_LOW = 2'd2, WAIT_UART = 2'd3; // Instanciation du module ultrason ultrasonic_fpga #( .CLK_FREQ(27_000_000) ) ultrasonic_inst ( .clk(clk), .start(start), .sig(sig), .distance(distance), .state(state) ); // Instanciation de la FIFO tx_fifo #( .WIDTH(8), .DEPTH(16) ) fifo_inst ( .clk(clk), .rst_p(rst_p), .tx_data_in(tx_data_in), .tx_data_valid(tx_data_valid), .tx_data_ready(tx_data_ready), .fifo_empty(fifo_empty), .fifo_full(fifo_full) ); // Instanciation de l'UART uart_tx uart_inst ( .clk(clk), .rst(rst_p), .tx_start(uart_start), .tx_data(uart_data), .tx(uart_tx), .tx_ready(uart_ready) ); reg [15:0] distance_reg; reg new_distance; // Détecte un nouveau résultat de distance always @(posedge clk or posedge rst_p) begin if (rst_p) begin distance_reg <= 16'd0; new_distance <= 1'b0; end else begin if (state == 3'd6 && distance != distance_reg) begin // Quand l'ultrason est à DONE distance_reg <= distance; new_distance <= 1'b1; end else begin new_distance <= 1'b0; end end end // Envoi dans la FIFO (distance sur 2 octets : high byte + low byte) always @(posedge clk or posedge rst_p) begin if (rst_p) begin tx_data_in <= 8'd0; tx_data_valid <= 1'b0; send_state <= IDLE; end else begin case (send_state) IDLE: begin tx_data_valid <= 1'b0; if (new_distance && !fifo_full) begin tx_data_in <= distance_reg[15:8]; // MSB en premier tx_data_valid <= 1'b1; send_state <= SEND_LOW; end end SEND_LOW: begin tx_data_valid <= 1'b0; if (tx_data_ready && !fifo_full) begin tx_data_in <= distance_reg[7:0]; // LSB ensuite tx_data_valid <= 1'b1; send_state <= WAIT_UART; end end WAIT_UART: begin tx_data_valid <= 1'b0; send_state <= IDLE; end default: send_state <= IDLE; endcase end end // Gestion FIFO -> UART always @(posedge clk or posedge rst_p) begin if (rst_p) begin uart_start <= 1'b0; uart_data <= 8'd0; end else begin uart_start <= 1'b0; // Par défaut if (uart_ready && !fifo_empty) begin uart_data <= fifo_inst.fifo_mem[fifo_inst.rd_ptr]; // Lecture de la FIFO uart_start <= 1'b1; fifo_inst.rd_ptr <= fifo_inst.rd_ptr + 1; fifo_inst.fifo_count <= fifo_inst.fifo_count - 1; end end end endmodule