SystemVerilogHDL简易频率计设计

本文介绍了如何使用SystemVerilog(SV)编写一个模块来自动检测输入信号的频率。通过捕捉连续的下降沿并计算周期,可以实现频率的精确测量。在50MHz时钟下,设计能够检测到MHz级别的频率误差,并在每个下降沿时显示当前的IO频率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

背景

最近写一个多路信号发生器的时候,发现用肉眼观察波形信号很麻烦,想着用SV写一个自动检测频率的设计让其自动输出。

设计思路

  捕捉连续的两个下降沿,然后根据cnt计数值计算频率,误差范围测量Mhz以内的方波时较小。
因为设计思路较为简单,笔者在这就不放出状态机的FSM了

代码

module PWM_catch(
    input clk_50m,
    input rstn,
    
    input io
    );
    
reg  io_d0;
reg  io_d1;
wire catch_negedge;    
    
int frequency_cycle;
int frequency_cnt;        
int frequency_io;    
    
always@(posedge clk_50m or negedge rstn) begin
    if(!rstn) begin
        io_d0 = 1'b0;
        io_d1 = 1'b0;
    end
    else begin
        io_d0 <= io;
        io_d1 <= io_d0;
    end
end    

assign  catch_negedge = io_d1 & (!io_d0);

always@(posedge clk_50m or negedge rstn) begin
    if(!rstn) begin
        frequency_cycle <= 32'd0;
        frequency_cnt <= 32'd0;
    end
    else if(catch_negedge) begin
        frequency_cycle <= frequency_cnt - 32'd1;
        frequency_cnt <= 32'd0;
    end
    else begin
        frequency_cnt <= frequency_cnt + 32'd1;
    end
end

always@(posedge clk_50m or negedge rstn) begin
    if(!rstn) begin
        frequency_io <= 32'd0;
    end
    else if(catch_negedge)begin
        frequency_io = 1000000000/(frequency_cnt*20);
        $display("IO frequency is %f",frequency_io);
    end
    else begin
    end
end
    
endmodule

仿真波形

笔者在此只简单的;写了500hz的频率测试,读者可以根据自己需求进行修改

笔者在此只简单的;写了500hz的频率测试,读者可以根据自己需求进行修改
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值