数字频率计的设计
1、module test(clk,rst_n,fre,duan,dig,clk_1ms);
input clk,rst_n,fre;
output [6:0]duan;
output [3:0]dig;
output clk_1ms;
reg [12:0]fre_out;
wire fre;
reg [31:0]cnt1;
reg [31:0]cnt2;
reg clk_1s;
//声明输入,输出端口和用到的变量
2、/*********************0.5hz clock************************************/
always@(posedge clk or negedge rst_n)begin
if(!rst_n)begin
cnt1<=0;
clk_1s<=0;
end
else if(cnt1==32'd50000000)begin
cnt1<=0;
clk_1s<=~clk_1s;
end
else
cnt1<=cnt1+1;
end
//通过分频获得周期为2s的时钟,用于计数
3、/**********************2s clock register ************************/
reg clk_1s_temp;
always@(posedge clk or negedge rst_n)begin
if(!rst_n)begin
clk_1s_temp<=0;
end
else
clk_1s_temp<=clk_1s;
end
/***********************2s clock register ************************/
reg clk_1s_temp2;
always@(posedge clk or negedge rst_n)begin
if(!rst_n)
clk_1s_temp2<=0;
else
clk_1s_temp2<=clk_1s_temp;
end
//2s时钟寄存器,用于判断上升沿或下降沿
4、/***********************input signal register ********************/
reg fre_temp;
always@(posedge clk or negedge rst_n)begin
if(!rst_n)
fre_temp<=0;
else
fre_temp<=fre;
end
/***********************input signal register *******************/
reg fre_temp2;
always@(posedge clk or negedge rst_n)begin
if(!rst_n)
fre_temp2<=0;
else
fre_temp2<=fre_temp;
end
//输入信号寄存器,用于判断输入信号的上升沿判断
5、/***********************counter *******************/
always@(posedge clk or negedge rst_n)begin
if(!rst_n)
cnt2<=0;
else if((~clk_1s_temp)&(clk_1s_temp2))//当 clk_1s 有下降沿,cnt2 归 0
cnt2<=0;
else if((~fre_temp)&(fre_temp2)&clk_1s)//当输入信号 fre 有上升沿
cnt2<=cnt2+1; // clk_1s信号 值为 1,cnt2 值加1
end
//计数器
6、/**************** pass cnt2 to fre_out ****************/
always@(posedge clk or negedge rst_n)begin
if(!rst_n)
fre_out<=0;
else if((~clk_1s)&(clk_1s_temp))//negative edge pass value
fre_out<=cnt2;
end
//把cnt2的值传递给fre_out
/**************** 1ms clock ****************/
reg [31:0]cnt;
reg clk_1ms;
always @(posedge clk or negedge rst_n)begin
if(!rst_n)
cnt<=0;
else if(cnt==17'd100000)begin//250hz
cnt<=0;
clk_1ms<=~clk_1ms;
end
else cnt<=cnt+1;
end
//1ms时钟用于数码管显示模块
7、/**************** Digital tube display section ****************/
reg [3:0]dig;
reg [6:0]duan;
wire [3:0]thou,hun,ten,one;
assign thou=(fre_out/1000)%10;
assign hun=(fre_out/100)%10;
assign ten=(fre_out/10)%10;
assign one=(fre_out)%10;
always@(posedge clk_1ms or negedge rst_n)begin
if(!rst_n)begin
dig=4'b1110;
end
else
dig={dig[0],dig[3:1]};
end
8、always@(posedge clk_1ms)begin
if(!rst_n)begin
duan<=7'b1111111;
end
else begin
case(dig)
4'b0111:begin case(hun)
4'd0:duan<=7'b1000000;
4'd1:duan<=7'b1111001;
4'd2:duan<=7'b0100100;
4'd3:duan<=7'b0110000;
4'd4:duan<=7'b0011001;
4'd5:duan<=7'b0010010;
4'd6:duan<=7'b0000010;
4'd7:duan<=7'b1111000;
4'd8:duan<=7'b0000000;
4'd9:duan<=7'b0010000;
default:;
endcase
end
4'b1011:begin
case(ten)
4'd0:duan<=7'b1000000;
4'd1:duan<=7'b1111001;
4'd2:duan<=7'b0100100;
4'd3:duan<=7'b0110000;
4'd4:duan<=7'b0011001;
4'd5:duan<=7'b0010010;
4'd6:duan<=7'b0000010;
4'd7:duan<=7'b1111000;
4'd8:duan<=7'b0000000;
4'd9:duan<=7'b0010000;
default:;
endcase
end
4'b1101:begin
case(one)
4'd0:duan<=7'b1000000;
4'd1:duan<=7'b1111001;
4'd2:duan<=7'b0100100;
4'd3:duan<=7'b0110000;
4'd4:duan<=7'b0011001;
4'd5:duan<=7'b0010010;
4'd6:duan<=7'b0000010;
4'd7:duan<=7'b1111000;
4'd8:duan<=7'b0000000;
4'd9:duan<=7'b0010000;
default:;
endcase
end
4'b1110:begin
case(thou)
4'd0:duan<=7'b1000000;
4'd1:duan<=7'b1111001;
4'd2:duan<=7'b0100100;
4'd3:duan<=7'b0110000;
4'd4:duan<=7'b0011001;
4'd5:duan<=7'b0010010;
4'd6:duan<=7'b0000010;
4'd7:duan<=7'b1111000;
4'd8:duan<=7'b0000000;
4'd9:duan<=7'b0010000;
default:;
endcase
end
default:duan<=7'b0000000;
endcase
end
end
endmodule