基于FPGA的频率计
1 简介
频率计又称为频率计数器,是一种专门对被测信号频率进行测量的电子测量仪器。
2 传统测量法
传统测量法有两种:周期测量法 和 频率测量法。
2.1 周期测量法
- 原理:先测出被测信号的周期 TTT,然后根据频率 f=1Tf=\frac{1}{T}f=T1 求出被测信号的频率。
- 实现方法:数一个被测信号的周期内有多少个基准时钟,用基准时钟的总周期数来代替被测信号的周期 TTT。
误差:被测信号和基准时钟存在一定的错位 △t△t△t。但假如被测信号的频率比较低,脉冲宽度很宽,当基准时钟频率很低,与被测时钟频率相差较大时,相对误差比较小。
周期测量法适合低频信号频率测量。
2.2 频率测量法
- 原理:在时间 ttt 内对被测信号的脉冲数 NNN 进行计数,然后求出单位时间的脉冲数即为被测信号的频率。
- 实现方法:在基准时钟的时间 ttt 内,数有多少个被测信号的脉冲。脉冲数除以 ttt 即为被测信号的频率。
误差:被测信号和基准时钟存在一定的错位。但假如被测信号的频率比较高,每个脉冲宽度很窄,当采样宽度足够宽时,误差就会比较小。
频率测量法适合高频信号频率测量。
3 等精度测量法
3.1 原理:
图中,gategategate 信号为门控信号,它的持续时间 GateGateGate_timetimetime 为整数倍的被测信号周期。clkclkclk _ fxf_xfx为被测信号(公式中表示被测信号频率),clkclkclk _ fsf_sfs为基准时钟(公式中表示基准时钟信号频率)。
由:
被测信号周期个数×被测信号周期长度被测信号周期个数 × 被测信号周期长度被测信号周期个数×被测信号周期长度
=基准时钟周期个数×基准时钟周期长度= 基准时钟周期个数 × 基准时钟周期长度=基准时钟周期个数×基准时钟周期长度
=Gate= Gate=Gate_timetimetime
可以推导出最终被测信号频率的计算公式:
clkclkclk _ fxfxfx ===clk−fsfs−cnt⋅\frac{clk-fs}{fs-cnt}·fs−cntclk−fs⋅ fxfxfx _ cntcntcnt
误差:只会差一个基准时钟周期。只要 GateGateGate_timetimetime 足够大,相对误差就可以忽略。
3.2 代码实现
顶层设计模块:
module top_cymometer(//system clockinput sys_clk , // 时钟信号(系统时钟,50MHz)input sys_rst_n, // 复位信号input clk_fx , // 被测时钟output [7:0] led0,output [7:0] led1,output [7:0] led2,output [7:0] led3,output [63:0]data_fx
);//parameter define
parameter CLK_FS = 26'd50000000; // 基准时钟频率值gate//生成门控信号
(.clk_fs (sys_clk ), // 基准时钟信号.rst_n (sys_rst_n), // 复位信号//cymometer interface.clk_fx (clk_fx ), //待测信号.gate(gate ) , //门控信号.gate_fs(gate_fs) // 同步到基准时钟的门控信号);pexg//边沿捕获
(.clk_fs (sys_clk ), // 基准时钟信号.rst_n (sys_rst_n), // 复位信号.gate(gate ) , //门控信号.gate_fs(gate_fs), // 同步到基准时钟的门控信号.clk_fx (clk_fx), //待测信号.neg_gate_fs(neg_gate_fs),.neg_gate_fx(neg_gate_fx));cnt (//system clock.clk_fs (sys_clk ), // 基准时钟信号.rst_n (sys_rst_n), // 复位信号//cymometer interface.clk_fx (clk_fx ), //待测信号.gate(gate ) ,//门控信号.gate_fs(gate_fs) ,// 同步到基准时钟的门控信号.neg_gate_fs(neg_gate_fs),.neg_gate_fx(neg_gate_fx),.fs_cnt(fs_cnt) , // 门控时间内基准时钟的计数值.fx_cnt(fx_cnt) , // 门控时间内被测时钟的计数值 .data_fx_temp(data_fx)
);
endmodule
gate模块:产生周期是待测信号周期整数倍(代码中为5000倍)的门信号gate
module gate
(input clk_fs , // 基准时钟信号input rst_n , // 复位信号//cymometer interfaceinput clk_fx ,//待测信号output reg gate , //门控信号output reg gate_fs // 同步到基准时钟的门控信号);localparam GATE_TIME = 16'd5_000; // 门控时间设置
reg [15:0] gate_cnt ; // 门控计数reg gate_fs_r ; // 用于同步gate信号的寄存器//门控信号计数器,使用被测时钟计数
always @(posedge clk_fx or negedge rst_n) beginif(!rst_n)gate_cnt <= 16'd0; else if(gate_cnt == GATE_TIME + 5'd20)gate_cnt <= 16'd0;elsegate_cnt <= gate_cnt + 1'b1;
end//门控信号,拉高时间为GATE_TIME个实测时钟周期
always @(posedge clk_fx or negedge rst_n) beginif(!rst_n)gate <= 1'b0;else if(gate_cnt < 4'd10)gate <= 1'b0; else if(gate_cnt < GATE_TIME + 4'd10)gate <= 1'b1;else if(gate_cnt <= GATE_TIME + 5'd20)gate <= 1'b0;else gate <= 1'b0;
end//将门控信号同步到基准时钟下
always @(posedge clk_fs or negedge rst_n) beginif(!rst_n) begingate_fs_r <= 1'b0;gate_fs <= 1'b0;endelse begingate_fs_r <= gate;gate_fs <= gate_fs_r;end
end
endmodule
pexg模块:用来捕获gate信号和基准时钟信号的低电平
module pexg
(input clk_fs , // 基准时钟信号input rst_n , // 复位信号input clk_fx , input gate,input gate_fs , output neg_gate_fs,output neg_gate_fx);
reg gate_fs_d0 ; // 用于采集基准时钟下gate下降沿
reg gate_fs_d1 ; //
reg gate_fx_d0 ; // 用于采集被测时钟下gate下降沿
reg gate_fx_d1 ; //
//wire define//边沿检测,捕获信号下降沿
assign neg_gate_fs = gate_fs_d1 & (~gate_fs_d0);
assign neg_gate_fx = gate_fx_d1 & (~gate_fx_d0);//打拍采门控信号的下降沿(被测时钟)
always @(posedge clk_fx or negedge rst_n) beginif(!rst_n) begingate_fx_d0 <= 1'b0;gate_fx_d1 <= 1'b0;endelse begingate_fx_d0 <= gate;gate_fx_d1 <= gate_fx_d0;end
end//打拍采门控信号的下降沿(基准时钟)
always @(posedge clk_fs or negedge rst_n) beginif(!rst_n) begingate_fs_d0 <= 1'b0;gate_fs_d1 <= 1'b0;endelse begingate_fs_d0 <= gate_fs;gate_fs_d1 <= gate_fs_d0;end
end
endmodule
cnt模块:用来计数,得到 fsfsfs _ cntcntcnt 和 fxfxfx _ cntcntcnt
module cnt#(parameter CLK_FS = 26'd50_000_000,// 基准时钟频率parameter MAX = 10'd64) // 定义数据位宽 ( //system clockinput clk_fs , // 时钟信号input rst_n , // 复位信号//cymometer interfaceinput clk_fx , // 待测信号input gate, // 门控信号(与待测时钟同步)input gate_fs, // 与基准时钟同步的门控信号input neg_gate_fx,//input neg_gate_fs,//output reg [MAX-1:0] fs_cnt , //门控时间内基准时钟信号的个数 output reg [MAX-1:0] fx_cnt , // 门控时间内待测信号的个数output reg [MAX-1:0] data_fx_temp // 待测信号的频率值
);reg [MAX-1:0] fs_cnt_temp ; // fs_cnt 计数
reg [MAX-1:0] fx_cnt_temp ; // fx_cnt 计数//门控时间内待测信号的计数,设置的为5000个,这里重新计数,只是用于检验信号是否正确
always @(posedge clk_fx or negedge rst_n) beginif(!rst_n) beginfx_cnt_temp <= 32'd0;fx_cnt <= 32'd0;endelse if(gate)beginfx_cnt_temp <= fx_cnt_temp + 1'b1;end else if(neg_gate_fx) beginfx_cnt_temp <= 32'd0;fx_cnt <= fx_cnt_temp;end
end//门控时间内基准时钟的计数
always @(posedge clk_fs or negedge rst_n) beginif(!rst_n) beginfs_cnt_temp <= 32'd0;fs_cnt <= 32'd0;endelse if(gate_fs)beginfs_cnt_temp <= fs_cnt_temp + 1'b1;endelse if(neg_gate_fs) beginfs_cnt_temp <= 32'd0;fs_cnt <= fs_cnt_temp;end
end
//计算待测信号的频率值
always @(posedge clk_fs or negedge rst_n) beginif(!rst_n) begindata_fx_temp <= 64'd0;endelse if(gate_fs == 1'b0)data_fx_temp <=CLK_FS*fx_cnt/fs_cnt;
endendmodule
RTL视图:
3.4 实际测量
按照DE0手册分配管脚
(注意:Quartus 18.1中没有DE0设备Cyclone III EP3C16F484,旧版Quartus 9.1中有,于是重新下载9.1版本。。)
分配管脚:
分配完成后,重新运行程序,然后将程序加载在开发板上。
将电脑、开发板和信号发生器连接:
100Hz:
500Hz:
1kHz:
signaltap结果:
10kHz:
1MHz:
出现了误差。
基于FPGA的频率计相关推荐
- 【频率计】基于FPGA的频率计设计
利用Altera公司的FPGA器件为主控器:在软件上,采用VHDL硬件描述语言编程,再MAXPLUSII中开发,极大地减少了硬件资源的占用.该数字频率计的lHz-10MHz输入被测脉冲信号具有频率测量 ...
- 基于FPGA的频率计设计
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言 一.频率计是什么 二.使用步骤 1.测量方法 2.测周方法: 3.系统框图 总结 前言 所谓"频率" ...
- CASE_02 基于FPGA的数字钟万年历
该系类博客序言和资源简介可浏览该博客:PREFACE FPGA经典案例序言 快速了解该系列博客的内容与可用 资源. 目录 1 简介 2 数字钟计数方案 2.1 计数方案一 2.2 计 ...
- 基于FPGA低频方波测量-频率与占空比
题目要求 设计基于FPGA的低频方波频率.占空比测量仪.实时测量输入方波信号的频率与占空比. 指标要求 1) 输入方波频率1Hz~1kHz:幅度VH=3V, VL=0V 2) 测量误差优于10-4:显 ...
- CASE_05 基于FPGA的DDS信号发生器
该系类博客序言和资源简介可浏览该博客:PREFACE FPGA经典案例序言 快速了解该系列博客的内容与可用 资源. 目录 1 简介 2 DDS原理与方案 2.1 方案一:基于CORD ...
- CASE_03 基于FPGA的等精度数字频率计
该系类博客序言和资源简介可浏览该博客:PREFACE FPGA经典案例序言 快速了解该系列博客的内容与可用 资源. 目录 1. 简介 2.数字频率计的基本原理 2.1 数字频率计的设 ...
- 基于FPGA的简易数字频率计+上板测试(小梅哥AC620FPGA开发板)
基于FPGA的简易数字频率计+上板测试(小梅哥AC620FPGA开发板 目录 主要架构 1.计数模块 2.数码显示模块 3.控制信号模块 4.分频模块 例化模块 上板测试图 附:74HC595移位寄存 ...
- 基于FPGA实现的MobileNet V1,FPGA深度学习加速器设计 CNN Accelerators based on FPGAs
Automatic Generation of Multi-precision Multi-arithmetic CNN Accelerators for FPGAs 最近arXiv上挂出来一篇文章, ...
- 基于FPGA系统合成两条视频流实现3D视频效果
目录 1.概述 2.时钟架构 3.带锁定视频解码器的同步系统 4.异步视频系统 4.1.时钟三态模式 4.2.两条视频流中的数据对齐误差 4.3.行锁定摄像机对齐误差 4.4.不同的连接长度 4.5. ...
最新文章
- yolor 测试笔记
- 求高精度幂(java)
- 338. Counting Bits_比特位计数_简单动态规划
- mysql access 2017_如何把Access的数据导入到Mysql中
- oracle与db2 市场占有率,oracle 与 DB2 的区别
- NOIP 2016(不是游记)
- Linux基本服务命令
- php 实现二叉树的最大深度_python实现二叉树的遍历以及其他基本操作
- 图像变换——对数变换
- 无法嵌入互操作类型NationalInstruments.TestStand.Interop.UI.ExecutionViewOptions。请改用适用的接口...
- oracle高效分页存储过程(百万数据级)
- 工信部同意中国互联网信息中心设立域名根服务器及运行机构
- 二十三 常量池作为同步对象可能造成困惑
- Java获取不到tfp目录内容_AndroidRuntime引起:java.lang.unsatisfiedLinkError:无法加载tfp_jni:findLibrary返回null...
- CSMA/CA与CSMA/CD的区别
- Cuil搜尋引擎 挑戰Google
- Python入门学习笔记
- LVS 负载均衡群集----NAT模式
- 微信小程序之线路查询
- java qt gui_GUI(图形界面)技术选型
热门文章
- 大数据之保险行业的领导驾驶舱到底怎么做!附上模板
- 计算机网络基础15:MikroTik路由器使用方法
- c语言程序设计新编教程答案钱雪忠,新编C语言程序设计教程
- C++ Builder ADO数据库连接与保存
- 超级计算机模拟生命起源,超级计算机模拟生命起源
- 据统计:程序员平均寿命仅为37.9岁!
- Ubuntu把不需要的模块blacklist掉
- 2022年,前端er们都在看哪些网站?(含面试、接活、学习、摸鱼等)
- php转存百度云盘,[转]Linux定时备份数据到百度云盘
- python zipapp_python zip文件 压缩