周期法频率计的设计

   

目录

   

周期法频率计

  分析:

设计过程:


周期法频率计

对于低频信号,应用周期法进行测频。周期法测频的基本原理是:应用标准频率信号统计被测信号两个相邻脉冲之间的脉冲数,然后通过脉冲数计算出被测信号的周期,再根据频率与周期之间的倒数关系计算出频率值。

  分析:

(1)10mHz信号的周期为100秒。若应用50MHz晶振信号统计被测信号的周期,则两个相邻脉冲之间需要统计(50×106×100=)5×109个脉冲,因此需要应用33位二进制计数器(233=8588934592>5×109)进行计数。 (2)被测信号的周期以两个相邻脉冲的边沿为基准进行测量。

    信号边沿检测的通用方法是:应用同步寄存器来捕获和存储被测频率信号。若应用三级右移寄存器作为同步器,如图所示,当存储数据Q0Q1Q2=x10 时,表示检测到被测信号的上升沿,存储数据Q0Q1Q2=x01时,表示检测到被测信号的下降沿,其中x表示无关位。

描述信号边沿检测电路的Verilog代码参考如下:

module edge_detector (
    input det_clk,        // 时钟,50MHz
    input rst_n,          // 复位信号,低电平有效
    input x_signal,       // 被测信号
    output wire rising_edge,  // 上升沿标志,高电平有效
    output wire fall_edge     // 下降沿标志,高电平有效
    );
    reg [0:2] sync_reg;      // 三级同步寄存器定义
    // 同步移存过程
    always @( posedge det_clk or negedge rst_n ) 
      if ( !rst_n )  sync_reg <= 3'b000;
      else   sync_reg <= { x_signal, sync_reg[0:1] };
    // 边沿检测逻辑
    assign rising_edge  =  sync_reg[1] & ~sync_reg[2];
    assign fall_edge    = ~sync_reg[1] &  sync_reg[2];
endmodule

设计过程:

对于周期法频率计,状态机内部需要定义4个状态:复位(RESET)、空闲(IDLE)、计数(COUNT)和结束(DONE)。   状态转换的基本思路是: (1)复位信号有效时,强制状态机处于RESET状态; (2)复位信号撤销后,状态机转入IDLE状态,等待被测信号的有效沿。 (3)检测到第一个有效沿时,状态机转入COUNT状态,开始进行计数; (4)检测到第二个有效沿时,状态机转入DONE状态,停止计数并输出周期计数值; (5)状态机处于DONE时,下一个时钟脉冲转入IDLE状态。

根据上述状态转换图,描述周期测量状态机的Verilog代码参考如下:

