EDA 数字时钟的课程设计论文(宁波工程学院电科版)

更新时间:2023-12-18 02:59:01 阅读量: 教育文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

EDA 课 程 设 计 报 告

学 院 名 称: 电子与信息工程学院 专 业: 电子科学与技术 班 级: 姓 名: 学 号

小 组 成 员: 指 导 教 师:

日期: 2013 年 月 日

设计(论文)题目: 多功能数字时钟的设计

摘要:

本文是基于Altera公司出品QuartusII软件以及相应的实验平台完成的多功能数字计时器实验,设计时采用了层次设计思想,功能逐级递加各种功能。该系统主要由时钟基本功能电路、闹钟电路、动态显示控制电路、分频电路,状态灯显示电路,开关复用电路组成,分别采用模60、24计数器实现了时分秒的计时、闹钟报时,整点报时,调整时分等功能。本文详细写出了该系统的系统设计、逻辑设计和门电路设计过程,并列出了设计框图、算法流程图、仿真波形图和实际测试结果等图表。

关键字:数字时钟 闹钟 动态显示 开关复用

Abstract:

This essay designs a multi-function digital clock which is based on QuartusII software that belong to Altera company and the corresponding experimental platform,we achieve these functions by adapting hierarchical designs and functional additive step by step, The system of multifunction digital clock mainly consist from many parts——basic functional clock circuit,alarm circuit, dynamic display control circuit, division circuit, mode-state-led display circuit, switch to reuse circuit. It mainly use mold 60 and mold 24 counter to count hour, minute, second, achieve alarm and adjusting. This essay introduce detailly about the process that contain system,logic,gating cicuit,

Key word: digital clock、alarm、dynamic display、switch multiplexing

1

一、简述·································································3 二、设计要求说明·························································3

2.1设计总体要求·····················································3 2.2设计基本要求·····················································3 2.3设计提高部分要求·················································3 三、系统设计·····························································4

3.1整体设计方案······················································4 3.2秒脉冲发生电路····················································5 3.3译码显示电路······················································6 3.4计时电路 ······················································7 3.5复位电路··························································7 四、功能模块电路设计······················································8

4.1秒脉冲发生电路模块················································8 4.2 整体时钟设计模块··················································8 五、系统调试·····························································21

5.1 系统调试·························································21 5.11消抖电路调试·····················································21 5.12计时电路调试·····················································23

5.13 秒产生电路调试····················································25 5.14整点报时电路调试···················································26 5.15 数码显示电路调试 ·················································28

5.16 时校时电路调试 ·················································30 5.17 状态灯电路调试 ·················································32 5.2 管脚分配·························································33

六、参考文献·····························································33 七、实验感想·····························································34

一、 简述

2

利用QuartusII软件设计一个数字钟,并下载到SmartSOPC实验系统中。

设计一个数字时钟,可以完成00:00:00到23:59:59的计时功能,并在控制电路的作用下具有保持、清零、快速校时、快速校分、整点报时、闹钟等功能。

数字计时器的系统框图如图1.1所示。

译码显示电路 段位码选择电路 脉冲发生电路 计时电路 报时电路 复用开关电路 校时分电路 清零电路 闹钟电路 图1.1 数字时钟系统结构框图

二、 设计要求说明

(1)设计总体要求:

利用QuartusII软件设计一个数字钟,对设计电路进行功能仿真,并下载到SmartSOPC实验系统中,可以完成00:00:00到23:59:59的计时功能,并在多用开关控制电路的作用下具有保持、清零、快速校时、快速校分、整点报时、闹钟等功能,做到能够创新的添加自己能够实现的功能。 (2)设计基本要求

1.进行正常的时、分、秒计时功能。 2.分别由六个数码管显示时、分、秒的计时。

3.K1是系统的复位开关(K1=0 清零复位,K1=1时钟保持不变)。 4.K2是计时和暂停开关(K2=0 启动工作,K2=1保持)。

5.K3是校时模式开关(K3=0 校时模式开启,K3=1保持原有模式)。

3

6.K4是闹钟模式开关(K4=0,K4=1时钟进行快速校时)。

7.K3+ K1在校时模式下的时增加调整按键,既两个按键都要被按下。 8. K4+ K1在闹钟模式下的时增加调整按键,既两个按键都要被按下。 9. K3+ K2在校时模式下的分增加调整按键,既两个按键都要被按下。 10.K3+ K2在闹钟模式下的分增加调整按键,既两个按键都要被按下。 (3)设计提高部分要求

1.使时钟具有整点报时功能(时钟从00’00’’开始报时,在00’00’’,00’01’’,00’02’’······00’05’’时报时频率为1KHz)。

2.闹钟设定功能

