1
0
forked from tanchou/Verilog

Add distance_ws2812_display module and testbench; implement ws2812_driver for LED control

This commit is contained in:
Gamenight77
2025-04-16 17:07:29 +02:00
parent 6dfd8768a0
commit fd09bb30e3
7 changed files with 751 additions and 49 deletions

View File

@@ -2,10 +2,9 @@ module ultrasonic_fpga #(
parameter integer CLK_FREQ = 27_000_000 // Fréquence d'horloge en Hz
)(
input wire clk,
input wire rst,
input wire start,
inout wire sig, // Broche bidirectionnelle vers le capteur
output reg [15:0] distance_cm // Distance mesurée en cm
output reg [15:0] distance // Distance mesurée en cm
);
reg [2:0] state;
@@ -22,68 +21,95 @@ module ultrasonic_fpga #(
TRIG_LOW = 3'd2,
WAIT_ECHO = 3'd3,
MEASURE_ECHO = 3'd4,
DONE = 3'd5;
DONE = 3'd5,
WAIT_NEXT = 3'd6;
localparam integer TRIG_PULSE_CYCLES = CLK_FREQ / 100_000; // 10us pulse
localparam integer DIST_DIVISOR = (58 * CLK_FREQ) / 1_000_000; // pour conversion us -> cm
localparam integer MAX_CM = 370;
localparam integer TIMEOUT_CYCLES = (MAX_CM * 58 * CLK_FREQ) / 1_000_000;
localparam WAIT_NEXT_CYCLES = (CLK_FREQ / 1000) * 100; // 60 ms
always @(posedge clk or posedge rst) begin
if (rst) begin
state <= IDLE;
trig_counter <= 0;
echo_counter <= 0;
sig_out <= 0;
sig_dir <= 0;
distance_cm <= 0;
end else begin
case (state)
IDLE: begin
sig_out <= 0;
sig_dir <= 1;
if (start) begin
state <= TRIG_HIGH;
trig_counter <= 0;
end
reg [31:0] wait_counter;
always @(posedge clk) begin
case (state)
IDLE: begin
sig_out <= 0;
sig_dir <= 1;
distance <= 0;
if (start) begin
state <= TRIG_HIGH;
trig_counter <= 0;
end
end
TRIG_HIGH: begin
sig_out <= 1;
sig_dir <= 1;
if (trig_counter < TRIG_PULSE_CYCLES) begin
trig_counter <= trig_counter + 1;
end else begin
trig_counter <= 0;
state <= TRIG_LOW;
end
TRIG_HIGH: begin
sig_out <= 1;
sig_dir <= 1;
if (trig_counter < TRIG_PULSE_CYCLES) begin
trig_counter <= trig_counter + 1;
end else begin
trig_counter <= 0;
state <= TRIG_LOW;
end
end
TRIG_LOW: begin
sig_out <= 0;
sig_dir <= 0; // Mettre en entrée
state <= WAIT_ECHO;
TRIG_LOW: begin
sig_out <= 0;
sig_dir <= 0; // Mettre en entrée
state <= WAIT_ECHO;
end
WAIT_ECHO: begin
if (sig_in) begin
echo_counter <= 0;
state <= MEASURE_ECHO;
end else if (echo_counter >= TIMEOUT_CYCLES) begin
distance <= 0;
state <= DONE;
end else begin
echo_counter <= echo_counter + 1;
end
end
WAIT_ECHO: begin
if (sig_in) begin
echo_counter <= 0;
state <= MEASURE_ECHO;
end
end
MEASURE_ECHO: begin
if (sig_in) begin
MEASURE_ECHO: begin
if (sig_in) begin
if (echo_counter < TIMEOUT_CYCLES) begin
echo_counter <= echo_counter + 1;
end else begin
distance_cm <= (echo_counter * 1000) / DIST_DIVISOR;
distance <= 0;
state <= DONE;
end
end else begin
distance <= (echo_counter * 1000) / DIST_DIVISOR;
state <= DONE;
end
end
DONE: begin
DONE: begin
if (start) begin
wait_counter <= 0;
state <= WAIT_NEXT;
end else begin
state <= IDLE;
end
endcase
end
end
WAIT_NEXT: begin
wait_counter <= wait_counter + 1;
if (wait_counter >= WAIT_NEXT_CYCLES) begin
state <= TRIG_HIGH;
end
end
endcase
end
endmodule