前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >源码系列:基于FPGA的频率计设计(附源工程)

源码系列:基于FPGA的频率计设计(附源工程)

作者头像
FPGA技术江湖
发布2020-12-29 17:54:04
1.2K0
发布2020-12-29 17:54:04
举报
文章被收录于专栏:FPGA技术江湖FPGA技术江湖

大侠好,欢迎来到FPGA技术江湖,江湖偌大,相见即是缘分。大侠可以关注FPGA技术江湖,在“闯荡江湖”、"行侠仗义"栏里获取其他感兴趣的资源,或者一起煮酒言欢。

今天给大侠带来基于FPGA的频率计设计,附源码,获取源码,请在“FPGA技术江湖”公众号内回复“ 频率计设计源码”,可获取源码文件。话不多说,上货。

设计背景

频率计又称为频率计数器,是一种专门对被测信号频率进行测量的电子测量仪器。频率计主要由四个部分构成:时基(T)电路、输入电路、计数显示电路以及控制电路。

频率,即是信号周期的倒数,也就是说,信号每单位时间完成周期的个数,一般取一秒为基本单位时间。

设计原理

本次设计主要是一个简单的二选一数据选择器,我们的设计主频率=1s/T,T=高电平的时间+低电平的时间。时间=周期数*周期。占空比=(高电平的时间/周期)100%。我们的时间单位都是以ns来计算的,所以要把1s换成1_000_000_000ns,驱动时钟是50MHz的,周期为20ns。计算占空比的时候,我们把周期20ns全部省略了。所以计算公式如下:

freq = 1_000_000_000/(low_time * 20 + high_time * 20);

duty_cycle = (high_time * 100)/(high_time + low_time)。

设计架构

设计架构图:

设计代码

设计模块freq_meter代码:

代码语言:javascript
复制
module freq_meter (clk, rst_n, wave, freq, duty_cycle);  //端口列表
  
  input clk;                   //时钟
  input rst_n;                 //复位
  input wave;                  //被测频率
  output [25:0] freq;          //输出频率
  output [6:0] duty_cycle;   //输出占空比
  
  reg [25:0] low_cnt;
  reg [25:0] high_cnt;
  reg [25:0] low_time;
  reg [25:0] high_time;
  reg state;
  
  localparam high_state = 1'b0;
  localparam low_state = 1'b1;
  
  always @ (posedge clk or negedge rst_n)
    begin
      if (!rst_n)
        begin
        low_cnt <= 26'd0;
        high_cnt <= 26'd0;
        low_time <= 26'd0;
        high_time <= 26'd0;
        state <= high_state;
        end
      else
      begin
        case (state)
          high_state : begin
              if (wave == 1'b1)       //判断输入为高电平
                begin
                  high_cnt <= high_cnt + 1'b1;
                  state <= high_state;
                end
              else
                begin
                  high_cnt <= 26'd0;
                  high_time <= high_cnt;
                  state <= low_state;
                end
            end
            
          low_state : begin
              if (wave == 1'b0)  //判断输入为低电平
                begin
                  low_cnt <= low_cnt + 1'b1;
                  state <= low_state;
                end
              else
                begin
                  low_cnt <= 26'd0;
                  low_time <= low_cnt;
                  state <= high_state;
                end
            end
          default : state <= low_state;
          endcase
      end
    end
    
  assign freq = 1_000_000_000/(low_time * 20 + high_time * 20);  //求频率
   assign duty_cycle = (high_time * 100)/(high_time + low_time);  //求占空比
  
endmodule

仿真测试

仿真测试freq_meter_tb代码:

代码语言:javascript
复制
`timescale 1ns/1ps

module freq_meter_tb;
  reg clk;
  reg rst_n;
  reg wave;
  wire [25:0] freq;
  wire [6:0] duty_cycle;
  
  initial begin
    clk = 1'b1;
    rst_n = 1'b0;
    
    # 200.1
      rst_n = 1'b1;
    # 1_000_000_0//仿真10ms
      $stop;
  end
  
  always # 10 clk = ~clk;
  
  initial begin
    wave = 1'b1;
    forever begin//产生占空比为60%,频率为1KHz的方波
      # 600_000
        wave = 1'b0;
      # 400_000
        wave = 1'b1;
    end
  end
  
  freq_meter freq_meter_dut(
    .clk(clk),
    .rst_n(rst_n),
    .wave(wave),
    .freq(freq),
    .duty_cycle(duty_cycle)
  );
  
endmodule     

仿真图:

由于在前面没有测完一个周期出现了不稳定的因素,就出现了不准确的数值,当测试完一个周期以后,测到的数值就比较的准确,基本的没有什么误差。相对的,如果测试的频率越大,测到的数值就越准确。

END

后续会持续更新,带来Vivado、 ISE、Quartus II 、candence等安装相关设计教程,学习资源、项目资源、好文推荐等,希望大侠持续关注。

大侠们,江湖偌大,继续闯荡,愿一切安好,有缘再见!

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-03-28,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 FPGA技术江湖 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档