【FPGA】频率计(等精度测量法)

等精度测量法的误差来自于标准时钟信号

复位信号的作用是给数据赋初值,还有一个是被测时钟信号

顶层模块框图绘制

子模块主要分为两大块,第一个是通过等精度测量法对频率进行测量。第二是将测量结果进行显示。

等精度测量子模块设计,内部需要一个IP核来产生标准时钟信号。

为什么要产生标准时钟信号

数码管子模块设计

系统框图

在整个1s的时间内拉高我们的软件闸门,软件闸门实际时间是1.5s,有0.25用来拉低电平和计算

因为使用的是时序逻辑,所以会延后一个周期。

这里除以20ns是因为50MHz的时钟

0.25s换算成ns单位,就是乘一个十的九次方,然后除以我们的时钟。

这里设置一个IP核来产生标准时钟信号。

IP核模版文件应用。

复制代码
`timescale  1ns/1ns
////////////////////////////////////////////////////////////////////////
// Author        : EmbedFire
// 实验平台: 野火FPGA系列开发板
// 公司    : http://www.embedfire.com
// 论坛    : http://www.firebbs.cn
// 淘宝    : https://fire-stm32.taobao.com
////////////////////////////////////////////////////////////////////////

module  freq_meter_calc
(
    input   wire            sys_clk     ,   //系统时钟,频率50MHz
    input   wire            sys_rst_n   ,   //复位信号,低电平有效
    input   wire            clk_test    ,   //待检测时钟

    output  reg     [33:0]  freq            //待检测时钟频率

);
//********************************************************************//
//****************** Parameter And Internal Signal *******************//
//********************************************************************//
//parameter define
parameter   CNT_GATE_S_MAX  =   28'd74_999_999  ,   //软件闸门计数器计数最大值
            CNT_RISE_MAX    =   28'd12_500_000  ;   //软件闸门拉高计数值
parameter   CLK_STAND_FREQ  =   28'd100_000_000 ;   //标准时钟时钟频率
//wire  define
wire            clk_stand           ;   //标准时钟,频率100MHz
wire            gate_a_fall_s       ;   //实际闸门下降沿(标准时钟下)
wire            gate_a_fall_t       ;   //实际闸门下降沿(待检测时钟下)

//reg   define
reg     [27:0]  cnt_gate_s          ;   //软件闸门计数器
reg             gate_s              ;   //软件闸门
reg             gate_a              ;   //实际闸门
reg             gate_a_stand        ;   //实际闸门打一拍(标准时钟下)
reg             gate_a_test         ;   //实际闸门打一拍(待检测时钟下)
reg     [47:0]  cnt_clk_stand       ;   //标准时钟周期计数器
reg     [47:0]  cnt_clk_stand_reg   ;   //实际闸门下标志时钟周期数
reg     [47:0]  cnt_clk_test        ;   //待检测时钟周期计数器
reg     [47:0]  cnt_clk_test_reg    ;   //实际闸门下待检测时钟周期数
reg             calc_flag           ;   //待检测时钟时钟频率计算标志信号
reg     [63:0]  freq_reg            ;   //待检测时钟频率寄存
reg             calc_flag_reg       ;   //待检测时钟频率输出标志信号

//********************************************************************//
//***************************** Main Code ****************************//
//********************************************************************//
//cnt_gate_s:软件闸门计数器
always@(posedge sys_clk or negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        cnt_gate_s  <=  28'd0;
    else    if(cnt_gate_s == CNT_GATE_S_MAX)
        cnt_gate_s  <=  28'd0;
    else
        cnt_gate_s  <=  cnt_gate_s + 1'b1;

//gate_s:软件闸门
always@(posedge sys_clk or negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        gate_s  <=  1'b0;
    else    if((cnt_gate_s>= CNT_RISE_MAX)
                && (cnt_gate_s <= (CNT_GATE_S_MAX - CNT_RISE_MAX)))
        gate_s  <=  1'b1;
    else
        gate_s  <=  1'b0;

//gate_a:实际闸门
always@(posedge clk_test or negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        gate_a  <=  1'b0;
    else
        gate_a  <=  gate_s;

//cnt_clk_stand:标准时钟周期计数器,计数实际闸门下标准时钟周期数
always@(posedge clk_stand or negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        cnt_clk_stand   <=  48'd0;
    else    if(gate_a == 1'b0)
        cnt_clk_stand   <=  48'd0;
    else    if(gate_a == 1'b1)
        cnt_clk_stand   <=  cnt_clk_stand + 1'b1;

//cnt_clk_test:待检测时钟周期计数器,计数实际闸门下待检测时钟周期数
always@(posedge clk_test or negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        cnt_clk_test    <=  48'd0;
    else    if(gate_a == 1'b0)
        cnt_clk_test    <=  48'd0;
    else    if(gate_a == 1'b1)
        cnt_clk_test    <=  cnt_clk_test + 1'b1;

//gate_a_stand:实际闸门打一拍(标准时钟下)
always@(posedge clk_stand or negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        gate_a_stand    <=  1'b0;
    else
        gate_a_stand    <=  gate_a;

//gate_a_fall_s:实际闸门下降沿(标准时钟下)
assign  gate_a_fall_s = ((gate_a_stand == 1'b1) && (gate_a == 1'b0))
                        ? 1'b1 : 1'b0;

//cnt_clk_stand_reg:实际闸门下标志时钟周期数
always@(posedge clk_stand or negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        cnt_clk_stand_reg   <=  32'd0;
    else    if(gate_a_fall_s == 1'b1)
        cnt_clk_stand_reg   <=  cnt_clk_stand;

//gate_a_test:实际闸门打一拍(待检测时钟下)
always@(posedge clk_test or negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        gate_a_test <=  1'b0;
    else
        gate_a_test <=  gate_a;

//gate_a_fall_t:实际闸门下降沿(待检测时钟下)
assign  gate_a_fall_t = ((gate_a_test == 1'b1) && (gate_a == 1'b0))
                        ? 1'b1 : 1'b0;

//cnt_clk_test_reg:实际闸门下待检测时钟周期数
always@(posedge clk_test or negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        cnt_clk_test_reg   <=  32'd0;
    else    if(gate_a_fall_t == 1'b1)
        cnt_clk_test_reg   <=  cnt_clk_test;

//calc_flag:待检测时钟时钟频率计算标志信号
always@(posedge sys_clk or negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        calc_flag   <=  1'b0;
    else    if(cnt_gate_s == (CNT_GATE_S_MAX - 1'b1))
        calc_flag   <=  1'b1;
    else
        calc_flag   <=  1'b0;

//freq_reg:待检测时钟信号时钟频率寄存
always@(posedge sys_clk or negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        freq_reg    <=  64'd0;
    else    if(calc_flag == 1'b1)
        freq_reg    <=  (CLK_STAND_FREQ * cnt_clk_test_reg / cnt_clk_stand_reg);

//calc_flag_reg:待检测时钟频率输出标志信号
always@(posedge sys_clk or negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        calc_flag_reg   <=  1'b0;
    else
        calc_flag_reg   <=  calc_flag;

//freq:待检测时钟信号时钟频率
always@(posedge sys_clk or negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        freq    <=  34'd0;
    else    if(calc_flag_reg == 1'b1)
        freq    <=  freq_reg[33:0];

//********************************************************************//
//*************************** Instantiation **************************//
//********************************************************************//
//---------- clk_gen_inst ----------
clk_gen clk_gen_inst
(
    .reset    (~sys_rst_n ),
    .clk_in1  (sys_clk    ),
     
    .clk_out1 (clk_stand  )
);

endmodule

IP核需要全局缓冲

IP核的复位信号是高电平有效

复制代码
`timescale  1ns/1ns
////////////////////////////////////////////////////////////////////////
// Author        : EmbedFire
// 实验平台: 野火FPGA系列开发板
// 公司    : http://www.embedfire.com
// 论坛    : http://www.firebbs.cn
// 淘宝    : https://fire-stm32.taobao.com
////////////////////////////////////////////////////////////////////////

