华中科技大学电子线路设计测试实验FPGA数字钟设计报告.docx
- 文档编号:23245234
- 上传时间:2023-05-15
- 格式:DOCX
- 页数:29
- 大小:673.57KB
华中科技大学电子线路设计测试实验FPGA数字钟设计报告.docx
《华中科技大学电子线路设计测试实验FPGA数字钟设计报告.docx》由会员分享,可在线阅读,更多相关《华中科技大学电子线路设计测试实验FPGA数字钟设计报告.docx(29页珍藏版)》请在冰豆网上搜索。
华中科技大学电子线路设计测试实验FPGA数字钟设计报告
华中科技大学电子线路设计与测试实验
数
字
钟
设
计
实
验
报
告
班级:
自动化1505班
姓名:
李蓝鑫
学号:
U201514280
2017年5月
一、实验目的
1、掌握数字钟电路的设计与调试方法
2、熟悉使用VERILOGHDL语言描述时序逻辑电路的方法,以及EDA仿真技术
二、实验内容
1、以数字形式显示时、分、秒的时间;
2、小时计数器为同步24进制;
3、要求手动校时、校分;
4、任意时刻闹钟;
5、小时显示(12/24)切换电路;
6、仿广播电台正点报时。
三、模块化,层次化设计(框图设计)
四、代码实现
1、顶层模块
moduleclock(decoder_h_m,decoder_s,alarm,_50mhz,
choose_h_m_de,hour_12_24,adj_min_key,adj_hour_key,
set_min_key,set_hr_key,ctrl_bell,mode,vdd);
input_50mhz;//DE0实验板上的晶振频率
wire_1khzin,_1hz,_2hz,_500hz;
//分频器的输出信号,1khz通过不同位权的二进制数字获得1hz,2hz,500hz的输出信号
inputvdd;//用于提供整个数字钟的异步清零端或者高电平电压,0时清零
wire[7:
0]hour,minute,second;//计时器的输出信号,作为中间变量存储和传输时间信号
wire[7:
0]hour_12,hour_all;
//12进制的小时计数器的变量,hour_all表示把12进制和24进制用一个变量统一,便于译码
inputadj_min_key,adj_hour_key;//校正计时器小时分钟的输入按键,为1时校正时间,为0时正常计时
//计时器的中间使能控制信号,用于计时器的扩展,比如分进位用于控制小时的计数,实现模拟数字钟计时功能
wireminl_en,minh_en,hour_en;
inputhour_12_24;
//12进制与24进制的显示切换,也就是选择hou还是hour_12当为1时12进制,为0时是24进制表达
regalarm_radio;//仿电台的报时信号输出,当此信号为1时报时信号输出,当此信号为0时不输出
wirealarm_clock;//闹钟的信号输出,同仿电台报时的功能,当此信号为1时,闹钟信号输出
inputctrl_bell;//控制闹钟的声音是否输出的按键
outputalarm;//仿电台报时或者闹钟声音信号的输出,集成在一个输出端口,采用或运算使之输出在一起
wire[7:
0]set_hr,set_min;//设定的闹钟时间输出信号,用于用户设置闹钟定时和用于和当前计时器的时间比较
inputset_hr_key,set_min_key;
//设定闹钟小时和分钟的输入按键,作为小时计数器和分钟计数器的使能信号
//如果按下,使能有效,正常递增,当松开时,使能无效,不再递增,保存当前的值为闹钟所设定的时间。
//闹钟设定时间和计时器比较器的结果输出,分别为小时的十位比较结果
//小时个位比较结果,分钟十位比较结果,分钟个位比较结果
wirehr_h_equ,hr_l_equ,min__h_equ,min_l_equ;
inputchoose_h_m_de;//因4个数码管显示限制,用于控制显示小时还是分钟信号,1表示小时,0表示分钟
output[13:
0]decoder_h_m,decoder_s;//译码器的输出,也就是小时、分、秒的译码,用于控制七段译码管的亮灭
wire[7:
0]led_hr,led_min,led_sec;
//输出8421BCD码给显示器,时分秒都是两位十进制数表示,需要八位二进制的BCD二进制码来表示
wire[7:
0]led_min,led_sec;//说明变量的类型
wire[7:
0]led_h_min;//由于译码管数量限制,所以把计时的时分集中在一个变量里便于译码
inputmode;//设定显示器的显示模式,MODE=1时,显示闹钟所设定的时间,反之则显示计时器的时间
//50MHZ分频器调用模块,50mhz为DE0实验板上的晶振频率
divided50mhzde1(_1khzin,vdd,_50mhz);
//1khz分频器的模块调用,vdd,作为使能信号和清零信号,都处于高电平状态。
前三种频率的信号为分频输出
divided_frequencyu0(_1hz,_2hz,_500hz,vdd,vdd,_1khzin);
//60进制秒计数器:
调用10进制和6进制底层模块构成
counter10u1(second[3:
0],vdd,vdd,_1hz);
//秒个位计数器,为十进制,使能信号接电源高电平,一直有效,即一直计数,符合秒的概念
counter6u2(second[7:
4],vdd,(second[3:
0]==4'h9),_1hz);
//秒计数器十位计数器,以秒个位是否达到九作为使能控制信号
//也就是个位是否产生进位,也就实现了60进制的扩展
assignminl_en=adj_min_key?
vdd:
(second==8'h59);
//分钟的个位使能信号产生,adj_min_key为1时校正分钟信号,所以无需等待秒的进位
//而为0时,则是正常计时状态,虚等待秒的进位来充当使能信号,产生正常的分钟计数
assignminh_en=(adj_min_key&&(minute[3:
0]==4'h59))||(mintue[3:
0]==4'h9)&&(second==8'h59);
//分钟的十位使能信号产生,adj_min_key为1时校正分钟信号
//但此时即便在校正状态,也需等待分钟信号的个位进位信号
//当其为0时,分钟是正常即使状态,需同时满足秒的进位与分钟的个位进位
//60进制分钟计数器,也是调用十进制计数器与6进制计数器完成,与秒计数器所不同的是使能信号的不同
counter10u3(mintue[3:
0],vdd,minl_en,_1hz);//分计数器的个位计数
counter6u4(mintue[7:
4],vdd,minh_en,_1hz);//分计数器的十位计数
//产生小时计数器使能信号
//为1时校正小时,为0时正常计时,由于小时直接采用底层的24进制计数器
//所以只有一个使能信号,无需十位与个位的使能信号相区分
//正常计数时,需同时满足秒的进位与分的进位
assignhour_en=adj_hour_key?
vdd:
((mintue==8'h59)&&(second==8'h59));
//调用24进制计数器进行小时计数
counter24u5(hour[7:
4],hour[3:
0],vdd,hour_en,_1hz);//24进制小时计数器
//调用12进制计数器进行小时计数
counter12u6(hour_12[7:
4],hour_12[3:
0],vdd,hour_en,_1hz);//12进制小时计数器
//仿电台整点报时功能
always@(minuteorsecond)//因为每逢整点都要报时。
所以无需引入小时hour信号
if(minute==8'h59)//先判断分钟计数器是否满足59,再进行判断秒计数器的数值
case(second)//由于需要在51,53,55,57,59秒时报时,所以用case语句
8'h51,
8'h53,
8'h55,
8'h57:
alarm_radio==_500hz;//当出现51,53,55,57,时都往下来执行输出500HZ的信号语句
8'h59:
alarm_radio==_1khzin;//当出现59秒时,开始输出1000HZ的信号语句
default:
alarm_radio=1'b0;//其他情况下输出0,也就是不报时
endcase
elsealarm_radio=1'b0;//当分钟信号不满足59时输出为0,也就是不输出报时信号
//闹钟设定模块
//60进制分计数器,用于闹钟设定分钟
counter10su1(set_min[3:
0],vdd,set_min_key,_2hz);
//当设置分钟的按键按下时使能信号有效,开始计数递增
//松开时,设定的分钟个位信号存入闹钟数字存储的低4位BCD码
counter6su2(set_min[7:
4],vdd,(set_min[3:
0]==4'h9),_2hz);//分钟的十位设置
//24进制小时计数器,用于闹钟设定小时
counter24su3(set_hr[7:
4],set_hr[3:
0],vdd,set_hr_key,_2hz);//此时,设定小时的按键充当使能信号
//比较闹钟时间和计时器设定时间是否相等
_4bitcomparersu4(hr_h_equ,set_hr_[7:
4],hour[7:
4]);//调用4位比较器,一次比较一个BCD码表示的十进制数字
_4bitcomparersu5(hr_l_equ,set_hr_[3:
0],hour[3:
0]);//小时的个位比较结果
_4bitcomparersu6(min_h_equ,set_min_[7:
4],minute[7:
4]);//分钟的十位比较结果
_4bitcomparersu7(min_l_equ,set_min_[3:
0],minute[3:
0]);//分钟的个位比较结果
//闹钟声音控制信号
assign
alarm_clock=ctrl_bell?
(((hr_h_equ&&hr_l_equ&&min_h_equ&&min_l_equ))&&(((second[0]==1'b1)&&_500hz)||((second[0]==1'b0)&&_1khzin)):
1'b0;
//当CTRL_BELL为1时,闹钟声音被允许输出,才进行后续判断,而为0时,不允许输出,时钟为0;
//hr_h_equ&&hr_l_equ&&min_h_equ&&min_l_equ)用于检测是否满足闹钟响铃条件
//即设定时间与当前时间是否相等。
//second[0]==1'b1)&&_500hz)||((second[0]==1'b0)&&_1khzin)用于给闹钟输出信号变量赋值
//500hz和1khz交替输出,用秒的最低位一直在0和1跳变来实现。
//把声音输出模块集成在一起,报时和闹钟信号
assignalarm=alarm_radio||alarm_clock;
//2选一模块用于选择显示12进制小时还是24进制小时
_2to1muxmu0(hour_all,hour_12_24,hour_12,hour);
//选择显示闹钟时间还是正常计时的时间
_2to1muxmu1(led_hr,mode,set_hr,hour_all);
_2to1muxmu2(led_min,mode,set_min,minute);
_2to1muxmu3(led_sec,mode,8'h00,second);
//用于选择是显示小时还是分钟
_2to1muxmu4(led_h_min,choose_h_m_de,led_hr,led_min);
//七段译码器模块调用
decoderde2(led_h_min,decoder_h_m);//译码小时和分钟的集成
decoderde3(led_sec,decoder_s);//译码秒的计数
endmodule
2、二选一模块
//二选一模块完成模式选择
module_2to1mux(out,sel,x,y);
input[7:
0]x,y;//声明模块内使用变量,用于接收小时与分钟的BCD码
inputsel;//选择信号
output[7:
0]out;//输出信号
assignout=sel?
x:
y;//用选择语句完成,为1时赋值X
Endmodule
3、四位比较器模块
//4位比较器模块
module_4bitcomparer(equ,a,b);
input[3:
0]a,b;//声明模块内使用变量,用于接收待比较1位十进制数的BCD码
outputequ;//输出变量,比较结果存储在此变量中,相等为1,不相等为0
assignequ=(a==b);
Endmodule
4、分频器模块
(1)、1KHZ分频到500hz,4hz,1hz模块
moduledivided_frequency(_1hzout,_2hzout,_500hzout,ncr,en,_1khzin);
input_1khzin,ncr,en;
output_1hzout,_2hzout,_500hzout;//分频器的结果输出,即不同频率的信号
wire[11:
0]q;//用于获取分频信号的变量,在不同位上取,就可获得不同的频率信号
wireen1,en2;//使能信号
//通过使用三个十进制计数器完成1000进制的计数器扩展
counter10du0(q[3:
0],ncr,en,_1khzin);
counter10du1(q[7:
4],ncr,en1,_1khzin);
counter10du3(q[11:
8],ncr,en2,_1khzin);
assignen1=(q[3:
0]==4'd9);
assignen2=(q[7:
4]==4'd9)&(q[3:
0]==4'd9);
assign_1hzout=q[11];
assign_2hzout=q[10];
assign_500hzout=q[0];//最低位实现二分频,位往高位移动,依次类推
Endmodule
(2)、50MHZ分频到1khz模块
moduledivided50mhz(_1khzin,ncr,_50mhz);
input_50mhz,ncr;//异步清零端
outputreg_1khzin;
reg[15:
0]q;//用于存储计数数字
always@(posedge_50mhz,negedgencr)
begin
if(~ncr)//异步清零
begin
q<=15'd0;
_1khzin<=1'b0;
end//当计数到24999时,1khz变量翻转,因为50mhz频率是1000hz的50000倍
elseif(q==15'b110000110100111)
Begin//所以1khz的周期是50mhz的50000倍,24999个周期翻转一次,翻转两次构成
q<=15'd0;//一个周期,恰好满足50000倍的周期关系,也就达到分频的效果
_1khzin<=(~_1khzin);
end
else
begin
q<=q+1'b1;//正常加1
end
end
endmodule
5、十进制模块
modulecounter10(q,ncr,en,cp);
inputcp,ncr,en;
output[3:
0]q;//输出变量
reg[3:
0]q;
always@(posedgecp,negedgencr)//上升沿出发的时钟脉冲信号,下降沿出发的异步清零信号
begin
if(~ncr)q<=4'b0000;//异步清零
elseif(~en)q<=q;//当使能为0时,暂停计数,保持原来的数值
elseif(q==4'b1001)q<=4'b0000;//当数字到达第十个状态,也就是九时再次清零,完成一次十进制计数
elseq<=q+1'b1;//正常计数
end
Endmodule
6、六进制模块
//6进制计数器
modulecounter6(q,ncr,en,cp);
inputcp,ncr,en;
output[3:
0]q;
reg[3:
0]q;
always@(posedgecp,negedgencr)
begin
if(~ncr)q<=4'b0000;
elseif(~en)q<=q;
elseif(q==4'b0101)q<=4'b0000;//与十进制所不同的就是清零的状态不同
elseq<=q+1'b1;
end
Endmodule
7、二十四进制模块
//24进制计数器,用于小时计数
modulecounter24(cnth,cntl,ncr,en,cp);
inputcp,ncr,en;//时钟脉冲,与异步清零信号和使能信号
output[3:
0]cnth,cntl;//24的十位和个位的BCD码表示
reg[3:
0]cnth,ctnl;
always@(posedgecp,negedgencr)
begin
if(~ncr){cnth,cntl}<=8'h00;//异步清零
elseif(~en){cnth,cntl}<={cnth,cntl};//使能为01时保持原有状态
elseif((cnth>2)||(cntl>9)||((cnth==2)&&(cntl>=3))){cnth,cntl}<=8'h00;//当满足十位大于2,个位大于9,整体大于23时,都属于越界的情况都需要清零
elseif((cnth==2)&&(cntl<3))//当十位为2,个位小于3时,个位正常加1
begincnth<=cnth;cntl<=cntl_1'b1;end
elseif(cntl==9)//个位为9时,需要进位,然后个位再清零
begincnth<=cnth+1'b1;cntl<=4'b0000;end
else
begincnth<=cnth;cntl<=cntl_1'b1;end//其他情况也是个位正常加1,十位保持原状
end
Endmodule
8、十二进制模块
modulecounter12(cnth,cntl,ncr,en,cp);
inputcp,ncr,en;
output[3:
0]cnth,cntl;
reg[3:
0]cnth,cntl;
always@(posedgecp,negedgencr)
begin
if(~ncr){cnth,cntl}<=8'h00;
elseif(~en){cnth,cntl}<={cnth,cntl};
elseif((cnth>1)||(cntl>9)||((cnth==1)&&(cntl>=1))){cnth,cntl}<=8'h00;
//与24进制所不同之处在于十位是1的时候开始复位
elseif((cnth==1)&&(cntl<1))
begincnth<=cnth;cntl<=cntl+1'b1;end
elseif(cntl==9)
begincnth<=cnth+1'b1;cntl<=4'b0000;end
else
begincnth<=cnth;cntl<=cntl+1'b1;end
end
endmodule
9、七段译码管模块
moduledecoder(number,num_decoder);
input[7:
0]number;//需要被译码的两位十进制数的BCD码
outputreg[13:
0]num_decoder;//译码输出变量,直接控制七段译码管的亮与灭
always@(number,num_decoder)
begin
case(number[7:
4])//十位译码,DE0实验板上的显示管是共阳极,为0时亮
4'd0:
num_decoder[13:
7]=7'b0000001;
4'd1:
num_decoder[13:
7]=7'b1001111;
4'd2:
num_decoder[13:
7]=7'b0010010;
4'd3:
num_decoder[13:
7]=7'b0000110;
4'd4:
num_decoder[13:
7]=7'b1001100;
4'd5:
num_decoder[13:
7]=7'b0100100;
4'd6:
num_decoder[13:
7]=7'b0100000;
4'd7:
num_decoder[13:
7]=7'b0001111;
4'd8:
num_decoder[13:
7]=7'b0000000;
4'd9:
num_decoder[13:
7]=7'b0000100;
default:
num_decoder[13:
7]=7'b1111111;
endcase
case(number[3:
0])//个位译码
4'd0:
num_decoder[6:
0]=7'b0000001;
4'd1:
num_decoder[6:
0]=7'b1001111;
4'd2:
num_decoder[6:
0]=7'b0010010;
4'd3:
num_decoder[6:
0]=7'b0000110;
4'd4:
num_decoder[6:
0]=7'b1001100;
4'd5:
num_decoder[6:
0]=7'b0100100;
4'd6:
num_decoder[6:
0]=7'b0100000;
4'd7:
num_decoder[6:
0]=7'b0001111;
4'd8:
num_decoder[6:
0]=7'b0000000;
4'd9:
num_decoder[6:
0]=7'b0000100;
default:
num_decoder[6:
0]=7'b1111111;
endcase
end
endmodule
五、模块功能仿真
1、二选一模块
2、四位比较器模块
3、1KHz分频器模块
4、十进制模块
5、六进制模块
6、十二进制模块
7、二十四进制模块
8、50MHz分频模块
9、译码器模块
六、数字钟整体功能仿真
1、说明
(1)、以闹钟为示例,因为闹钟基本覆盖所用功能
(2)、50mhz的分频功能暂时屏蔽,节省仿真时间
(3)、采用前一段设置闹钟时间,接着一段校正时间,基本校正到与闹钟时间相同,而后再正常计时,产生一分钟闹钟的输出。
2、波形
七、实验总结
1、调试收获
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 华中科技大学 电子线路 设计 测试 实验 FPGA 数字 报告