diff --git a/Semaine_6/UART_ULTRASON_COMMANDS/IP/verilog/ultrasonic_fpga.v b/Semaine_6/UART_ULTRASON_COMMANDS/IP/verilog/ultrasonic_fpga.v index c11d19e..5024891 100644 --- a/Semaine_6/UART_ULTRASON_COMMANDS/IP/verilog/ultrasonic_fpga.v +++ b/Semaine_6/UART_ULTRASON_COMMANDS/IP/verilog/ultrasonic_fpga.v @@ -32,7 +32,8 @@ module ultrasonic_fpga #( reg [2:0] state = IDLE; - localparam integer TRIG_PULSE_CYCLES = CLK_FREQ / 100_000; // 10us pulse + localparam integer TRIG_PULSE_CYCLES = CLK_FREQ / 100_000 + 5; // 10us pulse + // localparam integer DIST_DIVISOR = ((CLK_FREQ / 100) / 343) * 2; // pour conversion us -> cm localparam integer DIST_DIVISOR = (58 * CLK_FREQ) / 1_000_000; // pour conversion us -> cm localparam integer MAX_CM = 350; localparam integer TIMEOUT_CYCLES = (MAX_CM * 58 * CLK_FREQ) / 1000000; @@ -58,6 +59,10 @@ module ultrasonic_fpga #( sig_out <= 0; sig_dir <= 0; distance <= 0; + echo_counter <= 0; + distance_counter <= 0; + trig_counter <= 0; + if (start) begin state <= TRIG_HIGH; trig_counter <= 0; @@ -68,6 +73,7 @@ module ultrasonic_fpga #( TRIG_HIGH: begin sig_out <= 1; sig_dir <= 1; + if (trig_counter < TRIG_PULSE_CYCLES) begin trig_counter <= trig_counter + 1; end else begin diff --git a/Semaine_6/UART_ULTRASON_COMMANDS/IP/verilog/ultrasonic_sensor.v b/Semaine_6/UART_ULTRASON_COMMANDS/IP/verilog/ultrasonic_sensor.v index ea560c0..554c03b 100644 --- a/Semaine_6/UART_ULTRASON_COMMANDS/IP/verilog/ultrasonic_sensor.v +++ b/Semaine_6/UART_ULTRASON_COMMANDS/IP/verilog/ultrasonic_sensor.v @@ -1,95 +1,100 @@ -module ultrasonic_sensor( // Simulation of an ultrasonic sensor - input wire clk, - inout wire signal // Signal from the ultrasonic sensor +module ultrasonic_sensor( + parameter CLK_FREQ_MHZ = 27 // Clock frequency in MHz (default 27MHz) +) ( + input wire clk, // System clock + inout wire signal // Bidirectional pin for trigger and echo ); - parameter integer CLK_FREQ = 27_000_000; - reg [2:0] state = 3'd0; // State of the FSM - reg [2:0] next_state; - reg sig_dir; // 1: output, 0: input - reg [15:0] trig_counter = 0; // Counter for the trigger pulse - reg [31:0] echo_counter = 0; // Echo signal - reg valid_trig = 0; // Valid trigger signal + // Timing constants based on CLK_FREQ_MHZ + localparam CLK_PERIOD_NS = 1000 / CLK_FREQ_MHZ; // Clock period in ns + localparam TRIGGER_MIN_CYCLES = (10_000 / CLK_PERIOD_NS); // 10us minimum trigger pulse +// localparam CYCLE_TIME_CYCLES = (60_000_000 / CLK_PERIOD_NS); // 60ms cycle time + localparam CYCLE_TIME_CYCLES = (60 / CLK_PERIOD_NS); // 60ms cycle time + localparam ECHO_DELAY_CYCLES = (1000 / CLK_PERIOD_NS); // 1us delay before echo (sensor processing) - reg echo_sended = 0; // Flag to indicate if echo has been sent + // State machine states + localparam IDLE = 3'b000, + CHECK_TRIGGER = 3'b001, + ECHO_DELAY = 3'b010, + ECHO_PULSE = 3'b011, + WAIT_CYCLE = 3'b100; - reg signal_out = 0; - assign signal = sig_dir ? signal_out : 1'bz; // Assign the signal to the output if sig_dir is high, otherwise set it to high impedance + reg [2:0] state = IDLE; + reg [31:0] counter = 0; + reg signal_prev = 0; + reg [31:0] random_distance = 0; + reg [31:0] echo_cycles = 0; + reg drive_echo = 0; // Controls when model drives signal - localparam S_WAIT_TRIG = 3'd0, - S_MEASURE_TRIG = 3'd1, - S_SEND_ECHO = 3'd2; + // Calculate echo pulse width dynamically + // Speed of sound: 343 m/s = 0.0343 cm/us + // Echo duration (us) = 2 * distance (cm) / 0.0343 (cm/us) + // Convert to clock cycles: duration (us) * 1000 / CLK_PERIOD_NS + wire [31:0] echo_duration_us = (2 * random_distance * 10_000) / 343; // Echo time in us + wire [31:0] calculated_echo_cycles = (echo_duration_us * 1000) / CLK_PERIOD_NS; // Echo time in cycles - localparam integer TRIG_PULSE_CYCLES = CLK_FREQ / 100_000; // 10us pulse + // Bidirectional pin control: drive signal only during echo pulse + assign signal = drive_echo ? 1'b1 : 1'bz; + + // Main state machine + always @(posedge clk) begin + // Store previous signal value for edge detection + signal_prev <= signal; - always @(*) begin case (state) - S_WAIT_TRIG: begin - sig_dir = 0; - if (signal == 1) begin - next_state = S_MEASURE_TRIG; - end else begin - next_state = S_WAIT_TRIG; + IDLE: begin + drive_echo <= 0; + counter <= 0; + if (signal ) begin // Rising edge of trigger + random_distance <= $urandom_range(2, 400); // Generate random distance + state <= CHECK_TRIGGER; end end - S_MEASURE_TRIG: begin - sig_dir = 0; - if (valid_trig)begin - next_state = S_SEND_ECHO; + CHECK_TRIGGER: begin + counter <= counter + 1; + if (signal) begin // Trigger pulse ended + end + else begin + if (counter >= TRIGGER_MIN_CYCLES) begin + $display("HC-SR04: Random distance = %0d cm at time %0t", random_distance, $time); + echo_cycles <= calculated_echo_cycles; // Sample echo duration + state <= ECHO_DELAY; + counter <= 0; + end else begin + state <= IDLE; // Trigger too short + end end end - S_SEND_ECHO: begin - sig_dir = 1; // Mettre en sortie - - if (echo_sended) begin - echo_sended = 0; // Reset flag - next_state = S_WAIT_TRIG; - end else begin - next_state = S_SEND_ECHO; + ECHO_DELAY: begin + counter <= counter + 1; + if (counter >= ECHO_DELAY_CYCLES) begin + state <= ECHO_PULSE; + drive_echo <= 1; // Start driving signal + counter <= 0; end end - default: begin - sig_dir = 0; - next_state = S_WAIT_TRIG; + ECHO_PULSE: begin + counter <= counter + 1; + if (counter >= echo_cycles) begin + drive_echo <= 0; // Stop driving signal + state <= WAIT_CYCLE; + counter <= 0; + end end + + WAIT_CYCLE: begin + counter <= counter + 1; + if (counter >= CYCLE_TIME_CYCLES) begin + state <= IDLE; + counter <= 0; + end + end + + default: state <= IDLE; endcase end - always @(posedge clk) begin - state <= next_state; - end - - always @(posedge clk) begin - if (state == S_MEASURE_TRIG) begin - if (signal == 1) begin - trig_counter <= trig_counter + 1; - end else begin - if (trig_counter >= TRIG_PULSE_CYCLES-20) begin - valid_trig <= 1; - end else begin - valid_trig <= 0; - end - end - end - end - - reg [15:0] echo_delay_counter; - - always @(posedge clk) begin - if (state == S_SEND_ECHO) begin - if (echo_delay_counter == 5800) begin // - signal_out <= 0; - echo_sended <= 1; - end else begin - signal_out <= 1; - echo_delay_counter <= echo_delay_counter + 1; - end - end else begin - echo_delay_counter <= 0; - end - end - endmodule \ No newline at end of file diff --git a/Semaine_6/UART_ULTRASON_COMMANDS/src/verilog/top_uart_ultrason_command.v b/Semaine_6/UART_ULTRASON_COMMANDS/src/verilog/top_uart_ultrason_command.v index 1b5a4c0..009b600 100644 --- a/Semaine_6/UART_ULTRASON_COMMANDS/src/verilog/top_uart_ultrason_command.v +++ b/Semaine_6/UART_ULTRASON_COMMANDS/src/verilog/top_uart_ultrason_command.v @@ -64,21 +64,25 @@ module top_uart_ultrason_command ( always @(posedge clk) begin if (data_available) begin command <= rd_data[1:0]; - leds <= rd_data[7:2]; end else begin command <= 0; end + leds <= {~command, ~mesure_state}; end always @(posedge clk) begin // Mesure state machine case (mesure_state) IDLE: begin + if (command == 2'd1 && data_available) begin mesure_state <= ONESTART; rd_en <= 1; end else if (command == 2'd2 && data_available) begin mesure_state <= CONTINUOUSSTART; rd_en <= 1; + end else if (command == 2'd3 && data_available) begin + mesure_state <= IDLE; + rd_en <= 1; end else begin mesure_state <= IDLE; rd_en <= 0; diff --git a/Semaine_6/UART_ULTRASON_COMMANDS/tests/Python/ultrason_command.py b/Semaine_6/UART_ULTRASON_COMMANDS/tests/Python/ultrason_command.py index 2bdab1e..fdb8960 100644 --- a/Semaine_6/UART_ULTRASON_COMMANDS/tests/Python/ultrason_command.py +++ b/Semaine_6/UART_ULTRASON_COMMANDS/tests/Python/ultrason_command.py @@ -3,7 +3,7 @@ import time import struct # === Paramètres de communication === -SERIAL_PORT = "COM6" # Modifie selon ton système, ex. "/dev/ttyUSB0" sur Linux +SERIAL_PORT = "COM10" # Modifie selon ton système, ex. "/dev/ttyUSB0" sur Linux BAUDRATE = 115200 # Change si différent TIMEOUT = 2 # secondes diff --git a/Semaine_6/ULTRASON/src/verilog/hc_sr04_model.v b/Semaine_6/ULTRASON/src/verilog/hc_sr04_model.v index 97d157e..5853975 100644 --- a/Semaine_6/ULTRASON/src/verilog/hc_sr04_model.v +++ b/Semaine_6/ULTRASON/src/verilog/hc_sr04_model.v @@ -13,7 +13,8 @@ module hc_sr04_model #( // Timing constants based on CLK_FREQ_MHZ localparam CLK_PERIOD_NS = 1000 / CLK_FREQ_MHZ; // Clock period in ns localparam TRIGGER_MIN_CYCLES = (10_000 / CLK_PERIOD_NS); // 10us minimum trigger pulse - localparam CYCLE_TIME_CYCLES = (60_000_000 / CLK_PERIOD_NS); // 60ms cycle time +// localparam CYCLE_TIME_CYCLES = (60_000_000 / CLK_PERIOD_NS); // 60ms cycle time + localparam CYCLE_TIME_CYCLES = (60 / CLK_PERIOD_NS); // 60ms cycle time localparam ECHO_DELAY_CYCLES = (1000 / CLK_PERIOD_NS); // 1us delay before echo (sensor processing) // State machine states @@ -34,7 +35,7 @@ module hc_sr04_model #( // Speed of sound: 343 m/s = 0.0343 cm/us // Echo duration (us) = 2 * distance (cm) / 0.0343 (cm/us) // Convert to clock cycles: duration (us) * 1000 / CLK_PERIOD_NS - wire [31:0] echo_duration_us = (2 * random_distance * 1000) / 343; // Echo time in us + wire [31:0] echo_duration_us = (2 * random_distance * 10_000) / 343; // Echo time in us wire [31:0] calculated_echo_cycles = (echo_duration_us * 1000) / CLK_PERIOD_NS; // Echo time in cycles // Bidirectional pin control: drive sensor_pin only during echo pulse @@ -57,7 +58,9 @@ module hc_sr04_model #( CHECK_TRIGGER: begin counter <= counter + 1; - if (!sensor_pin) begin // Trigger pulse ended + if (sensor_pin) begin // Trigger pulse ended + end + else begin if (counter >= TRIGGER_MIN_CYCLES) begin $display("HC-SR04: Random distance = %0d cm at time %0t", random_distance, $time); echo_cycles <= calculated_echo_cycles; // Sample echo duration diff --git a/Semaine_6/ULTRASON/src/verilog/ultrason_driver.v b/Semaine_6/ULTRASON/src/verilog/ultrason_driver.v index 0af2250..d70e883 100644 --- a/Semaine_6/ULTRASON/src/verilog/ultrason_driver.v +++ b/Semaine_6/ULTRASON/src/verilog/ultrason_driver.v @@ -32,7 +32,8 @@ module ultrason_driver #( reg [2:0] state = IDLE; - localparam integer TRIG_PULSE_CYCLES = CLK_FREQ / 100_000; // 10us pulse + localparam integer TRIG_PULSE_CYCLES = CLK_FREQ / 100_000 + 5; // 10us pulse + // localparam integer DIST_DIVISOR = ((CLK_FREQ / 100) / 343) * 2; // pour conversion us -> cm localparam integer DIST_DIVISOR = (58 * CLK_FREQ) / 1_000_000; // pour conversion us -> cm localparam integer MAX_CM = 350; localparam integer TIMEOUT_CYCLES = (MAX_CM * 58 * CLK_FREQ) / 1000000; @@ -58,6 +59,9 @@ module ultrason_driver #( sig_out <= 0; sig_dir <= 0; distance <= 0; + echo_counter <= 0; + distance_counter <= 0; + trig_counter <= 0; if (start) begin state <= TRIG_HIGH; diff --git a/Semaine_6/ULTRASON/src/verilog/ultrasonic_fpga.v b/Semaine_6/ULTRASON/src/verilog/ultrasonic_fpga.v index c11d19e..5024891 100644 --- a/Semaine_6/ULTRASON/src/verilog/ultrasonic_fpga.v +++ b/Semaine_6/ULTRASON/src/verilog/ultrasonic_fpga.v @@ -32,7 +32,8 @@ module ultrasonic_fpga #( reg [2:0] state = IDLE; - localparam integer TRIG_PULSE_CYCLES = CLK_FREQ / 100_000; // 10us pulse + localparam integer TRIG_PULSE_CYCLES = CLK_FREQ / 100_000 + 5; // 10us pulse + // localparam integer DIST_DIVISOR = ((CLK_FREQ / 100) / 343) * 2; // pour conversion us -> cm localparam integer DIST_DIVISOR = (58 * CLK_FREQ) / 1_000_000; // pour conversion us -> cm localparam integer MAX_CM = 350; localparam integer TIMEOUT_CYCLES = (MAX_CM * 58 * CLK_FREQ) / 1000000; @@ -58,6 +59,10 @@ module ultrasonic_fpga #( sig_out <= 0; sig_dir <= 0; distance <= 0; + echo_counter <= 0; + distance_counter <= 0; + trig_counter <= 0; + if (start) begin state <= TRIG_HIGH; trig_counter <= 0; @@ -68,6 +73,7 @@ module ultrasonic_fpga #( TRIG_HIGH: begin sig_out <= 1; sig_dir <= 1; + if (trig_counter < TRIG_PULSE_CYCLES) begin trig_counter <= trig_counter + 1; end else begin diff --git a/Semaine_6/ULTRASON/tests/verilog/hc_sr04_tb.v b/Semaine_6/ULTRASON/tests/verilog/hc_sr04_tb.v index 6927fdb..81e683c 100644 --- a/Semaine_6/ULTRASON/tests/verilog/hc_sr04_tb.v +++ b/Semaine_6/ULTRASON/tests/verilog/hc_sr04_tb.v @@ -13,6 +13,7 @@ module hc_sr04_tb; // === Paramètres === localparam CLK_FREQ = 27_000_000; // 27 MHz localparam CLK_PERIOD = 37; // Période en ns (~37 ns pour 27 MHz) + localparam CLK_MS = CLK_PERIOD * 100; // Génération de l'horloge 27 MHz always #(CLK_PERIOD/2) clk = ~clk; @@ -46,7 +47,7 @@ module hc_sr04_tb; begin $display("[%0t ns] Déclenchement d'une mesure", $time); start = 1; - #(CLK_PERIOD * 2); + #CLK_PERIOD; start = 0; // Attendre que la mesure soit terminée wait(done); @@ -77,6 +78,7 @@ module hc_sr04_tb; // Test 1: Mesure unique $display("=== Test 1: Mesure unique ==="); + @(posedge clk); // Synchroniser avec l'horloge trigger_measurement(); // Supposons que hc_sr04_model simule une distance fixe, par exemple 1000 (à ajuster) check_distance(16'd1000); @@ -84,7 +86,9 @@ module hc_sr04_tb; // Test 2: Mesures multiples $display("=== Test 2: Mesures multiples ==="); repeat (3) begin - #(CLK_PERIOD * 1000); // Attendre entre mesures + #(CLK_MS * 100); // Attendre entre mesures + @(posedge clk); // Synchroniser avec l'horloge + $display("[%0t ns] Déclenchement d'une nouvelle mesure", $time); trigger_measurement(); check_distance(16'd1000); end