相关文章:
Verilog上机实验题目1:8位数字显示的简易频率计
Verilog上机实验题目2:11位巴克码序列峰值检测器
Verilog上机实验题目3:FIR滤波器
Verilog上机实验题目4:哈夫曼编码器
转载自https://blog.csdn.net/Reborn_Lee/article/details/80377207
简易数字频率计
原理:数字频率计的原理十分简单,简单的就是一句话和一幅图而已。
一句话:测量被测信号的频率,要清楚频率的定义,一言以蔽之,就是1s中信号的周期数,这不就是周期的倒数吗?
根据频率的定义,我们测量被测信号1s中变化的次数即可,即1s中的周期数。
首先我们设置一个基准时钟信号,频率为1Hz,从第一个上升沿开始计数(被测信号的上升沿数),直到下一个上升沿到达时停止计数,对数据进行锁存,再到达下一个上升沿时,对计数器进行清零,准备下一次的测量。
一幅图:
本图是简易频率计的工作时序图,从图中 可以看出:
基准信号的第一个上升沿到达时,计数使能信号有效,计数器开始计数;
第二上升沿到达时,计数结束,锁存使能有效,计数数据开始锁存;
第三个上升沿到达时,清零信号有效,对计数器的输出清零,准备下一次的测量。
一个测量过程需要3 sec(重要)。
下面是数字频率计的原理图:
由此原理图可以清晰的理解下面的verilog HDL程序:
- //简易频率计设计
- module freDetect(clk_1Hz, fin, rst, d0, d1, d2, d3, d4, d5, d6, d7);
- input clk_1Hz;//1Hz基准频率
- input fin; //待测信号
- input rst; //复位信号
- output[3:0] d0, d1, d2, d3, d4, d5, d6, d7; //8位显示测量数据
- wire[3:0] q0, q1, q2, q3, q4, q5, q6, q7; //中间数据
- wire[3:0] d0, d1, d2, d3, d4, d5, d6, d7;
- //控制模块实例
- control u_control(.clk_1Hz(clk_1Hz), .rst(rst), .count_en(count_en),
- .latch_en(latch_en), .clear(clear));
- //计数器模块实例
- counter_10 counter0(.en_in(count_en), .clear(clear), .rst(rst),
- .fin(fin), .en_out(en_out0), .q(q0));
- counter_10 counter1(.en_in(en_out0), .clear(clear), .rst(rst),
- .fin(fin), .en_out(en_out1), .q(q1));
- counter_10 counter2(.en_in(en_out1), .clear(clear), .rst(rst),
- .fin(fin), .en_out(en_out2), .q(q2));
- counter_10 counter3(.en_in(en_out2), .clear(clear), .rst(rst),
- .fin(fin), .en_out(en_out3), .q(q3));
- counter_10 counter4(.en_in(en_out3), .clear(clear), .rst(rst),
- .fin(fin), .en_out(en_out4), .q(q4));
- counter_10 counter5(.en_in(en_out4), .clear(clear), .rst(rst),
- .fin(fin), .en_out(en_out5), .q(q5));
- counter_10 counter6(.en_in(en_out5), .clear(clear), .rst(rst),
- .fin(fin), .en_out(en_out6), .q(q6));
- counter_10 counter7(.en_in(en_out6), .clear(clear), .rst(rst),
- .fin(fin), .en_out(en_out7), .q(q7));
- //锁存器模块实例
- latch u_latch(.clk_1Hz(clk_1Hz), .rst(rst), .latch_en(latch_en),
- .q0(q0), .q1(q1), .q2(q2), .q3(q3), .q4(q4), .q5(q5),
- .q6(q6), .q7(q7), .d0(d0), .d1(d1), .d2(d2), .d3(d3),
- .d4(d4), .d5(d5), .d6(d6), .d7(d7));
- endmodule
- //控制模块
- //控制模块产生计数使能信号、锁存使能信号和计数器清零信号
- module control(clk_1Hz, rst, count_en, latch_en, clear);
- input clk_1Hz;
- input rst;
- output count_en;
- output latch_en;
- output clear;
- reg[1:0] state; //状态信号,用于控制各种使能信号
- reg count_en;
- reg latch_en;
- reg clear;
- always @(posedge clk_1Hz or negedge rst)
- if(!rst) //复位信号有效
- begin //各种使能信号清零
- state <= 2’d0;
- count_en <= 1’b0;
- latch_en <=1’b0;
- clear <= 1’b0;
- end
- else //遇到基准信号的下一个上升沿,状态变化一次,每次变化后状态持续1s
- begin
- case(state)
- 2’d0:
- begin //第一个上升沿到达,开始计数,计数1个基准信号周期内待测信号的上升沿个数,此个数即为待测信号的频率
- count_en <= 1’b1; //计数使能信号有效
- latch_en <=1’b0;
- clear <= 1’b0;
- state <= 2’d1;
- end
- 2’d1:
- begin //第二个上升沿到达,计数完成,锁存使能信号有效,测得频率锁存至锁存器中
- count_en <= 1’b0;
- latch_en <=1’b1;
- clear <= 1’b0;
- state <= 2’d2;
- end
- 2’d2:
- begin //第三个上升沿到达,清零使能信号有效,计数器清零,为下一次计数做准备
- count_en <= 1’b0;
- latch_en <=1’b0;
- clear <= 1’b1;
- state <= 2’d0; //状态清零,进入下一次测量
- end
- default:
- begin
- count_en <= 1’b0;
- latch_en <=1’b0;
- clear <= 1’b0;
- state <= 2’d0;
- end
- endcase
- end
- endmodule
- //计数模块
- //模10计数器,当计数使能时计数开始,当计数器到达4’b1001,即9时,输出下一模式计数器的使能信号并将计数器清零
- module counter_10(en_in, rst, clear, fin, en_out, q);
- input en_in; //输入使能信号
- input rst; //复位信号
- input clear; //清零信号
- input fin; //待测信号
- output en_out; //输出使能,用于控制下一个计数器的状态,当输出使能有效时,下一个模10计数器计数加1
- output[3:0] q; //计数器的输出,4位BCD码输出
- reg en_out;
- reg[3:0] q;
- always@ (posedge fin or negedge rst) //输入待测信号的上升沿作为敏感信号
- if(!rst) //复位信号有效,计数器输出清零
- begin
- en_out <= 1’b0;
- q <= 4’b0;
- end
- else if(en_in) //进位输入使能信号有效
- begin
- if(q == 4’b1001) //若q = 4’b1001的话,q清零,同时进位输出使能有效,即en_out 赋值为1’b1
- begin
- q <= 4’b0;
- en_out <= 1’b1;
- end
- else //若q未达到4’b1001时,每到达待测信号的一个上升沿,q加1,同时输出进位清零
- begin
- q <= q + 1’b1;
- en_out <=1’b0;
- end
- end
- else if(clear) //若清零信号有效,计数器清零,主要用于为下一次测量准备
- begin
- q <= 4’b0;
- en_out <= 1’b0;
- end
- else
- begin
- q <= q;
- en_out <=1’b0;
- end
- endmodule
- //锁存器模块
- //当锁存使能时,锁存器将8个模10计数器的输出值锁存并输出
- module latch(clk_1Hz, latch_en, rst, q0, q1, q2, q3, q4, q5, q6, q7,
- d0, d1, d2, d3, d4, d5, d6, d7);
- input clk_1Hz, latch_en, rst;
- input[3:0] q0, q1, q2, q3, q4, q5, q6, q7;
- output[3:0] d0, d1, d2, d3, d4, d5, d6, d7;
- reg[3:0] d0, d1, d2, d3, d4, d5, d6, d7;
- always@ (posedge clk_1Hz or negedge rst)
- if(!rst) //复位信号有效时输出清零
- begin
- d0 <= 4’b0; d1 <= 4’b0; d2 <= 4’b0; d3 <= 4’b0; d4 <= 4’b0;
- d5 <= 4’b0; d6 <= 4’b0; d7 <= 4’b0;
- end
- else if(latch_en) //锁存信号有效时,将计数器的输出信号锁存至锁存器
- begin
- d0 <= q0; d1 <= q1; d2 <= q2; d3 <= q3; d4 <= q4;
- d5 <= q5; d6 <= q6; d7 <= q7;
- end
- else //上面两种情况均未发生时,输入不变
- begin
- d0 <= d0; d1 <= d1; d2 <= d2; d3 <= d3; d4 <= d4;
- d5 <= d5; d6 <= d6; d7 <= d7;
- end
- endmodule
测试文件为:
- `timescale 1ns/1ps
- //测试模块
- module freDetect_tb;
- parameter CLK_1HZ_DELAY = 5_0000_0000; //1Hz基准信号
- parameter FIN_DELAY = 100; //5MHz待测信号
- reg clk_1Hz;
- reg fin;
- reg rst;
- wire[3:0] d0, d1, d2, d3, d4, d5, d6, d7;
- initial
- begin
- rst =1’b0;
- #1 rst = 1’b1;
- end
- initial
- begin
- fin = 1’b0;
- forever
- #FIN_DELAY fin = ~fin;
- end
- initial
- begin
- clk_1Hz = 1’b0;
- forever
- #CLK_1HZ_DELAY clk_1Hz = ~clk_1Hz;
- end
- freDetect freDetect1(.clk_1Hz(clk_1Hz), .rst(rst), .fin(fin),
- .d0(d0), .d1(d1), .d2(d2), .d3(d3), .d4(d4), .d5(d5), .d6(d6), .d7(d7));
- endmodule
在Modelsim中仿真得到的波形图为:
看不清,再截一张:
相关文章:
Verilog上机实验题目1:8位数字显示的简易频率计
Verilog上机实验题目2:11位巴克码序列峰值检测器
Verilog上机实验题目3:FIR滤波器
Verilog上机实验题目4:哈夫曼编码器