3.自己添加其他功能:采用了开关复用技术,即电脑上ctrl的作用类似。

三、 系统设计

3.1整体设计方案

多功能数字计时器是由分频电路,计时电路、译码显示电路、脉冲发生电路和控制电路等几部分基本电路组成的,其中控制电路按照设计要求可以由校时电路、清零电路、报时电路和闹钟设计电路等组成。

多功能数字钟控制器的系统框图如图2.1所示 控制电路原则确定的思路:

首先需要考虑到的是此次设计要实现的功能有:

①正常的计时、保持、清零、校时、校分以及整点报时功能;

②闹铃功能,从使用者的角度来看闹铃需要设定相应的校分、校时功能; 其次需考虑控制电路的设计有以下一些要求:

①考虑到此次控制部分我们可以使用的只有8个独立开关,根据以上分析,可以知道,如果使用一个开关来控制一个功能显然,开关数是不够的,从而需要考虑到开关的功能复用技术,并且需要考虑到各个功能之间不能发生冲突;

4

译码显示电路 报时电路 脉冲发生电路 计时电路 闹钟电路 校对电路 清零电路 按键电路 图2.1 多功能数字钟控制器系统结构图

比如说使用者在选择了显示闹钟设置功能模块,如果又不小心摁错键(即拨错开关),电路要做出明确的选择,决定进行什么操作,此时的操作要明确,不可以让使用者不知所措。

所以在这个设计中采用如第二章所述的控制方法,使用四个按键实现多种功能搭配。 ②闹钟设定模块、正常时钟模块的切换不影响时钟的正常计时;

且在调整闹钟的时间的时候不显示现在的时间,必须转换到计时模式下的时候才可以显示计时的时间。 3.2秒脉冲发生电路

秒脉冲发生电路其实也可叫分频电路,需要说明的是,SmartSPOC实验系统不能直接产生频率为1Hz的脉冲,在本次实验中我们所用的是频率为48MHz的晶振脉冲,所以我们需要通过设计分频电路来获得所需要的频率脉冲,已达到所想要的要求。

此次试验实现基本功能所需要的脉冲频率有1hz,1ms,2ms三种不同的时钟,1hz的脉冲基本在秒计数上进行计数,1ms,2ms则用于扫描键盘以及数码显示模块,使得人的眼睛不能分辨它的动态,从而让余晖使得数码显示正常。

5

Y hour out 结束 输出 计时 比较 keyen Reset? Y + 时 101 Hour,min Y N + 分 + 时 nzH,min + 分 N 011 Which mode? Mode key 110 输入clk start 闹钟数据 图3.1.3 系统主要流程图

3.3译码显示电路

一般的显示分为两种,即静态显示与动态显示;

所谓静态显示,即每一个数码管由单独的七段显示译码器驱动,如要显示N位字符,必须用N个七段显示译码器,这种现实方法极大地浪费了芯片的控制管脚。动态显示则是利用

6

了数据选择器的分时复用功能,将任意多位数码管的显示驱动,由一个七段显示译码器来完成。这样即节省了器件及芯片管脚,又提高了元件的使用效率。

在此次实验中,我们采用了动态显示的方法,利用八进制计数器分别实现对秒个位、秒十位、分个位、分十位、时个位、时十位利用一个六进制计数器实现扫描,扫描到的显示管的位选信号为1同时相应段码信号同时传到七段显示。扫描频率设置为1KHz,这样躲过人眼的辨别范围,使得肉眼看上去与静态显示没有什么区别。

译码显示结构图:

Clk1ms seg 数码显示 dig 3.4计时电路

计时电路用的是1hz的时钟信号输入,从秒的个位开始分别开始自加1,直到秒信号累计到六十,开始进位至分钟的个位,一次类推一直到小时的十位。分别采用模60至模24 的计数方式,实现计时功能。

计时电路结构图:

Clk1hz nzhour 计时电路 jshour

3.5 复位电路

复位电路采用k1开关来控制,实现的功能则是,当该键被按下之后,就可以实现计时清零功能。

复位电路结构图:

K1 清零 复位电路 7

四、 功能模块电路设计

此次设计一共有以下几个模块:正常显示模块、分频模块闹铃设定模块、闹铃比较模块、显示管段选模块、显示管位选模块;为了写代码方便都放在一个module 里,只将分频单独隔离出来。

4.1秒脉冲发生电路模块

module make_sec(clk,out_clk1hz); input clk; output out_clk1hz; reg sec;

reg [24:0] count1; //定义计数器

always @(posedge clk) //定义clock上升沿触发 begin end

assign out_clk1hz=sec; //秒输出 endmodule

count1 = count1 + 1'b1; if(count1 == 25'd24000000) begin end

