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

2008-12-10 15:14 2382 7 7 分类: FPGA/CPLD
采用时钟频率为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测频法。
PARTNER CONTENT

文章评论0条评论)

登录后参与讨论
EE直播间
更多
我要评论
0
7
关闭 站长推荐上一条 /3 下一条