设计方案
1.系统功能描述
(1) 系统输入:系统状态及校时、定时转换的控制信号为k、set;时钟信号clk,采用1024Hz;系统复位信号为reset。输入信号由按键产生。
(2) 系统输出:LED显示输出;蜂鸣器声音信号输出。
(3) 多功能数字钟控制器的状态图如图所示
图中:S0:显示计时器时间 T0:显示闹铃时间
S1:调计时的时 T1:调闹铃的时
S2:调计时的分 T2:调闹铃的分
S3:调计时的秒 T3:调闹铃的秒
(4) 计时:正常工作状态下,按下“set键”,进入“小时”校准状态,之后按下“k键”则进入“分”校准状态,继续按下“k键”则进入“秒复零”状态,第三次按下“k 键”又恢复到正常计时显示状态。
(5) ”小时“校准状态:在“小时”校准状态下,显示”小时的数码管闪烁,通过按下”p键“使其递增计数。
(6) ”分“校准状态:在“分”校准状态下,显示“分”的数码管闪烁,通过按下”p键“使其递增计数。
(7) “秒”复零状态:在:“秒复零”状态下,显示“秒”的数码管闪烁并复零。
(8) 整点报时:蜂鸣器在“59”分钟的第51、53、55、57秒发出频率为512Hz的低音,在“59”秒发出频率为1024Hz的高音,结束时为整点。
(9) 显示:要求采用扫描显示方式驱动8个LED数码管分别显示时、分、秒并且他们之间用“—”隔开。
(10) 闹钟:闹钟定时时间到,蜂鸣器发出周期为1s的滴、滴声,持续时间为10秒;闹钟定时显示。
(11) 闹钟定时设置:在闹钟显示状态下,按下“set键”,进入“小时”校时状态,之后按下“k键”,进入“分”校时状态,继续按下“k键”,进入“秒”校时状态,第 三次按下“k键”又恢复到闹钟显示状态。
(12) 闹钟的时、分、秒设置过程和计时设置相同。
1.控制器
library ieee; use ieee.std_logic_1164.all; entity ctr is port(p:in std_logic; cp:in std_logic; k:in std_logic; set:in std_logic; reset:in std_logic; resec:out std_logic; rehour:out std_logic; setmin:out std_logic; setminen:out std_logic; sethour:out std_logic; sethouren:out std_logic; hourflash:out std_logic; minflash:out std_logic; secflash:out std_logic; ahourflash:out std_logic; aminflash:out std_logic; asecflash:out std_logic; changemode:out std_logic; setclksec:out std_logic; setclkmin:out std_logic; setclkhour:out std_logic); end ctr; architecture rtl of ctr is type state is(s0,s1,s2,s3,t0,t1,t2,t3); signal clock_s:state; begin process(cp,k,set,reset,p) begin if(reset='0') then resec<='1';remin<='1';rehour<='1';setminen<='0';setmin<='0';sethouren<='0';sethour<='0';hourflash<='0';minflash<='0'; secflash<='0';ahourflash<='0';aminflash<='0';asecflash<='0';setclksec<='0';setclkmin<='0';setclkhour<='0';clock_s<=s0; elsif(rising_edge(cp)) then case clock_s is when s0=>changemode<='0'; resec<='0';remin<='0';rehour<='0';setminen<='0';setmin<='0';sethouren<='0';sethour<='0';hourflash<='0';minflash<='0'; secflash<='0';ahourflash<='0';aminflash<='0';asecflash<='0';setclksec<='0';setclkmin<='0';setclkhour<='0'; if(k='0') then clock_s<=t0; elsif(set='0')then clock_s<=s1; else clock_s<=s0; end if; when s1=>changemode<='0'; resec<='0';remin<='0';rehour<='0';setminen<='0';setmin<='0';sethouren<='1';sethour<=p;hourflash<='1';minflash<='0'; secflash<='0';ahourflash<='0';aminflash<='0';asecflash<='0';setclksec<='0';setclkmin<='0';setclkhour<='0'; if(k='0')then clock_s<=s2; else clock_s<=s1; end if; when s2=>changemode<='0'; resec<='0';remin<='0';rehour<='0';setminen<='1';setmin<=p;sethouren<='0';sethour<='0';hourflash<='0';minflash<='1'; secflash<='0';ahourflash<='0';aminflash<='0';asecflash<='0';setclksec<='0';setclkmin<='0';setclkhour<='0'; if(k='0')then clock_s<=s3; else clock_s<=s2; end if; when s3=>changemode<='0'; resec<=p;remin<='0';rehour<='0';setminen<='0';setmin<='0';sethouren<='0';sethour<='0';hourflash<='0';minflash<='0'; secflash<='1';ahourflash<='0';aminflash<='0';asecflash<='0';setclksec<='0';setclkmin<='0';setclkhour<='0'; if(k='0')then clock_s<=s0; else clock_s<=s3; end if; when t0=>changemode<='1'; resec<='0';remin<='0';rehour<='0';setminen<='0';setmin<='0';sethouren<='0';sethour<='0';hourflash<='0';minflash<='0'; secflash<='0';ahourflash<='0';aminflash<='0';asecflash<='0';setclksec<='0';setclkmin<='0';setclkhour<='0'; if(k='0')then clock_s<=s0; elsif(set='0') then clock_s<=t1; else clock_s<=t0; end if; when t1=>changemode<='1'; resec<='0';remin<='0';rehour<='0';setminen<='0';setmin<='0';sethouren<='0';sethour<='0';hourflash<='0';minflash<='0'; secflash<='0';ahourflash<='1';aminflash<='0';asecflash<='0';setclksec<='0';setclkmin<='0';setclkhour<=p; if(k='0')then clock_s<=t2; else clock_s<=t1; end if; when t2=>changemode<='1'; resec<='0';remin<='0';rehour<='0';setminen<='0';setmin<='0';sethouren<='0';sethour<='0';hourflash<='0';minflash<='0'; secflash<='0';ahourflash<='0';aminflash<='1';asecflash<='0';setclksec<='0';setclkmin<=p;setclkhour<='0'; if(k='0')then clock_s<=t3; else clock_s<=t2; end if; when t3=>changemode<='1'; resec<='0';remin<='0';rehour<='0';setminen<='0';setmin<='0';sethouren<='0';sethour<='0';hourflash<='0';minflash<='0'; secflash<='0';ahourflash<='0';aminflash<='0';asecflash<='1';setclksec<=p;setclkmin<='0';setclkhour<='0'; if(k='0')then clock_s<=t0; else clock_s<=t3; end if; when others=>clock_s<=s0; end case; end if; end process; end rtl;
LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.STD_LOGIC_UNSIGNED.ALL; USE IEEE.STD_LOGIC_ARITH.ALL; ENTITY counter_60 IS PORT(rs,cp:IN STD_LOGIC; co :OUT STD_LOGIC; ql,qh :OUT STD_LOGIC_VECTOR(3 DOWNTO 0)); END counter_60; ARCHITECTURE rtl OF counter_60 IS SIGNAL ql_temp:STD_LOGIC_VECTOR(3 DOWNTO 0):="0000"; SIGNAL qh_temp:STD_LOGIC_VECTOR(3 DOWNTO 0):="0000"; BEGIN PROCESS (rs,cp,qh_temp,ql_temp) BEGIN if(rs='1') then qh_temp<="0000"; ql_temp<="0000"; co<='0'; elsIF(rising_edge(cp)) then if(qh_temp="0101" and ql_temp="1001") then ql_temp<="0000"; qh_temp<="0000"; co<='1'; elsif(qh_temp<="0101" and ql_temp<"1001") then ql_temp<=ql_temp+'1'; co<='0'; elsif(qh_temp<="0101" and ql_temp="1001") then qh_temp<=qh_temp+'1'; ql_temp<="0000"; co<='0'; end if; end if; qh<=qh_temp; ql<=ql_temp; END PROCESS; END rtl;
LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.STD_LOGIC_UNSIGNED.ALL; USE IEEE.STD_LOGIC_ARITH.ALL; ENTITY counter_24 IS PORT(rs,cp:IN STD_LOGIC; ql,qh :OUT STD_LOGIC_VECTOR(3 DOWNTO 0)); END counter_24; ARCHITECTURE rtl OF counter_24 IS SIGNAL ql_temp:STD_LOGIC_VECTOR(3 DOWNTO 0):="0000"; SIGNAL qh_temp:STD_LOGIC_VECTOR(3 DOWNTO 0):="0000"; SIGNAL rs_temp:STD_LOGIC; BEGIN PROCESS (rs,cp) BEGIN if(rs='1') then qh_temp<="0000"; ql_temp<="0000"; elsIF(rising_edge(cp)) then if(qh_temp="0010" and ql_temp="0011") then qh_temp<="0000"; ql_temp<="0000"; elsif(qh_temp<="0010" and ql_temp<"1001") then ql_temp<=ql_temp+'1'; elsif(qh_temp<="0010" and ql_temp="1001") then qh_temp<=qh_temp+'1'; ql_temp<="0000"; end if; end if; END PROCESS; qh<=qh_temp; ql<=ql_temp; END rtl;
library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; entity counter_10 is port(cp:in std_logic; d :out std_logic_vector(9 downto 0)); end counter_10; architecture rtl of counter_10 is signal d_temp:std_logic_vector(9 downto 0):="0000000000"; begin process(cp) begin if(rising_edge(cp)) then if(d_temp="1111111111") then d_temp<="0000000000"; else d_temp<=d_temp+'1'; end if; end if; end process; d<=d_temp; end rtl;
library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; entity counter_8 is port(cp,en:in std_logic; a: out std_logic_vector(2 downto 0)); end counter_8; architecture rtl of counter_8 is signal a_temp:std_logic_vector(2 downto 0):="000"; begin process(cp,en) begin if(rising_edge(cp) and en='1') then if(a_temp="111") then a_temp<="000"; else a_temp<=a_temp+'1'; end if; end if; end process; a<=a_temp; end rtl;
library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; entity d_ff is port(en:in std_logic; q0 :out std_logic_vector(3 downto 0); q1 :out std_logic_vector(3 downto 0); d0 :in std_logic_vector(3 downto 0); d1 :in std_logic_vector(3 downto 0)); end d_ff; architecture rtl of d_ff is begin process(en,d0,d1) begin if(en='1') then q0<=d0; q1<=d1; else q0<="1110"; q1<="1110"; end if; end process; end rtl;
LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; ENTITY decode_48 IS PORT(d:IN STD_LOGIC_VECTOR(3 DOWNTO 0); y:OUT STD_LOGIC_VECTOR(6 DOWNTO 0)); END decode_48; ARCHITECTURE rtl OF decode_48 IS BEGIN PROCESS(d) BEGIN CASE d IS WHEN "0000"=>y<="1111110"; WHEN "0001"=>y<="0110000"; WHEN "0010"=>y<="1101101"; WHEN "0011"=>y<="1111001"; WHEN "0100"=>y<="0110011"; WHEN "0101"=>y<="1011011"; WHEN "0110"=>y<="1011111"; WHEN "0111"=>y<="1110000"; WHEN "1000"=>y<="1111111"; WHEN "1001"=>y<="1111011"; WHEN "1111"=>y<="0000001"; WHEN OTHERS=>y<="0000000"; END CASE; END PROCESS; END rtl;
library ieee; use ieee.std_logic_1164.all; entity ring is port(cp1,cp512,cp1024,en:in std_logic; hourh,hourl,ahourh,ahourl,minh,minl,aminh,aminl,sech,secl,asech,asecl:in std_logic_vector(3 downto 0); r:out std_logic); end ring; architecture rtl of ring is begin process(en,hourh,hourl,ahourh,ahourl,minh,minl,aminh,aminl,sech,secl,asech,asecl,cp1,cp512,cp1024) begin if(en='1')then if(hourh=ahourh and hourl=ahourl and minh=aminh and minl=aminl)then if(cp1='1')then r<=cp512; else r<='0'; end if; elsif(minh="0101" and minl="1001" and sech="0101")then if(secl="0001" or secl="0011" or secl="0101" or secl="0111")then r<=cp512; elsif(secl="1001")then r<=cp1024; else r<='0'; end if; else r<='0'; end if; end if; end process; end rtl;
LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; ENTITY sel_81 IS PORT(a:IN STD_LOGIC_VECTOR(2 DOWNTO 0); y:OUT STD_LOGIC_VECTOR(3 DOWNTO 0); d0:IN STD_LOGIC_VECTOR(3 DOWNTO 0); d1:IN STD_LOGIC_VECTOR(3 DOWNTO 0); d2:IN STD_LOGIC_VECTOR(3 DOWNTO 0); d3:IN STD_LOGIC_VECTOR(3 DOWNTO 0); d4:IN STD_LOGIC_VECTOR(3 DOWNTO 0); d5:IN STD_LOGIC_VECTOR(3 DOWNTO 0); d6:IN STD_LOGIC_VECTOR(3 DOWNTO 0); d7:IN STD_LOGIC_VECTOR(3 DOWNTO 0)); END sel_81; ARCHITECTURE rtl OF sel_81 IS BEGIN PROCESS(d0,d1,d2,d3,d4,d5,d6,d7,a) BEGIN CASE a IS WHEN "000"=>y<=d7; WHEN "001"=>y<=d6; WHEN "010"=>y<=d5; WHEN "011"=>y<=d4; WHEN "100"=>y<=d3; WHEN "101"=>y<=d2; WHEN "110"=>y<=d1; WHEN "111"=>y<=d0; END CASE; END PROCESS; END rtl;
library ieee; use ieee.std_logic_1164.all; entity sel_21 is port(a:in std_logic; y:out std_logic_vector(3 downto 0); d0:in std_logic_vector(3 downto 0); d1:in std_logic_vector(3 downto 0)); end sel_21; architecture rtl of sel_21 is begin process(a,d0,d1) begin case a is when '0'=>y<=d0; when '1'=>y<=d1; end case; end process; end rtl;
library ieee; use ieee.std_logic_1164.all; entity selone_21 is port(a:in std_logic; y:out std_logic; d0:in std_logic; d1:in std_logic); end selone_21; architecture rtl of selone_21 is begin process(a,d0,d1) begin case a is when '0'=>y<=d0; when '1'=>y<=d1; end case; end process; end rtl;心得体会:
在课程设计开始之前,我便对电子钟的制作产生了兴趣,通过在课堂上和老师一起学习VHDL语言的使用方法,以及课下上机进行练习,我已经初步掌握了通过该语言编写程序的方法,如编写底层程序,编译,仿真,生成模块,顶层连接等。并在几次实验课上分别上机连接硬件验证了自己编写的程序的正确性,为课程设计的实现打下了基础。在课程设计的实现过程中,我也遇到了很多问题,一开始是软件使用不够熟练,经常忘记某些步骤,甚至还发生过代码被覆盖的情况,其次是我才用了从中心向四周扩散的设计思路,即首先实现基本的时钟计数和显示的功能,然后再分别添加调节时钟的功能,显示闪烁的功能,闹钟的功能等,这种方法有利有弊,好处是一开始不用想太多,不用管整体是怎样的,只要将各个模块做好即可,所以很适合在知识储备不足的情况下进行设计,但缺点就是最后会发现控制端口很多,导致控制器非常庞大,整个电路的布线较乱,集成度低,最后就是考虑问题不够周全,比如我一开始在连线测试的时候发现数字显示是反着的,但是由于电路基本已经成型,模块多,不便于查错,在一个星期的制作当中,我利用中午,晚上以及平时上机时空闲的时间进行制作,由于只有一个人,所以不会因为思路的冲突而和搭档发生争论,但由于精力有限,所以花的时间非常多,但是对于自己感兴趣的事情,即使很累依然开心。通过课程设计,我觉得自己独立思考的能力和模块化的思维有了提高,在给同学的改错和讲解过程中,我也了解了很多常见的错误以及解决方法,积累了知识和经验,同时也体现了同学之间互帮互助的精神。我还要非常感谢指导老师对我的细心指导,在老师的帮助下,我不仅顺利完成了课程设计,还体会到了作为老师的不易之处,每天面对相同的问题,几百个学生,压力和焦虑都是在所难免的,所以在以后的学习过程中,我会更加从老师的立场思考,不给老师带来额外的压力。