module ultrasonic_sensor(               // Simulation of an ultrasonic sensor
    input wire clk,               
    inout wire signal                  // Signal from the ultrasonic sensor
);
    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

    reg echo_sended = 0;                    // Flag to indicate if echo has been sent

    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

    localparam  S_WAIT_TRIG       = 3'd0,
                S_MEASURE_TRIG    = 3'd1,
                S_SEND_ECHO       = 3'd2;

    localparam integer TRIG_PULSE_CYCLES = CLK_FREQ / 100_000; // 10us pulse

    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;
                end
            end

            S_MEASURE_TRIG: begin
                sig_dir = 0; 
                if (valid_trig)begin
                    next_state = S_SEND_ECHO;
                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;
                end
            end

            default: begin
                sig_dir = 0; 
                next_state = S_WAIT_TRIG;
            end
        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) 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