FPGA学习系列:33. 设计一个简单的二选一数据选择器

电子说

1.3w人已加入

描述

设计背景:

频率计又称为频率计数器,是一种专门对被测信号频率进行测量的电子测量仪器。频率计主要由四个部分构成:时基(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);

设计架构图:

设计代码:

设计模块

0module freq_meter (clk, rst_n, wave, freq, duty_cycle);  //端口列表

1

2 input clk;                   //时钟

3 input rst_n;                 //复位

4 input wave;                  //被测频率

5 output[25:0] freq;          //输出频率

6 output[6:0] duty_cycle; //输出占空比

7

8 reg[25:0] low_cnt;

9 reg[25:0] high_cnt;

10 reg[25:0] low_time;

11 reg[25:0] high_time;

12 reg state;

13

14 localparam high_state =1'b0;

15 localparam low_state =1'b1;

16

17 always@(posedge clk ornegedge rst_n)

18  begin

19   if(!rst_n)

20    begin

21    low_cnt <=26'd0;

22    high_cnt <=26'd0;

23    low_time <=26'd0;

24    high_time <=26'd0;

25    state <= high_state;

26    end

27   else

28   begin

29    case(state)

30     high_state :begin

31       if(wave ==1'b1)       //判断输入为高电平

32        begin

33         high_cnt <= high_cnt +1'b1;

34         state <= high_state;

35        end

36       else

37        begin

38         high_cnt <=26'd0;

39         high_time <= high_cnt;

40         state <= low_state;

41        end

42      end

43      

44     low_state :begin

45       if(wave ==1'b0)  //判断输入为低电平

46        begin

47         low_cnt <= low_cnt +1'b1;

48         state <= low_state;

49        end

50       else

51        begin

52         low_cnt <=26'd0;

53         low_time <= low_cnt;

54         state <= high_state;

55        end

56      end

57     default: state <= low_state;

58     endcase

59   end

60  end

61

62 assign freq =1_000_000_000/(low_time *20+ high_time *20);  //求频率

63 assign duty_cycle =(high_time *100)/(high_time + low_time);  //求占空比

64

65endmodule

测试模块

0`timescale1ns/1ps

1module freq_meter_tb;

2 reg clk;

3 reg rst_n;

4 reg wave;

5 wire[25:0] freq;

6 wire[6:0] duty_cycle;

7

8 initialbegin

9  clk =1'b1;

10  rst_n =1'b0;

11

12  #200.1

13   rst_n =1'b1;

14  #1_000_000_0//仿真10ms

15   $stop;

16 end

17

18 always#10 clk =~clk;

19

20 initialbegin

21  wave =1'b1;

22  foreverbegin//产生占空比为60%,频率为1KHz的方波

23   #600_000

24    wave =1'b0;

25   #400_000

26    wave =1'b1;

27  end

28 end

29

30 freq_meter freq_meter_dut(

31  .clk(clk),

32  .rst_n(rst_n),

33  .wave(wave),

34  .freq(freq),

35  .duty_cycle(duty_cycle)

36 );

37

38endmodule

仿真图:

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

相对的,如果测试的频率越大,测到的数值就越准确。


打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分