60 lines
1.8 KiB
Verilog
60 lines
1.8 KiB
Verilog
`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; // 当前时钟周期计数
|
||
reg [31:0] target_cnt; // 当前窗口所需时钟周期数
|
||
|
||
// 脉冲计数(宽度与输出一致,防止溢出)
|
||
reg [23:0] pulse_cnt;
|
||
|
||
// 标志:是否正在计算新的 target_cnt(避免组合逻辑环路)
|
||
reg calc_done;
|
||
|
||
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
|
||
|
||
// 主控制逻辑
|
||
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 ;
|
||
// 窗口计数结束条件:当前计数值到达 target_cnt
|
||
if (window_cnt >= target_cnt) begin
|
||
cnt_out <= pulse_cnt;
|
||
vld_out <= 1'b1;
|
||
// 复位窗口计数器与脉冲计数器,并触发重新计算目标值
|
||
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 |