module period_detector (
   input det_clk,                      // 检测电路时钟,50MHz
   input rst_n,                        // 复位信号,低电平有效
   input x_signal,                     // 被测频率信号
   output reg [32:0] period_value   // 周期测量值
   );
   // 状态定义及编码
   localparam RESET  = 4'b0001;
   localparam IDLE    = 4'b0010;
   localparam COUNT = 4'b0100;
   localparam DONE   = 4'b1000;
   // 内部线网和变量定义
   reg [0:2] sync_reg;                                         // 移位寄存变量
   (* synthesis,probe_port,keep *) wire fall_edge;          // 下降沿标志
   reg [3:0] current_state,next_state;                       // 现态与次态
   (* synthesis,probe_port,keep *) wire cnt_en;             // 计数允许信号
   (* synthesis,probe_port,keep *) reg [32:0] period_cnt;  // 周期计数值
   // 下降沿检测逻辑
   assign fall_edge = ~sync_reg[1] & sync_reg[2];
   // 计数允许逻辑
   assign cnt_en = ( current_state == COUNT );
   // 同步移存过程
   always @( posedge det_clk or negedge rst_n ) 
       if ( !rst_n )   sync_reg <= 3'b000;
         else   sync_reg [0:2] <= { x_signal, sync_reg[0:1] };    
  // 状态机转换过程
  always @( posedge det_clk or negedge rst_n )
      if ( !rst_n )  current_state <= RESET; 
     else   current_state <= next_state;
  // 次态逻辑描述
  always @ ( current_state )
     case ( current_state )
         RESET: next_state <= IDLE;
         IDLE: if ( fall_edge )   next_state <= COUNT;
                  else       next_state <= IDLE;
         COUNT: if ( fall_edge )   next_state <= DONE;
                    else      next_state <= COUNT;
          DONE: next_state <= IDLE;
         default:  next_state <= RESET;
      endcase
    // 周期计数过程
    always @( posedge det_clk ) 
       if ( current_state == IDLE )
            period_cnt <= {33{1'b0}};
       else if ( cnt_en )
            period_cnt <= period_cnt + 1'b1;
    // 计数锁存过程
    always @ ( current_state )
       if ( current_state == DONE )
            period_value <= period_cnt; 
endmodule

上述状态机代码的仿真波形如图所示。从图中可以看出,状态机时序正确。

   应用状态机统计到被测信号周期的计数值period_value后,还需要将计数值转换为周期值,然后再换算为频率值。    由于状态机的时钟为50MHz,所以标准信号的周期 Tdet_clk=20ns,因此被测信号的周期值Tx为      Tx = period_value × Tdet_clk =  period_value × 20  (ns) 因此,被测信号的频率值为    fx = 1/Tx = 109/ (period_value × 20) = 5×107/ period_value  (Hz) 由上式可以看出,需要应用除法器来计算被测信号的频率值。

   测量10mHz~10kHz低频信号的频率,定义被测信号的频率大于等于1Hz时,频率值以“4位整数+4位小数”的格式显示,被测信号的频率小于1Hz时,频率值以“8位小数”的格式显示。  

   设fx=qqq...qqqq.rrrr rrrr...r。为处理方便,先将计算得到的频率值fx扩大108倍,因此,当频率小于1Hz时除法的商即为实际的频率值,以“8位小数”格式显示。当频率大于小于1Hz时,再缩小104倍(相当于将fx只扩大104倍),则以“4位整数+4位小数”加上小数点显示时,即为实际的频率值。     由于被除数5×1015需要用53位二进制数(252<5×1015<253)表示,而除数period_value为33位二进制数,因此需要定制53位二进制数除以33位二进制数的除法器。

 在“DIVIDER_for_freqor_inst.v”前打√,表示生成例化模板文件,以便可以应用例化语句调用定制的除法器。

根据上述处理思路,将周期计数值转换为频率的Verilog描述代码参考如下:

 module period2freq (
    input  [32:0] period_value,        // 33位周期计数值
    output wire [27:0] freq_value,    // 频率值,需要应用BIN28toBCD转换为8个BCD码
    output wire         DP_flag        // 小数点标志
    );
    // 内部线网定义
    wire [52:0] div_quotient;         // 53位除法商数
    wire [32:0] div_remain;           // 33位除法余数
    wire [52:0] freq_temp;           // 商数÷10000
    // 除法器IP例化 
   DIVIDER_for_freqor DIVIDER_for_freqor_inst (
	      .denom ( period_value ),                // 分母,周期计数值
	      .numer ( 53'd5000000000000000 ),  // 分子,常数5×1015
	      .quotient ( div_quotient ),              // 除法商数,53位
	      .remain ( div_remain )                  // 除法余数,33位
	      );
    // 频率显示值和小数点标志输出
    assign freq_temp  =  div_quotient/10000; 
    assign freq_value = (div_quotient<100000000)?   // 小于108?
                             div_quotient[27:0] :   // 小于1Hz,以“8位小数”显示
                             freq_temp[27:0];      // 大于等于1Hz,以“4位整数+4位小数”显示
    assign DP_flag = ( div_quotient<100000000 )?  0 : 1; 
  endmodule

   20路分频式信号源,输出信号频率为:0.01~6103Hz,由4.5节中模块fx32.v简化而来。

module fx20 (   
   input        clk50,   // 时钟,50MHz
   input [4:0]  fsel,    // 频率选择
   output reg  fpout    // 信号源输出
   );
   // 内部变量定义
   reg [31:0] q;         // 计数变量
   // 计数逻辑描述
   always @(posedge clk50 )  
          q <= q + 1'b1;
   // 输出选择过程 
   always @(fsel,q)     
       case (fsel)  // 根据fsel分频输出
           5'b01100: fpout = q[12];  // 6103.515625Hz
           5'b01101: fpout = q[13];  // 3051.7578125Hz 
           5'b01110: fpout = q[14];  // 1525.87890625Hz         
           5'b01111: fpout = q[15];   // 762.939453125Hz
           5'b10000: fpout = q[16];   // 381.4697265625Hz  
           5'b10001: fpout = q[17];   // 190.7348631825Hz
           5'b10010: fpout = q[18];   // 95.367431640625Hz
           5'b10011: fpout = q[19];   // 47.6837158203125Hz
           5'b10100: fpout = q[20];   // 23.84185791015625Hz
           5'b10101: fpout = q[21];   // 11.920928955078125Hz
           5'b10110: fpout = q[22];   // 5.9604644775390625Hz
           5'b10111: fpout = q[23];   // 2.9802322876953125Hz
           5'b11000: fpout = q[24];   // 1.490116119384765625Hz
           5'b11001: fpout = q[25];   // 0.7450580596923828125Hz
           5'b11010: fpout = q[26];   // 0.37252902984619140625Hz
           5'b11011: fpout = q[27];   // 0.186264514923095703125Hz
           5'b11100: fpout = q[28];   // 0.0931322574615478515625Hz
           5'b11101: fpout = q[29];   // 0.04656612873077392578125Hz
           5'b11110: fpout = q[30];   // 0.023283064365386962890625Hz
           5'b11111: fpout = q[31];   // 0.0116415321826934814453125Hz
              default:  fpout = q[14];  // 1525.87890625Hz
        endcase
     endmodule

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/921817.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

C语言--分支循环编程题目

第一道题目&#xff1a; #include <stdio.h>int main() {//分析&#xff1a;//1.连续读取int a 0;int b 0;int c 0;while (scanf("%d %d %d\n", &a, &b, &c) ! EOF){//2.对三角形的判断//a b c 等边三角形 其中两个相等 等腰三角形 其余情…

MySQL Join 的原理与优化实践

文章目录 引言一、基础准备&#xff1a;创建环境与示例数据1. 初始化示例表2. 示例 Join 查询3. EXPLAIN 输出分析 二、MySQL Join 的核心算法与执行机制1. 三种 Join 算法的实现与原理1.1 Index Nested-Loop Join&#xff08;INLJ&#xff09;1.2 Simple Nested-Loop Join&…

关于安卓模拟器或手机设置了BurpSuite代理和安装证书后仍然抓取不到APP数据包的解决办法

免责申明 本文仅是用于学习研究安卓系统设置代理后抓取不到App数据包实验,请勿用在非法途径上,若将其用于非法目的,所造成的一切后果由您自行承担,产生的一切风险和后果与笔者无关;本文开始前请认真详细学习《‌中华人民共和国网络安全法》【学法时习之丨网络安全在身边一…

飞凌嵌入式旗下教育品牌ElfBoard与西安科技大学共建「科教融合基地」

近日&#xff0c;飞凌嵌入式与西安科技大学共同举办了“科教融合基地”签约揭牌仪式。此次合作旨在深化嵌入式创新人才的培育&#xff0c;加速科技成果的转化应用&#xff0c;标志着双方共同开启了一段校企合作的新篇章。 出席本次签约揭牌仪式的有飞凌嵌入式梁总、高总等一行…

下载安装Android Studio

&#xff08;一&#xff09;Android Studio下载地址 https://developer.android.google.cn/studio 滑动到 点击下载文档 打开新网页 切换到english ![](https://i-blog.csdnimg.cn/direct/b7052b434f9d4418b9d56c66cdd59fae.png 等待一会&#xff0c;出现 点同意后&#xff0…

准备阶段 Profiler性能分析工具的使用(一)

Unity 性能分析器 (Unity Profiler) 性能分析器记录应用程序性能的多个方面并显示相关信息。使用此信息可以做出有关应用程序中可能需要优化的事项的明智决策&#xff0c;并确认所做的优化是否产生预期结果。 默认情况下&#xff0c;性能分析器记录并保留游戏的最后 300 帧&a…

01Web3.0行业

目录 一、什么是Web 3.0? 二、Web 1.0 vs Web 2.0 vs Web 3.0 三、为什么选择Web 3.0 四、从法律角度观察Web 3.0 1. Web 3.0前时代的数字身份 问题1&#xff1a;个人信息的过度收集 问题2&#xff1a;个人信息的泄露和滥用 2. Web 3.0的解决方案及其法律问题 问题一&…

archlinux安装waydroid

目录 参考资料 注意 第一步切换wayland 第二步安装binder核心模组 注意 开始安装 AUR安裝Waydroid 启动waydroid 设置网络&#xff08;正常的可以不看&#xff09; 注册谷歌设备 安装Arm转译器 重启即可 其他 参考资料 https://ivonblog.com/posts/archlinux-way…

互联网时代的隐私保护

在这个数字化时代&#xff0c;我们的生活与互联网密不可分。打开手机刷刷朋友圈&#xff0c;浏览一下购物网站&#xff0c;约个网约车&#xff0c;点个外卖&#xff0c;这些看似平常的行为都在默默产生着数据足迹。可就在这不经意间&#xff0c;我们的个人信息正在被收集、分析…

python之使用django框架开发web项目

本问将对django框架在python的web项目中的使用进行介绍,有不对之处,烦请指正。 首先使用创建一个django工程(本示例中使用pycharm2024+python3.12),名称和项目保存路径根据自己的需要自行修改,新手直接默认本机环境就好(关于conda将会另开一篇进行讲解。),最后点击cre…

基于YOLOv8深度学习的扰乱公共秩序打架异常行为检测系统研究与实现(PyQt5界面+数据集+训练代码)

随着智能监控技术和人工智能的发展&#xff0c;基于深度学习的行为检测技术在公共安全和防范领域中发挥着越来越重要的作用。传统的监控系统通常依赖于人工监控&#xff0c;这不仅耗费大量的人力和时间&#xff0c;且容易因为人的疲劳或疏忽而漏检关键的异常行为。而近年来&…

gocv调用opencv添加中文乱码的解决方案

前言 相信很多做视觉的同学在使用opencv给图片添加中文文字的时候会出现这样的乱码显示: 而实际上你期望的是“告警时间:2011-11-11 11:11:11 告警类型:脱岗检测告警 Area:XXXXX Camera:Camera001-001”这样的显示内容,那么这篇文章我将用很简单的方法来解决乱码问题,只需…

JavaScript中的this指向问题

JavaScript中的this指向问题 1.1 为什么需要this? 为什么需要this? 在常见的编程语言中&#xff0c;几乎都有this这个关键字&#xff08;Objective-C中使用的是self),但是在JavaScript中的this和常见的面向对象语言中的this不太一样 常见面向对象的编程语言中&#xff0c;比…

预测气动阻尼

TLDR&#xff1a;通过结合 ANSYS Mechanical 和 ANSYS CFX&#xff0c;可以通过模拟预测气动阻尼。此方法可用于涡轮叶片、飞机机翼或 MEMS 微镜&#xff01; MEMS 系统的频率响应。峰值的高度取决于阻尼……那么阻尼比是多少&#xff1f; 多年来&#xff0c;很多人问我“嘿&am…

在 CentOS 系统上直接安装 MongoDB 4.0.25

文章目录 步骤 1&#xff1a;配置 MongoDB 官方源步骤 2&#xff1a;安装 MongoDB步骤 3&#xff1a;启动 MongoDB 服务步骤 4&#xff1a;验证安装步骤 5&#xff1a;可选配置注意事项 以下是在 CentOS 系统上直接安装 MongoDB 4.0.25 的详细步骤&#xff1a; 步骤 1&#x…

.NET9 - 新功能体验(一)

被微软形容为“迄今为止最高效、最现代、最安全、最智能、性能最高的.NET版本”——.NET 9已经发布有一周了&#xff0c;今天想和大家一起体验一下新功能。 此次.NET 9在性能、安全性和功能等方面进行了大量改进&#xff0c;包含了数千项的修改&#xff0c;今天主要和大家一起体…

乐理的学习(调式)

大致了解乐理之后的总结 跟着西蒙哥也是把基础乐理差不多能有一个大致的总结框架了&#xff0c;主要还是为了弹钢琴&#xff0c;也是知道了很多的规则都是为了人们的感受服务的 对手指要了解 对于手指的弹音局限 各个手指的使用频率 不同年龄的不同的人对手指的使用存在差…

08 —— Webpack打包图片

【资源模块 | webpack 中文文档 | webpack中文文档 | webpack中文网】https://www.webpackjs.com/guides/asset-modules/?sid_for_share99125_3 Webpack打包图片以8KB为临界值判断 大于8KB的文件&#xff1a;发送一个单独的文件并导出URL地址 小于8KB的文件&#xff1a;导出一…

Python爬虫能处理动态加载的内容吗?

Python爬虫确实可以处理动态加载的内容。动态加载的内容通常是通过JavaScript在客户端执行&#xff0c;这意味着当网页首次加载时&#xff0c;服务器返回的HTML可能并不包含最终用户看到的内容。相反&#xff0c;JavaScript代码会在页面加载后从服务器请求额外的数据&#xff0…

SQL注入--DNSlog外带注入--理论

什么是DNSlog? DNS的作用是将域名解析为IP 而DNSlog就是存储在DNS服务器上的域名信息&#xff0c;它记录着用户对域名访问信息。可以理解为DNS服务器上的日志文件。 多级域名 比如blog.csdn.net&#xff0c;以点为分隔&#xff0c;从右向左依次是顶级域名、二级域名、三级域…