基于FPGA的频率计

这篇具有很好参考价值的文章主要介绍了基于FPGA的频率计。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

好久没更了,百忙之中写一篇so easy的代码——基于FPGA的频率计设计。

一、简介

废话不多说,下面是百度搜索关于频率计的简洁概念。

数字频率计是一种基本的测量仪器,被广泛应用于航天、电子、测控等领域。基于传统测频原理的频率计的测量精度将随被测信号频率的下降而降低,在使用中有较大的局限性,而等精度频率计不但具有较高的测量精度,而且在整个频率区域能保持恒定的测试精度。

二、设计方案

对于频率计的设计,常用的方法有三种:测周法、测频法以及等精度测量法。

(1)测周法

测周法的测量对象一般是频率较低的被测信号,一般是选择取被测时钟的一个周期的上升沿或者下降沿都是可以的,下图是选择被测时钟一个周期的上升沿。

fpga数字频率计,Verilog,fpga开发

 由波形图中可以很快速的写出测周法的代码:

module cymometer
   #(parameter    SYS_CLK = 32'd100_000_000) // 基准时钟频率值
    (   //system clock
        input                 sys_clk ,     // 基准时钟信号
        input                 rst_n  ,     // 复位信号

        //cymometer interface
        input                 in_signal ,     // 被测时钟信号

       // output wire [31:0] fs_cnt_t/* synthesis syn_keep=1 */,
        output  reg  [31:0]   fre      // 被测时钟频率输出
);

//测周法(低频)
	
reg [31:0]	signal_cnt;						//对被测信号高电平进行计数的计数器


