`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 [31:0] win_time, 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 <= win_time ; // 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