`timescale 1ns/1ns module pulse_detc#(parameter WIDTH = 32) ( input clk , input rst , input pulse_in ,//脉冲默认最后是低电平 output reg [WIDTH-1:0] period_max ,//最大周期值 output reg [WIDTH-1:0] period_min ,//最小周期值 output reg [WIDTH-1:0] pulse_max ,//最大高电平持续时间 output reg [WIDTH-1:0] pulse_min ,//最小高电平持续时间 output reg [WIDTH-1:0] period_cur ,//上一次的周期结果 output reg [WIDTH-1:0] pulse_cur //上一次的高电平结果 ); reg [WIDTH-1:0] cnt;//相当于计时器 //都是从上升沿开始计数 wire pulse_in_1p,pulse_in_n1p; reg [3:0] pulse_reg ; //打拍 always @(posedge clk ) pulse_reg[3:0] <= #1 {pulse_reg[2:0],pulse_in}; assign pulse_in_1p = (~pulse_reg[3])& pulse_reg[2];//脉冲上升沿 assign pulse_in_n1p = (~pulse_reg[2])& pulse_reg[3];//脉冲下升沿 reg pulse_in_1p_1d,pulse_in_n1p_1d;//延时1拍 always @(posedge clk or posedge rst) begin if(rst) {pulse_in_1p_1d,pulse_in_n1p_1d} <=#1 2'b00; else {pulse_in_1p_1d,pulse_in_n1p_1d} <=#1 {pulse_in_1p,pulse_in_n1p}; end //复位后到第一个pulse_in_1p之间应该忽略不统计 //如果复位期间脉冲是0,那么上升沿先来,反之下降沿先来。都兼容 reg no_pulse_in;//第一个脉冲上升沿还没来,算高电平时间用 always @(posedge clk or posedge rst) begin if(rst) no_pulse_in <=#1 1'b1; else if(pulse_in_1p) no_pulse_in <=#1 1'b0 ; end reg no_pulse_in2;//第2个脉冲上升沿还没来,算周期用得上 always @(posedge clk or posedge rst) begin if(rst) no_pulse_in2 <=#1 1'b1; else if(pulse_in_1p&(no_pulse_in==1'b0)) no_pulse_in2 <=#1 1'b0 ; end always @(posedge clk or posedge rst) begin if(rst) cnt <=#1 32'b0; else if(pulse_in_1p) cnt <=#1 32'b1 ; else if (no_pulse_in==1'b0) cnt <=#1 1'b1 +cnt; end always @(posedge clk or posedge rst) begin if(rst) pulse_cur <=#1 32'h0; else if(pulse_in_n1p) pulse_cur <=#1 cnt; end always @(posedge clk or posedge rst) begin if(rst) period_cur <=#1 32'h0; else if(pulse_in_1p & (~no_pulse_in) ) period_cur <=#1 cnt; end //max/min always @(posedge clk or posedge rst) begin if(rst) pulse_max <=#1 32'b0; else if ((pulse_in_n1p_1d==1'b1)&(pulse_max<pulse_cur)) pulse_max <=#1 pulse_cur; end always @(posedge clk or posedge rst) begin if(rst) pulse_min <=#1 32'hFFFFFFFF; else if((pulse_in_n1p_1d==1'b1)&(pulse_min>pulse_cur)) pulse_min <=#1 pulse_cur; end always @(posedge clk or posedge rst) begin if(rst) period_min <=#1 32'hFFFFFFFF; else if( (~no_pulse_in2)&&pulse_in_1p_1d && (period_min>period_cur)) period_min <=#1 period_cur; end always @(posedge clk or posedge rst) begin if(rst) period_max <=#1 32'b0; else if ( pulse_in_1p_1d && (period_max<period_cur) ) period_max <=#1 period_cur; end endmodule