module  freq_meter
(
    input   wire            sys_clk     ,   //系统时钟,频率50MHz
    input   wire            sys_rst_n   ,   //复位信号,低电平有效
    input   wire            clk_test    ,   //待检测时钟

    output  wire            clk_out         //生成的待检测时钟
);

//wire  define
(* keep = "true" *)  wire    [33:0]  freq    ;   //计算得到的待检测信号时钟频率

//********************************************************************//
//*************************** Instantiation **************************//
//********************************************************************//
//---------- clk_gen_test_inst ----------
clk_test_gen    clk_gen_test_inst
(
    .reset     (~sys_rst_n ),  //复位端口,高电平有效
    .clk_in1   (sys_clk    ),  //输入系统时钟

    .clk_out1  (clk_out    )   //输出生成的待检测时钟信号
);

//------------- freq_meter_calc_inst --------------
freq_meter_calc freq_meter_calc_inst
(
    .sys_clk    (sys_clk    ),   //系统时钟,频率50MHz
    .sys_rst_n  (sys_rst_n  ),   //复位信号,低电平有效
    .clk_test   (clk_test   ),   //待检测时钟

    .freq       (freq       )    //待检测时钟频率
);

ila_0 ila_inst (
	.clk        (sys_clk    ), // input wire clk

	.probe0     (freq       )  // input wire [33:0] probe0
);

endmodule

这里主要是为了频率测量模块

但是使用除法会消耗比较多的逻辑资源

相关推荐
坏孩子的诺亚方舟1 天前
FPGA系统架构设计实践15_高云Arora V系列时钟体系
fpga开发·系统架构
FPGA小徐1 天前
入门 CNN 结构全解析|从流程图理论到 FPGA Verilog 硬件实现(含习题带讲解)
fpga开发
FPGA小徐1 天前
FPGA 数字信号处理:并行 FIR 与串行滤波器设计原理、对比与完整 Verilog 实现
fpga开发
Saniffer_SH2 天前
【高清视频】Gen6 服务器还没到,Gen6 SSD 怎么测?Emily 现场演示三种测试环境
人工智能·驱动开发·测试工具·缓存·fpga开发·计算机外设·压力测试
zlinear数据采集卡2 天前
双核架构深度解析:ARM+FPGA如何让数据采集卡实现500Ksps高性能?
arm开发·fpga开发·架构
9527华安2 天前
FPGA实现GTH Transceivers Wizard传输2路视频,基于aurora 8b10b编解码架构,提供4套工程源码和技术支持
fpga开发·gth·aurora 8b10b·transceivers
FPGA小徐3 天前
FPGA 数字信号处理(二):并行 FIR 滤波器的 Verilog 全流程设计与实现
fpga开发
国科安芯3 天前
基于AS32S601ZIT2型抗辐照MCU的商业航天卫星姿态确定与控制系统研究
单片机·嵌入式硬件·安全·fpga开发·架构·risc-v
ALINX技术博客3 天前
【黑金云课堂】FPGA技术教程FPGA基础:I2C 总线通信技术
fpga开发·i2c
Hello-FPGA3 天前
Xilinx KU040 FPGA Camera Link 图像采集
c++·fpga开发