基于FPGA的数字频率测量仪
- 格式:doc
- 大小:63.50 KB
- 文档页数:9
EDA实验报告
题目:基于FPGA的数字频率测量仪姓名:吕游
学号:201212171909
1.实验目的
1)掌握偶数倍分频电路的设计思路。
2)掌握带有计数使能输入端和异步清零功能的模为10的计数模块。
3)掌握动态扫描数码管的计数的工作原理及其使用方法。
2.实验任务
1)利用所学的知识设计一个4位的频率计,可以测量从1-9999Hz的信号频率。
2)将被测信号的频率在四个动态数码管上显示出来。采用文本设计的方法,设计软件用Quartus2。
3.实验原理
1. 功能与原理
采用一个标准的基准时钟,在单位时间(如1s)里对被测信号的脉冲数进行计数。
即为信号的频率。4位数字频率计的顶层框如下图所示,整个系统分三个模块:控制模块、计数测量模块和数据锁存器。
1)控制模块
控制模块的作用是产生测频所需要的各种控制信号。控制模块的标准输入时钟为
1Hz,每两个周期进行一次频率测量。该模块产生三个控制信号,分别是:count_en,count_clr和load。Count_clr信号用于在每一次测量开始时,对计数模块进行复位,以清除上次测量的结果。复位信号高电平有效,持续半个时钟周期的时间。Count_en 信号为计数允许信号,在Count_en信号的上升沿时刻,计数模块开始对输入信号的频率进行测量,测量时间恰为一个时钟周期(1s),在此时间里对被测信号的脉冲数进行计数,即为信号的频率。然后将该值锁存,并送到数码管显示出来。设置锁存器的好处是,显示的数据稳定,不会由于周期性的清零信号而闪烁不断。在每一次测量开始时,都必须重新对计数模块清零。
控制模块所产生的几个控制信号的时序关系如下图所示。从图中可以看到,计数使能信号Count_en在1s的高电平后,利用其反相值的上跳沿产生一个锁存信号Load,然后产生清零信号上升沿。
2)锁存器模块
锁存器模块也是必不可少的。测频模块测量完后,在Load信号的上升沿时刻将测量值锁存到寄存器中,然后输出,送到实验板上的数码管上显示出相应的数据。
3)计数模块
计数模块用于在单位时间中对输入信号的脉冲数进行计数,该模块必须有计数允许、异步清零等端口,以便于控制模块对其进行控制。
2. 设计实现
4位数字频率测试仪的顶层原理图,其中fre_ctrl是控制模块,count_10是计数模块,latch_16是16位锁存器模块。这三个模块都采用文本方式设计实现。
1) fre_ctrl控制模块
fre_ctrl控制模块用Verilog HDL语言描述如下:
module fre_ctrl(clk, rst,count_en,count_clr,load);
input clk,rst;
output count_en,count_clr,load;
reg count_en,load;
always @(posedge clk)
begin if(rst)
begin count_en<=0;
load<=1;
end
else
begin count_en<=~count_en;
load<=~count_en;
end
end
assign count_clr=~clk&load;
endmodule
2)Count10计数模块
Count10是一个带有计数使能输入端(EN)和异步清零(CLR)的模为10的计数模块。当EN为高电平时开始计数,为低电平时停止计数。CLR为异步清零端,当它为高电平时,计数器输出为零。
4位数字频率计计数子模块
module count10(out,cout,en,clr,clk);
input en,clr,clk;
output [3:0] out;output cout;reg [3:0] out;
always@(posedge clk or posedge clr)
begin
if(clr)
out<=0;
else if(en)
begin if(out==9)
out<=0;
else out<=out+1;
end
end
assign cout=((out==9)&en)?1:0;
endmodule
3)16位锁存器模块Latch_16
module latch_16(qo,din,load);
input load;
input[15:0] din;
output [15:0] qo;
reg[15:0] qo;
always@(posedge load)
begin
qo<=din;
end
endmodule
3)数字频率计的顶层文件
数字频率计的顶层采用文本输入的方式,在顶层文件中调用子模块,采用例化的方式编写程序。顶层中还包括偶数倍分频和动态数码管扫描程序,以实现特定的功能。
顶层文件的Verilog HDL如下:
module prequency(clk,signal,seg7,hex);
input clk, signal;
output[6:0] seg7;
output[3:0] hex;
wire[15:0] din;
wire[15:0] q;
wire cout_1, cout_2, cout_3, cout_4;
wire en, clr, load;
reg [6:0] seg7;
reg [3:0] hex;
reg [3:0] dat;
reg [24:0] cnt;
reg clk_cnt;
always@(posedge clk )
begin if (cnt==25'b1011111010111100000111111) begin clk_cnt<=~clk_cnt;
cnt<=0;
end
else cnt<=cnt+1;
end
wire rst;
assign rst=1'b0;
fre_ctrl inst1 (
.clk(clk_cnt),
.rst(rst),
.count_en(en),
.count_clr(clr),
.load(load)
);
count10 count10_1(
.out(din[3:0]),
.cout(cout_1),
.en(en),
.clr(clr),