EDA数字钟系统设计.docx
《EDA数字钟系统设计.docx》由会员分享,可在线阅读,更多相关《EDA数字钟系统设计.docx(22页珍藏版)》请在冰豆网上搜索。
![EDA数字钟系统设计.docx](https://file1.bdocx.com/fileroot1/2022-12/7/ff8d22ca-c99e-4975-be69-0b9e57ee0ad8/ff8d22ca-c99e-4975-be69-0b9e57ee0ad81.gif)
EDA数字钟系统设计
目录
摘要………………………………………………………………………2
1设计目的………………………………………………………………2
2设计内容……………………………………………………………2
2.1设计任务……………………………………………………………2
2.2扩展……………………………………………………………2
3系统方案及设计原理………………………………………………3
3.1方案选择…………………………………………………………3
3.2数字钟的基本工作原理………………………………………………3
3.3底层元件接口………………………………………………………4
3.4数字钟设计的RTL电路……………………………………………5
4设计步骤………………………………………………………………5
5心得体会………………………………………………………………10
6程序代码…………………………………………………………10
摘要:
人类社会已进入到高度发达的信息化社会。
信息化社会的发展离不开电子信息产品开发技术、产品品质的提高和进步。
电子信息产品随着科学技术的进步,其电子器件和设计方法更新换代的速度日新月异。
实现这种进步的主要原因就是电子设计技术和电子制造技术的发展,其核心就是电子设计自动化(EDA,Electronics Design Automation)技术,EDA技术的发展和推广应用又极大地推动了电子信息产业的发展。
为保证电子系统设计的速度和质量,适应“第一时间推出产品”的设计要求,EDA技术正逐渐成为不可缺少的一项先进技术和重要工具。
目前,在国内电子技术教学和产业界的技术推广中已形成“EDA热”,完全可以说,掌握EDA技术是电子信息类专业学生、工程技术人员所必备的基本能力和技能。
EDA技术在电子系统设计领域越来越普及,本设计主要利用VHDL语言在EDA平台上设计一个电子数字钟,它的计时为24小时小时制,显示满刻度为23时59分59秒,另外还具有校时功能和闹钟功能。
总的程序由几个各具不同功能的单元模块程序拼接而成,其中包括分频程序模块、时分秒计数和校时程序模块、数据选择器程序模块、显示程序模块和例化程序模块。
并且使用QUARTUS II软件进行电路波形仿真,下载到EDA实验箱进行验证。
关键词:
数字钟EDAVHDL语言
一、设计目的
1、熟练地运用数字系统的设计方法进行数字系统设计;
2、能进行较复杂的数字系统设计;
3、按要求设计一个数字钟。
二、设计内容
2.1、设计任务:
设计一台能显示时、分、秒的数字钟。
具体要求如下:
(1)由实验箱上的时钟信号经分频产生秒脉冲;
(2)计时计数器用24进制计时电路;
(3)可手动校时,能分别进行时、分的校正;
(4)整点报时;
2.2、扩展:
设置闹时功能,当计时计到预定时间时,扬声器发出闹铃信号,闹铃时间为4s,并可提前终止闹铃。
三、系统方案及设计原理。
3.1、方案选择:
数字钟无非就是分频计数,设计出60进制,24进制计数器,在这里,秒分计数是60进制,时计数是24进制,对1Hz信号进行60分频也就产生了分计数脉冲,对1Hz进行60*60分频(对分60分频)也就产生了时计数脉冲,为了方便校时,系统设计时未直接采用实验箱上的1Hz作为基准时钟源,而是对65536Hz进行32768分频产生秒脉冲,8192分频作为校时与闹钟时间设置脉冲,为方便调闹钟,采用了数据选择器选择输出正常走时或闹钟时间。
为节省代码,数码管译码工作直接交给了实验箱自带的译码器,选择工作模式0。
3.2、数字钟的基本工作原理:
数字钟以其显示时间的直观性、走时准确性作为一种计时工具,数字钟的基本组成部分离不开计数器,在控制逻辑电路的控制下完成预定的各项功能。
数字钟的基本原理方框图如图1:
时显示器
秒显示器
分显示器
时译码器
秒译码器
分译码器
报时/闹钟
时计数器
分计数器
秒计数器
校时电路
1Hz
5HZ
分频器
振荡器
图1数字钟的系统框图
图3.1数字钟实现原理框图
该系统由振荡器、分频器、“时、分、秒”计数器、译码器及显示器、校时电路、整点报时电路等组成。
石英晶体振荡器和分频器产生整个系统的时基信号,它直接决定计时系统的精度。
“秒计数器”采用六十进制计数器,每累计60秒向“分计数器”进位;“分计数器”采用六十进制计数器,每累计60分向“时计数器”进位;“时计数器”采用二十四进制计数器,按照“24翻1”规律计数。
“时、分、秒”计数器的输出经译码器送显示器显示。
校时电路用来当计时出现误差时对“时、分、秒”进行校对调整。
整点报时(闹钟)电路是根据计时系统的输出状态产生一脉冲信号,然后去触发音频发生器实现报时(闹铃)。
3.3、底层元件接口:
componenthour
port(rst,carry,en:
instd_logic;
ADJclk,ADJEN:
instd_logic;
ADJ:
instd_logic_vector(3downto0);
decade,unit:
outstd_logic_vector(3downto0));
endcomponent;
componentmin
port(rst,carry,en:
instd_logic;
ADJclk,ADJEN:
instd_logic;
ADJ:
instd_logic_vector(3downto0);
carryout:
outstd_logic;
decade,unit:
outstd_logic_vector(3downto0));
endcomponent;
componentsec
port(rst,clk,en:
instd_logic;
ADJEN:
instd_logic;
carryout:
outstd_logic;
decade,unit:
outstd_logic_vector(3downto0));
endcomponent;
componentalarm
port(clk,en,ADJclk:
instd_logic;
alarmADJ:
instd_logic;
AlarmEn:
instd_logic;
ADJ:
instd_logic_vector(3downto0);
hour_unit:
instd_logic_vector(3downto0);
hour_decade:
instd_logic_vector(3downto0);
min_unit:
instd_logic_vector(3downto0);
min_decade:
instd_logic_vector(3downto0);
ADJhour_unit:
outstd_logic_vector(3downto0);
ADJhour_decade:
outstd_logic_vector(3downto0);
ADJmin_unit:
outstd_logic_vector(3downto0);
ADJmin_decade:
outstd_logic_vector(3downto0);
sound:
outstd_logic);
endcomponent;
componentPrescalClk
port(clkin:
instd_logic;
clkout_1Hz:
outstd_logic;
clkout_4Hz:
outstd_logic);
endcomponent;
3.4、数字钟设计的RTL电路:
图2
从RTL电路中可以看到,通过综合后系统模块划分为分频模块、秒计数模块、分计数模块、时计数模块、闹钟模块,数据选择输出模块,由于系统设计时硬件平台选用的是模式0,显示部由硬件译码。
分频模块产生正常走时的1Hz频率与校时用的5Hz频率,时分秒计数都可有外部按键清零,时分可分别进行校时,闹钟模块可根据需要设置闹铃时间,输出部分采用了数据选择器,用于选择输出正常走时或闹钟设置时间。
四、设计步骤
步骤1:
输入设计项目和存盘
打开QUARTUS
,单击“file”菜单,将鼠标移到NewProjectWizard选项单击则显示如图3
图3建立NewProject
在第一栏选择或写入工程文件名,第二、三栏中建立项目名和实体名,工程文件不能包含中文字符,项目名和实体必须保持一致,然后选择目标器件如图4
图4选择没标器件
目标器件一定要与实际所用器件一致,最后点击finish完成弹出图5
图5建立VHDL文件
步骤2:
输入程序并运行编译;
在工具栏中点击file→new,选择VHDLFile,点击确定建立VHDL文件,在里面键入程序,如图6
图6输入程序
输入完程序以后点击工具栏中的保存,再点击右方一个紫色的三角符号“
”,然后运行程序,如果程序出现错误在改正。
编译通过后如图7
7通过编译
步骤3:
时序仿真:
1.建立波形文件:
选择File->New,在OtherFile里选择VectorWaveformFile,单击OK建立波形文件,在Edit->EndTime选项中为仿真设置仿真时间。
双击Name下的空白处,弹出InsertNodorBus对话框,单击NodeFinder如图7
图7选择添加结点设置
在图8所示选定各个选择项。
图8选择结点
单击OK,完成引脚输入,加上输入信号后波形文件存盘。
2.运行仿真器。
在Processing菜单下选择StartSimulation项,直到Simulatorwassuccessful出现,仿真结束。
完成波形如图9所示。
图9仿真波形图
步骤4:
引脚锁定
选择AssignmentsAssignmentsEditor,锁定引脚,输入以后如下图,设定完成以后再运行一次程序。
图10引脚锁定
步骤5:
编程下载:
1)首先将下载线把计算机的打印机口与目标板(如开发板或实验板)连接好,打开电源
2)下载方式设定。
选择ToolsProgrammer选项,跳出下图左侧所示的编程器窗口,然后选择HardwareSetup硬件设置选项,其窗口图中左侧所示。
在其下拉菜单中选ByteBlaster(MV)编程方式,在Model栏选定JTAG模式。
然后点击start按钮下载,进入下载模式,等待下载完成以后在试验箱上进行调试检测是否正确。
五、心得体会
经过两周EDA课程设计,使我受益匪浅。
这不仅增强了我对EDA设计的兴趣,更巩固了基本的电路设计流程、方法以及技巧。
具备了这些基本知识,为今后的自主学习奠定了良好的基础。
在编写时可以相互借鉴,这样可以节省一定的时间,但在一个问题上纠结了很久,现还未明白,为什么一个变量在进程中只能被一个边沿信号触发进行修改,无奈之下选择了另一种方法,通过一个控制端来进行选频,以实现快速调时,在闹钟的处理上使用了数据选择,设置闹铃时数码管显示闹钟时间。
在设计中还是需要注意一些常见的问题,比如实体名、项目名等,还有在编写VHDL文件时,一些文件名也是需要注意的;在编写程序的过程中,信号与变量的使用是一个特需要注意的,进程中一个信号不应有多个复制源,信号的复值是在进程结束之时,而变量的复值是立即的,在书写时容易出错的地方是,信号的赋值与变量的赋值符号,信号作为全局的联络线,信号往往不允许在多个进程中被赋值,因为进程之间是并行的;整个系统是由多个底层元件组成,底层元件之间的相互连接是通过信号实现。
由于时间比较紧,在准备智能车比赛,就没有挑战难度高点的题了,但本人对FPGA是挺感兴趣的,在今后的学习中我会把握时间好好学学。
最后感谢姚老师对我们的指导,使得实验能够顺利完成!
六、程序代码:
1分频:
libraryieee;
useieee.std_logic_1164.all;
useieee.std_logic_unsigned.all;
entityPrescalClkis
port(clkin:
instd_logic;
clkout_1Hz:
outstd_logic;
clkout_4Hz:
outstd_logic);
end;
ArchitecturebhvofPrescalClkis
begin
process(clkin)
variablecount1:
integerrange0to32768;
variablecount2:
integerrange0to8192;
begin
ifclkin'eventandclkin='1'thencount1:
=count1+1;count2:
=count2+1;
if(count1=32768)thenclkout_1Hz<='1';
elseclkout_1Hz<='0';
endif;
if(count2=8192)thenclkout_4Hz<='1';
elseclkout_4Hz<='0';
endif;
endif;
endprocess;
end;
2时计数模块
libraryieee;
useieee.std_logic_1164.all;
useieee.std_logic_unsigned.all;
entityhouris
port(rst,carry,en:
instd_logic;
ADJclk,ADJEN:
instd_logic;
ADJ:
instd_logic_vector(3downto0);
decade,unit:
outstd_logic_vector(3downto0));
end;
architecturebhvofhouris
signalclk:
std_logic;
begin
process(carry,ADJ,ADJEN,ADJclk)
begin
if(ADJEN='1'andADJ="1100")thenclk<=ADJclk;
elseclk<=carry;
endif;
endprocess;
process(rst,en,clk)
variableunitcount:
std_logic_vector(3downto0);
variabledecadecount:
std_logic_vector(3downto0);
begin
if(rst='1')thenunitcount:
="0000";decadecount:
="0000";
elsif(en='1')then
ifclk'eventandclk='1'then
if(unitcount<10)thenunitcount:
=unitcount+1;
elseunitcount:
="0000";
endif;
if(unitcount=10)thendecadecount:
=decadecount+1;unitcount:
="0000";
endif;
if(decadecount=2andunitcount=4)thenunitcount:
="0000";decadecount:
="0000";
endif;
endif;
endif;
decade<=decadecount;
unit<=unitcount;
endprocess;
end;
3分计数模块:
libraryieee;
useieee.std_logic_1164.all;
useieee.std_logic_unsigned.all;
entityminis
port(rst,carry,en:
instd_logic;
ADJclk,ADJEN:
instd_logic;
ADJ:
instd_logic_vector(3downto0);
carryout:
outstd_logic;
decade,unit:
outstd_logic_vector(3downto0));
end;
architecturebhvofminis
signalclk:
std_logic;
begin
process(carry,ADJ,ADJEN,ADJclk)
begin
if(ADJEN='1'andADJ="0011")thenclk<=ADJclk;
elseclk<=carry;
endif;
endprocess;
process(rst,en,clk,ADJEN)
variableunitcount:
std_logic_vector(3downto0);
variabledecadecount:
std_logic_vector(3downto0);
begin
if(rst='1')thenunitcount:
="0000";decadecount:
="0000";
elsif(en='1')then
if(clk'eventandclk='1')then
if(unitcount<10)thenunitcount:
=unitcount+1;
elseunitcount:
="0000";
endif;
if(unitcount=10)thendecadecount:
=decadecount+1;unitcount:
="0000";
endif;
if(decadecount=6andunitcount=0)thenunitcount:
="0000";decadecount:
="0000";
ifADJEN='0'thencarryout<='1';--whenADJEN=1,donotgeneratecarry
elsecarryout<='0';
endif;
elsecarryout<='0';
endif;
endif;
endif;
decade<=decadecount;
unit<=unitcount;
endprocess;
end;
4秒计数模块:
libraryieee;
useieee.std_logic_1164.all;
useieee.std_logic_unsigned.all;
entitysecis
port(rst,clk,en:
instd_logic;
ADJEN:
instd_logic;
carryout:
outstd_logic;
decade,unit:
outstd_logic_vector(3downto0));
end;
architecturebhvofsecis
begin
process(rst,en,clk)
variableunitcount:
std_logic_vector(3downto0);
variabledecadecount:
std_logic_vector(3downto0);
begin
if(rst='1')thenunitcount:
="0000";decadecount:
="0000";
elsif(en='1')then
ifclk'eventandclk='1'then
if(unitcount<10)thenunitcount:
=unitcount+1;
elseunitcount:
="0000";
endif;
if(unitcount=10)thendecadecount:
=decadecount+1;unitcount:
="0000";
endif;
if(decadecount=6andunitcount=0)
thenunitcount:
="0000";decadecount:
="0000";
if(ADJEN='0')thencarryout<='1';--whenADJEN=1,donotgeneratecarry
elsecarryout<='0';
endif;
elsecarryout<='0';
endif;
endif;
endif;
decade<=decadecount;
unit<=unitcount;
endprocess;
end;
5闹钟模块:
libraryieee;
useieee.std_logic_1164.all;
useieee.std_logic_unsigned.all;
entityalarmis
port(clk,en,ADJclk:
instd_logic;
alarmADJ:
instd_logic;
AlarmEn:
instd_logic;
ADJ:
instd_logic_vector(3downto0);
hour_unit:
instd_logic_vector(3downto0);
hour_decade:
instd_logic_vector(3downto0);
min_unit:
instd_logic_vector(3downto0);
min_decade:
instd_logic_vector(3downto0);
ADJhour_unit:
outstd_logic_vector(3downto0);
ADJhour_decade:
outstd_logic_vector(3downto0);
ADJmin_unit:
outstd_logic_vector(3downto0);
ADJmin_decade:
outstd_logic_vector(3downto0);
sound:
outstd_logic);
end;
architectu