(一)设计原理:
图 1 设计原理图
如上图所示实现频率检测整体思路就是在1HZ的时钟周期内对被检测信号进行计数器计数,计数结果即为其频率。具体需要分为3个模块进行:
第一部分控制模块,即依次进行计数、存储计数结果、以及对之前的计数进行清0操作,本次实验U0模块即实现该功能,引入state对上述三种状态依次输出达到控制的目的,下图即为本模块的时序输出。
图 2 控制模块时序图
第二个模块为计数器模块,本次实验采用模为10的计数器,进行复用,师兄本实验的U1-U8模块,以输入信号fin为激励信号进行计数,将计数结果存放在q0-q7中,同时兼有rst异步清零以及clear同步清零。
第三个模块为锁存器结构,当锁存器使能时,计数结果从第二个模块传输到锁存器中,同时兼有锁存功能以及异步清零功能,最后结结果通过d0-d7输出出来。
仿真实现原理:首先利用rst复位信号对程序进行复位,使得程序正常工作,其次使用always+延迟参数 书写标准时钟clk_1HZ 以及输入激励信号fin。
(二)设计方案
module test(clk_1HZ,fin,rst,d0,d1,d2,d3,d4,d5,d6,d7);
input clk_1HZ,fin,rst;
output [3:0]d0,d1,d2,d3,d4,d5,d6,d7;
wire [3:0] q0,q1,q2,q3,q4,q5,q6,q7;
wire count_en,latch_en,clear;
control U0(clk_1HZ,rst,count_en,latch_en,clear);
counter_10 U1(count_en,clear,rst,fin,dout0,q0);
counter_10 U2(dout0,clear,rst,fin,dout1,q1);
counter_10 U3(dout1,clear,rst,fin,dout2,q2);
counter_10 U4(dout2,clear,rst,fin,dout3,q3);
counter_10 U5(dout3,clear,rst,fin,dout4,q4);
counter_10 U6(dout4,clear,rst,fin,dout5,q5);
counter_10 U7(dout5,clear,rst,fin,dout6,q6);
counter_10 U8(dout6,clear,rst,fin,dout7,q7);
latch U9(clk_1HZ,latch_en,rst,q0,q1,q2,q3,q4,q5,q6,q7,d0,d1,d2,d3,d4,d5,d6,d7);
endmodule
module control(clk_1HZ,rst,count_en,latch_en,clear);
input clk_1HZ,rst;
output count_en,latch_en,clear;
reg count_en,latch_en,clear;
reg [1:0]state;
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
begin
case(state)
2'd0:
begin
state<=2'd1;
count_en<=1'b1;
latch_en<=1'b0;
clear<=1'b0;
end
2'd1:
begin
state<=2'd2;
count_en<=1'b0;
latch_en<=1'b1;
clear<=1'b0;
end
2'd2:
begin
state<=2'd0;
count_en<=1'b0;
latch_en<=1'b0;
clear<=1'b1;
end
default:
begin
state<=2'd0;
count_en<=1'b0;
latch_en<=1'b0;
clear<=1'b0;
end
endcase
end
endmodule
module counter_10(din,clear,rst,fin,dout,q);
input din,rst,fin,clear;
output dout;
output [3:0]q;
reg dout;
reg [3:0]q;
always@(posedge fin or negedge rst)
if(!rst)
begin
dout<=1'b0;
q<=4'b0;
end
else if(din)
begin
if(q==4'b1001)
begin
q<=4'b0;
dout<=1'b1;
end
else
begin
q<=q+1'b1;
dout<=1'b0;
end
end
else if(clear)
begin
q<=4'b0;
dout=1'b0;
end
else
begin
q<=q;
dout=1'b0;
end
endmodule
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 test_tb;
reg clk_1HZ;
reg fin,rst;
wire[3:0] d0,d1,d2,d3,d4,d5,d6,d7;
test U11(clk_1HZ,fin,rst,d0,d1,d2,d3,d4,d5,d6,d7);
initial
begin
rst =1'b0;
fin = 1'b0;
clk_1HZ = 1'b0;
#5 rst = 1'b1;
#5 rst = 1’b0;
#5 rst = 1’b1;
end
always #5000_0000 fin = ~fin; //10HZ
always #50000_0000 clk_1HZ = ~clk_1HZ; //1HZ
endmodule
(四)结果分析
①根据仿真测试程序,输入的激励信号fin为10HZ信号,如下图仿真程序所示可以看出d1为1即表示,该仿真程序测试出的激励信号频率为10HZ。
图 3 10HZ输入仿真图
②对仿真测试语句进行修改 always #500_0000 fin = ~fin; //100HZ
得到输入激励信号为100HZ,同理可以从仿真图中看出d2为1即表示,该仿真程序测试出的激励信号频率为100HZ。由此可以外推出本次实验设计程序理论上可以实现对10HZ-10MHZ的方波信号的频率进行检测并通过8位数字进行对外显示。
图 4 100HZ输入仿真图