基于 FPGA 的数字频率计的源代码
主模块 top
module
top(clk,rst_n,fre_in,LCD_E,LCD_DI,LCD_RW,LCD_CS_0,LCD_CS_1,LCD_RESET,LCD_DATA,BUSY_DAT
A,write
);
input clk;
input rst_n;
input fre_in;//输入频率
output
output
output
output
output
output
output
output
inout
LCD_E;
LCD_DI;
LCD_RW;
LCD_CS_0;
LCD_CS_1;
LCD_RESET;
[7:0]BUSY_DATA;
write;
[7:0]LCD_DATA;
wire
wire
[19:0] fre_out;
[3:0] million,hunthousand,tenthousand,thousand,hundred,ten,one;
fre_meter
fre_meter(
.clk(clk),
.rst_n(rst_n),
.fre_in(fre_in),
.fre_out(fre_out)
);
bin_dec
bin_dec(
.clk(clk),
.rst(rst_n),
.hex(fre_out),
.million(million),
.hunthousand(hunthousand),
.tenthousand(tenthousand),
.thousand(thousand),
.hundred(hundred),
.ten(ten),
.one(one)
);
(
clk,//系统时钟 50MHZ
LCD_E,
LCD_DI,
LCD_RW,
LCD_CS_0,
LCD_CS_1,
LCD_RESET,
LCD_DATA,//LCD 数据口
BUSY_DATA,//读 LCD 状态输出
write
);
LCD
LCD
endmodule
测频模块 fre_meter
//rst_n 为异步复位信号,fre_in 为被测输入信号
// 被测频率输出值,由最高1MHz,二进制达20bit 宽
//enb 为使能端
//lob 为使能端处的反转载入信号,clr 为清零信号
modulefre_meter(clk,rst_n,fre_in,fre_out
);
input
clk,rst_n,fre_in;
output[19:0]
fre_out;
[19:0]
fre_out;
reg
reg
[30:0]count1,count2;//两个计数器,count1 为分频计数器,count2 为频率值计数
器,将频率值传给fre_out
reg
clk_1hz,enb;
wire
lob,clr;
////////////////////////////////////////////////进行分频
always@(posedgeclkornegedgerst_n)
begin
//如果进行复位(处于低电平),进行if 条件栏
if(!rst_n)
begincount1<=0;
clk_1hz<=0;
endelsebeginif(count1<25000000-1)
方波begin
//将50MHz 的失踪进行分频,得到一个2Hz 占空比1:1 的
//分频器的计数器加一,
count3<=count3+1;
count1<=count1+1;
clk_1hz<=1;
endelseif(count1<50000000-1)
begincount1<=count1+1;
clk_1hz<=0;
end
elsebegincount1<=0;
clk_1hz<=0;
end
endend////////////////////////////////////////检测脉冲宽度
/*always@(posedgeclkornegedgerst_n)
beginif(!rst_n)count3<=0;
elsebeginif(clk_in)
end
endassignclk_1=~clk_in;
always@(posedgeclk_1ornegedgerst_n)
beginif(!rst_n)
pulse_width<=0;
elsebegin
pulse_width<=count3;
//单位us,clk 周期为20ns
count3<=0;
endend*/
//////////////////////////////////////////////////测量频率值
always@(posedgeclk_1hzornegedgerst_n )//negedge 为下降沿
begin
if(!rst_n)
enb<=0;
elsebegin
enb<=~enb;
//使能端处于低电平
//使能端取反,为载入信号做准备
//计数器加1,直至加到所测的频率值为止
endend
//进行相应的逻辑运算
assignload=~enb;
assignclr=load&&(~clk_1hz);
always@(posedgefre_inorposedgeclr)
beginif(clr)
//进行清零操作
count2<=0;
elsebeginif(enb)
count2<=count2+1;
elsecount2<=count2;
end
end
always@(posedgeloadornegedgerst_n)
beginif(!rst_n)
begin
fre_out<=0;
endelsefre_out<=count2/2;
end
endmodule
modulebin_dec(clk,rst,hex,million,hunthousand,tenthousand,thousand,hundred,ten,one
);
//hex 为20bit 的二进制频率值,rst 为异步复位信号
clk;
input
rst;
input
[19:0]hex;
input
reg[3:0] million;
output
reg[19:0]d5;
output
reg[3:0] hunthousand;
//将计数器中的频率值传送给fre_out
进制转换模块 bin_dec
//百万位
//十万位
//万位
//千位
//百位
//十位
//频率测量值最低为100Hz
output
output
output
output
output
reg[19:0]d6;
reg[3:0]
tenthousand;
reg[19:0]d1;
thousand;
reg[3:0]
reg[16:0]d2;
reg[3:0] hundred;
reg[16:0]d3;
reg[3:0]
ten;
reg[3:0]d4;
reg[3:0] one;
initialbeginmillion=4'h0;
d5=20'h00000;
hunthousand=4'h0;
d6=20'h00000;
tenthousand=4'h0;
d1=20'h00000;
thousand=4'h0;
d2=16'h0000;
hundred=4'h0;
d3=16'h0000;
d4=4'h0;
end
//百万位
always@(posedgeclk)begin
if(!rst)
位
//进行同步复
end elsebegin
begin
million<=4'h0;
d5<=20'h00000;
if(hex>999999)begin
million<=4'd1;
d5<=hex-20'd1000000;
endelsebegin
million<=4'd0;
d5<=hex;
end
//进行十万位的每位转换,大于某一特定值分别输入9,8,7,6,5,4,3,2,1,0 等
//同步复位
end
end
always@(posedgeclk)begin
if(!rst)begin
endelsebegin
hunthousand<=4'h0;
d6<=20'h00000;
if(d5>899999)begin
hunthousand<=4'd9;
d6<=d5-20'd900000;
endelseif(d5>799999)begin
hunthousand<=4'd8;
d6<=d5-20'd800000;
endelseif(d5>699999)begin
hunthousand<=4'd7;
d6<=d5-20'd700000;
endelseif(d5>599999)begin
hunthousand<=4'd6;
d6<=d5-20'd600000;
endelseif(d5>499999)begin
hunthousand<=4'd5;
d6<=d5-20'd500000;
endelseif(d5>399999)begin
hunthousand<=4'd4;
d6<=d5-20'd400000;
endelseif(d5>299999)begin
hunthousand<=4'd3;
d6<=d5-20'd300000;
endelseif(d5>199999)begin
hunthousand<=4'd2;
d6<=d5-20'd200000;
endelseif(d5>99999)begin
hunthousand<=4'd1;
d6<=d5-20'd100000;
endelsebegin
hunthousand<=4'd0;
d6<=d5;
end
end
end//万位
always@(posedgeclk)begin
if(!rst)begin
tenthousand<=4'h0;
d1<=20'h00000;
if(d6>89999)begin
endelsebegin
tenthousand<=4'd9;
d1<=d6-20'd90000;
endelseif(d6>79999)begin
tenthousand<=4'd8;
d1<=d6-20'd80000;
endelseif(d6>69999)begin
tenthousand<=4'd7;
d1<=d6-20'd70000;
//同步复位