thermometer_digital/spi_thermometer_digital/rtl/therm/pulse_cnt.v

59 lines
1.7 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; // 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