count1 = 25'd0; sec = ~sec;

//计数器清零 //置位秒标志

//判断0.5S

4.2 整体时钟模块

module clock(clk,clk1h,key,dig,seg,modestateled,bsbeep); input clk; input clk1h; input[5:0] key; output[7:0]

//输入时钟

//模块名clock

//输入按键

//数码管选择输出引脚

dig;

output[7:0] seg;//数码管段码 output[2:0] modestateled;//模式灯

8

output bsbeep; //蜂鸣器输出

reg [7:0]seg_r; //数码管段输出引脚 reg [7:0]dig_r; //数码管位输出引脚 reg[3:0] disp_dat; reg[24:0]count;

//定义显示数据寄存器

//定义计数寄存器

reg [24:0]hour,jzhour,nzhour; //定义时钟,闹钟,校时寄存器

reg sec,keyen,bsbeep_r,zdbeep_r; //定义秒信号,乒乓开关,蜂鸣器寄存器 reg[2:0] modestate;//定义状态模式 reg[5:0]dout1,dout2,dout3;

//寄存器

reg[27:0]zdcount;//定义整点计时器 wire[5:0]key_done;//定义按下后稳定的键值 wire bsbeep;

//输出数码管选择 //输出数码管译码结果

assign dig = dig_r; assign seg = seg_r; //各类触发信号

always @(posedge clk) begin

//定义clock上升沿触发

