基于FPGA的频率计设计

1.频率计

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

2.测量方法与基本原理

FPGA 主要完成测量待测信号频率,对输入信号个数和标准信号个数进行计数等工作;或采用测周法测量输入信号脉宽, 对输入待测信号的高电平时间进行计数 。

1.等精度测频

等精度测量法就是人为设定一段时间 ,由被测信号的上升沿来控制闸门的开启和关闭 ,测量精度与被测信号频率无关 ,因而可以保证在整个测量频段内的测量精 度保持不变 。

图示为等精度测量原理时序图, 等精度测频法 同时使用两个计数器分别对待测信号频率 f x 和频标信号频率 f m 在设定的精确门内进行计数, 精确门与预置 门门限时间相同 , f x 的上升沿触发精确门。用两个计数 器在精确门内对 f x 和 f m 分别计数 ,若两个计数器的计数值分别为 M 和 N , 则: 待测信号的频率为: f x =Mf m/N

 2.测周法

在一个被测信号的周期内,测量基准时钟的个数,得到被测信号的周期,再将其转化为频率。

3.实验程序

1.RTL:

 2.代码

1.计数器:

module CNT
   #(parameter    CLK_FS = 26'd50_000_000,// 基准时钟频率
	parameter  MAX       =  10'd64)  // 定义数据位宽        
    (   //system clock
        input                 clk_fs ,     // 时钟信号
        input                 rst_n   ,  // 复位信号
 
        //cymometer interface
        input                 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) begin
    if(!rst_n) begin
        fx_cnt_temp <= 32'd0;
        fx_cnt <= 32'd0;
    end
    else if(gate)begin
      fx_cnt_temp <= fx_cnt_temp + 1'b1;
    end   
    else if(neg_gate_fx) begin
        
        fx_cnt_temp <= 32'd0;
        fx_cnt <= fx_cnt_temp;
        
    end
end
 
//门控时间内基准时钟的计数
always @(posedge clk_fs or negedge rst_n) begin
    if(!rst_n) begin
        fs_cnt_temp <= 32'd0;
        fs_cnt <= 32'd0;
    end
    else if(gate_fs)
        begin
        fs_cnt_temp <= fs_cnt_temp + 1'b1;
        end
    else if(neg_gate_fs) begin
        
        fs_cnt_temp <= 32'd0;
		fs_cnt <= fs_cnt_temp;
    end
end
//计算待测信号的频率值
always @(posedge clk_fs or negedge rst_n) begin
    if(!rst_n) begin
        data_fx_temp <= 64'd0;
    end
    else if(gate_fs == 1'b0)
			data_fx_temp <=CLK_FS*fx_cnt/fs_cnt;
end
 
endmodule

2.门控 :

module gate
(
        input                 clk_fs ,     // 基准时钟信号
        input                 rst_n   ,  // 复位信号
 
        //cymometer interface
        input                 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) begin
    if(!rst_n)
        gate_cnt <= 16'd0; 
    else if(gate_cnt == GATE_TIME + 5'd20)
        gate_cnt <= 16'd0;
    else
        gate_cnt <= gate_cnt + 1'b1;
end
	  
 
//门控信号,拉高时间为GATE_TIME个实测时钟周期
always @(posedge clk_fx or negedge rst_n) begin
    if(!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) begin
    if(!rst_n) begin
        gate_fs_r <= 1'b0;
        gate_fs   <= 1'b0;
    end
    else begin
        gate_fs_r <= gate;
        gate_fs   <= gate_fs_r;
    end
end
endmodule

3.边沿检测:

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) begin
    if(!rst_n) begin
        gate_fx_d0 <= 1'b0;
        gate_fx_d1 <= 1'b0;
    end
    else begin
        gate_fx_d0 <= gate;
        gate_fx_d1 <= gate_fx_d0;
    end
end
 
//打拍采门控信号的下降沿(基准时钟)
always @(posedge clk_fs or negedge rst_n) begin
    if(!rst_n) begin
        gate_fs_d0 <= 1'b0;
        gate_fs_d1 <= 1'b0;
    end
    else begin
        gate_fs_d0 <= gate_fs;
        gate_fs_d1 <= gate_fs_d0;
    end
end
endmodule

4.顶层:

按照DE0手册分配管脚 :

 4.调试测验

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值