南昌大学实验报告学生姓名:邓儒超学号:6100210045 专业班级:卓越通信101 实验类型:□验证□综合□√设计□创新实验日期:2012.10.28 实验成绩:实验三数字钟设计一、实验目的(1)掌握数字钟的设计二、实验内容与要求(1)设计一个数字钟,要求具有调时功能和24/12进制转换功能(2)进行波形仿真,并分析仿真波形图;(3)下载测试是否正确;三、设计思路/原理图本次数字钟的设计采用了自顶向下分模块的设计。
底层是实现各功能的模块,各模块由vhdl语言编程实现:顶层采用原理图形式调用。
其中底层模块包括秒、分、时三个计数器模块、按键去抖动模块、按键控制模块、时钟分频模块、数码管显示模块,其中,时计数器模块又包括24进制计数模块、12进制计数模块、24/12进制转换模块。
设计框图如下:由图可以清晰的看到数字钟系统设计中各功能模块间连接关系。
系统时钟1KHZ经过分频后产生1秒的时钟信号,1秒的时钟信号作为秒计数模块的输入信号,秒计数模块产生的进位信号作为分计数模块的输入信号,分计数模块的进位信号作为时计数模块的输入信号。
秒计数模块、分计数模块、时计数模块的计数输出分别送到显示模块。
由于设计中要使用按键进行调节时间,而按键的动作过程中存在产生得脉冲的不稳定问题,所以就牵扯到按键去抖动的问题,对此系统中设置了按键去抖动模块,按键去抖动模块产生稳定的脉冲信号送入按键控制模块,按键控制模块根据按键的动作对秒、分、时进行调节。
原理图如下:四、实验程序(程序来源:参考实验室里的和百度文库的稍加改动,还有自己写的)1、分频模块LIBRARY IEEE;USE IEEE.STD_LOGIC_1164.ALL;USE IEEE.STD_LOGIC_UNSIGNED.ALL;ENTITY fenpin ISPORT(CLK:IN STD_LOGIC;CLK1:OUT STD_LOGIC);END fenpin;ARCHITECTURE behav OF fenpin ISSIGNAL X,CNT:STD_LOGIC_VECTOR(11 DOWNTO 0);BEGINP1:PROCESS(CLK)BEGINX<="001111101000";--1000分频IF CLK'EVENT AND CLK = '1' THEN CNT<=CNT+1;IF CNT=X-1 THEN CLK1<='1';CNT<="000000000000";ELSE CLK1<='0';END IF;END IF;END PROCESS;END behav;2、60进制计数器(秒、分计数器)模块LIBRARY IEEE;USE IEEE.STD_LOGIC_1164.ALL;USE IEEE.STD_LOGIC_UNSIGNED.ALL;ENTITY count60 ISPORT(EN,RST,CLK1: IN STD_LOGIC;Q: OUT STD_LOGIC_VECTOR(7 DOWNTO 0);COUT: OUT STD_LOGIC);END count60;ARCHITECTURE behav OF count60 ISSIGNAL J : STD_LOGIC_VECTOR(7 DOWNTO 0); --8位BCD计数值SIGNAL GW,SW : STD_LOGIC_VECTOR(3 DOWNTO 0);--计数器的个,十BEGINP2:PROCESS(EN,RST,CLK1)BEGINGW<=J(3 downto 0);SW<=J(7 downto 4);IF RST='1' THEN J<=(others=>'0');ELSIF CLK1'EVENT AND CLK1='1' THENIF EN='1' THENIF J<"01011001" THENIF GW=9 THEN --个位为9时加7调整J<=J+7;ELSE J<=J+1;END IF;ELSE J<=(others=>'0');END IF;END IF;IF J ="01011001" THENCOUT <='1'; ELSE COUT<='0';END IF;END IF;Q<=J;END PROCESS;END behav;3、24进制计数器模块LIBRARY IEEE;USE IEEE.STD_LOGIC_1164.ALL;USE IEEE.STD_LOGIC_UNSIGNED.ALL;ENTITY count24 ISPORT(EN,RST,CLK1: IN STD_LOGIC;Q: OUT STD_LOGIC_VECTOR(7 DOWNTO 0);COUT: OUT STD_LOGIC);END count24;ARCHITECTURE behav OF count24 ISSIGNAL J : STD_LOGIC_VECTOR(7 DOWNTO 0); --8位BCD计数值SIGNAL GW,SW : STD_LOGIC_VECTOR(3 DOWNTO 0);--计数器的个,十BEGINP2:PROCESS(EN,RST,CLK1)--计数BEGINGW<=J(3 downto 0);SW<=J(7 downto 4);IF RST='1' THEN J<=(others=>'0');ELSIF CLK1'EVENT AND CLK1='1' THENIF EN='1' THENIF J<"00100011" THENIF GW=9 THEN --个位为9时加7调整J<=J+7;ELSE J<=J+1;END IF;ELSE J<=(others=>'0');END IF;END IF;IF J ="00100011" THENCOUT <='1'; ELSE COUT<='0';END IF;END IF;Q<=J;END PROCESS;END behav;4、12进制计数器模块LIBRARY IEEE;USE IEEE.STD_LOGIC_1164.ALL;USE IEEE.STD_LOGIC_UNSIGNED.ALL;ENTITY count12 ISPORT(EN,RST,CLK1: IN STD_LOGIC;Q: OUT STD_LOGIC_VECTOR(7 DOWNTO 0);COUT: OUT STD_LOGIC);END count12;ARCHITECTURE behav OF count12 ISSIGNAL J : STD_LOGIC_VECTOR(7 DOWNTO 0); --8位BCD计数值SIGNAL GW,SW : STD_LOGIC_VECTOR(3 DOWNTO 0);--计数器的个,十BEGINP2:PROCESS(EN,RST,CLK1)--计数BEGINGW<=J(3 downto 0);SW<=J(7 downto 4);IF RST='1' THEN J<=(others=>'0');ELSIF CLK1'EVENT AND CLK1='1' THENIF EN='1' THENIF J<"00010010" THENIF GW=9 THEN --个位为9时加7调整J<=J+7;ELSE J<=J+1;END IF;ELSE J<="00000001";END IF;END IF;IF J ="00010010" THENCOUT <='1'; ELSE COUT<='0';END IF;END IF;Q<=J;END PROCESS;END behav;5、24/12进制转换模块LIBRARY IEEE;USE IEEE.STD_LOGIC_1164.ALL;USE IEEE.STD_LOGIC_UNSIGNED.ALL;ENTITY control ISPORT(TMODE: IN STD_LOGIC;C24: IN STD_LOGIC_VECTOR(7 DOWNTO 0);C12: IN STD_LOGIC_VECTOR(7 DOWNTO 0);Q: BUFFER STD_LOGIC_VECTOR(7 DOWNTO 0);COUT: BUFFER STD_LOGIC);END control;ARCHITECTURE behav OF control ISBEGINP1:PROCESS(TMODE,C24,C12,Q,COUT)BEGINIF TMODE='0' THENQ<=C24;ELSE Q<=C12;END IF;COUT<='0';IF TMODE='1' THENIF C24>"00010010" THENCOUT<='1';END IF;END IF;END PROCESS;END behav;6、按键去抖模块library ieee;use ieee.std_logic_1164.all;use ieee.std_logic_unsigned.all;entity qudou isport(clk,k1,k2,k3,k4:in std_logic;o1,o2,o3,o4:out std_logic);--设置按键输入信号输出端口end;architecture beh of qudou isbeginprocess(clk,k1,k2,k3,k4)variable cant1:integer;variable cant2:integer;variable cant3:integer;variable cant4:integer;beginif clk'event and clk='1' thenif k1='1' then cant1:=0;end if;--设置计数初值if k2='1' then cant2:=0;end if; --设置计数初值if k3='1' then cant3:=0;--设置计数初值end if;if k4='1' then cant4:=0;end if; --设置计数初值if cant1>2499999 then o1<='0';else o1<='1';--延时0.5send if;if cant2>2499999 then o2<='0';else o2<='1'; --延时0.5send if;if cant3>2499999 then o3<='0';else o3<='1'; --延时0.5send if;if cant4>2499999 then o4<='0';else o4<='1'; --延时0.5send if;cant1:=cant1+1; --加一计数cant2:=cant2+1; --加一计数cant3:=cant3+1; --加一计数cant4:=cant4+1; --加一计数end if;end process;end beh;7、按键控制模块LIBRARY IEEE;USE IEEE.STD_LOGIC_1164.ALL;USE IEEE.STD_LOGIC_UNSIGNED.ALL;ENTITY control2 ISPORT(CLK,CHANGE,CCLK: IN STD_LOGIC;CLK1: OUT STD_LOGIC);END control2;ARCHITECTURE behav OF control2 ISSIGNAL M:STD_LOGIC;BEGINPROCESS(CLK,CHANGE,CCLK)BEGINIF CHANGE'EVENT AND CHANGE='1' THENM<=NOT(M);END IF;IF M='1' THENCLK1<=CCLK;ELSECLK1<=CLK;END IF;END PROCESS;END behav;8、数码管显示模块LIBRARY IEEE;USE IEEE.STD_LOGIC_1164.ALL;USE IEEE.STD_LOGIC_UNSIGNED.ALL;ENTITY DISPLAY ISPORT(CLK:IN STD_LOGIC;SEC:IN STD_LOGIC_VECTOR(7 DOWNTO 0);MIN:IN STD_LOGIC_VECTOR(7 DOWNTO 0);HOUR:IN STD_LOGIC_VECTOR(7 DOWNTO 0);sel0,sel1,sel2:buffer STD_LOGIC;SG:OUT STD_LOGIC_VECTOR(7 DOWNTO 0));END DISPLAY;ARCHITECTURE behav OF DISPLAY ISSIGNAL A: STD_LOGIC_VECTOR(3 DOWNTO 0);--计数器的个,十SIGNAL CNT8: STD_LOGIC_VECTOR(2 DOWNTO 0);--数码管选择BEGINP3:PROCESS(CLK) --数码管控制BEGINIF CLK'EVENT AND CLK='1' THENIF CNT8<"111" THEN CNT8 <=CNT8+1;ELSE CNT8<=(OTHERS=>'0');END IF;END IF;CASE CNT8 IS --时、分、秒分别送数码管动态显示WHEN "111" => sel2<='0';sel1<='0';sel0<='0';A<=HOUR(7 downto 4);WHEN "110" => sel2<='0';sel1<='0';sel0<='1';A<=HOUR(3 downto 0);WHEN "101" => sel2<='0';sel1<='1';sel0<='0';A<="1111";WHEN "100" => sel2<='0';sel1<='1';sel0<='1';A<=MIN(7 downto 4);WHEN "011" => sel2<='1';sel1<='0';sel0<='0';A<=MIN(3 downto 0);WHEN "010" => sel2<='1';sel1<='0';sel0<='1';A<="1111";WHEN "001" => sel2<='1';sel1<='1';sel0<='0';A<=SEC(7 downto 4);WHEN "000" => sel2<='1';sel1<='1';sel0<='1';A<=SEC(3 downto 0);WHEN OTHERS =>NULL;END CASE;END PROCESS ;P4:PROCESS(A)--七段译码BEGINCASE A ISWHEN "0000" =>SG<="00111111"; WHEN "0001" =>SG<="00000110";WHEN "0010" =>SG<="01011011"; WHEN "0011" =>SG<="01001111";WHEN "0100" =>SG<="01100110"; WHEN "0101" =>SG<="01101101";WHEN "0110" =>SG<="01111101"; WHEN "0111" =>SG<="00000111";WHEN "1000" =>SG<="01111111"; WHEN "1001" =>SG<="01101111";WHEN "1111" =>SG<="01000000";WHEN OTHERS=>NULL;END CASE;END PROCESS;END behav;五、实验步骤1.打开Quartus II,新建一个工程,然后在工程里建立VHDL文件,把各个模块程序输入进去,保存,编译。