abcsmile的笔记 https://bbs.21ic.com/?820787 [收藏] [复制] [RSS]

日志

FPGA初学者入门实例:数字频率计(转)

已有 1279 次阅读2012-10-18 07:21 |系统分类:网上好文

昨晚翻箱倒柜终于把以前学FPGA时做的例子找出来了,比如说乒乓操作,流水线等等都是入门的经典实例,但那些都是单独独立的模块,数字频率计应该算是我用FPGA做的第一个完整的例子吧。

数字频率计的基本原理(关于这部分的内容网上有很多,大家可以参考看看)


  频率测量的方法常用的有测频法和测周法两种。


•测频法

      测频法的基本思想是让计数器在闸门信号的控制下计数1秒时间,计数结果是1秒内被测信号的周期数,即被测信号的频率。若被测信号不是矩形脉冲,则应先变换成同频率的矩形脉冲。测频法的原理框图如图3-1所示。

图中,秒脉冲作为闸门信号,当其为高电平时,计数器计数;低电平时,计数器停止计数。显然,在同样的闸门信号作用下,被测信号的频率越高,测量误差越小。当被测频率一定时,闸门信号高电平的时间越长,测量误差越小。但是闸门信号周期越长,测量的响应时间也越长。例如,闸门信号高电平时间为1秒,被测信号频率的真值为2Hz。

无论被测信号的频率是多少,测量时可能产生的最大绝对误差均为±1Hz,即

                   f测-f真=±1Hz

所以,最大相对误差为:σmax= (f测-f真)/ f真=±1/ f真

由上式可知,在闸门信号相同时,测频法的相对误差与被测信号的频率成反比。因此测频法适合于测量频率较高的信号。

 

 •测周法

       当被测信号频率较低时,为保证测量精度,常采用测周法。即先测出被测信号的周期,再换算成频率。测周法的实质是把被测信号作为闸门信号,在它的高电平的时间内,用一个标准频率的信号源作为计数器的时钟脉冲。若计数结果为N,标准信号频率为f1,则被测信号的周期为

               T = T1•N

被测信号的频率为

                  f = 1/T1•N = f1/N

利用测周法所产生的最大绝对误差,显然也等于±1个标准信号周期。如果被测信号周期的真值为T真= T1•N,则T测= T1•(N±1)

               σmax= (f测-f真)/ f真= T真/T测 – 1=±1/(N±1)

由上式可知,对于一定的被测信号,标准信号的频率越高,则N的值越大,因而相对误差越小。





数字频率计的基本设计方案

     数字频率计的关键组成部分包括一个测频控制信号发生器、一个计数器和一个锁存器,另外包含信号整形电路、脉冲发生器、译码驱动电路和显示电路。工作过程:系统正常工作时,脉冲信号发生器输入1Hz的标准信号,经过测频控制信号发生器的处理,2分频后即可产生一个脉宽为1秒的时钟信号,以此作为计数闸门信号。测量信号时,将被测信号通过信号整形电路,产生同频率的矩形波,输入计数器作为时钟。当计数闸门信号高电平有效时,计数器开始计数,并将计数结果送入锁存器中。设置锁存器的好处是显示的数据稳定,不会由于周期性的清零信号而不断闪烁。最后将锁存的数值由外部的七段译码器译码并在数码管上显示。




计数器模块


      由于系统要求的精度是0.1HZ~100000000HZ,该十进制计数模块由十个一位十进制计数器组成,计数器的特殊之处是,有一个时钟使能输入端ENA,用于锁定计数值。当高电平是计数允许,低电平时计数禁止。


      该测频的十位十进制频率计的计数模块,先通过Verilog语言编写一位十进制计数器,再将其原件例化后搭建一个十位十进制计数模块。


module CNT10(


            clk,


                          rst,


                          en,


                          cq,


                          carry_out


              );


input clk;


input rst;


input en;


output [3:0]cq;


output carry_out;


reg [3:0]cq;


reg carry_out;


always @(posedge clk)


begin


     if(!rst)


       begin


       cq       <=4'd0;


       carry_out<=1'b0;


       end


