华科数电大作业多功能数字钟.docx
《华科数电大作业多功能数字钟.docx》由会员分享,可在线阅读,更多相关《华科数电大作业多功能数字钟.docx(18页珍藏版)》请在冰点文库上搜索。
华科数电大作业多功能数字钟
数字逻辑
自主设计
多功能数字钟
报告人:
实验指导教师:
赵贻竹
报告批阅教师:
赵贻竹
计算机科学与技术学院
2015年06月26日
目录
多功能数字钟1
1.整体功能描述3
2.模块功能描述及设计思路3
2.1“clock“功能描述及设计思路3
2.2“myclock”功能描述及设计思路3
2.3”int_div“功能描述及设计思路4
2.4“clkgen“功能描述和设计思路4
2.5“disp_dec“功能描述及设计思想4
3.源程序及仿真程序5
3.1源程序5
3.2仿真程序11
4.验证结果13
1.整体功能描述
功能主要为计时和显示时间。
这里实现的电子表具有显示和调时功能,可以显示时、分、秒和毫秒,并通过按键进行工作模式的选择,工作模式有四种,分别是正常记时模式、调时模式、调分模式、调秒模式。
2.模块功能描述及设计思路
构成电子表的基本模块有5个,分别是顶层模块clock,时钟调校及计时模块myclock,整数分频模块int_div,时钟信号选择模块clkgen,七段显示模块disp_dec。
2.1“clock“功能描述及设计思路
clock模块的目的是将功能模块连接起来,实现完整功能。
输入:
iCLK_50——50Mhz时钟信号
RSTn——复位信号
FLAG——工作模式控制信号
UP——加1调节
DN——减1调节
输出:
H_dis——时数据的七段段码
M_dis——分数据的七段段码
S_dis——秒数据的七段段码
MS_dis——百分秒数据的七段段码
Mode——工作模式输出
H——时数据
M——分数据
S——秒数据
2.2“myclock”功能描述及设计思路
Myclock实现的功能是根据当前的工作状态进行时、分、秒的调整和正常计时。
端口信号:
输入:
RSTn——复位信号
CLK——100hz时钟信号
FLAG[1:
0]——工作模式信号,模式定义为:
00为正常显示,01为调时,10为调分,11为调秒
UP——调校模式下以加1方式调节信号
DN——调校模式下以减1方式调节信号
输出:
H[7:
0]——“时”数据(16进制)
M[7:
0]——“分”数据(16进制)
S[7:
0]——”秒“数据(16进制)
MS[7:
0]——”百分秒“数据(16进制)
设计思路是RTSn有效时,时分秒信号清0,否则根据工作模式控制信号FLAG的值决定当前工作状态。
正常工作时,对输入的100hz信号进行计数,并修改H,M,S,MS的计数值。
调时时,UP信号加1,DN信号减1。
调分和调秒时同调时。
2.3”int_div“功能描述及设计思路
Int_div实现对输入时钟clock进行F_DIV分频后输出clk_out。
设计思路:
F_DIV分频系数范围为1~2^n(n=F_DIV_WIDTH),若要改变分频系数,改变参数F_DIV或者F_DIV_WIDTH。
分频系数为偶数,输出时钟的占空比为50%,为奇数,时钟的输出占空比取决于输入占空比和分频系数。
2.4“clkgen“功能描述和设计思路
Clkgen用于提供时钟调校及计时模块所需要的时钟脉冲。
输入:
flag——时钟选择输入信号
clk_100hz——100hz时钟信号
clk_2hz——2hz时钟信号
输出:
Clkout——输出时钟信号
设计思路:
电子表工作在正常状态时选择100hz时钟信号,工作在调节状态下选用2hz时钟信号。
2.5“disp_dec“功能描述及设计思想
该模块用于将时间数据显示到数码管上。
即时钟的原始信号转换为十进制信号,再将十进制信号转换为七段段码。
设计思想:
本模块由BCD码显示模块和七段译码两个模块实现。
其中BCD码的功能是将8位二进制数转换为2位十进制数,之后进行七段码显示。
这样BCD模块内部需要调用七段显示模块。
hex为BCD输入信号,dispout为七段数码管段码。
七段显示模块的作用就是将十进制数转换为七段段码。
3.源程序及仿真程序
3.1源程序
moduleclock(iCLK_50,RSTn,FLAG,UP,DN,H_dis,M_dis,S_dis,MS_dis,Mode,H,M,S
);
inputiCLK_50;
inputRSTn,UP,DN;
input[1:
0]FLAG;
output[1:
0]Mode;
output[15:
0]H_dis,M_dis,S_dis,MS_dis;
output[7:
0]H,M,S;
wire[7:
0]MS;
wireclk_100hz,clk_2hz;
wireclk;
assignMode=FLAG;
int_div#(500000,32)nclk100(iCLK_50,clk_100hz);
int_div#(50000000,32)nclk2(iCLK_50,clk_2hz);
clkgenu0(FLAG,clk_100hz,clk_2hz,clk);
myclocku1(RSTn,clk,FLAG,UP,DN,H,M,S,MS);
disp_decHour(H,H_dis);
disp_decMinute(M,M_dis);
disp_decSecond(S,S_dis);
disp_dechour1(MS,MS_dis);
endmodule
//////////////////////////////////////////////////////////////////////////////////
//时钟调校及计时模块
modulemyclock(RSTn,CLK,FLAG,UP,DN,H,M,S,MS
);
inputRSTn,CLK,UP,DN;
input[1:
0]FLAG;
output[7:
0]H,M,S;
output[7:
0]MS;
reg[5:
0]m_H,m_M,m_S;
reg[6:
0]m_MS;
assignH=m_H;
assignM=m_M;
assignS=m_S;
assignMS=m_MS;
always@(posedgeCLK)
//复位状态
if(~RSTn)
begin
m_H<=8'd23;
m_M<=8'd52;
m_S<=8'b0;
m_MS<=8'b0;
end
//调时状态
elseif(FLAG==2'b01)
begin
if(UP)
begin
if(m_H==8'd23)
m_H<=8'd0;
else
m_H<=m_H+1'b1;
end
elseif(DN)
begin
if(m_H==8'h00)
m_H<=8'd23;
else
m_H<=m_H-1'b1;
end
end
//调分状态
elseif(FLAG==2'b10)
begin
if(UP)
if(m_M==8'd59)
m_M<=8'd0;
else
m_M<=m_M+1'b1;
elseif(DN)
if(m_M==8'h00)
m_M<=8'd59;
else
m_M<=m_M-1;
end
//调秒状态
elseif(FLAG==2'b11)
begin
if(UP)
if(m_S==8'd59)
m_S<=8'b0;
else
m_S<=m_S+1'b1;
elseif(DN)
if(m_S==8'h00)
m_S<=8'd59;
else
m_S<=m_S-1'b1;
end
//正常计时状态
else
begin
if(m_MS==8'd99)
begin
m_MS<=8'd0;
if(m_S==8'd59)
begin
m_S<=8'd0;
if(m_M==8'd59)
begin
m_M<=8'd0;
if(m_H==8'd23)
m_H<=0;
else
m_H<=m_H+1'b1;
end
else
m_M<=m_M+8'd1;
end
else
m_S<=m_S+1'b1;
end
else
m_MS<=m_MS+1'b1;
end
endmodule
//////////////////////////////////////////////////////////////////////////////////
//整数分频模块
moduleint_div(clock,clk_out);
//分频系数
parameterF_DIV=48000000;
//分频计数器宽度
parameterF_DIV_WIDTH=32;
//输入时钟
inputclock;
//输出时钟
outputclk_out;
regclk_p_r;
regclk_n_r;
reg[F_DIV_WIDTH-1:
0]count_p;
reg[F_DIV_WIDTH-1:
0]count_n;
//上升沿计数满标志
wirefull_div_p;
//上升沿计数半满标志
wirehalf_div_p;
//下降沿计数满标志
wirefull_div_n;
//下降沿计数半满标志
wirehalf_div_n;
//判断计数标志位置位与否
assignfull_div_p=(count_passignhalf_div_p=(count_p<(F_DIV>>1)-1);
assignfull_div_n=(count_nassignhalf_div_n=(count_n<(F_DIV>>1)-1);
//时钟输出
assignclk_out=(F_DIV==1)?
clock:
(F_DIV[0]?
(clk_p_r&clk_n_r):
clk_p_r);
//上升沿脉冲计数
always@(posedgeclock)
begin
if(full_div_p)
begin
count_p<=count_p+1'b1;
if(half_div_p)
clk_p_r<=1'b0;
else
clk_p_r<=1'b1;
end
else
begin
count_p<=0;
clk_p_r<=1'b0;
end
end
//下降沿脉冲计数
always@(negedgeclock)
begin
if(full_div_n)
begin
count_n<=count_n+1'b1;
if(half_div_n)
clk_n_r<=1'b0;
else
clk_n_r<=1'b1;
end
else
begin
count_n<=0;
clk_n_r<=1'b0;
end
end
endmodule
//////////////////////////////////////////////////////////////////////////////////
//时钟信号选择模块
moduleclkgen(flag,clk_100hz,clk_2hz,clkout
);
//若flag=0则clkout=100hz,否则为clkout=2hz
input[1:
0]flag;
inputclk_100hz,clk_2hz;
outputclkout;
assignclkout=(flag==2'b00)?
clk_100hz:
clk_2hz;
endmodule
//////////////////////////////////////////////////////////////////////////////////
//BCD码显示模块
moduledisp_dec(hex,dispout
);
//8位二进制输入数据
input[7:
0]hex;
//2位十进制的七段段码显示数据
output[15:
0]dispout;
reg[7:
0]dec;
always@(hex)
//8位二进制数转换成2位BCD码
begin
dec[7:
4]=hex/4'd10;
dec[3:
0]=hex%4'd10;
end
//调用2位共阳极七段显示模块
dual_hexul(1'b0,dec,dispout);
endmodule
//////////////////////////////////////////////////////////////////////////////////
//2位七段显示模块
moduledual_hex(iflag,datain,dispout
);
//共阴或共阳输出选择
inputiflag;
//2位的十进制或十六进制数据
input[7:
0]datain;
//2个七段段码数据
output[15:
0]dispout;
seg_decoderu1(iflag,datain[7:
4],dispout[15:
8]);
seg_decoderu2(iflag,datain[3:
0],dispout[7:
0]);
endmodule
//////////////////////////////////////////////////////////////////////////////////
//1位七段译码模块
moduleseg_decoder(iflag,iA,oY
);
//共阴或共阳输出选择
inputiflag;
//4位二进制数据
input[3:
0]iA;
//七段段码显示数据
outputreg[7:
0]oY;
always@(iflag,iA)
begin
//共阴极七段输出
case(iA)
4'b0000:
oY=8'h3f;
4'b0001:
oY=8'h06;
4'b0010:
oY=8'h5b;
4'b0011:
oY=8'h4f;
4'b0100:
oY=8'h66;
4'b0101:
oY=8'h6d;
4'b0110:
oY=8'h7d;
4'b0111:
oY=8'h27;
4'b1000:
oY=8'h7f;
4'b1001:
oY=8'h6f;
4'b1010:
oY=8'h77;
4'b1011:
oY=8'h7c;
4'b1100:
oY=8'h58;
4'b1101:
oY=8'h5e;
4'b1110:
oY=8'h79;
4'b1111:
oY=8'h71;
endcase
//共阳极七段输出
if(!
iflag)
oY=~oY;
end
endmodule
3.2仿真程序
`timescale1ns/1ps
////////////////////////////////////////////////////////////////////////////////
//Company:
//Engineer:
//
//CreateDate:
01:
34:
5106/26/2015
//DesignName:
clock
//ModuleName:
F:
/SIGNAIL/BIG/test.v
//ProjectName:
BIG
//TargetDevice:
//Toolversions:
//Description:
//
//VerilogTestFixturecreatedbyISEformodule:
clock
//
//Dependencies:
//
//Revision:
//Revision0.01-FileCreated
//AdditionalComments:
//
////////////////////////////////////////////////////////////////////////////////
moduletest;
//Inputs
regiCLK_50;
regRSTn;
reg[1:
0]FLAG;
regUP;
regDN;
//Outputs
wire[15:
0]H_dis;
wire[15:
0]M_dis;
wire[15:
0]S_dis;
wire[15:
0]MS_dis;
wire[1:
0]Mode;
wire[7:
0]H;
wire[7:
0]M;
wire[7:
0]S;
//InstantiatetheUnitUnderTest(UUT)
clockuut(
.iCLK_50(iCLK_50),
.RSTn(RSTn),
.FLAG(FLAG),
.UP(UP),
.DN(DN),
.H_dis(H_dis),
.M_dis(M_dis),
.S_dis(S_dis),
.MS_dis(MS_dis),
.Mode(Mode),
.H(H),
.M(M),
.S(S)
);
initialbegin
//InitializeInputs
iCLK_50=0;
RSTn=0;
FLAG=0;
UP=0;
DN=0;
//Wait100nsforglobalresettofinish
#100;
//Addstimulushere
end
endmodule
4.验证结果
FLAG=2‘b00,图中显示的时间是从23:
59:
49计数到0:
0:
7
FLAG=2’b01,调时过程
FLAG=2‘b10,调分过程
FLAG=2’b11,调秒过程