if(count == 25'd24000000) begin

count = 25'd0; sec=~sec;

//0.5S到了吗?

end end

else begin

//计数器清零

count = count + 1'b1; end

//按键消抖处理部分

assign key_done = (dout1 | dout2 | dout3); //按键消抖输出 always @(posedge count[17])

9

begin end

always @(negedge key_done[1])//计数开关 begin

keyen = ~keyen; end

dout1 <= key; dout2 <= dout1; dout3 <= dout2;

//按键输入工作模式led显示处理部分

assign modestateled = modestate;//令状态可以用灯输出 always @(key_done)//工作模式 begin

if(key_done[3:1]==3'b110)

begin

modestate = 3'b110;//计时模式 end

else if(key_done[3:1]==3'b101)//校时模式 end

//数码管动态扫描显示部分 always @(posedge clk)

begin

modestate = 3'b101; end

else if(key_done[3:1]==3'b011)//闹钟模式

begin

modestate = 3'b011; end

else if (key_done[3:1]==3'b001) modestate=3'b001;

//count[17:15]大约1ms改变一次

10

begin case(count[17:15]) 3'd0:disp_dat = hour[3:0]; 3'd1:disp_dat = hour[7:4]; 3'd2:disp_dat = 4'ha;

3'd3:disp_dat = hour[11:8];

3'd4:disp_dat = hour[15:12]; 3'd5:disp_dat = 4'ha;

3'd6:disp_dat = hour[19:16];

3'd7:disp_dat = hour[23:20];

endcase

case(count[17:15])

3'd0:dig_r = 8'b11111110; 3'd1:dig_r = 8'b11111101; 3'd2:dig_r = 8'b11111011; 3'd3:dig_r = 8'b11110111; 3'd4:dig_r = 8'b11101111; 3'd5:dig_r = 8'b11011111; 3'd6:dig_r = 8'b10111111;

3'd7:dig_r = 8'b01111111;

endcase

end

always @(posedge clk) begin case(disp_dat) 4'h0:seg_r = 8'hc0; 4'h1:seg_r = 8'hf9; 4'h2:seg_r = 8'ha4; 4'h3:seg_r = 8'hb0;

4'h4:seg_r = 8'h99;

//选择扫描显示数据 //秒个位 //秒十位 //显示\//分个位

//分十位 //显示\

//时个位 //时十位

//选择数码管显示位 //选择第一个数码管显示//选择第二个数码管显示//选择第三个数码管显示//选择第四个数码管显示//选择第五个数码管显示//选择第六个数码管显示//选择第七个数码管显示//选择第八个数码管显示//显示0 //显示1 //显示2 //显示3 //显示4

11

end

4'h5:seg_r = 8'h92; 4'h6:seg_r = 8'h82; 4'h7:seg_r = 8'hf8; 4'h8:seg_r = 8'h80; 4'h9:seg_r = 8'h90; 4'ha:seg_r = 8'hbf; default:seg_r = 8'hff;

//显示5 //显示6 //显示7 //显示8 //显示9 //显示- //不显示

endcase

if((count[17:15]== 3'd2)&sec)

seg_r = 8'hff;

if ((count[17:15]==3'd5)&sec)//数码管秒和分,分和时之间显示“-” seg_r=8'hff;

//校时以及闹钟校时处理部分 always @(negedge key_done[4]) begin

if(modestate == 3'b101) //计时模式下

begin

end

if(modestate == 3'b011) //闹钟模式下

jzhour[19:16] = jzhour[19:16] + 1'b1;//时个位加一 if(jzhour[19:16] == 4'ha) begin

end

jzhour[19:16] = 4'h0;

jzhour[23:20] = jzhour[23:20] + 1'b1;//时十位加一

if(jzhour[23:16] == 8'h24) jzhour[23:16] = 8'h0;

begin

nzhour[19:16] = nzhour[19:16] + 1'b1;//时个位加一

12

end

if(nzhour[19:16] == 4'ha) begin

end

nzhour[19:16] = 4'h0;

nzhour[23:20] = nzhour[23:20] + 1'b1;//时十位加一

if(nzhour[23:16] == 8'h24) nzhour[23:16] = 8'h0;

end

//校时分处理部分

always @(negedge key_done[5]) begin

if(modestate == 3'b101) //校时模式

begin

jzhour[11:8] = jzhour[11:8] + 1'b1;//分个位加一 if(jzhour[11:8] == 4'ha) begin

jzhour[11:8] = 4'h0;

jzhour[15:12] = jzhour[15:12] + 1'b1;//分十位加一

end

if(jzhour[15:8] == 8'h60) jzhour[15:8] = 8'h0;

end

if(modestate == 3'b011) //闹钟模式

begin

nzhour[11:8] = nzhour[11:8] + 1'b1;//分个位加一 if(nzhour[11:8] == 4'ha) begin

nzhour[11:8] = 4'h0;

nzhour[15:12] = nzhour[15:12] + 1'b1;//分十位加一

13

end

if(nzhour[15:8] == 8'h60) nzhour[15:8] = 8'h0;

end end

//计时处理部分

always @(posedge sec or negedge key_done[0])//计时处理 begin

if(!key_done[0]) begin end

//是清零键吗?

hour = 24'h0; //是,则清零

else if(modestate == 3'b101)//是校对时间模式吗?

hour=jzhour;//是的话则让显示时间为校时的时间

else if (modestate == 3'b011)//is alarm state?

hour=nzhour;//是的话则让显示时间为闹钟的时间

else if((!keyen)&&((modestate == 3'b110)||(modestate==3'b011)))//是计时间模式吗? begin

hour[3:0] = hour[3:0] + 1'b1; if(hour[3:0] == 4'ha) begin

hour[3:0] = 4'h0;

hour[7:4] = hour[7:4] + 1'b1; //秒的十位加一 if(hour[7:4] == 4'h6) begin

hour[7:4] = 4'h0;

hour[11:8] = hour[11:8] + 1'b1;//分个位加一 if(hour[11:8] == 4'ha) begin

hour[11:8] = 4'h0;

hour[15:12] = hour[15:12] + 1'b1;//分十位加一

14

//秒加1

end

end

end

end

end

if(hour[15:12] == 4'h6) begin end

hour[15:12] = 4'h0;

hour[19:16] = hour[19:16] + 1'b1;//时个位加一 if(hour[19:16] == 4'ha) begin end

if(hour[23:16] == 8'h24)

hour[23:16] = 8'h0; hour[19:16] = 4'h0;

hour[23:20] = hour[23:20] + 1'b1;//时十位加一

//闹钟歌曲 reg yqbeep_r; reg[7:0] state;

//寄存器

//乐谱状态机

reg[15:0]count1,count_end; reg[23:0]count2;

//乐谱参数:D=F/2K (D:参数,F:时钟频率,K:音高频率) parameter L_5 = 16'd61224,

//低音5 //低音6 //中音1 //中音2 //中音3 //中音5 //中音6

15

L_6 = 16'd54545, M_1 = 16'd45863, M_2 = 16'd40865, M_3 = 16'd36402, M_5 = 16'd30612, M_6 = 16'd27273,

H_1 = 16'd22956;

//高音1

parameterTIME = 12000000; always@(posedge clk) begin end

always @(posedge clk) begin

if(count2 < TIME) else begin

count2 = 24'd0; if(state == 8'd147) else

state = state + 1'b1; state = 8'd0;

count1 <= count1 + 1'b1; if(count1 == count_end) begin end

count1 <= 16'h0;

//控制每一个音的长短(250ms)

//计数器加1

//计数器清零 //输出取反

yqbeep_r <= !yqbeep_r;

//一个节拍250mS

count2 = count2 + 1'b1;

case(state)

8'd0,8'd1:

count_end = L_5;//低音\持续2个

节拍

8'd2,8'd3,8'd4,8'd5,8'd6,8'd7,8'd8: count_end = M_1;//中音\持续7个节拍 8'd9,8'd10:

count_end = M_3;//中音\持续2个

节拍

8'd11,8'd12,8'd13,8'd14:

16

count_end = M_2;

8'd15:

count_end = M_1;

8'd16,8'd17: 8'd18,8'd19:

count_end = M_2; count_end = M_3; count_end = M_1; 8'd20,8'd21,8'd22,8'd23,8'd24: 8'd25,8'd26: 8'd27,8'd28:

8'd29,8'd30,8'd31,8'd32,8'd33: 8'd34,8'd35,8'd36,8'd37,8'd38: 8'd39,8'd40,8'd41,8'd42: 8'd43,8'd44,8'd45: 8'd46,8'd47:

8'd48,8'd49,8'd50,8'd51: 8'd52:

8'd53,8'd54: 8'd55,8'd56:

8'd57,8'd58,8'd59,8'd60: 8'd61,8'd62,8'd63: 8'd64,8'd65:

8'd66,8'd67,8'd68,8'd69: 8'd70,8'd71,8'd72,8'd73: 8'd74,8'd75:

8'd76,8'd77,8'd78,8'd79: 8'd80,8'd81,8'd82: 8'd83,8'd84:

8'd85,8'd86,8'd87,8'd88: 8'd89:

8'd90,8'd91: 8'd92,8'd93:

8'd94,8'd95,8'd96,8'd97: 8'd98,8'd99,8'd100:

count_end = M_3; count_end = M_5; count_end = M_6; count_end = M_6; count_end = M_5; count_end = M_3; count_end = M_1; count_end = M_2;

count_end = M_1;

count_end = M_2; count_end = M_3; count_end = M_1; count_end = L_6;

count_end = M_5;

count_end = M_1; count_end = M_1;

count_end = M_6; count_end = M_5; count_end = M_3;

count_end = M_1; count_end = M_2;

count_end = M_1;

count_end = M_2;

count_end = M_6;

count_end = M_5;

count_end = M_3;

17

end

end

8'd101,8'd102: count_end = M_5;

8'd103,8'd104,8'd105,8'd106: 8'd107,8'd108,8'd109,8'd110: 8'd111,8'd112:

count_end = M_6;

count_end = M_6;

count_end = H_1;

8'd113,8'd114,8'd115,8'd116: 8'd117,8'd118,8'd119: 8'd120,8'd121:

count_end = M_5; count_end = M_3;

count_end = M_1;

8'd122,8'd123,8'd124,8'd125: 8'd126:

count_end = M_2; count_end = M_1;

8'd127,8'd128: 8'd129,8'd130:

count_end = M_2; count_end = M_3;

8'd131,8'd132,8'd133,8'd134: 8'd135,8'd136,8'd137: 8'd138,8'd139:

count_end = M_1; count_end = L_6;

count_end = M_5;

8'd140,8'd141,8'd142,8'd143: 8'd144,8'd145,8'd146,8'd147: default:count_end = 16'h0;

count_end = M_1;

count_end = M_1;

endcase

//整点报时处理部分 assign bsbeep=bsbeep_r; always@(posedge clk)

begin

if((modestate == 3'b110)&&(hour[15:0]>=4'h0000)&&(hour[15:0]<=4'h0005)

bsbeep_r=zdbeep_r; //蜂鸣器输出为整点报时

else if((modestate==3'b110)&&(nzhour[23:8]==hour[23:8]))

bsbeep_r=yqbeep_r; //蜂鸣器输出为闹钟输出 bsbeep_r=1'b0;

else

end

18

//整点滴滴处理部分 always@(posedge clk) begin end

always @(zdcount[9])//计时第十位,让其产生半秒的滴答声 begin end endmodule

zdbeep_r = !(zdcount[13]&zdcount[24]&zdcount[27]); zdcount <= zdcount + 1'b1;

① 输入输出模块框图

图4.2.1模块输入输出图

② 逻辑图

19

图4.2.2 整体输入输出逻辑图

图4.2.3 秒计数器门电路原理图

20

图4.2.4 小时计数器原理图

五、 系统调试

5.1

系统调试

5.11按键消抖仿真调试

1、仿真代码 `timescale 1ns/1ns module anjianxiaodou_tp; reg clk1ms,key,dout1,dout2,dout3; wire key_done,dout1o,dout2o,dout3o; parameter DELY=100;

always #(DELY/2) clk1ms=~clk1ms;

anjianxiaodou u1(key_done,clk1ms,key,dout1o,dout2o,dout3o); initial begin

clk1ms=0;key=1; #DELY key=0; #DELY key=0; #DELY key=0;

21

#(DELY*20); # DELY $finish; end initial

$monitor($time,,,\

dout1=%b

dout2=%b

dout3=%b

key=%b\endmodule

module anjianxiaodou(key_done,clk1ms,key,dout1o,dout2o,dout3o); input key,clk1ms; output key_done; reg dout1,dout2,dout3; output dout1o,dout2o,dout3o; assign dout1o=dout1; assign dout2o=dout2; assign dout3o=dout3; always @(posedge clk1ms) begin end

assign key_done = (dout1 | dout2 | dout3); //按键消抖输出 endmodule 2、仿真波形

dout1 <= key; dout2 <= dout1; dout3 <= dout2;

22

图5.1按键消抖 3、分析

一个按键按下之后测试在三个十周中期内是否被按下,如果保持,这说明是被确实按下。

5.12 计时模块仿真

1、仿真代码:

`timescale 1ns/1ns module jishichuli_tp; reg reset,clk;

wire [23:0]hourout; parameter DELY=100;

always #(DELY/2) clk=~clk; jishichuli u1(clk,reset,hourout);

initial begin

clk=0;reset=0; #DELY reset=1; #DELY reset=0; #(DELY*300); # DELY $finish; end

initial $monitor ($time,,,\endmodule

module jishichuli(clk,reset,hourout); input clk,reset;

output [23:0] hourout; reg [23:0] hour;

assign hourout=hour; always @(posedge clk) begin if(reset)

23

//清零?

hour[23:0]=0;

else

begin end

endmodule

hour[3:0] = hour[3:0] + 1'b1; //秒个位+1 if(hour[3:0] == 4'ha) begin hour[3:0] = 4'h0; hour[7:4] = hour[7:4] + 1'b1; //秒十位+1 if(hour[7:4] == 4'h6) begin hour[7:4] = 4'h0; hour[11:8] = hour[11:8] + 1'b1;//分个位+1 if(hour[11:8] == 4'ha) begin hour[11:8] = 4'h0; hour[15:12] = hour[15:12] + 1'b1;//分十位+1 if(hour[15:12] == 4'h6) begin hour[15:12] = 4'h0; hour[19:16] = hour[19:16] + 1'b1; if(hour[19:16] == 4'ha) begin hour[19:16] = 4'h0; hour[23:20] = hour[23:20] + 1'b1; end if(hour[23:16] == 8'h24) hour[23:16] = 8'h0; end end end end end

24

图5.12 计时模块 3、分析:

在秒的地方采用模60计数,分采用60 计数,时采用24计数。

5.13 秒产生仿真

1、仿真代码: `timescale 1ns/1ns

module make_clock_tp; reg clk,reset; wire clock_out; wire [1:0]count_out;

parameter DELY=100;

always #(DELY/2) clk=~clk;

make_clock u1(clk,clock_out,count_out,reset); initial begin

clk=0;reset=0; #DELY reset =1; #DELY reset =0; #(DELY*20); # DELY $finish; end

initial$monitor($time,,,\reset=%d count_out=%d\

endmodule

module make_clock(clk,clock_out,count_out,reset); input clk; input reset;

output clock_out;

25

clock_out=%d

output [1:0]count_out; reg [1:0] count1; reg sec;

assign clock_out=sec; assign count_out=count1; //定义计数器

always @(posedge clk) begin

if (reset) begin count1<=0;sec<=0;end else

begin count1 <= count1 + 1'b1; if(count1 == 2'd3) begin count1 = 2'd0; sec = ~sec; end end end

Endmodule 2、仿真图

//判断0.5S

//计数器清零 //置位秒标志

图5.13秒产生 3、分析:

三个时钟周期产生一个脉冲,因为原计数器过于庞大,为了是波形更加可见,采用3分频,即可清晰看见分频的产生。

5.14 整点报时

1、仿真代码 `timescale 1ns/1ns

module zhengdiandidi_tp; reg clk,reset; wire zdbeep;

26

wire [2:0]zdcountout;

parameter DELY=100;

always #(DELY/2) clk=~clk;

zhengdiandidi u1(reset,clk,zdbeep,zdcountout); initial begin

clk=0;reset=0; #DELY reset =1; #DELY reset =0; #(DELY*20); # DELY $finish; end

initial $monitor($time,,,\ zdcountout=%d \endmodule

module zhengdiandidi(reset,clk,zdbeep,zdcountout); input clk,reset; output zdbeep;

output [2:0]zdcountout; reg [2:0] zdcount; reg zdbeep_r;

assign zdbeep=zdbeep_r; assign zdcountout=zdcount; always@(posedge clk) begin

if(reset) zdcount=0; else

begin zdcount <= zdcount + 1'b1; if (zdcount==8) zdcount=0; end end

always @(zdcount[1]) begin zdbeep_r = !(zdcount[2]&zdcount[1]&zdcount[0]); end

endmodule 2、仿真图

27

图5.14 整点报时滴滴声 3、分析 :

当时钟信号来的时候,计数器的不同位同时为1的时候取反,是的信号反转,从而产生平率一定的声音信号。

5.15 数码显示仿真

1、仿真代码

`timescale 1ns/1ns module shumaxianshi_tp; reg clk,reset;

wire [3:0]disp_dato; wire [2:0] counto; reg [2:0] count; wire [7:0]dig,seg;

parameter DELY=100;

always #(DELY/2) clk=~clk;

shumaxianshi u1(reset,clk,disp_dato,dig,seg,counto); initial begin

clk=0;reset=0;

#DELY reset =1;//出现复位信号使得整体时序电路得以走动 #DELY reset =0; #(DELY*20); # DELY $finish; end

initial $monitor($time,,,\ dig=%d seg=%d count=%d\endmodule

module shumaxianshi(reset,clk,disp_dato,dig,seg,counto);

28

input clk,reset; output [3:0]disp_dato; output [2:0] counto; reg [3:0]disp_dat;

assign disp_dato=disp_dat; output [8:0]dig,seg; reg [7:0]dig_r,seg_r; assign dig=dig_r; assign seg=seg_r; reg [2:0] count; assign counto=count; reg [23:0] hour;

always @(posedge clk) begin end

always @(posedge clk) begin if (reset)

count=3'd0; else begin

count<=count+1'b1;

//count[17:15]大约1ms改变一次 case(count[2:0]) //选择扫描显示数据 3'd0:disp_dat = 4'h1; //秒个位 3'd1:disp_dat = 4'h2; //秒十位 3'd2:disp_dat = 4'ha; //显示\ 3'd3:disp_dat = 4'h0; //分个位 3'd4:disp_dat = 4'h0; //分十位 3'd5:disp_dat = 4'ha; //显示\ 3'd6:disp_dat = 4'h0; //时个位 3'd7:disp_dat = 4'h0; //时十位 endcase case(count[2:0]) //选择数码管显示位 3'd0:dig_r = 8'b11111110; //选择第一个数码管显示 3'd1:dig_r = 8'b11111101; //选择第二个数码管显示 3'd2:dig_r = 8'b11111011; //选择第三个数码管显示 3'd3:dig_r = 8'b11110111; //选择第四个数码管显示 3'd4:dig_r = 8'b11101111; //选择第五个数码管显示 3'd5:dig_r = 8'b11011111; //选择第六个数码管显示 3'd6:dig_r = 8'b10111111; //选择第七个数码管显示 3'd7:dig_r = 8'b01111111; //选择第八个数码管显示 endcase if(count==3'd8)

29

end End

always @(posedge clk) begin end

endmodule

2.仿真图

count=3'd0;

case(disp_dat)

4'h0:seg_r = 8'hc0; 4'h1:seg_r = 8'hf9; 4'h2:seg_r = 8'ha4; 4'h3:seg_r = 8'hb0; 4'h4:seg_r = 8'h99; 4'h5:seg_r = 8'h92; 4'h6:seg_r = 8'h82; 4'h7:seg_r = 8'hf8; 4'h8:seg_r = 8'h80; 4'h9:seg_r = 8'h90; 4'ha:seg_r = 8'hbf; default:seg_r = 8'hff; endcase

//显示0 //显示1 //显示2 //显示3 //显示4 //显示5 //显示6 //显示7 //显示8 //显示9 //显示- //不显示

图5.15数码显示 3、分析:

为了测试方便在数码管显示已经设定好的时间12:00:00 就直接写入该值,如上所示。

5.16 时校时仿真

1、代码

`timescale 1ns/1ns

30

module jiaoshi_tp; reg clk,reset;

wire [23:16]jzhourout; parameter DELY=10;

always #(DELY/2) clk=~clk; jiaoshi u1(reset,clk,jzhourout); initial begin

clk=0;reset=0; #DELY reset =1; #DELY reset =0; #(DELY*100); # DELY $finish; end

initial $monitor($time,,,\endmodule

module jiaoshi(reset,clk,jzhourout); input clk,reset;

output [23:16] jzhourout; reg [23:16]jzhour;

assign jzhourout=jzhour;

always @(negedge clk) begin

if (reset) jzhour[23:16]=0; else begin end end

Endmodule

2、仿真波形图

\ jzhour[19:16] = jzhour[19:16] + 1'b1;//时个位+1 if(jzhour[19:16] == 4'ha) begin jzhour[19:16] = 4'h0; jzhour[23:20] = jzhour[23:20] + 1'b1;//时十位+1 end if(jzhour[23:16] == 8'h24) jzhour[23:16] = 8'h0; 31

图5.16时校时 3、分析:

时24到了之后清零,否则自加。

5.17 状态灯仿真

1、仿真代码 `timescale 1ns/1ns module modestate_tp; reg [3:1] key;

wire [3:1] modestateled; parameter DELY=100;

modestate u1(key,modestateled); initial begin

key=3'b011;//输入不同的状态 #DELY key=3'b101; #DELY key=3'b110; #DELY key=3'b011; #DELY key=3'b101; #DELY key=3'b110; #DELY key=3'b011; #DELY key=3'b101; #DELY key=3'b110; #DELY key=3'b011; #DELY $finish; end

initial $monitor ($time,,,\输出不同的状态 endmodule

module modestate(key,modestateled); input [3:1] key;

32

output [3:1] modestateled; reg [3:1] key_done,modestate; assign modestateled = modestate;

always @(key)//判断键值并匹配状态 begin if(key[3:1]==3'b110) begin modestate = 3'b110;//计时? end else if(key[3:1]==3'b101)//校时? begin modestate = 3'b101; end else if(key[3:1]==3'b011)//闹钟? begin modestate = 3'b011; end end

endmodule

2、仿真波形图

图5.17状态灯 3、分析:

输入三个不同的状态,状态灯输出与之相对应的状态信号。

5.2管脚分配

set_location_assignment PIN_28 -to clk set_location_assignment PIN_121 -to key[0] set_location_assignment PIN_122 -to key[1] set_location_assignment PIN_236 -to dig[4] set_location_assignment PIN_237 -to dig[5] set_location_assignment PIN_238 -to dig[6] set_location_assignment PIN_239 -to dig[7] set_location_assignment PIN_161 -to dig[3] set_location_assignment PIN_162 -to dig[2] set_location_assignment PIN_159 -to dig[1] set_location_assignment PIN_160 -to dig[0] set_location_assignment PIN_164 -to seg[7] set_location_assignment PIN_163 -to seg[6] set_location_assignment PIN_166 -to seg[5]

33

set_location_assignment PIN_165 -to seg[4] set_location_assignment PIN_168 -to seg[3] set_location_assignment PIN_167 -to seg[2] set_location_assignment PIN_170 -to seg[1] set_location_assignment PIN_169 -to seg[0]

set_location_assignment PIN_54 -to modestateled[2] set_location_assignment PIN_53 -to modestateled[1] set_location_assignment PIN_50 -to modestateled[0] set_location_assignment PIN_123 -to key[2] set_location_assignment PIN_124 -to key[3] set_location_assignment PIN_143 -to key[4] set_location_assignment PIN_141 -to key[5]

set_instance_assignment -name CLOCK_SETTINGS clk -to clk

set_instance_assignment -name CLOCK_SETTINGS count -to count[17] set_instance_assignment -name CLOCK_SETTINGS sec -to sec set_instance_assignment -name CLOCK_SETTINGS key -to dout1 set_instance_assignment -name CLOCK_SETTINGS key -to dout2 set_instance_assignment -name CLOCK_SETTINGS key -to dout3

set_instance_assignment -name CLOCK_SETTINGS key_done -to key_done[0]~36 set_location_assignment PIN_175 -to bsbeep

5.3 实际调试

① 测试条件

在实验箱上装载进去,并且连结必要的线进行实际仿真。 ② 测试结果及数据

结果和设计的基本一致,除了按键不灵敏之外,其他都达到了预期的效果。

六、参考文献

1. 王金明.数字系统设计与verilog HDL(第四版).电子工业出版社.北京.2011. 2.臧春华.数字系统设计与PLD应用(第三版).电子工业出版社.北京.2009.

七.实验感想

通过本次的实验将大三学习的硬件设计语言的内容以及EDA设计重新复习了一遍,把原本很多只能在理论上学习到的东西,付出到实践当中去。刚开始的三天,有设计的思想,但已经忘记了很多语法上应该注意的东西,使得很多想法没有办法实现。后来,因为想做好这样的课程设计,就去老师的办公室,帮助老师一起完成程序的编写。老师也给自己分配了一些任务,但是,因为自己的能力有限,实在完成不了。尽管如此,还是会更多的过去学习,时间证明了一切,在老师办公室的三天的时间里,将自己原来很多不会的东西,都基本弄懂,也给了老师提供了一些微不足道的帮助。整体的实验步骤比较多,调试是非常测试人的耐心的,很多时候一个问题可以困扰半天,但是收货确实很多。感谢老师的悉心教导!

34

本文来源:https://www.bwwdw.com/article/4iv5.html

Top