EDA课程设计多功能数字钟设计程序清单数字系统设计与verilogHDL第四版王金明.docx

上传人:b****5 文档编号:7995704 上传时间:2023-01-27 格式:DOCX 页数:14 大小:19.25KB
下载 相关 举报
EDA课程设计多功能数字钟设计程序清单数字系统设计与verilogHDL第四版王金明.docx_第1页
第1页 / 共14页
EDA课程设计多功能数字钟设计程序清单数字系统设计与verilogHDL第四版王金明.docx_第2页
第2页 / 共14页
EDA课程设计多功能数字钟设计程序清单数字系统设计与verilogHDL第四版王金明.docx_第3页
第3页 / 共14页
EDA课程设计多功能数字钟设计程序清单数字系统设计与verilogHDL第四版王金明.docx_第4页
第4页 / 共14页
EDA课程设计多功能数字钟设计程序清单数字系统设计与verilogHDL第四版王金明.docx_第5页
第5页 / 共14页
点击查看更多>>
下载资源
资源描述

EDA课程设计多功能数字钟设计程序清单数字系统设计与verilogHDL第四版王金明.docx

《EDA课程设计多功能数字钟设计程序清单数字系统设计与verilogHDL第四版王金明.docx》由会员分享,可在线阅读,更多相关《EDA课程设计多功能数字钟设计程序清单数字系统设计与verilogHDL第四版王金明.docx(14页珍藏版)》请在冰豆网上搜索。

EDA课程设计多功能数字钟设计程序清单数字系统设计与verilogHDL第四版王金明.docx

EDA课程设计多功能数字钟设计程序清单数字系统设计与verilogHDL第四版王金明

EDA课程设计

多功能数字钟设计程序清单

数字系统设计与verilogHDL(第四版)王金明

 

/*引脚锁定基于DE2一70,芯片为EP2C70F896,信号定义如下:

Clk50m:

50MHz时钟输,

mode:

模式选择0:

计时模式1:

设置闹钟模式

mcheck:

手动调整时间

turn:

手动调整时间,在时、分之间选择

change:

对选中的数据调整

ledhourl,led_hour0,led_minul,led_minu0,led_secl,ledsec0;

alert:

闹钟输出

ld_alert:

是否设置了闹钟

ld_hour,id_min,ld_sec:

在调整时,指示选中了时,分还是秒*/

moduleclock(clk50m,mode,turn,change,mreset,led_hour1,led_hour0,led_minu1,led_minu0,led_sec1,led_sec0,alert,ld_alert,ld_check,ld_hour,ld_min,ld_sec);

inputclk50m;

inputmode;//key0键

inputturn;//keyl键

inputchange;//key2键

inputmreset;//switch0复位,低电平有效

outputalert;//gpioO->IOAO

outputld_alert;//ledgO-led19

outputld_check;//ledgl-led22

outputld_hour;//ledr3-led13

outputld_min;//ledr9-led9

outputld_sec;//ledr7-led7

output[6:

0]led_hour1;

output[6:

0]led_hour0;

output[6:

0]led_minu1;

output[6:

0]led_minu0;

output[6:

0]led_sec1;

output[6:

0]led_sec0;

reg[1:

0]modestate;

//00:

计时模式10:

闹钟模式;01:

手动调整模式;11:

非法模式

wirenowmode;//记录当前模式,0:

计时模式;1:

设置闹钟模式

wireischecking;//是否在手动调整时间

assign{nowmode,ischecking}=modestate;

always@(negedgemode)//两个按钮都是低电平有效

begin

case(modestate)

2'b00:

modestate<=2'b10;//设置闹钟模式优先

2'b10:

modestate<=2'b01;//手动调整模式

2'b01:

modestate<=2'b00;

default:

modestate<=2'b00;

endcase

end

wirereset,clk_1hz;

switch#(8)rmjitter(clk50m,mresetr,reset);

clk50mtolgenlhz(clk50m,clk_1hz);//生成1Hz的时钟

wire[2:

0]selcode;//对turn信号在不同模式

