设计背景:
频率计又称为频率计数器,是一种专门对被测信号频率进行测量的电子测量仪器。频率计主要由四个部分构成:时基(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);
设计架构图:
设计代码:
设计模块
0 module 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 or negedge 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
65 endmodule
测试模块
0 `timescale 1ns/1ps
1 module 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 initial begin
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 initial begin
21 wave = 1'b1;
22 forever begin//产生占空比为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
38 endmodule
仿真图:
由于在前面没有测完一个周期出现了不稳定的因素,就出现了不准确的数值,当测试完一个周期以后,测到的数值就比较的准确,基本的没有什么误差。
相对的,如果测试的频率越大,测到的数值就越准确。
全部0条评论
快来发表一下你的评论吧 !