一、系統的設計要求 假設外部輸入脈沖為1Hz,要求使用該頻率設計一個時間可調,并通過LED七段共陰極數碼管能夠顯示時、分、秒的數字鐘。 二、系統的設計實現 眾所周知,一天等于24h,1h等于60min,1min等于60s。進行設計數字鐘的設計時,先對1s的時鐘進行計數,當計數達到60次時,輸出1個分鐘(min)脈沖;當1min的時鐘計數達到60次時,輸出1個小時(h)脈沖,若1h時鐘計數達到23次時,并且1min的計數到59次、1s的計數也達到59次,再來1個1s的脈沖,數字鐘就自己復位,重新從零開始計時。 綜上所述,數字鐘由3個計數模塊(二十四進制計數器、十進制計數器和六進制計數器)、7段LED驅動顯示模塊和頂層模塊構成,如圖下所示。頂層模塊通過調用相應的模塊,將這些模塊進行有機的連接即可實現設計任務。 1.頂層模塊程序 頂層模塊程序的實體中應定義時鐘脈沖輸入端(CLK)、設置時間使能端(SET)。時間調整輸入端(包括時、分、秒的高位和低位)、時鐘數據顯示輸出端(包括時、分、秒的高位和低位)。 由于十進制計數模塊和六進制計數模塊會產生計數溢出信號(CARRY_OUT)而這些溢出信號有可能作為下一計數模塊的時鐘輸入脈沖(CLK),因此在頂層模塊程序的結構體中需要定義相應的暫存計數溢出信號(CARRY1~CARRY4)。3個計數模塊的輸出將為4位,這些4位輸出的數據作為LED驅動模塊的顯示內容,所以也需定義一些4為輸出信號。頂層模塊程序編寫如下: --數字鐘的頂層模塊程序 dianzizhong.VHD LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; ENTITY dianzizhong IS PORT( CLK: IN STD_LOGIC; --定義外部脈沖輸入端 SET: IN STD_LOGIC; --設置時間使能端 DIN_S_L: IN STD_LOGIC_VECTOR(3 DOWNTO 0); --秒鐘的低位調整輸入端 DIN_S_H: IN STD_LOGIC_VECTOR(3 DOWNTO 0); --秒鐘的高位調整輸入端 DIN_M_L: IN STD_LOGIC_VECTOR(3 DOWNTO 0); --分鐘的低位調整輸入端 DIN_M_H: IN STD_LOGIC_VECTOR(3 DOWNTO 0); --分鐘的高位調整輸入端 DIN_H_L: IN STD_LOGIC_VECTOR(3 DOWNTO 0); --小時的低位調整輸入端 DIN_H_H: IN STD_LOGIC_VECTOR(3 DOWNTO 0); --小時的高位調整輸入端 CQ_S_L: OUT STD_LOGIC_VECTOR(6 DOWNTO 0); --秒鐘的低位顯示輸入端 CQ_S_H: OUT STD_LOGIC_VECTOR(6 DOWNTO 0); --秒鐘的高位顯示輸入端 CQ_M_L: OUT STD_LOGIC_VECTOR(6 DOWNTO 0); --分鐘的低位顯示輸入端 CQ_M_H: OUT STD_LOGIC_VECTOR(6 DOWNTO 0); --分鐘的高位顯示輸入端 CQ_H_L: OUT STD_LOGIC_VECTOR(6 DOWNTO 0); --小時的低位顯示輸入端 CQ_H_H: OUT STD_LOGIC_VECTOR(6 DOWNTO 0)); --小時的高位顯示輸入端 END dianzizhong; ARCHITECTURE ART OF dianzizhong IS COMPONENT CNT10 PORT(CLK: IN STD_LOGIC; --定義外部脈沖輸入端 SET: IN STD_LOGIC; --設置時間使能端 DIN: IN STD_LOGIC_VECTOR(3 DOWNTO 0); --預置時間值輸入端 CQ: OUT STD_LOGIC_VECTOR(3 DOWNTO 0); --十進制計數輸出端 CARRY_OUT: OUT STD_LOGIC); --十進制計數溢出端 END COMPONENT CNT10; COMPONENT CNT6 PORT(CLK: IN STD_LOGIC; --定義外部脈沖輸入端 SET:IN STD_LOGIC; --設置時間使能端 DIN: IN STD_LOGIC_VECTOR(3 DOWNTO 0); --預置時間值輸入端 CQ: OUT STD_LOGIC_VECTOR(3 DOWNTO 0); --六進制計數輸入端 CARRY_OUT: OUT STD_LOGIC); --六進制計數溢出端 END COMPONENT CNT6; COMPONENT CNT24 PORT(CLK: IN STD_LOGIC; --定義外部脈沖輸入端 SET:IN STD_LOGIC; --設置時間使能端 DIN_H: IN STD_LOGIC_VECTOR(3 DOWNTO 0); --預置時間的高位輸入端 DIN_L: IN STD_LOGIC_VECTOR(3 DOWNTO 0); --預置時間的低位輸入端 CQ_H: OUT STD_LOGIC_VECTOR(3 DOWNTO 0); --計數高位輸出端 CQ_L: OUT STD_LOGIC_VECTOR(3 DOWNTO 0)); --計數低位輸出端 END COMPONENT CNT24; COMPONENT LED_DRIV IS PORT( DIN: IN STD_LOGIC_VECTOR(3 DOWNTO 0); --顯示數據輸入端 DOUT: OUT STD_LOGIC_VECTOR(6 DOWNTO 0)); --顯示數據輸出端 END COMPONENT LED_DRIV; SIGNAL CARRY1: STD_LOGIC; SIGNAL CARRY2: STD_LOGIC; SIGNAL CARRY3: STD_LOGIC; SIGNAL CARRY4: STD_LOGIC; SIGNAL CQI_S_L: STD_LOGIC_VECTOR(3 DOWNTO 0); SIGNAL CQI_S_H: STD_LOGIC_VECTOR(3 DOWNTO 0); SIGNAL CQI_M_L: STD_LOGIC_VECTOR(3 DOWNTO 0); SIGNAL CQI_M_H: STD_LOGIC_VECTOR(3 DOWNTO 0); SIGNAL CQI_H_L: STD_LOGIC_VECTOR(3 DOWNTO 0); SIGNAL CQI_H_H: STD_LOGIC_VECTOR(3 DOWNTO 0); BEGIN --使用元件例化語句,通過基本模塊的級聯實現數字鐘 U0: CNT10 PORT MAP(CLK=>CLK,SET=>SET,DIN=>DIN_S_L, CQ=>CQI_S_L,CARRY_OUT=>CARRY1); U2: CNT6 PORT MAP(CLK=>CARRY1,SET=>SET,DIN=>DIN_S_H, CQ=>CQI_S_H,CARRY_OUT=>CARRY2); U3: CNT10 PORT MAP(CLK=>CARRY2,SET=>SET,DIN=>DIN_M_L, CQ=>CQI_M_L,CARRY_OUT=>CARRY3); U4: CNT6 PORT MAP(CLK=>CARRY3,SET=>SET,DIN=>DIN_M_H, CQ=>CQI_M_H,CARRY_OUT=>CARRY4); U5: CNT24 PORT MAP(CLK=>CARRY4,SET=>SET,DIN_H=>DIN_H_H, DIN_L=>DIN_H_L,CQ_H=>CQI_H_H,CQ_L=>CQI_H_L); U6: LED_DRIV PORT MAP(DIN=>CQI_S_L,DOUT=>CQ_S_L); U7: LED_DRIV PORT MAP(DIN=>CQI_S_H,DOUT=>CQ_S_H); U8: LED_DRIV PORT MAP(DIN=>CQI_M_L,DOUT=>CQ_M_L); U9: LED_DRIV PORT MAP(DIN=>CQI_M_H,DOUT=>CQ_S_H); U10: LED_DRIV PORT MAP(DIN=>CQI_H_L,DOUT=>CQ_H_L); U11: LED_DRIV PORT MAP(DIN=>CQI_H_H,DOUT=>CQ_H_H); END ART; 2.十進制計數器模塊程序 使用VHDL編寫程序時,在實體中應定義時鐘脈沖輸入端(CLK)、設置時間使能端(SET)、預置數據輸入端(DIN)、計數脈沖輸出端(CQ)和計數脈沖溢出端(CARRY_OUT)。十進制計數器模塊程序編寫如下: --十進制計數器的源程序CNT10.VHD LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.STD_LOGIC_UNSIGNED.ALL; ENTITY CNT10 IS PORT( CLK: IN STD_LOGIC; SET: IN STD_LOGIC; DIN: IN STD_LOGIC_VECTOR(3 DOWNTO 0); CQ: OUT STD_LOGIC_VECTOR(3 DOWNTO 0); CARRY_OUT: OUT STD_LOGIC); END CNT10; ARCHITECTURE ART OF CNT10 IS SIGNAL CQI:STD_LOGIC_VECTOR(3 DOWNTO 0); BEGIN PROCESS(CLK,SET,DIN) BEGIN IF SET='1' THEN CQI<=DIN; CARRY_OUT<='0'; ELSIF CLK'EVENT AND CLK='1' THEN IF CQI="1001" THEN CQI<="0000"; CARRY_OUT<='1'; ELSE CQI<=CQI+'1'; CARRY_OUT<='0'; END IF; END IF; END PROCESS ; CQ<=CQI; END ART; 3.六進制計數器模塊程序 使用VHDL編寫程序時,在實體中應定義時鐘脈沖輸入端(CLK)、設置時間使能端(SET)、預置數據輸入端(DIN)、計數脈沖輸出端(CQ)和計數脈沖溢出端(CARRY_OUT)。六進制計數器模塊程序編寫如下: --六進制計數器的源程序CNT6.VHD LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.STD_LOGIC_UNSIGNED.ALL; ENTITY CNT6 IS PORT( CLK: IN STD_LOGIC; SET: IN STD_LOGIC; DIN: IN STD_LOGIC_VECTOR(3 DOWNTO 0); CQ: OUT STD_LOGIC_VECTOR(3 DOWNTO 0); CARRY_OUT: OUT STD_LOGIC); END CNT6; ARCHITECTURE ART OF CNT6 IS SIGNAL CQI:STD_LOGIC_VECTOR(3 DOWNTO 0); BEGIN PROCESS(CLK,SET,DIN) BEGIN IF SET='1' THEN CQI<=DIN; CARRY_OUT<='0'; ELSIF CLK'EVENT AND CLK='1' THEN IF CQI="0101" THEN CQI<="0000"; CARRY_OUT<='1'; ELSE CQI<=CQI+'1'; CARRY_OUT<='0'; END IF; END IF; END PROCESS ; CQ<=CQI; END ART; 4.二十四進制計數器模塊程序 使用VHDL編寫程序時,在實體中應定義時鐘脈沖輸入端(CLK)、設置時間使能端(SET_)、預置數據輸入端(DIN_H、DIN_L)、計數脈沖輸出端(CQ_H、CQ_L)。二十四進制計數器模塊程序編寫如下: --二十四進制計數器的源程序CNT24.VHD LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.STD_LOGIC_UNSIGNED.ALL; ENTITY CNT24 IS PORT( CLK: IN STD_LOGIC; SET: IN STD_LOGIC; DIN_H: IN STD_LOGIC_VECTOR(3 DOWNTO 0); DIN_L: IN STD_LOGIC_VECTOR(3 DOWNTO 0); CQ_H: OUT STD_LOGIC_VECTOR(3 DOWNTO 0); CQ_L: OUT STD_LOGIC_VECTOR(3 DOWNTO 0)); END CNT24; ARCHITECTURE ART OF CNT24 IS SIGNAL CQI_H:STD_LOGIC_VECTOR(3 DOWNTO 0); SIGNAL CQI_L:STD_LOGIC_VECTOR(3 DOWNTO 0); BEGIN PROCESS(CLK,SET,DIN_H,DIN_L) BEGIN IF SET='1' THEN CQI_H<=DIN_H; CQI_L<=DIN_L; ELSIF CLK'EVENT AND CLK='1' THEN IF (CQI_H="0010" AND CQI_L="0011") THEN CQI_H<="0000"; CQI_L<="0000"; ELSIF (CQI_H/="0010" AND CQI_L="1001") THEN CQI_H<=CQI_H+'1'; CQI_L<="0000"; ELSE CQI_H<=CQI_H; CQI_L<=CQI_L+1; END IF; END IF; END PROCESS ; CQ_H<=CQI_H; CQ_L<=CQI_L; END ART; 5. 7段LED顯示驅動模塊程序 7段LED由7個發光二極管組成,當某一發光二極管導通時,相應地點亮某一點或某一段筆畫,通過二極管不同的亮暗組合形成不同的數字、字母及其它符號。其結構如下 --共陰極LED顯示模塊程序LED_DRIV.VHD LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; ENTITY LED_DRIV IS PORT (DIN: IN STD_LOGIC_VECTOR(3 DOWNTO 0); DOUT: OUT STD_LOGIC_VECTOR(6 DOWNTO 0)); END LED_DRIV; ARCHITECTURE ART OF LED_DRIV IS BEGIN PROCESS(DIN) BEGIN CASE DIN IS WHEN "0000"=>DOUT<="0111111"; --顯示“0” WHEN "0001"=>DOUT<="0000110"; --顯示“1” WHEN "0010"=>DOUT<="1011011"; --顯示“2” WHEN "0011"=>DOUT<="1001111"; --顯示“3” WHEN "0100"=>DOUT<="1100110"; --顯示“4” WHEN "0101"=>DOUT<="1101101"; --顯示“5” WHEN "0110"=>DOUT<="1111101"; --顯示“6” WHEN "0111"=>DOUT<="0000111"; --顯示“7” WHEN "1000"=>DOUT<="1111111"; --顯示“8” WHEN "1001"=>DOUT<="1101111"; --顯示“9” WHEN OTHERS=>NULL; END CASE; END PROCESS; END ART;
|