`timescale 1ns / 1ps

module pulse_cnt #(
    parameter CLK_FREQ = 50_000_000          
) (
    input  wire        clk,                  
    input  wire        rst_n,                
    input  wire        sig_in,               
    input  wire [23:0] win_us,               
    output reg  [23:0] cnt_out,             
    output reg         vld_out               
);


    reg [31:0] window_cnt;      // Current clock cycle count
    reg [31:0] target_cnt;      // Required clock cycles for current measurement window

    // Pulse counter (width matches output to prevent overflow)
    reg [23:0] pulse_cnt;

 

    reg sig_sync1, sig_sync2, sig_sync3;
    wire sig_rise = sig_sync2 & ~sig_sync3;  

    always @(posedge clk) begin
        sig_sync1 <= sig_in;
        sig_sync2 <= sig_sync1;
        sig_sync3 <= sig_sync2;
    end

    // Main control logic
    always @(posedge clk or negedge rst_n) begin
        if (!rst_n) begin
            window_cnt <= 0;
            pulse_cnt  <= 0;
            cnt_out    <= 0;
            vld_out    <= 0;
            target_cnt <= 24'd50_000;

        end else begin
            vld_out <= 1'b0;  
            target_cnt <= ( {40'd0, win_us} * CLK_FREQ) / 1_000_000 ;                 
            // Window count end condition: current count reaches target_cnt
            if (window_cnt >= target_cnt) begin
                cnt_out <= pulse_cnt;
                vld_out <= 1'b1;
                // Reset window counter and pulse counter, trigger target value recalculation
                window_cnt <= 0;
                pulse_cnt  <= 0;
            end else begin
                window_cnt <= window_cnt + 1;
                if (sig_rise)
                    pulse_cnt <= pulse_cnt + 1;
            end
        end
    end

endmodule