《VHDL课程设计》实验报告
多功能数字电子钟
姓 名:XXX
班 级:XX班
学 号:XXXXXXXXX
指导老师:XXX
●设计要求
在Quartus II环境下设计芯片完成二十四小时制计时、显示、整点报时、时间设置和闹钟的功能。
●实验目的
(1)充分了解Quartus II运行环境以及基本操作。
(2)学习并熟练掌握控制器、计数器、数据选择器等基本元件的基本原理以及级联方式。
(3)认识数码管的显示原理以及连接方式。
(4)充分理解数字逻辑中硬件与软件相结合的设计方式和思想。
●整体设计方案
(1)整体设计:通过基本的输入输出控制状态的转换以及时间、闹钟的设置以实现的电子钟基本功能。
(2)系统输入:set、k键控制系统状态及校时、定时中时分秒状态转换;clk为1HZ的时钟信号;reset为系统复位信号;p为计数及闹钟设置键;输入信号中只有reset为开关键,其他全由按键产生。
(3)系统输出:LED显示输出;蜂鸣器(bell)声音信号输出。
(4)结构逻辑框图(多功能数字电子钟):
|
|
|
1Hz
k
p 1024Hz
|
reset 1024Hz 蜂鸣器
512Hz
set
|
clk(1Hz) clk 1024Hz
512Hz
1Hz
(5) 控制器的MDS图
●系统功能
(1)计时:正常工作状态下,每日按24h计时制计时并显示,蜂鸣器无声,逢整点报时。
(2)校时:在计时显示状态下,set=0,进入“小时”校准状态,之后按下“k=0”则进入“分”校准状态,继续按下“k=0”则进入“调秒”状态,第三次按下“k键”又恢复到正常计时显示状态。
①“小时”校准状态:在“小时”校准状态下,显示“小时”的数码管闪烁,此时按下“p键”,每按一次小时加1。
②“分”校准状态:在“分”校准状态下,显示“分”的数码管闪烁,此时按下“p键”,每按一次分钟加1。
③“秒”校准状态:在“调秒”状态下,显示“秒”的数码管闪烁,此时长按“p键”,秒清零。
(3)整点报时:蜂鸣器在“59”分钟的第“54”、“56”、“58”秒发频率为512HZ的低音,在“59”分钟的第“60”秒即整点时发频率为1024HZ的高音。
(4)显示:采用1024HZ的频率扫描,显示驱动6个LED数码管显示小时、分、秒。在“时”“分”“秒”之间扫描数码管的“g”管。
(5)闹钟:闹钟定时时间到,蜂鸣器发出周期为1秒频率为1HZ的“滴”、“滴”声,持续时间为60秒。
(6)闹钟定时设置:在正常计数状态下,按下“k=0”,进入闹钟设置状态,再按下“set=0”进入闹钟的“时”设置状态,之后按下“k=0”进入闹钟的“分”设置状态,继续按下“k=0”,又恢复到闹钟定时显示状态。
①闹钟“小时”设置状态:在闹钟“小时”设置状态下,显示“小时”的数码管闪烁,此时按下“p键”,每按一次小时加1。
②闹钟“分”设置状态:在闹钟“分”设置状态下,显示“分”的数码管闪烁此时按下“p键”,每按一次分钟加1。
●各个模块分析
(一)概述:本电子钟整体芯片包括主控芯片(control2)、分频器(fenpin)、计
数和时钟设置芯片(set_and_count)、闹钟设置芯片、译码芯片(ym)、显示控制芯片(show_control)、模8计数芯片(m8)、8选一芯片(m8_1)、整点报时芯片(sound_control_sec)、闹钟响铃控制芯片(control_sound)、显示闪烁芯片(flash)
其中在计数和时钟控制芯片中又有模24计数芯片(m24)、模60计数芯片(m64)、、2选1芯片(m2_1)几个底层芯片
顶层框图
功能分割图(计数和时钟设置芯片)
(二)分述
(2)主控芯片(control2)
I模块说明
总体:控制整个电子钟,通过对输入信号的判断,实现状态转换并决定下属芯片是否启动,保证整个电路正常工作和运行。
输入端口:k,set键来控制8个状态,这八个状态分别是显示计时时间状态,调计时的时、分、秒状态,显示闹铃时间状态调闹铃的时、分、秒的状态,reset键是复位键,用来回复到“00”状态。
输出端口:outreset是输出清零信号;sethour、setmin、setsec分别输出调整计数状态时、分、秒信号,且setsec为输出秒的清零信号;setclkhour、setclkmin分别输出调整闹钟时、分信号;sethouren、setminen、setsecen
分别为调节时、分、秒的使能端;hourfla、minfla、secfla分别为输出调计数时、分、秒的闪烁信号;clkhourfla、clkminfla、clksecfla分别为输出调闹钟时、分的闪烁信号;changemode输出数码管显示闹钟状态信号。
II模块图
III仿真图
IV源代码
library ieee;
use ieee.std_logic_1164.all;
entity control2 is
port(
set,reset,k,cp,p:instd_logic;
outreset,setmin,setminen,sethour,sethouren,setsec,setsecen,hourfla,minfla,secfla,clkhourfla,clkminfla,changemode,setclkhou,setclkmin,clksecfla:outstd_logic);
end control2;
architecture rtl of control2 is
type state is(s0,s1,s2,s3,t0,t1,t2,t3);
signal sta:state;
begin
process(cp,k,set,reset,p)
begin
if(reset='0') then
outreset<='1';sethouren<='0';setminen<='0';setsecen<='0';
sethour<='1';setmin<='1';setsec<='1';setclkhou<='1';setclkmin<='1';hourfla<='0';minfla<='0';secfla<='0';clkhourfla<='0';clkminfla<='0';clksecfla<='0';sta<=s0;
elsif(rising_edge(cp)) then
case sta is
when s0=>changemode<='0';outreset<='0';sethouren<='0';setminen<='0';setsecen<='0';sethour<='1';setmin<='1';setsec<='1';setclkhou<='1';setclkmin<='1';hourfla<='0';minfla<='0';secfla<='0';clkhourfla<='0';clkminfla<='0';clksecfla<='0';
if(k='0') then
sta<=t0;
elsif(set='0')then
sta<=s1;
else
sta<=s0;
end if;
when s1=>changemode<='0';outreset<='0';sethouren<='1';setminen<='0';setsecen<='0';sethour<=p;setmin<='1';setsec<='1';setclkhou<='1';setclkmin<='1';hourfla<='1';minfla<='0';secfla<='0';clkhourfla<='0';clkminfla<='0';clksecfla<='0';
if(k='0')then
sta<=s2;
else
sta<=s1;
end if;
when s2=>changemode<='0';outreset<='0';sethouren<='0';setminen<='1';setsecen<='0';sethour<='1';setmin<=p;setsec<='1';setclkhou<='1';setclkmin<='1';hourfla<='0';minfla<='1';secfla<='0';clkhourfla<='0';clkminfla<='0';clksecfla<='0';
if(k='0')then
sta<=s3;
else
sta<=s2;
end if;
whens3=>changemode<='0';outreset<='0';setminen<='0';sethouren<='0';setsecen<='1';sethour<='1';setmin<='1';setsec<=p;setclkhou<='1';setclkmin<='1';hourfla<='0';minfla<='0';secfla<='1';clkhourfla<='0';clkminfla<='0';clksecfla<='0';
if(k='0')then
sta<=s0;
else
sta<=s3;
end if;
when
t0=>changemode<='1';outreset<='0';setminen<='0';sethouren<='0';setsecen<='0';sethour<='1';setmin<='1';setsec<='1';setclkhou<='1';setclkmin<='1';hourfla<='0';minfla<='0';secfla<='0';clkhourfla<='0';clkminfla<='0';clksecfla<='0';
if(k='0')then
sta<=s0;
elsif(set='0')then
sta<=t1;
else
sta<=t0;
end if;
when
t1=>changemode<='1';outreset<='0';setminen<='0';sethouren<='0';setsecen<='0';sethour<='1';setmin<='1';setsec<='1';setclkhou<=p;setclkmin<='1';hourfla<='0';minfla<='0';secfla<='0';clkhourfla<='1';clkminfla<='0';clksecfla<='0';
if(k='0')then
sta<=t2;
else
sta<=t1;
end if;
when t2=>changemode<='1';outreset<='0';setminen<='0';sethouren<='0';setsecen<='0';sethour<='1';setmin<='1';setsec<='1';setclkhou<='1';setclkmin<=p;hourfla<='0';minfla<='0';secfla<='0';clkhourfla<='0';clkminfla<='1';clksecfla<='0';
if(k='0')then
sta<=t3;
else
sta<=t2;
endif;
when t3=>changemode<='1';outreset<='0';setminen<='0';sethouren<='0';setsecen<='0';sethour<='1';setmin<='1';setsec<='1';setclkhou<='1';setclkmin<='1';hourfla<='0';minfla<='0';secfla<='0';clkhourfla<='0';clkminfla<='0';clksecfla<='1';
if(k='0')then
sta<=t0;
else
sta<=t3;
end if;
whenothers=>sta<=s0;
end case;
end if;
end process;
end rtl;
(2)分频芯片(fenpin)
I模块说明:
总体:将输入频率(1024Hz)进行分频,输出分频后的频率。
输入:1024Hz的时钟信号
输出:分别输出分频后的频率(其中仅有1Hz、512Hz、1024Hz的频率在该实验中用到)
II模块图
III仿真图
IV源代码:
library ieee;
use ieee.std_logic_1164.all;
useieee.std_logic_unsigned.all;
entity fenpin is
port (
clk:in std_logic;
put:buffer std_logic_vector(9 downto 0));
end entity ;
architecture rt1 of fenpin is
begin
process(clk)
begin
if(clk'event and clk='0')then
put<=put+'1';
end if;
end process;
end rt1;
(3)模24 芯片
I模块说明
总体说明:实现24进制的计数芯片
输入:使能控制信号;时钟信号(本实验中将分的仅为作为时钟信号)。
输出:24进制中的高低位。
II模块图
III仿真图
IV源代码
library ieee;
use ieee.std_logic_1164.all;
useieee.std_logic_unsigned.all;
entity m24 is
port(clk,clr:in std_logic;
ql,qh:buffer std_logic_vector (3downto 0));
end m24;
architecture aaa of m24 is
begin
process(clk,clr)
begin
if(clr='1')then
ql<="0000";
qh<="0000";
elsif (clk'event and clk='1')then
if(qh="0010" andql="0011")then--23
ql<="0000";
qh<="0000";
elsif(ql="1001")then--l=9
qh<=qh+'1';
ql<="0000";
else
ql<=ql+'1';
qh<=qh;
end if;
end if;
end process;
end aaa;
(4) 模60芯片(m60)
I模块说明
总体说明:实现60进制的计数芯片
输入:使能控制信号;时钟信号(本实验中将分的仅为作为时钟信号)。
输出:60进制中的高低位。
II模块图
III仿真图
IV源代码
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity m60 is
port(clk,clr,ctr,clr1:in std_logic;
co:bufferstd_logic;
ql,qh:bufferstd_logic_vector (3 downto 0));
end m60;
architecture aaa of m60 is
begin
process(clk,clr,clr1,ctr)
begin
if(clr='1' orclr1='1')then
ql<="0000";
qh<="0000";
co<='0';
elsif (clk'event andclk='1')then
if(qh="0101" and ql="1001")then--23
ql<="0000";
qh<="0000";
if(ctr='0')then
co<='1';
elsif(ctr='1')then
co<='0';
end if;
elsif(ql="1001")then--l=9
qh<=qh+'1';
ql<="0000";
co<='0';
else
ql<=ql+'1';
qh<=qh;
co<='0';
end if;
end if;
end process;
end aaa;
(5)2选1芯片(m2-1)
I模块说明
总体说明:在使能的控制下实现对输入信号(两种)的选择作用。
输入:使能控制信号;时钟信号;设置时间的时钟信号。
输出:选择出的时钟或者是调时信号
II模块图
III仿真图
IV源代码
library ieee;
use ieee.std_logic_1164.all;
entity m2_1 is
port (
clk,set:instd_logic;
ctr:instd_logic;
put:bufferstd_logic);
end m2_1;
architecture rt1 of m2_1 is
begin
process(clk,set,ctr)
begin
if(ctr='1')then
put<=set;
else
put<=clk;
end if;
end process;
end rt1;
(6)译码芯片(ym)
I模块说明
总体说明:通过对输入的判断,实现对输入信号的译码,使其在数码管上显示数字。
输入:要显示的数字信号。
输出:点亮数码管的使能信号。
II模块图
III仿真图
IV源代码
library ieee;
use ieee.std_logic_1164.all;
entity ym is
port (
q:in std_logic_vector(3 downto 0);
put:bufferstd_logic_vector (0 to 6));
end entity;
architecture rt1 of ym is
begin
process(q)
begin
case q is
when"0000"=>put<="1111110";
when "0001"=>put<="0110000";
when"0010"=>put<="1101101";
when"0011"=>put<="1111001";
when"0100"=>put<="0110011";
when"0101"=>put<="1011011";
when"0110"=>put<="1011111";
when"0111"=>put<="1110000";
when"1000"=>put<="1111111";
when"1001"=>put<="1111011";
when "1111"=>put<="0000001";
whenothers=>put<="0000000";
end case;
end process;
end rt1;
(7)显示控制芯片---数据选择(show_control)
I模块说明
总体说明:在使能的控制下实现对输入信号(两种)的选择作用。
输入:使能控制信号;时钟信号;设置时间的时钟信号。
输出:选择出的显示技术状态或者是闹钟状态信号。
II模块图
III仿真图
IV源代码
library ieee;
use ieee.std_logic_1164.all;
entity show_control is
port(
c,cl:instd_logic_vector (3 downto 0);
ctr:in std_logic;
p:outstd_logic_vector (3 downto 0));
end show_control;
architecture rt1 of show_control is
begin
process(ctr,c,cl)
begin
if(ctr='1')then
p<=cl;
else
p<=c;
end if;
end process;
end rt1;
(8)模8计数芯片(m8)
I模块说明
总体说明:实现8进制的计数芯片
输入:时钟信号。
输出:当前计数状态。
II模块图
III仿真图
IV源代码
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity m8 is
port(cp:in std_logic;
q:bufferstd_logic_vector(2 downto 0));
end m8;
architecture rtl of m8 is
begin
process(cp)
begin
if(rising_edge(cp)) then
q<=q+'1';
end if;
end process;
end rtl;
(9)8选一芯片(m8_1)
I模块说明
总体说明:对输入的八种信号进行选择,输出满足输出控制信号(input)的信号。
输入:八种信号(q0~~q7);输出控制信号(input)。
输出:选择出来的信号。
II模块图
III仿真图
IV源代码
library ieee;
use ieee.std_logic_1164.all;
entity m8_1 is
port (
q0,q1,q2,q3,q4,q5,q6,q7:in std_logic_vector (3 downto 0);
input:instd_logic_vector (2 downto 0);
output:buffer std_logic_vector(3 downto 0));
end entity ;
architecture rt1 of m8_1 is
begin
process(q0,q1,q2,q3,q4,q5,q6,q7,input)--此处不用process行不行
begin
case input is
when"000"=>output<=q0;
when"001"=>output<=q1;
when"010"=>output<=q2;
when "011"=>output<=q3;
when"100"=>output<=q4;
when"101"=>output<=q5;
when"110"=>output<=q6;
when"111"=>output<=q7;
end case;
end process;
end rt1;
(10)闹钟响铃控制芯片(sound_control)
I模块说明
总体说明:对输入闹钟时间的时分和计数时分信号进行比对,当两个时间相同时输出1,启动蜂鸣器,否则输出0
输入:闹钟时间的时分(hl、hh、ml、mh),计数时分(chl、chh、cml、cmh)。
输出:选择出来的信号(put)。
II模块图
III仿真图
IV源代码
library ieee;
use ieee.std_logic_1164.all;
entity sound_control2 is
port(
hl,hh,ml,mh,chl,chh,cml,cmh:in std_logic_vector (3 downto 0);
clk1:in std_logic;
put:out std_logic);
end sound_control2;
architecture rt1 of sound_control2 is
begin
process(hl,hh,ml,mh,chl,chh,cml,cmh,clk1)
begin
if(hl=chl andhh=chh and mh=chh and ml=cml)then
put<=clk1;
else
put<='0';
end if;
end process;
end rt1;
(11)整点报时芯片(sound_control_sec)
I模块说明
总体说明:对输入计数分秒信号进行判断,当时间为59分且秒为54、56、58时,将512Hz输出,或者如果时间为整点时,将1024Hz输出,启动蜂鸣器,否则输出0。
输入:计数分秒高低位(ml、mh、sl、sh);时钟信号(512Hz、1024Hz)
输出:选择出来的信号(put)。
II模块图
IV源代码
library ieee;
use ieee.std_logic_1164.all;
entity sound_control_sec is
port(
ml,mh,sl,sh:instd_logic_vector (3 downto 0);
clk1024,clk512:instd_logic;
put:out std_logic);
end sound_control_sec;
architecture rt1 of sound_control_sec is
begin
process(ml,mh,sl,sh,clk1024,clk512)
begin
if(mh="0101" and ml="1001" and sh="0101"and sl="0110") or (mh="0101" and ml="1001" andsh="0101" and sl="1000" ) or (mh="0101" andml="1001" and sh="0101" and sl="0100" )then
put<=clk512;
elsif(mh="0000" and ml="0000"and sh="0000" and sl="0000")
then
put<=clk1024;
else
put<='0';
end if;
end process;
end rt1;
(12)显示闪烁芯片(flash)
I模块说明
总体说明:由使能端控制是否闪烁,当使能为1时,输出频率为1Hz的高低位信号,否则按照8选1输出信号正常输出高低位。
输入:计数高低位(dil、dih);时钟信号(1Hz);使能控制端。
输出:处理后的计数高低位(dol、doh)。
II模块图
III仿真图
IV源代码
library ieee;
use ieee.std_logic_1164.all;
entity flash is
port(
en,clk:instd_logic;
dih,dil:instd_logic_vector(3 downto 0);
doh,dol:outstd_logic_vector(3 downto 0));
end flash;
architecture rt1 of flash is
begin
process(en,clk,dih,dil)
begin
if(en='1')then
if(clk='1')then
doh<=dih;
dol<=dil;
else
doh<="1110";
dol<="1110";
end if;
else
doh<=dih;
dol<=dil;
end if;
end process;
end rt1;
●反思总结:
在本次实验中,犹豫最初对本操作程序不是很了解,导致了很多的错误,以致翻了很多的错误,但是在这个过程里无论是在考虑问题的方式上还是在专业知识层面的认识上确实让我收获了很多,一下是自己的一点认识和总结
(1)设置技巧:
①总体设置技巧:在设置一个较为复杂的设计时应该选择“由上到下”,而不是“由下到上”的的设计思路,另外首先要整理好设计思路以及基本的构思,这样能对整体的设计有足够的了解,不至于在实验中频繁出现思路“短路”的现象。
②控制器的设置:在设置控制器时应该统筹下设原件的端口设置特点,否则将会出主
控端口剩余或者是下设端口无法控制的现象。
③元件名称及端口设置:在设置元件是应尽量做到功能明确,并且端口设置易于区分,这样在连接时不会出现端口功能不明确而造成难于连接的问题。
④底层元件连接:在设置像本设计一样元件比较多且连线复杂的实验的时候,应尽量将最底层的元件连接形成一个新的能完成比较完整的功能的芯片,这样会简化最终的芯片复杂程度更加易于观看和最后的调整、检查。
⑤基本元件的使用:在设计时一定注意库中最基本与非门的使用,这样能够使写代码的工作量减少且能是程序尽量的简单化。
(2)合作及成长:
①在做实验之前应该有足够的交流,碰撞思想的“火花”以弥补个人想法不全面或是存在错误的局限性,在交流时主要融汇每个人的整体设计思路和实现方法,并且团队中的每一个人都要参与进来,这样也将让每个人都获得巨大的收获。
②在做完实验后,务必将本次的实验优缺点进行总结和整理,以便在以后的实验中能进一步的完善和借鉴。
③足够的耐心和毅力,我想这是一个合格的设计者的基本素养,在实验中必定会遇到很多棘手的问题,这正是考验自己让自己成长的关键点,所以即使在实验中遇到难以解决的问题,也应该在交流和思考之中尽力解决,将设计做的更好更完美。