verilog奇怪的频率统计代码
想要实现一个频率统计
首先生成一个1hz的信号用于重置计数器
always @(posedge clk or negedge rst_n)
begin
if(!rst_n)
begin
cnt_1hz <= 32'd0;
clk_1hz <= 1'd0;
end
else if(cnt_1hz == 32'd99999999)
begin
cnt_1hz <= 32'd0;
clk_1hz <= ~clk_1hz;
end
else
cnt_1hz <= cnt_1hz + 32'd1;
end
pclk是一个大概85MHz左右的稳定信号,我想统计这个信号的实际频率。
我写了如下代码,但是实际运行发现pclk_freq的值非常大,已经达到了G级,结果明显是错的
always @(posedge pclk or posedge clk_1hz or negedge rst_n)
begin
if(!rst_n)
begin
pclk_cnt <= 32'd0;
pclk_freq <= 32'd0;
pclk_rst <= 32'd0;
end
else if(pclk)
if(pclk_rst)
begin
pclk_cnt <= 32'd1;
pclk_rst <= 1'd0;
end
else
pclk_cnt <= pclk_cnt + 1'b1;
else if(clk_1hz)
begin
pclk_freq <= pclk_cnt;
pclk_rst <= 1'd1;
end
end
我调整了代码的elseif分支判断顺序
always @(posedge pclk or posedge clk_1hz or negedge rst_n)
begin
if(!rst_n)
begin
pclk_cnt <= 32'd0;
pclk_freq <= 32'd0;
pclk_rst <= 32'd0;
end
else if(clk_1hz)
begin
pclk_freq <= pclk_cnt;
pclk_rst <= 1'd1;
end
else if(pclk)
if(pclk_rst)
begin
pclk_cnt <= 32'd1;
pclk_rst <= 1'd0;
end
else
pclk_cnt <= pclk_cnt + 1'b1;
end
也就是说我把判断clk_1hz上升沿的elseif判断提前了,这时pclk_freq的结果是准确的,可是仍然有一个小问题
我是用nios2程序去读这个pclk_freq的,读几十次总有那么一次是错的,结果远小于85M大概只有16M左右的样子。
我想知道的是我上面两种不同的elseif写法为什么会导致频率统计错误呢?是因为elseif分支太长导致信号传递比被统计的信号慢?这种情况是叫时序不满足吗?
另外我最后改进的这个代码为什么偶尔也会统计错误呢?
统计频率还有没有更好的写法呢?求高手赐教!