forked from tanchou/Verilog
uart v3
This commit is contained in:
133
Semaine_3/UARTV3/top_uart_ultrasonic.v
Normal file
133
Semaine_3/UARTV3/top_uart_ultrasonic.v
Normal file
@@ -0,0 +1,133 @@
|
||||
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
|
Reference in New Issue
Block a user