//在测信号高电平期间进行计数
always @(posedge sys_clk or negedge rst_n)begin	
	if(!rst_n)
		signal_cnt <= 0;
	else if(low_flag)
		signal_cnt <= signal_cnt + 1;
	else if(low_flag == 1'b0)
		signal_cnt <= signal_cnt;
end

reg [31:0] low_cnt;
reg low_flag;

always @(negedge in_signal or negedge rst_n )begin	
	if(!rst_n) begin
        low_cnt <= 4'd0;
        low_flag <= 1'b0;
    end
    else if(low_cnt < 4'd3) begin
        low_cnt <= low_cnt + 1'b1;
        low_flag <= 1'b0;
    end
    else if(low_cnt == 4'd3) begin
        low_cnt <= low_cnt + 1'b1;
        low_flag <= 1'b1;
    end
    else if(low_cnt == 4'd4) begin
        low_cnt <= low_cnt;
        low_flag <= 1'b0;
    end
end
            

//低频除法器
//在测信号低电平期输出测量数据
always @(negedge low_flag or negedge rst_n )begin	
	if(!rst_n)
		fre <= 0;
	else	
		fre <= SYS_CLK / signal_cnt;
end

一直比较忙,所以仿真图暂时不更新了,之前验证过了没啥问题,如果有问题需要的小伙伴可以自己调试哦。

(2)测频法

一般是使用比被测信号高得多的标准信号,基准时钟可以取一个固定值(如1S),然后被测时钟以上升沿或者下降沿计数,计数就为该被测时钟的频率,波形图如下。

fpga数字频率计,Verilog,fpga开发

 代码如下:

parameter CNT_2S = 32'd199_999_999;

//高频
reg [31:0] cnt_high;
reg    flag_1s;

always @(posedge sys_clk or negedge rst_n) begin
    if(!rst_n) begin
        cnt_high <= 32'd0;
        flag_1s <= 1'd0;
    end
    else if(cnt_high < 32'd10) begin
        cnt_high <= cnt_high + 32'd1;
        flag_1s <= 1'd0;
    end
    else if(cnt_high == 32'd10) begin
        cnt_high <= cnt_high + 32'd1;
        flag_1s <= 1'd1;
    end
    else if(cnt_high < 32'd10 + SYS_CLK) begin
        cnt_high <= cnt_high + 32'd1;
        flag_1s <= 1'd1;
    end
    else if(cnt_high == 32'd10 + SYS_CLK) begin
        cnt_high <= cnt_high + 32'd1;
        flag_1s <= 1'd0;
    end
    else if(cnt_high == 32'd10 + SYS_CLK + CNT_2S) begin
        cnt_high <= 32'd0;
        flag_1s <= 1'd0;
    end
end

reg [31:0] fre_high;

always @(posedge in_signal or negedge rst_n) begin
    if(!rst_n)
        fre_high <= 32'd0;
    else if(flag_1s == 1'b1)
        fre_high <= fre_high + 1'd1;
    else if(flag_1s == 1'b0)
        fre_high <= fre_high;
end

always@(negedge flag_1s or negedge rst_n) begin
    if(!rst_n)
        fre <= 32'd0;
    else
        fre <= fre_high;
end

(3)等精度测量法:

        等精度测量法与前两种方式不同,其最大的特点是,测量的实际门控时间不是一个固
定值,它与被测时钟信号相关,是被测时钟信号周期的整数倍。在实际门控信号下,同时
对标准时钟和被测时钟信号的时钟周期进行计数,再通过公式计算得到被测信号的时钟频
率。

        等精度测量法与前两种方式不同,其最大的特点是,测量的实际门控时间不是一个固
定值,它与被测时钟信号相关,是被测时钟信号周期的整数倍。在实际门控信号下,同时
对标准时钟和被测时钟信号的时钟周期进行计数,再通过公式计算得到被测信号的时钟频
率。
fpga数字频率计,Verilog,fpga开发

        结合等精度测量原理和原理示意图可得:被测时钟信号的时钟频率 fx 的相对误差与被测时钟信号无关;增大“软件闸门”的有效范围或者提高“标准时钟信号”的时钟频率fs,可以减小误差,提高测量精度。
        了解了等精度测量原理之后,我们来说明一下被测时钟信号的计算方法。首先我们先分别对实际闸门下被测时钟信号和标准时钟信号的时钟周期进行计数。

        我们设实际闸门被测时钟的计数为x,被测信号时钟周期为Tfx,他的时钟频率fx=1/Tfx,由此可以得公式:X * Tfx = X / fx = Tx(实际闸门)。
        实际闸门下标准时钟信号周期数为 Y,设被测信号时钟周期为 Tfs,它的时钟频率 fs =1/Tfs,由此可得等式: Y * Tfs = Y / fs = Tx(实际闸门)。

        其次,将两等式结合得到只包含各自时钟周期计数和时钟频率的等式: X / fx = Y / fs =Tx(实际闸门),等式变换, 得到被测时钟信号时钟频率计算公式: fx = X * fs / Y。最后,将已知量标准时钟信号时钟频率 fs 和测量量 X、 Y 带入计算公式, 得到被测时钟信号时钟频率 fx。

        根据上面的分析,我们可以设计一个等精度的频率计模块。首先是进行波形图的绘制:

fpga数字频率计,Verilog,fpga开发

 文章来源地址https://www.toymoban.com/news/detail-662388.html

module frequency(
	input				sys_clk		,
	input				sys_rst_n	,
	input				clk_test	,
	input               clk_100M    ,
    
	output	reg	[33:0]	freq
);

parameter   CLK = 100_000_000;

parameter	CNT_X	=	28'd12_499_999,
			CNT_5X	=	28'd62_499_999,
			CNT_6X	= 	28'd74_999_999;


wire			gate_fx_neg;		//被测闸门下降沿
wire			gate_fs_neg;		//基准闸门下降沿
wire            locked;

assign locked = 1'b1;

reg		[27:0]	cnt;				//
reg				gate_soft;          //软件闸门
reg				gate_a	 ;			//实际闸门
reg				gate_fx_reg;          //被测闸门
reg				gate_fs_reg;          //基准闸门
reg		[31:0]	cnt_gate_fx;		//被测闸门计数器
reg		[31:0]	cnt_gate_fs;		//基准时钟闸门计数器
reg     [31:0]  fx_cnt     ;        //被测频率计数
reg     [31:0]  fs_cnt     ;        //标准频率计数
reg             cala_flag  ;        //计算标志位
reg     [63:0]  fre_cnt    ;        //频率计数器
reg             cala_flag_reg  ;    //计算标志寄存器

always@(posedge sys_clk	or negedge sys_rst_n)
	if(!sys_rst_n)
		cnt <= 28'd0;
	else if(cnt == CNT_6X)
		cnt <= 28'd0;
	else
		cnt <= cnt + 28'd1;
		
//软件闸门
always@(posedge sys_clk	or negedge sys_rst_n)
	if(!sys_rst_n)
		gate_soft <= 1'b0;
	else if(cnt <= CNT_X || cnt > CNT_5X)
		gate_soft <= 1'b0;
	else
		gate_soft <= 1'b1;
		
//实际闸门
always@(posedge sys_clk	or negedge sys_rst_n)
	if(!sys_rst_n)
		gate_a <= 1'b0;
	else
		gate_a <= gate_soft;
		
//被测闸门		
always@(posedge clk_test or negedge sys_rst_n)
	if(!sys_rst_n)
		gate_fx_reg <= 1'b0;
	else
		gate_fx_reg <= gate_a;

//被测计数器
always@(posedge clk_test or negedge sys_rst_n)
	if(!sys_rst_n)		
		cnt_gate_fx <= 32'd0;
	else if(gate_a == 1'b0)
		cnt_gate_fx <= 32'd0;
	else if(gate_a == 1'b1)
		cnt_gate_fx <= cnt_gate_fx + 32'd1;
		
//取下降沿
assign  gate_fx_neg = gate_fx_reg && ~gate_a; 

//被测计数器
always@(posedge clk_test or negedge sys_rst_n)
	if(!sys_rst_n)		
		fx_cnt <= 32'd0;
    else if(gate_fx_neg == 1'b1)
        fx_cnt <= cnt_gate_fx;

		
//基准闸门		
always@(posedge clk_100M or negedge sys_rst_n)
	if(!sys_rst_n)
		gate_fs_reg <= 1'b0;
	else
		gate_fs_reg <= gate_a;
    
		
//基准闸门计数器		
always@(posedge clk_100M or negedge sys_rst_n)
	if(!sys_rst_n)		
		cnt_gate_fs <= 32'd0;
	else if(gate_a == 1'b0)
		cnt_gate_fs <= 32'd0;
	else if(gate_a == 1'b1)
		cnt_gate_fs <= cnt_gate_fs + 32'd1;
		
//取下降沿	
assign  gate_fs_neg = gate_fs_reg && ~gate_a; 	
	
//标准时钟计数
always@(posedge clk_100M or negedge sys_rst_n)
	if(!sys_rst_n)		
		fs_cnt <= 32'd0;
    else if(gate_fs_neg == 1'b1)
        fs_cnt <= cnt_gate_fs;	


//频率计数器
always@(posedge sys_clk or negedge sys_rst_n)
	if(!sys_rst_n)
		fre_cnt <= 64'd0;
    else if(cala_flag == 1'b1)
        fre_cnt <= CLK*fx_cnt/fs_cnt;
        
//计算标志位
always@(posedge sys_clk or negedge sys_rst_n)
	if(!sys_rst_n) begin
		cala_flag <= 1'b0;
        cala_flag_reg <= 1'b0;
    end
    else if(cnt == CNT_6X) begin
        cala_flag <= 1'b1;
        cala_flag_reg <= cala_flag;
    end
		

always@(posedge sys_clk or negedge sys_rst_n)
	if(!sys_rst_n) 
        freq <= 34'd0;
    else if(cala_flag_reg == 1'b1)
        freq <= fre_cnt;
          
        
endmodule		

仿真代码:

`timescale 1ns / 1ns

module tb_freq();


reg				sys_clk		;
reg				sys_rst_n	;
reg				clk_test	;
	                        
wire	[33:0]	freq        ;

initial begin   
    sys_clk = 1'b1;
    sys_rst_n <= 1'b0;
    clk_test = 1'b1;
    #201
    sys_rst_n <= 1'b1;
end

always #10 sys_clk = ~sys_clk;

always #30  clk_test = ~clk_test;

defparam    frequency_inst.CNT_X = 12_4,
            frequency_inst.CNT_5X = 62_4,
            frequency_inst.CNT_6X = 74_9;


frequency   frequency_inst(
	.sys_clk	(sys_clk    ),
	.sys_rst_n	(sys_rst_n  ),
	.clk_test	(clk_test   ),
	
	.freq       (freq       )
);

endmodule

然后我们看一下仿真波形:

首先是被测时钟的计数波形

fpga数字频率计,Verilog,fpga开发

 其次是标准时钟计数波形

fpga数字频率计,Verilog,fpga开发

最后看一下计算的结果

fpga数字频率计,Verilog,fpga开发

        计算的结果为100_000_000*167/1000=16_700_000,结果是没有问题的,我们再看一下上板验证的结果:

fpga数字频率计,Verilog,fpga开发

         这里测试时钟设置的频率为34.15926,PLL会保留小数点后三位也就是34.146,然后我们看一下上板之后的结果:fpga数字频率计,Verilog,fpga开发

 结果跟我们设置的锁相环结果是一致的,我们再来试一下高频的测试:

fpga数字频率计,Verilog,fpga开发

 fpga数字频率计,Verilog,fpga开发

 

        锁相环输出的结果为109.091,而我们频率计显示的频率为109.09,结果有一丢丢差异,就跟我们前面讲的一样,如果为了计算的精确,可以调节基准时钟频率或软件闸门的保持时间对同一信号进行频率测量。但相对于测频和测周法来说,等精度的精度相度更加灵活和精准。

 

 

 

 

 

到了这里,关于基于FPGA的频率计的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • FPGA—简易频率计(附代码)

    目录 1. 内容概要 2. 理论学习 3. 实操 3.1 整体设计 3.2 频率计算模块 3.2.1 模块框图 3.2.2  波形图绘制 3.2.3  RTL代码 3.3 顶层模块 3.4 仿真验证 3.5 上板验证 4. 总结        频率测量在电子设计领域和测量领域经常被使用,本文讲解 等精度测量法 的原理和实现方法,使用FPGA 设

    2024年02月09日
    浏览(18)
  • 孩子都能学会的FPGA:第二十五课——用FPGA实现频率计

    (原创声明:该文是 作者的原创 ,面向对象是 FPGA入门者 ,后续会有进阶的高级教程。宗旨是 让每个想做FPGA的人轻松入门 , 作者不光让大家知其然,还要让大家知其所以然 !每个工程作者都搭建了全自动化的仿真环境,只需要双击 top_tb.bat 文件就可以完成整个的仿真(前

    2024年02月02日
    浏览(19)
  • 基于51单片机数字频率计的设计与实现

    目录 第一章 系统原理与总体设计 1.1系统组成 1.2系统原理 1.3测量原理 1.4频率测量与总体设计 第二章 硬件电路设计 2.1硬件电路框图 2.2数字频率计原理图 2.3硬件电路设计 第三章 软件程序设计 3.1程序流程图 3.2显示电路程序设计 3.3 定时器初始化程序设计 3.4中断控制程序设计

    2024年02月08日
    浏览(23)
  • 基于STM32的简易数字频率计仿真设计(仿真+程序+设计报告+讲解)

    基于STM32的简易数字频率计仿真设计(仿真+程序+设计报告+讲解) 仿真图proteus 8.9 程序编译器:keil 5 编程语言:C语言 设计编号:C0079 基于STM32的简易数字频率计仿真设计(仿真+程序+设计报告+讲解) 结合实际情况,基于STM32F103单片机设计一个数字频率计仿真设计。该设计应满

    2024年02月09日
    浏览(16)
  • 基于51单片机数字频率计仿真设计(proteus仿真+程序+原理图+参考报告+器件清单)

    (proteus仿真+程序+原理图+参考报告+器件清单) 仿真图proteus 8.9 程序编译器:keil 4/keil 5 编程语言:C语言 设计编号:C0052 由51单片机+信号输入+74HC14整形电路+74HC390分频电路+LCD1602显示模块+电源构成。 1、能测出正弦波、三角波或方波等波形的频率; 2、频率的测量范围为1Hz—

    2024年02月09日
    浏览(21)
  • 多功能频率计周期/脉宽/占空比/频率测量verilog,视频/代码

    名称:多功能频率计周期、脉宽、占空比、频率测量verilog 软件:Quartus 语言:Verilog 代码功能:    多功能频率计,可测量信号的周期、脉冲宽度、占空比、频率,语言为verilog,quartus软件设计仿真 代码下载: 多功能频率计周期、脉宽、占空比、频率测量verilog_Verilog/VHDL资源

    2024年02月06日
    浏览(20)
  • 数字频率计

      电子技术应用实习 目录 1  实习目的、内容和要求 1 1.1 实习目的 1 1.2 实习内容 1 1.3 实习要求 1         1.3.1设计要求..................................................................................................................1 1.3.2实习任务要求 2 2  设计原理及软件简介 3 2.1设计原理 3 2.2M

    2023年04月18日
    浏览(15)
  • 等精度频率计verilog,quartus仿真视频,原理图,代码

    名称:等精度频率计设计verilog quartus仿真 软件:Quartus 语言:Verilog 要求: A:测量范围信号:方波     频率:100Hz~1MHz; B:测试误差:0.1%(全量程) C:时钟频率:50kHz D:预闸门时间:01s E:系统时钟频率:50MHz F:频率计算:保留1位小数 本代码下载:等精度频率计设计verilog,quartus仿真

    2024年02月07日
    浏览(39)
  • VHDL实现数字频率计的设计

    当设计文件加载到目标器件后,拨动开关的K1,使其置为高电平,从输入输出观测模块的输入端输入一个频率大于1Hz的时钟信号,这时在数码管上显示这个时钟信号的频率值。如果使拨动开关置为低电平,数码管上显示的值为系统上的数字信号源的时钟频率。改变数字信号源

    2024年02月02日
    浏览(32)
  • 基于51单片机的频率计

    前言:设计一个能产生固定频率的电路,然后经过单片机处理后显示该固定频率的系统。 1、指标以及功能要求 指标:该系统要能够产生一个31KHz的方波,进过单片机脉冲采集后能够在液晶上显示出该频率。要求:所用的知识要涉及到模拟电路知识和数字电路知识。 2、设计分

    2024年02月09日
    浏览(24)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包