等精度频率计的设计与验证

· 浏览次数 : 2

小编点评

本文介绍了一种基于QuartusII PLL_IP核的等精度频率测量模块的设计与实现。通过设计一个等精度测量模块,利用QuartusII产生的任意频率被测时钟信号,经过处理后在数码管上显示出六位的测量频率数值,以验证测量的准确度。 1. 文章首先介绍了等精度频率测量的基本原理,包括频率测量法、周期测量法和等精度测量法。等精度测量法的特点在于门控时间的设定,可以根据被测时钟信号的周期进行调整。 2. 在基础原理部分,文章详细描述了等精度测量法的时序逻辑设计,包括系统时钟、被测信号、门限计数周期、实际门限范围、被测时钟信号相对于参考门限的周期个数测量等。 3. 文章还提供了一个Verilog程序模块,用于实现上述时序逻辑设计。通过编写Verilog程序,可以实现对被测信号频率的精确测量,并在数码管上显示测量结果。 4. 在频测模块仿真验证部分,文章通过设定不同的系统时钟和被测时钟信号,对等精度测量模块进行了仿真验证。仿真结果表明,该模块能够准确地测量出被测信号的频率,并且具有较高的测量准确度。 5. 最后,文章还讨论了如何将最终的结果输入到六位数码管上显示出来,并通过板级验证方案,验证了测量的准确性。 总体而言,本文提出了一种基于QuartusII PLL_IP核的等精度频率测量模块的设计与实现方法,具有较高的测量准确度和实用性。

正文

文章摘要:借助于QuartusII PLL_IP核产生一个任意频率被测时钟信号,设计一个等精度测量模块,通过其处理后,再数码管上显示出六位的测量频率数值,验证测量的准确度。

关键词:Verilog HDL;等精度频率测量;数码管;PLL_IP核

最终框图:

image


频率计,即频率计数器,专用于测量被测信号频率,基本工作原理就是当被测信号在特定时间段T内的周期个数为N时,则被测信号的频率freq可以通过公式freq=N/T计算得出。

在EDA设计中,常见的频率测量方法包括频率测量法(适合高频被测信号)、周期测量法(适合低频被测信号)和等精度测量法。频率测量法是通过统计单位时间内上升沿(或下降沿等)来计算频率,而周期测量法是通过测量上升沿(或下降沿等)的时间间隔来计算频率。等精度测量法与前两种不同,其在于门控时间的设定。

【基础原理】

在等精度测量法中,门控时间的长度并非固定,而会根据被测时钟信号的周期进行调整,保证其为被测时钟信号周期的整数倍。在这样的参考门限范围内,同时记录标准时钟和被测时钟信号的周期数,随后通过计算两者的比例关系,得到被测信号的时钟频率。

image

预先设定一个软件门限,在此门限划定测量参考范围,通过对测量信号Measured_sig上升沿触发,可得到一个相对的参考门限REF_threshold,其是被测时钟周期的整数倍,消除了被测信号存在的±1个时钟周期误差。

测量方法:

参考门限范围内,计数被测信号周期个数为N;给一个高频(固定频率Fs)标准信号,并计数得到其在同样门限下周期个数为Y;借助 N * 1 / Fn = Y * 1/Fs 可知被测信号频率 Fn = Fs * N / Y。

f为被测信号频率的测量值,f'为实际频率,参考门限T;

测量误差β = | f'-f | / f' * 100%,若忽略标准信号的误差,可得到f' = N / (Y ± ΔY)* Fs;

联立得到 β = ΔY/Y *100% ≤ 1/Y = 1/(Fs * T)

结论:被测信号的频率接近或高于标准信号,测量的误差会大,就是说,增大标准信号频率,或者扩大软件门限,这样可提高测量精度。

【时序逻辑设计】

系统时钟sys_clk为50Mhz信号,sys_rst为系统复位。被测信号Measured_sig设定任意频率,thres_cnt门限计数周期定位1.5s(可调),前0.25s为信号保持,在中间的1.00s内是软件门限测量范围,后0.25s为计算时间。actual_thres是参考门限范围,也就是被测信号的实际测量范围,是被测时钟周期的整数倍。

image

meas_clk_cntact_cnt_reg是被测时钟信号相对于参考门限的周期个数测量,最终得到计数N。由被测时钟信号上升沿触发,act_thres_regactual_thres做了一个延后保持(打拍),得到计数结束信号act_reg_flag,通过其高电平触发计数值转移值act_cnt_reg保持。std_clk_cntstd_cnt_reg原理同样如此,是标准高频信号相对于参考门限的周期个数测量,最终得到计数Y,通过公式计算得到被测信号频率。

对上述时序图中的信号,编写Verilog程序:(注意不同的信号触发类型)

parameter   THRES_CNT_MAX = 27'd75_000_000;
parameter   THRES_CNT_250MS = 27'd12_500_000;
parameter   CNT_STAND_FREP = 27'd100_000_000;

assign Std_flag = (Std_reg)&&(!act_thres)?1'b1:1'b0;
assign act_reg_flag = (act_thres_reg)&&(!act_thres)?1'b1:1'b0;

