FPGA 频率计实验

FPGA 频率计实验
实验要求:实现等精度频率计,通过数码管显示。
 频率计实验又称为频率计数器,是一种专门对被测信号进行测量的电子仪器。
 计数法:直接计数单位时间内的被测信号的脉冲数,这种方式测量精度高、速度快、适合不同频率、不同精确度测频的需要。
 测待测频率,需要有一个基准时钟,基准时钟频率设置为CLK_FS,基准时钟的脉冲数为fs_cnt,生成门控信号为高,在门控信号为高的时候,查待测信号的脉冲数,设待测信号的频率为clk_fx,待测信号的脉冲数为fx_cnt;
 则满足下列比例:
fs_cnt/CLK_FS=fx_cnt/clk_fx;
 这是一个理想的公式
  因为门控信号拉高的长度不一定等于基准时钟与待测信号时钟的整数倍。
 等精度频率计:是以待测信号为基准,拉高门控信号,保证门控信号是待测信号周期的整数倍,但是会对基准信号产生误差。
 下面是频率计的代码:
测试频率为基准时钟/100的代码

> module frequency(clk,rst_n,data_fx); 
> input clk,rst_n;
>  output [19:0] data_fx;
> //parameter define parameter CLK_FS=26'd50000000; //基准时钟频率值
> 
> //wire define  wire [19:0] data_fx;  //被测信号测量值
> cymometer #(.CLK_FS(CLK_FS))  
> u_cymometer(
>               .clk(clk),
>               .rst_n(rst_n),
>               .clk_fx(clk_out),
>               .data_fx(data_fx)
>                 );
>  clk_test #(.DIV_N(7'd100) ) 
>  u_clk_test(
>               .clk(clk),
>               .rst_n(rst_n),
>               .clk_out(clk_out)
>              ); 
>          endmodule 
`



>  module clk_test #(parameter DIV_N=7'd100) 
>    (  input clk,   
>       input rst_n,  
>      output reg clk_out   
>      );   
>      reg [6:0] cnt;
>     always @(posedge clk or negedge rst_n)   begin  
>     if(!rst_n)  
>        begin   
>           cnt  <= 0;    
>          clk_out <= 0; 
>         end  
>     else begin   
>       if(cnt==DIV_N/2-1)
>         begin 		
>          cnt         <= 0;  
>          clk_out   <= ~clk_out; 		
>        end
>    else 
> 	    begin
> 	        cnt  <= cnt+1;
> 	        clk_out  <= clk_out;
> 	        end    
>       end 
>   end 
>endmodule
>


> module cymometer #(parameter CLK_FS=50000000) 
> (   
>    input clk, 
>    input rst_n,  
>    input clk_fx,   
>    output reg [19:0] data_fx  );
>     parameter CNT_FS=500;
>     //define reg [19:0] cnt_fs; 
>     //生成门信号 reg gate; 
>      reg gate_fs_reg;  //中间寄存器 
>      reg gate_fs;
>      reg gate_fx0; 
>      reg gate_fx1;
>      reg gate_fs0; 
>      reg gate_fs1;
>     reg [19:0] count_fx;
>     reg [19:0] count_fx_reg; 
>     reg [19:0] count_fs; 
>     reg   [19:0] count_fs_reg;
>     wire gate_fs_en; 
>     wire gate_fx_en; //cnt_fs
>      always @(posedge clk_fx or negedge rst_n)  begin    
>       if(!rst_n)   
>          cnt_fs  <= 0;  
>         else  begin
>         if(cnt_fs==CNT_FS+20)
> 	        cnt_fs   <= 0;
> 	      else
>         cnt_fs    <=  cnt_fs+1;
>     end 
>   end
> 
> //gate
>  always @(posedge clk_fx or negedge rst_n)  begin   
>  if(!rst_n)
>       gate  <= 0; 	
>   else  begin 
>      if(cnt_fs < 20 || cnt_fs > CNT_FS)
> 	    gate  <= 0; 		
>     else
> 	     gate  <= 1;
>      end  
>   end   //gate_fs
>    always @(posedge clk or negedge rst_n) 
>    begin  if(!rst_n)   
>        begin   
>        gate_fs         <= 0;   
>        gate_fs_reg  <= 0;   
>    end  
>     else begin  
>          gate_fs_reg   <= gate;    
>          gate_fs          <= gate_fs_reg;   
>      end 
>   end
> 
> //基准信号下降沿 
> always @(posedge clk or negedge rst_n)  begin  
> if(!rst_n)  
>      begin  
>         gate_fs0  <= 0;  
>          gate_fs1 <= 0;   
>     end  
>     else begin  
>          gate_fs0   <= gate_fs;   
>          gate_fs1   <= gate_fs0;  
>         end 
>      end
> assign gate_fs_en=~gate_fs0&&gate_fs1;
> always @(posedge clk_fx or negedge rst_n)  begin  
> if(!rst_n)    
>    begin  
>        gate_fx0  <= 0;   
>        gate_fx1  <= 0;   
>       end  
>     else begin   
>         gate_fx0   <= gate;  
>         gate_fx1  <= gate_fx0;   
>       end
>     end   
>      assign  gate_fx_en=~gate_fx0&&gate_fx1;
>   always @(posedge clk_fx or negedge rst_n)  begin  
>   if(!rst_n)   
>    begin  
>       count_fx  <= 0;   
>        count_fx_reg <=0;   
>    end 
>  else begin   
>  if(gate==1)
>     count_fx_reg  <= count_fx_reg+1; 	
>   else if(gate_fx_en)
>     begin
>         count_fx_reg <= 0;
>          count_fx   <=  count_fx_reg; 	 
>          end   
>        end 
>  end
> 
> always @(posedge clk or negedge rst_n)  begin
>   if(!rst_n)    begin  
>        count_fs  <= 0;   
>        count_fs_reg  <= 0;   
>     end 
>  else  begin  
>   if(gate_fs==1)
>      count_fs_reg   <=  count_fs_reg+1; 
>  else if(gate_fs_en)  begin
>     count_fs_reg    <= 0;
>     count_fs           <= count_fs_reg; 	
>               end  
>          end 
>   end
> 
> //输出频率
>  always @(posedge clk or negedge rst_n)  begin      
>  if(!rst_n)   
>    data_fx  <= 0; 
>  else if(gate_fs==0)  
>    data_fx   <= CLK_FS/(count_fs/count_fx); 
>     end  
>  endmodule
> 
>

>   `timescale 1ns/1ns 
>   module frequency_tb; 
>   reg clk,rst_n; 
>   wire [19:0] data_fx;
> always #5 clk=~clk;
> initial 
> begin 
>   rst_n=0; 
>   clk=0;
> #100  rst_n=1;
> #70000000 $stop;
>  end
>   frequency inst(clk,rst_n,data_fx); 
>   endmodule


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值