当我们需要部分长短只对脉冲的个数进行计数时,可以使用这种方式
边沿检测分为上升沿检测和下降沿检测,这里主要介绍下降沿检测和仿真结果
`timescale 1ns / 1ps
//该模块给出当前memory 存储长维度的计数
module Nc_or_Ns_count(
input sys_clk,
input rst_n,
input fft_out_valid,
input [10:0] mode, //计数总长度
output [10:0] Ns_or_Nc //计数结果
);
//上升沿检测,产生单脉冲
wire pos;
reg [1:0] data_in_buffer; //移位寄存器
always@(posedge sys_clk or negedge rst_n) begin
if(!rst_n)
data_in_buffer<='d0;
else
data_in_buffer<={data_in_buffer[0],fft_out_valid};
end
//assign neg=data_in_buffer[1] & ~data_in_buffer[0]; //下降沿检测
assign pos=~data_in_buffer[1] & data_in_buffer[0];//该信号的期望波形应该是每次有拉高的
//fft_out_valid长信号给出,该信号延迟一个周期给出单个脉冲
reg [10:0] Ns_or_Nc_buffer;
always@(posedge sys_clk or negedge rst_n) begin
if(!rst_n)
Ns_or_Nc_buffer<='d0;
else if(pos) begin //检测到单脉冲就计数
Ns_or_Nc_buffer<=Ns_or_Nc_buffer+1'b1;
if(Ns_or_Nc_buffer==mode-1)
Ns_or_Nc_buffer<='dz;
end
else
Ns_or_Nc_buffer<=Ns_or_Nc_buffer;
end
assign Ns_or_Nc=Ns_or_Nc_buffer;
endmodule
testbench
`timescale 1ns / 1ps
module test_Nc_or_Ns_count();
reg sys_clk;
reg rst_n;
reg fft_out_valid;
reg [10:0] mode;
wire [10:0] Ns_or_Nc;
initial begin
sys_clk='d0;
rst_n='d0;
fft_out_valid='d0;
mode='d0;
#1000;
rst_n=1'b1;
mode='d3; //mode这个测试里给的很小
#50; //用简陋的方式实现不同长度的长脉冲
fft_out_valid<=1'b1;
#100;
fft_out_valid<=1'b0;
#100;
fft_out_valid<=1'b1;
#120;
fft_out_valid<=1'b0;
#100;
fft_out_valid<=1'b1;
#140;
fft_out_valid<=1'b0;
#1000;
$stop;
end
always #10 sys_clk=~sys_clk; //50MHz
Nc_or_Ns_count u0(
.sys_clk(sys_clk),
.rst_n(rst_n),
.fft_out_valid(fft_out_valid),
.mode(mode),
.Ns_or_Nc(Ns_or_Nc)
);
endmodule
仿真结果:
从仿真结果可以看出,在长脉冲出现之后,单脉冲会延迟一个时钟周期给出,而计数结果会延迟两个时钟周期,这一点需要注意。