【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 天前
PCIe 授时卡原理及应用
运维·服务器·windows·单片机·嵌入式硬件·fpga开发
落chen1 天前
基于Vivado的FIFO-IP核-强化篇
fpga开发
公众号:fuwuqiBMC1 天前
(转自“服务器BMC”)服务器BMC芯片——AST1840
运维·服务器·fpga开发
国科安芯1 天前
还是4位?ASC8T245S 与 ASC4T245S 的双向电平转换选型实战
单片机·嵌入式硬件·物联网·fpga开发·机器人·云计算
Rambo.xia2 天前
接口协议避坑 · 第5篇:多器件级联时序踩坑实录
fpga开发
紫霄芯语2 天前
观察者模式在FPGA中断系统的实战重构
观察者模式·fpga开发·重构
ARM+FPGA+AI工业主板定制专家3 天前
国产化RK3576+FPGA架构|晶圆传输机器人高速定位+AI瑕疵检测一体化方案
fpga开发·架构·机器人·嵌入式·fpga·工控·机器人运控
Eloudy4 天前
FPGA (QSFP28 + CMAC US+ RoCEv2) 与 Ubuntu22 + Mellanox 网卡直连分析
fpga开发
szxinmai主板定制专家4 天前
RK3568+FPGA高速并行采集|半导体探针测试设备多通道同步数据采集系统设计
人工智能·嵌入式硬件·计算机视觉·fpga开发
ARM|X86+FPGA工业主板厂家5 天前
RK3588+FPGA+EtherCAT异构架构解析|工业场景如何同时保住AI算力与微秒级运动实时性
人工智能·fpga开发·架构