bitselseldecoder(nowmode,ischecking,turn,selcode,reset);

wire[3:

0]clocktime0,clocktimel,clocktime2,clocktime3,clocktime4,clockthre5;

//计时输出的时钟数值

wireclockalarmon;//整点报时的闹钟输出

wire[2:

0]counterselcode;

assigncounterselcode=(modestate==2'b01)?

selcode:

3'b000;

counter_timeclock_time(clk_1hz,counterselcode,~change,clocktime5,clocktime4,clocktime3,clocktime2,clocktime1,clocktime0,clockalarmon,reset);

wire[3:

0]alarmtime0,alarmtime1,alarmtime2,alarmtime3;

wirealarmon;

alarm_timealarm_time(clk_1hz,nowmode,selcode[2:

1],change,

{clocktime5,clocktime4,clocktime3,clocktime2,clocktime1},

{alarmtime3,alarmtime2,alarmtime1,alarmtime0},alarmon,reset);

wirevoiceout;

alarmalarmvoice(clk50m,{clockalarmon,alarmon},voiceout,raset);

//显示输出部分

assign{ld_hour,ld_min,ld_sec}=(ischecking||nowmode)?

selcode:

3'b000;

assignalert=voiceout;

reg[3:

0]showout2,showout3,showout4,showout5;

ledled5(showout5,led_hour1);//led译码显示

ledled4(showout4,led_hour0);

ledled3(showout3,led_minu1);

ledled2(showout2,led_minu0);

ledled1(clocktime1,led_sec1);

ledled0(clocktime0,led_sec0);

always

beginif(nowmode)

beginshowout5=alarmtime3;showout4=alarmtime2;

showout3=alarmtime1;showout2=alarmtime0;end

elsebegin

showout5=clocktime5;showout4=clocktime4;

showout3=clocktime3;showout2=clocktime2;end

end

assignld_alert=nowmode;assignld_check=ischecking;

endmodule

/*alarm.V:

闹铃模块

Clk50m:

50MHz输入时钟

alarmon:

闹铃是否打开,2'b00:

不打开:

2'b01:

闹钟;2'b10:

整点报时

alarmoUt:

闹铃声音输出*/

modulealarm(clk50m,alarmon,alarmout,reset);

input[1:

0]alarmon;

inputclk50m,reset;

outputregalarmout;

reg[15:

0]counter_1k;

wireclk_1k;

assignclk_1k=counter_1k[4];

always@(posedgeclk50m)

beginif(counter_1k==20)counter_1k<=0;

elsecounter_1k<=counter_1k+1'b1;end

wireddd_du_out,ddd_out;

sound_ddd_duddd_du(clk_1k,alarmon[1],ddd_du_out);

sound_dddddd(clk_1k,alarmon[0],ddd_out);

always

beginif(!

reset)

beginif(alarmon[0]==1'b1)//ddd,闹钟的响铃优先级更高

alarmout=ddd_out;

elseif(alarmon==2'b10)alarmout=ddd_du_out;

elsealarmout=0;

endelsealarmout=0;

end

endmodule

/*alarm_time.V:

闹钟时间设定模块

enable:

使能信号

Sel:

在时、分之间切换选择10:

时;01:

inc:

对选中的信号自增

basetime:

基准时钟*/

modulealarm_time(clk_1hz,enable,sel,inc,basetime,alarmouttime,alarm_on,reset);

inputclk_1hz,enable,inc,reset;

input[1:

0]sel;

input[4*5-1:

0]basetime;

outputregalarm_on;

output[4*4-1:

0]alarmouttime;

reg[3:

0]hour1,hour0,minu1,minu0;//存储的设定时间

always@(posedgeincorposedgereset)

beginif(reset)//reset=1时复位

begin{hour1,hour0,minu1,minu0}<=16'h0;end

elsebegin

if(enable)begin

if(sel==2'b10)//设置时

beginif({hour1,hour0}==8'h23){hour1,hour0}<=8'h00;

elseif(hour0==9)

beginhour0<=0;hour1<=hour1+1'b1;end

elsehour0<=hour0+1'b1;

end

elseif(sel===2'b01)//设置分

beginif({minu1,minu0}==8'h59){minu1,minu0}<=8'h00;

elseif(minu0==4'h9)

beginminu0<=4'h0;minu1<=minu1+4'h1;end

elseminu0<=minu0+4'h1;end

else{hour1,hour0,minu1,minu0}<=16'h0;

endend

end

always//闹钟开始条件

begin

if(({hour1,hour0,minu1,minu0}==basetime[(4*5-1):

4])&&(basetime[3:

0]<2))

alarm_on=1'b1;

elsealarm_on=1'b0;end

assignalarmouttime={hour1,hour0,minu1,minu0};

endmodule

/*countertime,v:

计时模块,并留有调整接;

check:

调整信号,3位,分别调整时、分、秒,调整方法:

将计数输出给加法器,把调整信息

转换成异步置数信息,将加法器的输出作为置数值;

hour1,hour0,minul,minu0,sec1,sec0:

输出的计时时钟;

alarmout:

整点报时输出*/

modulecounter_time(clk_1hz,check,inc,hour1,hour0,minu1,minu0,sec1,sec0,alarmout,reset);

inputclk_1hz,inc,reset;

input[2:

0]check;

output[3:

0]hour1,hour0,minu1,minu0,sec1,sec0;

outputregalarmout;

regclk_1hz_md;

wire[6:

0]carryclk;

reg[5:

0]incplus;//自增脉冲

wire[5:

0]carry;//进位时钟

wire[3:

0]adderout0,adderout1,adderout2,adderout3,adderout4,adderout5;

wire[3:

0]timerout0,timerout1,timerout2,timerout3,timerout4,timerout5;

hexcountercounter_sec0(carryclk[0],reset,4'd9,4'b0,timerout0,carry[0]);

hexcountercounter_sec1(carryclk[1],reset,4'd5,4'b0,timerout1,carry[1]);

hexcountercounter_minu0(carryclk[2],reset,4'd9,4'b0,timerout2,carry[2]);

hexcountercounter_minu1(carryclk[3],reset,4'd5,4'b0,timerout3,carry[3]);

wire[3:

0]hour0max;

assignhour0max=(timerout5==4'h2)?

(4'h3):

(4'h9);

hexcountercounter_hour0(carryclk[4],reset,hour0max,4'b0,timerout4,carry[4]);

hexcountercounter_hour1(carryclk[5],reset,4'd2,4'b0,timerout5,carry[5]);

//每个计时器的时钟,由前级进位和自堦脉冲相加得到

assigncarryclk[0]=(check==4'h0)?

clk_1hz_md:

incplus[0];

assigncarryclk[1]=carry[0]|incplus[1];

assigncarryclk[2]=(check==4'h0)?

carry[1]:

incplus[2];

assigncarryclk[3]=carry[2]|incplus[3];

assigncarryclk[4]=(check==4'h0)?

carry[3]:

incplus[4];

assigncarryclk[5]=carry[4]|incplus[5];

always//对异步置位信号进行解码

begincase(check)

3'b001:

beginclk_1hz_md=0;

incplus={5'b00000,inc};end

3'b010:

beginclk_1hz_md=0;

incplus={3'b000,inc,2'b00};end

3'b100:

begin//在正常的调节状态中

clk_1hz_md=0;

incplus={1'b0,inc,4'b000};end

default:

beginincplus=6'b000000;

clk_1hz_md=clk_1hz;

end

endcase

end

alwaysbeginif(((reset|check)==0)&&(timerout3==0)&&(timerout2==0)&&(timerout1<2))alarmout=1;

//时间小于20秒的时间内

elsealarmout=0;end

assignhour1=timerout5;

assignhour0=timerout4;

assignminu1=timerout3;

assignminu0=timerout2;

assignsec1=timerout1;

assignsec0=timerout0;

endmodule

/*Clk50mtol.v:

50mhz时钟分频到lhz*/

moduleclk50mtol(clk50m,clk1hz);

inputclk50m;

outputclk1hz;

reg[25:

0]counter_1hz;//从50mhz分频到lhz的计数器

assignclk1hz=counter_1hz[14];//assignclk1hz=counter_1hz[25];

always@(posedgeclk50m)

begin

if(counter_1hz==20000)counter_1hz<=0;

elsecounter_1hz<=counter_1hz+1'b1;

end

endmodule

/*led.v:

7段数码管(led)译码显示模块

datain:

4位,10进制数输入

ledout:

7位,数码管的7段*/

moduleled(datain,ledout);

parameterINWIDTH=4;

parameterOUTWIDTH=7;

input[INWIDTH-1:

0]datain;

output[OUTWIDTH-1:

0]ledout;

reg[OUTWIDTH-1:

0]dataout;

assignledout=dataout;

alwaysbegin

case(datain)

0:

dataout<=7'b1000000;

1:

dataout<=7'b1111001;

2:

dataout<=7'b0100100;

3:

dataout<=7'b0110000;

4:

dataout<=7'b0011001;

5:

dataout<=7'b0010010;

6:

dataout<=7'b0000010;

7:

dataout<=7'b1111000;

8:

dataout<=7'b0000000;

9:

dataout<=7'b0010000;

default:

dataout<=7'b1000000;

endcase

end

endmodule

/*switch-v:

对按键开关的消抖电路,采用一个频率较低的时钟,

对输入进行采样,消除抖动*/

moduleswitch(clk,keyin,keyout);

parameterCOUNTWIDTH=8;

inputclk,keyin;

outputregkeyout;

reg[COUNTWIDTH-1:

0]counter;

wireclk_use;//频率较低的时钟

assignclk_use=counter[COUNTWIDTH-1];

always@(posedgeclk)

counter<=counter+1'b1;

always@(posedgeclk_use)

keyout<=keyin;

endmodule

/*bitsel-v:

将输出解码成对时、分、秒的选择(并且分闹钟设置模式还是计时模式)

Alarmmode:

是否是在设置闹钟模式

checkmode:

是否是在调整时间模式*/

modulebitsel(alarmmode,checkmode,sel,selcode,reset);

inputalarmmode,checkmode,sel,reset;

outputreg[2:

0]selcode;

reg[2:

0]check_code;

reg[1:

0]alarm_code;

always@(negedgeselorposedgereset)

beginif(reset)check_code<=3'b000;//reset=1复位

elsebegin

case(check_code)

3'b000:

check_code<=3'b001;

3'b001:

check_code<=3'b010;

3'b010:

check_code<=3'b100;

3'b100:

check_code<=3'b001;

default:

check_code<=3'b000;

endcase

end

end

always@(negedgeselorposedgereset)

beginif(reset)alarm_code<=2'b00;//低电平复位

elsebegin

case(alarm_code)

2'b00:

alarm_code<=2'b01;

2'b01:

alarm_code<=2'b10;

2'b10:

alarm_code<=2'b01;

default:

alarm_code<=2'b00;

endcase

end

end

always

beginif(alarmmode^checkmode)//两个当中只有1个为1

beginif(checkmode)selcode=check_code;

elseselcode={alarm_code,1'b0};end

elseselcode=3'b000;

end

endmodule

/*adder.v:

加法器*/

moduleadder(in1,in2,out);

parameterin1width=8;

parameterin2width=8;

parameteroutwidth=8;

input[in1width-1:

0]in1;

input[in2width-1:

0]in2;

output[outwidth-1:

0]out;

assignout=in1+in2;

endmodule

/*excounter-v:

16进制计数的一个计数器*/

modulehexcounter(clk,set,max,setdata,dataout,carryout);

inputclk,set;

input[3:

0]max,setdata;

outputcarryout;

output[3:

0]dataout;

reg[3:

0]counter;

regcarrybit;

assigncarryout=carrybit;

assigndataout=counter;

always@(posedgeclkorposedgeset)

beginif(set)//set是高电平有效

begincounter<=setdata;

carrybit<=0;

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 农林牧渔 > 林学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1