概述
设计要求:
1.设计一个12/24小时制数字钟。
2.按下时调整键,“时”迅速增加,并按24/12小时制规律循环。
3.按下分调整键,“分”迅速增加,并按60分制规律循环。
4.按下秒清零键,“秒”清零。
5.整点报时,从59分55秒开始报时,每隔一秒报时一次。
6.具有12/24小时显示切换的功能。
7.增加万年历功能,输入2000~2100年任意一天日期,输出为周几。
8.具有按键切换功能,在日期,周几,计时三种显示模式中切换。
模块设计
分频模块
分频产生2k,1k,50,10,2,1等频率的信号,占空比尽量都为50%,为此,设计任意整数进制占空比50%的分频模块。
代码如下:
module fenpin(clk,N,clk_out);
input clk;
output clk_out;
input[15:0] N;
reg[15:0] count1,count2;
reg clkA,clkB;
assign clk_re = ~clk;
assign clk_out = clkA | clkB;
always@(posedge clk)
if(N%2==1)
begin
if(count1<N-1)
begin
count1<=count1+1'b1;
if(count1==(N-1)/2)
begin
clkA<=~clkA;
end
end
else
begin
clkA<=~clkA;
count1<=1'b0;
end
end
else
begin
if(count1<N/2-1)
begin
count1<=count1+1'b1;
end
else
begin
clkA<=~clkA;
count1<=1'b0;
end
end
always@(posedge clk_re)
if(N%2==1)
begin
if(count2<(N-1))
begin
count2<=count2+1'b1;
if(count2==(N-1)/2)
begin
clkB<=~clkB;
end
end
else
clkB=1'b0;
end
endmodule
调用时只要将N改为对应的分频系数即可。
对应代码如下:
module clock_fenpin(clk_50M,clk_2k,clk_1k,clk_50,clk_10,clk_2,clk_1);
input clk_50M;
output clk_2k,clk_1k,clk_50,clk_10,clk_2,clk_1;
fenpin(clk_50M,25000,clk_2k);
fenpin(clk_2k,2,clk_1k);
fenpin(clk_1k,20,clk_50);
fenpin(clk_50,5,clk_10);
fenpin(clk_50,25,clk_2);
fenpin(clk_2,2,clk_1);
endmodule
时间计数模块
由一个12/24计数器和两个60进制计数器组成,要实现时分的迅速增加和秒的清零,可以由一个二选一的数选器控制计数器的计数时钟,具体实现如下:
带清零的60进制计数:
module counter60_S(clk_1,rst,key_S,cout,dout_H,dout_L);
input clk_1,rst,key_S;
output [3:0] dout_H,dout_L;
reg[7:0] cnt;
output reg cout;
wire rst_tmp;
assign dout_H=cnt[7:4];
assign dout_L=cnt[3:0];
assign rst_tmp=key_S?rst?1:0:0;
always@(posedge clk_1 or negedge rst_tmp)
begin
if(!rst_tmp)
cnt = 0;
else
begin
if(cnt == 'h59)
begin
cnt = 0;
cout=1;
end
else
begin
cout=0;
cnt<=cnt+1;
if(cnt[3:0]=='h9)
begin
cnt[3:0]=0;
cnt[7:4]=cnt[7:4]+1;
end
end
end
end
endmodule
可以迅速增加的60进制分计数器:
module counter60_M(clk_s,clk_2,rst,key_M,cout,dout_H,dout_L);
input clk_s,clk_2,rst,key_M;
output [3:0] dout_H,dout_L;
reg[7:0] cnt;
output reg cout;
wire clk_tmp;
assign dout_H=cnt[7:4];
assign dout_L=cnt[3:0];
assign clk_tmp=key_M?clk_s:clk_2;
always@(posedge clk_tmp or negedge rst)
begin
if(!rst)
cnt = 0;
else
begin
if(cnt == 'h59)
begin
cnt = 0;
cout=1;
end
else
begin
cout=0;
cnt<=cnt+1;
if(cnt[3:0]=='h9)
begin
cnt[3:0]=0;
cnt[7:4]=cnt[7:4]+1;
end
end
end
end
endmodule
12进制计数器:
module counter12(clk_m,rst,dout_H,dout_L);
input clk_m,rst;
output [3:0] dout_H,dout_L;
reg[7:0] cnt;
assign dout_H=cnt[7:4];
assign dout_L=cnt[3:0];
always@(posedge clk_m or negedge rst)
begin
if(!rst)
cnt = 0;
else
begin
if(cnt == 'h11)
begin
cnt = 0;
end
else
begin
cnt<=cnt+1;
if(cnt[3:0]=='h9)
begin
cnt[3:0]=0;
cnt[7:4]=cnt[7:4]+1;
end
end
end
end
endmodule
24进制计数器:
module counter24(clk_m,rst,dout_H,dout_L);
input clk_m,rst;
output [3:0] dout_H,dout_L;
reg[7:0] cnt;
assign dout_H=cnt[7:4];
assign dout_L=cnt[3:0];
always@(posedge clk_m or negedge rst)
begin
if(!rst)
cnt = 0;
else
begin
if(cnt == 'h23)
begin
cnt = 0;
end
else
begin
cnt<=cnt+1;
if(cnt[3:0]=='h9)
begin
cnt[3:0]=0;
cnt[7:4]=cnt[7:4]+1;
end
end
end
end
endmodule
组合成为12/24小时计数器:
module counter12_24(clk_m,rst,sw1,dout_H,dout_L,clk_2,key_H,A_P);
input clk_m,rst,sw1,clk_2,key_H;
output[3:0] dout_H,dout_L;
output[1:0] A_P;
wire[3:0] dout12_H,dout12_L,dout24_H,dout24_L; //调用模块时必须有相应的定义,否则结果有问题
wire clk;
assign clk=key_H?clk_m:clk_2;
counter12(clk,rst,dout12_H,dout12_L);
counter24(clk,rst,dout24_H,dout24_L);
assign dout_H=sw1?dout12_H:dout24_H;
assign dout_L=sw1?dout12_L:dout24_L;
assign A_P=sw1?(((dout24_H==1)&&(dout24_L>2))||(dout24_H==2))?2'b01:2'b10:2'b00;
endmodule
A_P用来显示上午或者下午。
万年历模块
代码如下:
module calendar(clk_50M,clk,rst,key_y,key_m,key_d,year_3,year_2,year_1,year_0,month_H,month_L,day_H,day_L,week);
input clk,rst,key_d,key_m,key_y,clk_50M;
output[3:0] year_3,year_2,year_1,year_0,month_H,month_L,day_H,day_L;
reg[15:0] year;
reg[7:0] month,day;
output [3:0] week;
wire[7:0] week_W;
wire[7:0] year_H,year_L,month_M,day_D;
reg clk_year,clk_month;
reg[7:0] data;
reg clk_y1,clk_y2,clk_y3;
initial
begin
clk_y1=0;
clk_y2=0;
clk_y3=0;
end //初始化很重要,尤其是后面要用边沿触发时
initial
begin
year='h2000;
month=1;
day=1;
end
always@(negedge (clk^key_d) or negedge rst)
begin
if(!rst)
day=1;
else if(!key_d)
begin
if(day==data)
day=1;
else
day=day+1;
if(day[3:0]==4'ha)
begin
day[3:0]=0;
day[7:4]=day[7:4]+1;
end
end
else
begin
if(day==data)
day=1;
else
day=day+1;
if(day[3:0]==4'ha)
begin
day[3:0]=0;
day[7:4]=day[7:4]+1;
end
if((day==data)&&(clk))
clk_month=1;
else
clk_month=0;
end
end
always @(negedge (clk_month^key_m) or negedge rst)
begin
if (!rst)
month=1;
else
begin
if(month=='h12)
month=1;
else
month=month+1;
if(month[3:0]=='ha)
begin
month[3:0]=0;
month[7:4]=month[7:4]+1;
end
if(month=='h12)
clk_year=1;
else
clk_year=0;
end
end
always @(posedge clk_50M)
begin
case(month)
'h01:
data='h31;
'h02:
begin
case(year)
16'h2004:
data='h29;
16'h2008:
data='h29;
16'h2012:
data='h29;
16'h2016:
data='h29;
16'h2020:
data='h29;
16'h2024:
data='h29;
16'h2028:
data='h29;
16'h2032:
data='h29;
16'h2036:
data='h29;
16'h2040:
data='h28;
16'h2044:
data='h29;
16'h2048:
data='h29;
16'h2052:
data='h29;
16'h2056:
data='h29;
16'h2060:
data='h29;
16'h2064:
data='h29;
16'h2068:
data='h29;
16'h2072:
data='h29;
16'h2076:
data='h29;
16'h2080:
data='h28;
16'h2084:
data='h29;
16'h2088:
data='h29;
16'h2092:
data='h29;
16'h2096:
data='h29;
16'h2104:
data='h29;
default:
data='h28;
endcase
end
'h03:
data='h31;
'h04:
data='h30;
'h05:
data='h31;
'h06:
data='h30;
'h07:
data='h31;
'h08:
data='h31;
'h09:
data='h30;
'h10:
data='h31;
'h11:
data='h30;
'h12:
data='h31;
default:
data='h30;
endcase
end
always@(posedge (clk_year^key_y) or negedge rst)
begin
if(!rst)
year[3:0]=0;
else
begin
if(year[3:0]==9)
year[3:0]=0;
else
year[3:0]=year[3:0]+1;
if(year[3:0]==9)
clk_y1=1;
else
clk_y1=0;
end
end
always@(negedge clk_y1 or negedge rst)
begin
if(!rst)
year[7:4]=0;
else
begin
if(year[7:4]==9)
year[7:4]=0;
else
year[7:4]=year[7:4]+1;
if(year[7:4]==9)
clk_y2=1;
else
clk_y2=0;
end
end
always@(negedge clk_y2 or negedge rst)
begin
if(!rst)
year[11:8]=0;
else
begin
if(year[11:8]==9)
year[11:8]=0;
else
year[11:8]=year[11:8]+1;
if(year[11:8]==9)
clk_y3=1;
else
clk_y3=0;
end
end
always@(negedge clk_y3 or negedge rst)
begin
if(!rst)
year[15:12]=2;
else
begin
if(year[15:12]==9)
year[15:12]=0;
else
year[15:12]=year[15:12]+1;
end
end
assign year_H=year[15:12]*10+year[11:8];
assign year_L=year[7:4]*10+year[3:0];
assign month_M=month[7:4]*10+month[3:0];
assign day_D=day[7:4]*10+day[3:0];
assign week_W=(month=='h1)?((year_H/4)-2*year_H+year_L-1+(year_L-1)/4+35+day_D)%7:(month_M=='h2)?((year_H/4)-2*year_H+year_L-1+(year_L-1)/4+38+day_D)%7:((year_H/4)-2*year_H+year_L+year_L/4+(13*(month_M+1))/5+day_D-1)%7;
assign week=(week_W==0)?7:week_W;
assign year_3=year[15:12];
assign year_2=year[11:8];
assign year_1=year[7:4];
assign year_0=year[3:0];
assign month_H=month[7:4];
assign month_L=month[3:0];
assign day_H=day[7:4];
assign day_L=day[3:0];
endmodule
显示模块
硬件开发板为xx大学的LB0板,别的板子根据硬件结构自己调整,代码如下:
module display(data,clk_1k,sel,hex,sw2,A_P,key_state);
input[31:0] data;
input clk_1k,sw2;
input[1:0] key_state;
output reg[2:0] sel;
output reg[7:0] hex;
reg[3:0] seg;
input[1:0] A_P;
reg[3:0] A_P_tmp;
parameter N=3;
reg[N-1:0] regN;
wire[3:0] data_0,data_1,data_2,data_3,data_4,data_5,data_6,data_7;
assign data_0=data[3:0];
assign data_1=data[7:4];
assign data_2=data[11:8];
assign data_3=data[15:12];
assign data_4=data[19:16];
assign data_5=data[23:20];
assign data_6=data[27:24];
assign data_7=data[31:28];
always@(posedge clk_1k)
case(A_P)
2'b00:A_P_tmp<=4'hF;
2'b10:A_P_tmp<=4'hA;
2'b01:A_P_tmp<=4'hD;
endcase
always@(posedge clk_1k)
begin
regN<=regN+1;
sel<=regN;
end
always@*
case(regN)
3'b000: seg=data_1;
3'b001: seg=data_6;
3'b010: seg=((A_P_tmp==4'h0) && (key_state!=2'b01))?data_7:(key_state==2'b01)?data_7:A_P_tmp;
3'b011: seg=data_4;
3'b100: seg=data_5;
3'b101: seg=data_2;
3'b110: seg=data_3;
3'b111: seg=data_0;
default:begin seg=4'b0000;end
endcase
always@*
case(seg)
4'h0:hex = 8'h3f;
4'h1:hex = 8'h06;
4'h2:hex = 8'h5b;
4'h3:hex = 8'h4f;
4'h4:hex = 8'h66;
4'h5:hex = 8'h6d;
4'h6:hex = 8'h7c;
4'h7:hex = 8'h07;
4'h8:hex = 8'h7f;
4'h9:hex = 8'h67;
4'hA:hex = 8'h77;
4'hB:hex = 8'h00;
4'hC:hex = 8'h00;
4'hD:hex = 8'h5E;
4'hE:hex = 8'h00;
4'hF:hex = 8'h00;
default:hex=8'h3f;
endcase
endmodule
按键去抖动模块
module keySkew(clk,keyin,keyout);
input keyin,clk;
output keyout;
reg key_tmp1,key_tmp2;
reg keyout_tmp;
assign keyout=keyout_tmp;
always@(posedge clk)begin
key_tmp1<=keyin;
key_tmp2<=key_tmp1;
keyout_tmp<=~(~key_tmp1 && key_tmp2);
end
endmodule
四个按键:
module key4(key1,key2,key3,key4,key_clk,key_o1,key_o2,key_o3,key_o4);
input key1,key2,key3,key4,key_clk;
output key_o1,key_o2,key_o3,key_o4;
keySkew(key_clk,key1,key_o1);
keySkew(key_clk,key2,key_o2); //对应端口一定不能错
keySkew(key_clk,key3,key_o3);
keySkew(key_clk,key4,key_o4);
endmodule
顶层调用
module clock_top(clk_50M,sw0,sw1,sw2,key1_in,key2_in,key3_in,key4_in,sound,sel,hex);
input clk_50M,sw0,sw1,sw2,key1_in,key2_in,key3_in,key4_in;
output sound;
output[2:0] sel;
output[7:0] hex;
wire clk_2k,clk_1k,clk_50,clk_10,clk_2,clk_1,key1,key2,key3,rst,key_year,key_month,key_day,key_hour,key_minute,key_second;
wire cout,cout_S,cout_M;
wire[1:0] A_P;
wire[3:0] doutS_H,doutS_L,doutM_H,doutM_L,doutH_H,doutH_L,year_3,year_2,year_1,year_0,month_H,month_L,day_H,day_L,week;
reg[1:0] key_state;
reg key1_state,key2_state;
parameter zero=4'hf;
always@(negedge key4)
key_state<=key_state+1;
always@(negedge key1)
key1_state<=key1_state+1;
always@(negedge key2)
key2_state<=key2_state+1;
key4(key1_in,key2_in,key3_in,key4_in,clk_50,key1,key2,key3,key4);
keySkew(clk_50,sw1,sw1_out);
keySkew(clk_50,sw2,sw2_out);
assign key_year=(sw1_out)?key1_state:1;
assign key_month=(sw1_out)?key2_state:1;
assign key_day=(sw1_out)?key3:1;
assign key_hour=(sw2_out)?key1_state:1;
assign key_minute=(sw2_out)?key2_state:1;
assign key_second=(sw2_out)?key3:1;
clock_fenpin(clk_50M,clk_2k,clk_1k,clk_50,clk_10,clk_2,clk_1);
counter60_S(clk_1,1,key_second,cout_S,doutS_H,doutS_L);
counter60_M(cout_S,clk_2,1,key_minute,cout_M,doutM_H,doutM_L);
counter12_24(cout_M,1,sw0,doutH_H,doutH_L,clk_2,key_hour,A_P);
calendar(clk_50M,cout,1,key_year,key_month,key_day,year_3,year_2,year_1,year_0,month_H,month_L,day_H,day_L,week);
wire [31:0]Number_Sig,Number_Sig_Clo,Number_Sig_Cal,Number_Sig_week;
assign Number_Sig_Clo={zero,doutH_H,doutH_L,doutM_H,doutM_L,doutS_H,doutS_L};
assign Number_Sig_Cal={year_3,year_2,year_1,year_0,month_H,month_L,day_H,day_L};
assign Number_Sig_week={week};
assign Number_Sig=(key_state==2'b01)?Number_Sig_Cal:(key_state==2'b10)?Number_Sig_week:Number_Sig_Clo;
display(Number_Sig,clk_1k,sel,hex,sw2,A_P,key_state);
assign cout=((A_P==2'b00)&&(doutH_H==4'h2)&&(doutH_L==4'h3)&&(doutM_H==4'h5)&&(doutM_L==4'h9)&&(doutS_H==4'h5)&&(doutS_L==4'h9))?1:((A_P==2'b01)&&(doutH_H==4'h1)&&(doutH_L==4'h1)&&(doutM_H==4'h5)&&(doutM_L==4'h9)&&(doutS_H==4'h5)&&(doutS_L==4'h9))?1:0;
assign sound=(({doutM_H,doutM_L}=='h59)&&(({doutS_H,doutS_L}=='h55)||({doutS_H,doutS_L}=='h57)||({doutS_H,doutS_L}=='h59)))?clk_1k:(({doutM_H,doutM_L}=='h00)&&({doutS_H,doutS_L}=='h00))?clk_2k:1;
endmodule
最后
以上就是孝顺过客为你收集整理的EDA课设:12/24小时数字钟设计设计要求:模块设计的全部内容,希望文章能够帮你解决EDA课设:12/24小时数字钟设计设计要求:模块设计所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复