always @(posedge sys_clk or negedge sys_rst)begin
    if(!sys_rst)	thres_cnt <= 27'd0;
    else if(thres_cnt == THRES_CNT_MAX -1'b1)	thres_cnt <= 27'd0;
    else thres_cnt <= thres_cnt + 1'b1;
end

always @(posedge sys_clk or negedge sys_rst)begin
    if(!sys_rst)	thres_range <= 1'b0;
    else if((thres_cnt > (THRES_CNT_250MS-1'b1))&&(thres_cnt < (THRES_CNT_MAX-THRES_CNT_250MS-1'b1)))	 thres_range <= 1'b1;
    else thres_range <= 1'b0;
end

always @(posedge measured_sig or negedge sys_rst)begin
    if(!sys_rst)	act_thres <= 1'b0;
    else 	act_thres <= thres_range;
end

always @(posedge measured_sig or negedge sys_rst)begin
    if(!sys_rst)	meas_clk_cnt <= 48'd0;
    else if(!act_thres)	meas_clk_cnt <= 48'd0;
    else meas_clk_cnt <= meas_clk_cnt + 1'b1;
end

always @(posedge measured_sig or negedge sys_rst)begin
    if(!sys_rst)	act_thres_reg <= 1'b0;
    else 	act_thres_reg <= act_thres;
end

always @(posedge measured_sig or negedge sys_rst)begin
    if(!sys_rst)act_cnt_reg <= 48'd0;
    else if(act_reg_flag) act_cnt_reg <= meas_clk_cnt;
end

always @(posedge clk_stand or negedge sys_rst)begin
    if(!sys_rst) std_clk_cnt <= 48'd0;
    else if(!act_thres)std_clk_cnt <= 48'd0;
    else std_clk_cnt <= std_clk_cnt + 1'b1;
end

always @(posedge clk_stand or negedge sys_rst)begin
    if(!sys_rst) Std_reg <= 1'd0;
    else Std_reg <= act_thres;
end

always @(posedge clk_stand or negedge sys_rst)begin
    if(!sys_rst)    std_cnt_reg <= 48'd0;
    else if(Std_flag)	std_cnt_reg <= std_clk_cnt;
end

always @(posedge sys_clk or negedge sys_rst)begin
    if(!sys_rst)	calc_flag <= 1'd0;
    else if(thres_cnt == THRES_CNT_MAX-1)calc_flag <= 1'd1;
    else calc_flag <= 1'd0;
end

always @(posedge sys_clk or negedge sys_rst)begin
    if(!sys_rst)frep_result <= 32'd0;
    else if(calc_flag)frep_result <= (CNT_STAND_FREP/ std_cnt_reg* act_cnt_reg);
end

其中的标准高频信号clk_stand需要借助于QuartusII的PLL_IP核产生,模块实例化其中。

//Stand_clk from PLL_IP_core
clk_stand	clk_stand_inst (
	.areset ( !sys_rst  ),//Hign Level take effect
	.inclk0 ( sys_clk   ),
	.c0 ( clk_stand )	);

【频测模块仿真验证】

在仿真程序及仿真现象中,设定系统时钟20ns,即50Mhz,而被测时钟周期216ns,即1 / 216 * 10e9 ≈ 4.6296Mhz。并且,为方便观察波形变化,将软件门限缩小了10e5倍(精度减小),最终得到被测信号频率 32'h46a806 ≈ 4.6305Mhz,误差0.9khz,仿真上的时序变化均达到时序逻辑要求。

always #10 sys_clk =~sys_clk;
always #108 clk_test =~clk_test;
defparam frep_calc_inst.THRES_CNT_MAX = 750;
defparam frep_calc_inst.THRES_CNT_250MS = 125;

image
image

【部署其他模块】

考虑到最后的板级验证,没有信号源和示波器通过,在此再建立一个PLL_IP核产生一个“任意时钟信号”,作为被测信号,并且将最终的结果输入到六位数码管上显示出来观察,该被测信号的实际频率为3.580097Mhz。

image

其次,实例化数码管显示模块,这里还是存在问题的,测信号的实际频率十六进制显示采用六位即可,这里图个方便,用assign直接赋值了。

digital digital_inst(
    .sys_clk    (sys_clk    ),
    .sys_rst    (sys_rst    ),

    .clk_2khz   (clk_2khz   ), 
    .num6       (num6       ),	//assign  num6  = frep_result[23:20];
    .num5       (num5       ),	//assign  num5  = frep_result[19:16];
    .num4       (num4       ),	//......
    .num3       (num3       ),
    .num2       (num2       ),
    .num1       (num1       ),
    .sel_cnt    (sel_cnt    ),	//所使用到的位数
    .dp_cnt     (dp_cnt     ),	//小数点所在位号
    
    .seg_sel    (seg_sel    ),	//数码管位选
    .seg_led    (seg_led    )	//数码管段选
);

【板级验证方案】

从下图可以看到,代码里采用了除法运算。在FPGA或ASIC设计中,除法运算本身是一种复杂的算术操作,相比于加法、减法和乘法,它需要更多的计算步骤和逻辑单元来完成,除法操作往往需要专门的硬件除法器。

image

上机测试后,烧录至EP4CE10F17C8开发板,数码管显示十六进制36A0C1,刚好是3,580,097hz。软件门限范围为1.00s,标准信号设定100Mhz,测量准确度还是比较高的。

image

文献参考:

[1]基于Altera EP4CE10 征途Mini开发板文档(https://doc.embedfire.com/fpga/altera/ep4ce10_mini/zh/latest/fpga/Frequency_Meter.html)

[2]王立华,周松江,高世皓,等. 基于内嵌Cortex-M3内核FPGA的等精度频率计设计[J]. 实验室研究与探索,2017,36(7):139-143,181. DOI:10.3969/j.issn.1006-7167.2017.07.033.


本篇文章中使用的Verilog程序模块,若有需见网页左栏Gitee仓库链接:https://gitee.com/silly-big-head/little-mouse-funnyhouse/tree/FPGA-Verilog/

与等精度频率计的设计与验证相似的内容:

等精度频率计的设计与验证

文章摘要:借助于QuartusII PLL_IP核产生一个任意频率被测时钟信号,设计一个等精度测量模块,通过其处理后,再数码管上显示出六位的测量频率数值,验证测量的准确度。 关键词:Verilog HDL;等精度频率测量;数码管;PLL_IP核 最终框图: 频率计,即频率计数器,专用于测量被测信号频

解决卡顿发热,超帧技术焕发中重载游戏动力

近几年,中国手游市场规模不断扩大,开发者通过在画面、玩法等方面的持续创新和打磨,推出更加精品化的产品。然而愈发精美的画质和复杂的玩法,也给硬件带来超高的负载,导致玩家在游戏过程中,频繁出现掉帧卡顿、发烫、续航差等体验降低的现象。 HarmonyOS SDK 图形加速服务(Graphics Accel

【numpy基础】--广播计算

`numpy`的广播计算是指在多维数组上进行的一种高效计算方式。 它可以将计算任务分配到每个维度上,并且可以在计算过程中进行数据共享和同步,从而提高计算效率和精度。 广播计算在数值计算、科学计算、机器学习等领域都有广泛的应用。 例如,在数值计算中,广播计算可以用于求解大规模的非线性方程组;在科学计算

Elasticsearch与Clickhouse数据存储对比

Elasticsearch的查询语句维护成本较高、在聚合计算场景下出现数据不精确等问题。Clickhouse是列式数据库,列式型数据库天然适合OLAP场景,类似SQL语法降低开发和学习成本,采用快速压缩算法节省存储成本,采用向量执行引擎技术大幅缩减计算耗时。所以做此对比,进行Elasticsearch切换至Clickhouse工作。

心理健康数据集:mental_health_chatbot_dataset

一.数据集描述 1.数据集摘要 该数据集包含与心理健康相关的问题和答案的对话对,以单一文本形式呈现。数据集是从流行的医疗博客(如WebMD、Mayo Clinic和HealthLine)、在线常见问题等来源精选而来的。所有问题和答案都经过匿名化处理,以删除任何个人身份信息(PII),并经过预处理以删

[转帖]iftop流量监控

https://www.cnblogs.com/zh-dream/p/16691807.html iftop 是 Linux 系统一个免费的网卡实时流量监控工具,类似于 top 命令。iftop 可以监控指定网卡的实时流量、端口连接信息、反向解析 IP 等,还可以精确显示本机网络流量及网络内各主机和

通过Scrum实现最大生产力的五种方法

在数字化、信息化、智能化蓬勃发展的今天,敏捷开发和Scrum已成为重塑项目管理的重要方式。 敏捷是一种体现不同方法的思维方式,包括了Scrum,看板,极限编程(XP)、精益开发等众多框架。 Scrum是上述列出框架中使用最广泛的一种敏捷方法,个人、团队和组织使用Scrum通过对复杂问题的自适应解决方

推荐系统:精排多目标融合与超参数学习方法

粗排/精排的个性化多任务学习模型,能预估20多个不同的预估值,如点击率、有效播放率、播放时长、点赞率、关注率等,那如何用它来排序呢?从多任务学习到多目标排序,中间有一个过渡,即如何把这些预估值融合成一个单一的排序分,最后实现多目标精排。这也就引入了本文要介绍的正题:多目标融合(multi-task ...

[转帖]Oracle入门精读28-字符集 AL32UTF8与UTF8

字符(Character) 字符是各种文字和符号的总称,包括各国家文字、标点符号、图形符号、数字等。 字符编码(Character Encoding) 是一套法则,使用该法则能够对自然语言的字符的一个集合,与其它的一个集合(如数值编码)进行配对。 即在符号集合与数字系统之间建立对应关系。 字符集(C

如何利用窗口函数实现精确排名计算?

前言 SQL语句中,聚合函数在统计业务数据结果时起到了重要作用,比如计算每个业务地区的业务总数、每个班级的学生平均分以及每个分类的最大值等。然而,今天小编将为大家介绍窗口函数,与聚合函数相比,它们也是一组函数,但在使用方法和适用场景上有所不同。在本章节中,我将重点介绍窗口函数中的RANK和DENSE