else begin


          if(en==1'b1)


                    begin


                         if(cq==4'd9)


                                 begin


                                 cq<=4'd0;


                                 carry_out<=1'b1;


                                 end


                    else begin


                         cq<=cq+4'd1;


                                 carry_out<=1'b0;


                                 end


                    end


       else begin


                 carry_out<=1'b0;


               cq<=4'd0;


          end        


     end


end


endmodule


数据锁存器


 


     锁存模块由锁存器构成,主要功能是数据的稳定显示,不会由于周期行的清零信号而不断闪烁。在信号LOAD的上升沿后即被所存到寄存器的内部,并由锁存器的输出端输出,然后由实验板的7段译码器译成能在数码管上显示的相对应的数值。


module REG32B(


              load,


                            din,


                            dout


                );


input load;


input[39:0]din;


output[39:0]dout;


reg[39:0]dout;


always @(load or din)


begin


     if(load==1'b1)


       dout<=din;


end


endmodule






·系统总体设计


    module FREQ(


               fsin,


                         clk,


                         dout2


                  );


input fsin;


input clk;


output[39:0]dout2;


wire TSTEN;


wire CLR_CNT;


wire LOAD;              


TESTCTL TESTCTL_u(


                                      .CLK     (clk),


                                          .TSTEN   (TSTEN),


                                          .CLR_CNT (CLR_CNT),


                                          .LOAD    (LOAD)


                                      );


wire[39:0]dout;


wire s1;


wire s2;


wire s3;


wire s4;


wire s5;


wire s6;


wire s7;


wire s8;


wire s9;


wire s10;


CNT10 CNT10_u1(


                              .clk       (fsin),


                              .rst       (CLR_CNT),


                              .en        (TSTEN),


                              .cq        (dout[3:0]),


                              .carry_out (s1)


                              );


                    


CNT10 CNT10_u2(


                              .clk       (s1),


                              .rst       (CLR_CNT),


                              .en        (TSTEN),


                              .cq        (dout[7:4]),


                              .carry_out (s2)


                              );


CNT10 CNT10_u3(


                              .clk       (s2),


                              .rst       (CLR_CNT),


                              .en        (TSTEN),


                              .cq        (dout[11:8]),


                              .carry_out (s3)


                              );


CNT10 CNT10_u4(


                              .clk       (s3),


                              .rst       (CLR_CNT),


                              .en        (TSTEN),


                              .cq        (dout[15:12]),


                              .carry_out (s4)


                              );


CNT10 CNT10_u5(


                              .clk       (s4),


                              .rst       (CLR_CNT),


                              .en        (TSTEN),


                              .cq        (dout[19:16]),


                              .carry_out (s5)


                              );


CNT10 CNT10_u6(


                              .clk       (s5),


                              .rst       (CLR_CNT),


                              .en        (TSTEN),


                              .cq        (dout[23:20]),


                              .carry_out (s6)


                              );




CNT10 CNT10_u7(


                              .clk       (s6),


                              .rst       (CLR_CNT),


                              .en        (TSTEN),


                              .cq        (dout[27:24]),


                              .carry_out (s7)


                              );


CNT10 CNT10_u8(


                              .clk       (s7),


                              .rst       (CLR_CNT),


                              .en        (TSTEN),


                              .cq        (dout[31:28]),


                              .carry_out (s8)


                              );


CNT10 CNT10_u9(


                              .clk       (s8),


                              .rst       (CLR_CNT),


                              .en        (TSTEN),


                              .cq        (dout[35:32]),


                              .carry_out (s9)


                              );


CNT10 CNT10_u10(


                              .clk       (s9),


                              .rst       (CLR_CNT),


                              .en        (TSTEN),


                              .cq        (dout[39:36]),


                              .carry_out (s10)


                              );


REG32B REG32B_u(


                                    .load (LOAD),


                                    .din  (dout),


                                    .dout (dout2)


                                    );

endmodule





 


ISE/Modelsim联合仿真

     一般对于系统的仿真,我们均采用Modelsim进行,我们在建立工程的时候,将仿真设置为Modelsim即可

路过

鸡蛋

鲜花

握手

雷人

评论 (0 个评论)