diff --git a/Semaine 1/Capteur_recule_bidirectionel/Ultrasonic/ultrasonic_fpga.v b/Semaine 1/Capteur_recule_bidirectionel/Ultrasonic/ultrasonic_fpga.v index ec05936..0d773c6 100644 --- a/Semaine 1/Capteur_recule_bidirectionel/Ultrasonic/ultrasonic_fpga.v +++ b/Semaine 1/Capteur_recule_bidirectionel/Ultrasonic/ultrasonic_fpga.v @@ -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 \ No newline at end of file diff --git a/Semaine 1/Capteur_recule_bidirectionel/distance_ws2812_display/distance_ws2812_display.v b/Semaine 1/Capteur_recule_bidirectionel/distance_ws2812_display/distance_ws2812_display.v new file mode 100644 index 0000000..ed1af99 --- /dev/null +++ b/Semaine 1/Capteur_recule_bidirectionel/distance_ws2812_display/distance_ws2812_display.v @@ -0,0 +1,27 @@ +module distance_ws2812_display( + input wire clk, + input wire [8:0] distance, // distance mesurer + output wire ws2812_dout // broche de données pour la LED WS2812 +); + + reg [23:0] led_color; // couleur à envoyer à la LED (format RGB) + + always @(posedge clk) begin + // Mapper la distance sur une couleur + if (distance < 100) begin + led_color <= 24'hFF0000; // Rouge (proche) + end else if (distance < 200) begin + led_color <= 24'hFFFF00; // Jaune (distance moyenne) + end else begin + led_color <= 24'h00FF00; // Vert (très loin) + end + end + + // Instance du module de transmission pour WS2812 + ws2812_driver ws2812_inst ( + .clk(clk), + .color(led_color), + .ws2812_dout(ws2812_dout) + ); + +endmodule \ No newline at end of file diff --git a/Semaine 1/Capteur_recule_bidirectionel/distance_ws2812_display/distance_ws2812_display.vcd b/Semaine 1/Capteur_recule_bidirectionel/distance_ws2812_display/distance_ws2812_display.vcd new file mode 100644 index 0000000..1825ab1 --- /dev/null +++ b/Semaine 1/Capteur_recule_bidirectionel/distance_ws2812_display/distance_ws2812_display.vcd @@ -0,0 +1,441 @@ +$date + Wed Apr 16 16:42:16 2025 +$end +$version + Icarus Verilog +$end +$timescale + 1s +$end +$scope module tb_distance_ws2812_display $end +$var wire 1 ! ws2812_dout $end +$var reg 1 " clk $end +$var reg 9 # distance [8:0] $end +$var integer 32 $ i [31:0] $end +$scope module uut $end +$var wire 1 " clk $end +$var wire 9 % distance [8:0] $end +$var wire 1 ! ws2812_dout $end +$var reg 24 & led_color [23:0] $end +$scope module ws2812_inst $end +$var wire 1 " clk $end +$var wire 24 ' color [23:0] $end +$var reg 8 ( bit_count [7:0] $end +$var reg 24 ) shift_reg [23:0] $end +$var reg 1 ! ws2812_dout $end +$upscope $end +$upscope $end +$upscope $end +$enddefinitions $end +$comment Show the parameter values. $end +$dumpall +$end +#0 +$dumpvars +bx ) +bx ( +bx ' +bx & +b0 % +b0 $ +b0 # +0" +x! +$end +#5 +b0 ( +bx0 ) +b111111110000000000000000 & +b111111110000000000000000 ' +1" +#10 +0" +b1010 # +b1010 % +b1010 $ +#15 +b1 ( +0! +b111111110000000000000000 ) +1" +#20 +0" +b10100 # +b10100 % +b10100 $ +#25 +b10 ( +b111111100000000000000000 ) +1! +1" +#30 +0" +b11110 # +b11110 % +b11110 $ +#35 +b11 ( +b111111000000000000000000 ) +1" +#40 +0" +b101000 # +b101000 % +b101000 $ +#45 +b100 ( +b111110000000000000000000 ) +1" +#50 +0" +b110010 # +b110010 % +b110010 $ +#55 +b101 ( +b111100000000000000000000 ) +1" +#60 +0" +b111100 # +b111100 % +b111100 $ +#65 +b110 ( +b111000000000000000000000 ) +1" +#70 +0" +b1000110 # +b1000110 % +b1000110 $ +#75 +b111 ( +b110000000000000000000000 ) +1" +#80 +0" +b1010000 # +b1010000 % +b1010000 $ +#85 +b1000 ( +b100000000000000000000000 ) +1" +#90 +0" +b1011010 # +b1011010 % +b1011010 $ +#95 +b1001 ( +b0 ) +1" +#100 +0" +b1100100 # +b1100100 % +b1100100 $ +#105 +b1010 ( +0! +b111111111111111100000000 & +b111111111111111100000000 ' +1" +#110 +0" +b1101110 # +b1101110 % +b1101110 $ +#115 +b1011 ( +1" +#120 +0" +b1111000 # +b1111000 % +b1111000 $ +#125 +b1100 ( +1" +#130 +0" +b10000010 # +b10000010 % +b10000010 $ +#135 +b1101 ( +1" +#140 +0" +b10001100 # +b10001100 % +b10001100 $ +#145 +b1110 ( +1" +#150 +0" +b10010110 # +b10010110 % +b10010110 $ +#155 +b1111 ( +1" +#160 +0" +b10100000 # +b10100000 % +b10100000 $ +#165 +b10000 ( +1" +#170 +0" +b10101010 # +b10101010 % +b10101010 $ +#175 +b10001 ( +1" +#180 +0" +b10110100 # +b10110100 % +b10110100 $ +#185 +b10010 ( +1" +#190 +0" +b10111110 # +b10111110 % +b10111110 $ +#195 +b10011 ( +1" +#200 +0" +b11001000 # +b11001000 % +b11001000 $ +#205 +b10100 ( +b1111111100000000 & +b1111111100000000 ' +1" +#210 +0" +b11010010 # +b11010010 % +b11010010 $ +#215 +b10101 ( +1" +#220 +0" +b11011100 # +b11011100 % +b11011100 $ +#225 +b10110 ( +1" +#230 +0" +b11100110 # +b11100110 % +b11100110 $ +#235 +b10111 ( +1" +#240 +0" +b11110000 # +b11110000 % +b11110000 $ +#245 +b11000 ( +1" +#250 +0" +b11111010 # +b11111010 % +b11111010 $ +#255 +b0 ( +1" +#260 +0" +b100000100 # +b100000100 % +b100000100 $ +#265 +b1 ( +b1111111100000000 ) +1" +#270 +0" +b100001110 # +b100001110 % +b100001110 $ +#275 +b10 ( +b11111111000000000 ) +1" +#280 +0" +b100011000 # +b100011000 % +b100011000 $ +#285 +b11 ( +b111111110000000000 ) +1" +#290 +0" +b100100010 # +b100100010 % +b100100010 $ +#295 +b100 ( +b1111111100000000000 ) +1" +#300 +0" +b100101100 # +b100101100 % +b100101100 $ +#305 +b101 ( +b11111111000000000000 ) +1" +#310 +0" +b100110110 # +b100110110 % +b100110110 $ +#315 +b110 ( +b111111110000000000000 ) +1" +#320 +0" +b101000000 # +b101000000 % +b101000000 $ +#325 +b111 ( +b1111111100000000000000 ) +1" +#330 +0" +b101001010 # +b101001010 % +b101001010 $ +#335 +b1000 ( +b11111111000000000000000 ) +1" +#340 +0" +b101010100 # +b101010100 % +b101010100 $ +#345 +b1001 ( +b111111110000000000000000 ) +1" +#350 +0" +b101011110 # +b101011110 % +b101011110 $ +#355 +b1010 ( +b111111100000000000000000 ) +1! +1" +#360 +0" +b101101000 # +b101101000 % +b101101000 $ +#365 +b1011 ( +b111111000000000000000000 ) +1" +#370 +0" +b101110010 # +b101110010 % +b101110010 $ +#375 +b1100 ( +b111110000000000000000000 ) +1" +#380 +0" +b101111100 # +b101111100 % +b101111100 $ +#385 +b1101 ( +b111100000000000000000000 ) +1" +#390 +0" +b110000110 $ +#395 +b1110 ( +b111000000000000000000000 ) +1" +#400 +0" +#405 +b1111 ( +b110000000000000000000000 ) +1" +#410 +0" +#415 +b10000 ( +b100000000000000000000000 ) +1" +#420 +0" +#425 +b10001 ( +b0 ) +1" +#430 +0" +#435 +b10010 ( +0! +1" +#440 +0" +#445 +b10011 ( +1" +#450 +0" +#455 +b10100 ( +1" +#460 +0" +#465 +b10101 ( +1" +#470 +0" +#475 +b10110 ( +1" +#480 +0" +#485 +b10111 ( +1" +#490 diff --git a/Semaine 1/Capteur_recule_bidirectionel/distance_ws2812_display/distance_ws2812_display.vvp b/Semaine 1/Capteur_recule_bidirectionel/distance_ws2812_display/distance_ws2812_display.vvp new file mode 100644 index 0000000..72df17a --- /dev/null +++ b/Semaine 1/Capteur_recule_bidirectionel/distance_ws2812_display/distance_ws2812_display.vvp @@ -0,0 +1,141 @@ +#! +:ivl_version "13.0 (devel)" "(s20250103-31-g7e238e7ca-dirty)"; +:ivl_delay_selection "TYPICAL"; +:vpi_time_precision + 0; +:vpi_module "C:\Users\louis\BUT2\Verilog\OSS-CA~1\lib\ivl\system.vpi"; +:vpi_module "C:\Users\louis\BUT2\Verilog\OSS-CA~1\lib\ivl\vhdl_sys.vpi"; +:vpi_module "C:\Users\louis\BUT2\Verilog\OSS-CA~1\lib\ivl\vhdl_textio.vpi"; +:vpi_module "C:\Users\louis\BUT2\Verilog\OSS-CA~1\lib\ivl\v2005_math.vpi"; +:vpi_module "C:\Users\louis\BUT2\Verilog\OSS-CA~1\lib\ivl\va_math.vpi"; +S_000002057b2ea610 .scope module, "tb_distance_ws2812_display" "tb_distance_ws2812_display" 2 2; + .timescale 0 0; +v000002057b2c69d0_0 .var "clk", 0 0; +v000002057b1dbfc0_0 .var "distance", 8 0; +v000002057b2f7a30_0 .var/i "i", 31 0; +v000002057b2f7c10_0 .net "ws2812_dout", 0 0, v000002057b2c66b0_0; 1 drivers +S_000002057b1db840 .scope module, "uut" "distance_ws2812_display" 2 9, 3 1 0, S_000002057b2ea610; + .timescale 0 0; + .port_info 0 /INPUT 1 "clk"; + .port_info 1 /INPUT 9 "distance"; + .port_info 2 /OUTPUT 1 "ws2812_dout"; +v000002057b2c6750_0 .net "clk", 0 0, v000002057b2c69d0_0; 1 drivers +v000002057b2c67f0_0 .net "distance", 8 0, v000002057b1dbfc0_0; 1 drivers +v000002057b2c6890_0 .var "led_color", 23 0; +v000002057b2c6930_0 .net "ws2812_dout", 0 0, v000002057b2c66b0_0; alias, 1 drivers +S_000002057b1db9d0 .scope module, "ws2812_inst" "ws2812_driver" 3 21, 4 1 0, S_000002057b1db840; + .timescale 0 0; + .port_info 0 /INPUT 1 "clk"; + .port_info 1 /INPUT 24 "color"; + .port_info 2 /OUTPUT 1 "ws2812_dout"; +v000002057b1dbb60_0 .var "bit_count", 7 0; +v000002057b2fba40_0 .net "clk", 0 0, v000002057b2c69d0_0; alias, 1 drivers +v000002057b2ea7a0_0 .net "color", 23 0, v000002057b2c6890_0; 1 drivers +v000002057b2c6610_0 .var "shift_reg", 23 0; +v000002057b2c66b0_0 .var "ws2812_dout", 0 0; +E_000002057b2e9430 .event posedge, v000002057b2fba40_0; + .scope S_000002057b1db9d0; +T_0 ; + %wait E_000002057b2e9430; + %load/vec4 v000002057b1dbb60_0; + %pad/u 32; + %cmpi/e 0, 0, 32; + %jmp/0xz T_0.0, 4; + %load/vec4 v000002057b2ea7a0_0; + %assign/vec4 v000002057b2c6610_0, 0; + %pushi/vec4 0, 0, 1; + %assign/vec4 v000002057b2c66b0_0, 0; + %jmp T_0.1; +T_0.0 ; + %load/vec4 v000002057b2c6610_0; + %parti/s 1, 23, 6; + %assign/vec4 v000002057b2c66b0_0, 0; + %load/vec4 v000002057b2c6610_0; + %ix/load 4, 1, 0; + %flag_set/imm 4, 0; + %shiftl 4; + %assign/vec4 v000002057b2c6610_0, 0; +T_0.1 ; + %load/vec4 v000002057b1dbb60_0; + %pad/u 32; + %cmpi/u 24, 0, 32; + %jmp/0xz T_0.2, 5; + %load/vec4 v000002057b1dbb60_0; + %addi 1, 0, 8; + %assign/vec4 v000002057b1dbb60_0, 0; + %jmp T_0.3; +T_0.2 ; + %pushi/vec4 0, 0, 8; + %assign/vec4 v000002057b1dbb60_0, 0; +T_0.3 ; + %jmp T_0; + .thread T_0; + .scope S_000002057b1db840; +T_1 ; + %wait E_000002057b2e9430; + %load/vec4 v000002057b2c67f0_0; + %pad/u 32; + %cmpi/u 100, 0, 32; + %jmp/0xz T_1.0, 5; + %pushi/vec4 16711680, 0, 24; + %assign/vec4 v000002057b2c6890_0, 0; + %jmp T_1.1; +T_1.0 ; + %load/vec4 v000002057b2c67f0_0; + %pad/u 32; + %cmpi/u 200, 0, 32; + %jmp/0xz T_1.2, 5; + %pushi/vec4 16776960, 0, 24; + %assign/vec4 v000002057b2c6890_0, 0; + %jmp T_1.3; +T_1.2 ; + %pushi/vec4 65280, 0, 24; + %assign/vec4 v000002057b2c6890_0, 0; +T_1.3 ; +T_1.1 ; + %jmp T_1; + .thread T_1; + .scope S_000002057b2ea610; +T_2 ; + %delay 5, 0; + %load/vec4 v000002057b2c69d0_0; + %inv; + %store/vec4 v000002057b2c69d0_0, 0, 1; + %jmp T_2; + .thread T_2; + .scope S_000002057b2ea610; +T_3 ; + %pushi/vec4 0, 0, 1; + %store/vec4 v000002057b2c69d0_0, 0, 1; + %pushi/vec4 0, 0, 9; + %store/vec4 v000002057b1dbfc0_0, 0, 9; + %vpi_call 2 22 "$dumpfile", "distance_ws2812_display.vcd" {0 0 0}; + %vpi_call 2 23 "$dumpvars", 32'sb00000000000000000000000000000000, S_000002057b2ea610 {0 0 0}; + %pushi/vec4 0, 0, 32; + %store/vec4 v000002057b2f7a30_0, 0, 32; +T_3.0 ; Top of for-loop + %load/vec4 v000002057b2f7a30_0; + %cmpi/s 380, 0, 32; + %flag_or 5, 4; + %jmp/0xz T_3.1, 5; + %load/vec4 v000002057b2f7a30_0; + %pad/s 9; + %store/vec4 v000002057b1dbfc0_0, 0, 9; + %delay 10, 0; + %vpi_call 2 29 "$display", "Distance: %3d cm => LEDs: %b", v000002057b1dbfc0_0, v000002057b2f7c10_0 {0 0 0}; +T_3.2 ; for-loop step statement + %load/vec4 v000002057b2f7a30_0; + %addi 10, 0, 32; + %store/vec4 v000002057b2f7a30_0, 0, 32; + %jmp T_3.0; +T_3.1 ; for-loop exit label + %delay 100, 0; + %vpi_call 2 32 "$stop" {0 0 0}; + %end; + .thread T_3; +# The file index is used to find the file name in the following table. +:file_names 5; + "N/A"; + ""; + "tb_distance_ws2812_display.v"; + "distance_ws2812_display.v"; + "ws2812_driver.v"; diff --git a/Semaine 1/Capteur_recule_bidirectionel/distance_ws2812_display/tb_distance_ws2812_display.v b/Semaine 1/Capteur_recule_bidirectionel/distance_ws2812_display/tb_distance_ws2812_display.v new file mode 100644 index 0000000..b889ea3 --- /dev/null +++ b/Semaine 1/Capteur_recule_bidirectionel/distance_ws2812_display/tb_distance_ws2812_display.v @@ -0,0 +1,34 @@ +// Testbench pour distance_ws2812_display +module tb_distance_ws2812_display; + + reg clk; + reg [8:0] distance; + wire ws2812_dout; + + // Instance du module à tester + distance_ws2812_display uut ( + .clk(clk), + .distance(distance), + .ws2812_dout(ws2812_dout) + ); + + always #5 clk = ~clk; + integer i; + initial begin + // Initialiser les signaux + clk = 0; + distance = 0; + + $dumpfile("distance_ws2812_display.vcd"); + $dumpvars(0, tb_distance_ws2812_display); + + // Test de la conversion de distance en LED + for (i = 0; i <= 380; i = i + 10) begin + distance = i; + #10; + $display("Distance: %3d cm => dout: %b", distance, ws2812_dout); + end + + #100 $stop; // Arrêter la simulation après un certain temps + end +endmodule diff --git a/Semaine 1/Capteur_recule_bidirectionel/distance_ws2812_display/ws2812_driver.v b/Semaine 1/Capteur_recule_bidirectionel/distance_ws2812_display/ws2812_driver.v new file mode 100644 index 0000000..c26751d --- /dev/null +++ b/Semaine 1/Capteur_recule_bidirectionel/distance_ws2812_display/ws2812_driver.v @@ -0,0 +1,27 @@ +module ws2812_driver( + input wire clk, + input wire [23:0] color, // couleur RGB (8 bits par composant) + output reg ws2812_dout // broche de données vers la LED +); + reg [7:0] bit_count; // compteur de bits pour envoyer les données + reg [23:0] shift_reg; // registre pour envoyer la couleur + + always @(posedge clk) begin + + if (bit_count == 0) begin + shift_reg <= color; // Charger la couleur à transmettre + ws2812_dout <= 1'b0; // Commencer par envoyer un "0" + end else begin + // Envoyer chaque bit un à un en contrôlant la durée de l'impulsion + ws2812_dout <= shift_reg[23]; // Le bit le plus significatif + shift_reg <= shift_reg << 1; // Décalage des bits + end + // Incrémentation du compteur de bits + if (bit_count < 24) + bit_count <= bit_count + 1; + else + bit_count <= 0; // Réinitialiser pour envoyer la prochaine couleur + + end +endmodule + diff --git a/Semaine 1/Capteur_recule_bidirectionel/top_ultrasonic_led.v b/Semaine 1/Capteur_recule_bidirectionel/top_ultrasonic_led.v index 6e64591..ae29ccd 100644 --- a/Semaine 1/Capteur_recule_bidirectionel/top_ultrasonic_led.v +++ b/Semaine 1/Capteur_recule_bidirectionel/top_ultrasonic_led.v @@ -1,17 +1,16 @@ module top_ultrasonic_led ( input wire clk, - input wire rst, input wire start, // bouton de déclenchement inout wire sig, // broche unique pour trigger + echo output wire [5:0] leds // LEDs pour affichage distance + output wire ws2812_dout // broche de données pour la LED WS2812 (optionnel) ); wire [8:0] distance; // Module de mesure (version bidirectionnelle du capteur) - ultrasonic_fpga_onewire ultrasonic_inst ( + ultrasonic_fpga ultrasonic_inst ( .clk(clk), - .rst(rst), .start(start), .sig(sig), .distance(distance) @@ -23,4 +22,11 @@ module top_ultrasonic_led ( .leds(leds) ); + // Module d'affichage WS2812 (optionnel, si vous souhaitez utiliser une LED RGB) + distance_ws2812_display ws2812_display_inst ( + .clk(clk), + .distance(distance), + .ws2812_dout(ws2812_dout) + ); + endmodule