恒精度频率计的Verlog可综合代码

采用时钟频率为2MHz,不同的时钟频率需要修改相应的参数。在此只给出本时钟下的程序,其他时钟下请自行修正。

module Cymometer(clk, reset, signal, FreqNs, FreqNx, Freq);

parameter clk_freq = 2_000_000;/*clk为2MHz*/

input   clk;
input   reset;
input   signal;
output  reg[20:0] FreqNs;
output  reg[31:0]FreqNx, Freq;
//============================================================
wire start;/*此信号为高电平时计数器开始计数,高电平时长1s*/
reg [20:0]CNT0;
/*产生一个门控信号,高电平有效,为了得到更快的响应速度,
此处门控信号的占空比很大,相应低电平时间很短,因此可以
使频率计大部分时间处于工作状态,可以有效提高响应速度*/
always@(posedge clk)
begin
    if(reset)
        CNT0 <= 0;
    else
        CNT0 <= CNT0 + 1;
end

assign start = ( CNT0 < (clk_freq * 3 / 4) );
//============================================================
reg CTRL;/*CTRL信号为待测信号和门控信号产生的计数器启动信号*/
always@(posedge signal)
begin
    if(reset)
        CTRL <= 0;
    else
        CTRL <= start;
end
//============================================================
//用两个计数器分别对标准信号clk和待测信号signal计数
reg [20:0]CNTs;
reg [31:0]CNTx;
/*CTRL高电平期间计数标准信号*/
always@(posedge clk)
begin
    if(reset)
        CNTs <= 0;
    else if(CTRL)
        CNTs <= CNTs + 1;
     else
          CNTs <= 0;
end
/*CTRL高电平期间计数待测信号*/
always@(posedge signal)
begin
    if(reset)
        CNTx <= 0;
    else if(CTRL)
        CNTx <= CNTx + 1;
     else
          CNTx <= 0;
end
/*CTRL下降沿输出*/
always@(negedge CTRL)
begin
    if(reset)
    begin
        FreqNs <= 0;
        FreqNx <= 0;
        Freq <= 0;
    end
    else
    begin
        FreqNs <= CNTs;
        FreqNx <= CNTx;
        Freq <= clk_freq / CNTs * CNTx;
    end
end
//============================================================
endmodule


下面是为上面的模块编写的测试平台,在Modelsim下仿真通过,因为数据量较大,建议不要使用Altera及ISE仿真。


`timescale 1ns / 1ps

module tb;

    // Inputs
    reg clk;
    reg reset;
    reg signal;

    // Outputs
    wire [20:0] FreqNs;
    wire [31:0] FreqNx;
    wire [31:0] Freq;

    // Instantiate the Unit Under Test (UUT)
    Cymometer uut (
        .clk(clk), 
        .reset(reset), 
        .signal(signal), 
        .FreqNs(FreqNs), 
        .FreqNx(FreqNx), 
        .Freq(Freq)
    );

    always #250 clk = ~clk;
    
    always #500 signal = ~signal;
    initial begin
        // Initialize Inputs
        clk = 0;
        reset = 1;
        signal = 0;

        // Wait 100 ns for global reset to finish
        #1000;
      reset = 0;
        // Add stimulus here
        
        #2_000_000_000 $stop;
    end
      
endmodule

参考原理M/T测频法。
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值