基于VHDL的数字钟设计

来源:互联网 发布:手机测大气压软件 编辑:程序博客网 时间:2024/05/16 17:03

这个是以前的一个作业,当时写的比较用心。先贴个程序有时间就再写写详细的设计思路吧!

工程结构如下:
这里写图片描述

下面分部贴上程序

1.模块综合

-----------------------------------------------------  -- 数字钟----------------------------------------------------- LIBRARY IEEE;USE IEEE.STD_LOGIC_1164.ALL;USE IEEE.STD_LOGIC_UNSIGNED.ALL;ENTITY CLOCK ISPORT(                     CLK : IN STD_LOGIC;  -- 1Hz时钟信号输入                C_SCALE_SEL : IN STD_LOGIC;  -- 时钟进制选择                    C_RESET : IN STD_LOGIC;  -- 时钟复位信号  C_SET_MIN, C_SET_HOUR : IN STD_LOGIC;  -- 时间调节                 BUZZER : OUT STD_LOGIC;  -- 蜂鸣器控制                SEGMENT_SEL : OUT STD_LOGIC_VECTOR(5 DOWNTO 0);  -- 数码位选信号输出                SEGMENT_SEG : OUT STD_LOGIC_VECTOR(7 DOWNTO 0);  -- 数码管短信信号输出                  FLASH_LED : OUT STD_LOGIC_VECTOR(3 DOWNTO 0));  -- 流水灯END CLOCK;ARCHITECTURE BHV OF CLOCK IS   -- 调用秒钟计数模块声明    COMPONENT SECOND_BCD_COUNT      PORT(clk_to_second, reset, set_min : IN STD_LOGIC;                                              CO : OUT STD_LOGIC;                                         DATOUT : OUT STD_LOGIC_VECTOR(7 DOWNTO 0));    END COMPONENT;    -- 调用分钟计数模块声明    COMPONENT MINUTE_BCD_COUNT      PORT(clk_to_minute, reset, set_hour : IN STD_LOGIC;                                                CO : OUT STD_LOGIC;                                          DATOUT : OUT STD_LOGIC_VECTOR(7 DOWNTO 0));    END COMPONENT;    -- 调用小时计数模块声明    COMPONENT HOUR_BCD_COUNT      PORT(clk_to_hour, reset, SCALE_SEL : IN STD_LOGIC;                 DATOUT : OUT STD_LOGIC_VECTOR(7 DOWNTO 0));    END COMPONENT;    -- 调用译码显示模块声明    COMPONENT SELTIME      PORT(            SCAN_CLK : IN STD_LOGIC;  -- 扫描时钟输入           HOUR, MINUTE, SECOND : IN STD_LOGIC_VECTOR(7 DOWNTO 0);  -- 时间数据输入                                 SEL : OUT STD_LOGIC_VECTOR(5 DOWNTO 0);  -- 位选信号输出                                                               SEG : OUT STD_LOGIC_VECTOR(7 DOWNTO 0));  -- 段选信号输出    END COMPONENT;    -- 调用分频模块声明    COMPONENT DEV      PORT(                  CLK_50MHz : IN STD_LOGIC;   CLK_1Hz, CLK_5Hz, CLK_250Hz : OUT STD_LOGIC);    END COMPONENT;    -- 整点报时模块    COMPONENT  ALERT      PORT(  CLK : IN STD_LOGIC;  -- 激励LED变化            M_IN : IN STD_LOGIC_VECTOR(7 DOWNTO 0);  -- 输入分钟显示数据             S_IN : IN STD_LOGIC_VECTOR(7 DOWNTO 0);  -- 输入秒钟显示数据         SPEAKER : OUT STD_LOGIC;  -- 蜂鸣器控制             LED : OUT STD_LOGIC_VECTOR(3 DOWNTO 0));  -- 流水灯    END COMPONENT;    -- 按键延时消抖模块    COMPONENT KEY_DELAY      PORT(CLK, KEY_IN : IN STD_LOGIC;                  KEY_OUT : OUT STD_LOGIC);    END COMPONENT;SIGNAL AD_HOUR, AD_MIN : STD_LOGIC;  -- 时钟调节信号SIGNAL S_CO, M_CO : STD_LOGIC;  -- 计数进位SIGNAL C_CLK, SCAN_CLK, FLOW_CLK : STD_LOGIC;  -- 计数时钟,扫描时钟,流水灯驱动时钟SIGNAL S_DAT, M_DAT, H_DAT : STD_LOGIC_VECTOR(7 DOWNTO 0);  -- 秒,分,时显示数据    BEGIN       u1 : SECOND_BCD_COUNT PORT MAP(C_CLK, C_RESET, AD_MIN, S_CO, S_DAT);  -- 秒钟        u2 : MINUTE_BCD_COUNT PORT MAP(S_CO, C_RESET, AD_HOUR, M_CO, M_DAT);  -- 分钟        u3 : HOUR_BCD_COUNT   PORT MAP(M_CO, C_RESET, C_SCALE_SEL, H_DAT);  -- 小时        u4 : SELTIME          PORT MAP(SCAN_CLK, H_DAT, M_DAT, S_DAT, SEGMENT_SEL, SEGMENT_SEG);  -- 译码显示        u5 : DEV                 PORT MAP(CLK, C_CLK, FLOW_CLK , SCAN_CLK);  -- 分频        u6 : KEY_DELAY        PORT MAP(SCAN_CLK, C_SET_MIN, AD_MIN);  -- 分钟调整        u7 : KEY_DELAY        PORT MAP(SCAN_CLK, C_SET_HOUR, AD_HOUR);  -- 小时调整        u8 : ALERT            PORT MAP(FLOW_CLK, M_DAT,S_DAT, BUZZER, FLASH_LED);  -- 整点报时END BHV;        

2.时分秒计数模块

----------------------------------------------------- -- 小时24进制或12进制的BCD计数模块-----------------------------------------------------LIBRARY IEEE;USE IEEE.STD_LOGIC_1164.ALL;USE IEEE.STD_LOGIC_UNSIGNED.ALL;ENTITY HOUR_BCD_COUNT ISPORT(clk_to_hour, reset, SCALE_SEL : IN STD_LOGIC;                 DATOUT : OUT STD_LOGIC_VECTOR(7 DOWNTO 0));END HOUR_BCD_COUNT;ARCHITECTURE BHV OF HOUR_BCD_COUNT ISSIGNAL COUNT_SHI, COUNT_GE : STD_LOGIC_VECTOR(3 DOWNTO 0);BEGIN     PROCESS(clk_to_hour, reset)     BEGIN        IF reset = '0'      THEN COUNT_SHI <= "0000"; COUNT_GE <= "0000"; -- 有复位信号,则清除计数。        ELSIF clk_to_hour'EVENT AND clk_to_hour = '1'    THEN           IF SCALE_SEL = '1' THEN  -- 24进制                IF COUNT_SHI = "0010" AND COUNT_GE = "0011"     THEN COUNT_SHI <= "0000"; COUNT_GE <= "0000";  -- 24进制溢出清零                ELSIF COUNT_GE < "1001"     THEN COUNT_GE <= COUNT_GE + 1;                ELSE COUNT_GE <= "0000"; COUNT_SHI <= COUNT_SHI + 1;                END IF;            ELSE  -- 12进制               IF COUNT_SHI = "0001" AND COUNT_GE = "0001"      THEN COUNT_SHI <= "0000"; COUNT_GE <= "0000";  -- 12进制溢出清零              ELSIF COUNT_GE < "1001"       THEN COUNT_GE <= COUNT_GE + 1;                ELSE COUNT_GE <= "0000"; COUNT_SHI <= COUNT_SHI + 1;                END IF;            END IF;        END IF;    DATOUT <= COUNT_SHI & COUNT_GE;  -- 数据输出    END PROCESS;END BHV;-----------------------------------------------------  -- 分钟BCD60进制计数-----------------------------------------------------LIBRARY IEEE;USE IEEE.STD_LOGIC_1164.ALL;USE IEEE.STD_LOGIC_UNSIGNED.ALL;ENTITY MINUTE_BCD_COUNT ISPORT(clk_to_minute, reset, set_hour : IN STD_LOGIC;                                 CO : OUT STD_LOGIC;                               DATOUT : OUT STD_LOGIC_VECTOR(7 DOWNTO 0));END MINUTE_BCD_COUNT;ARCHITECTURE BHV OF MINUTE_BCD_COUNT ISSIGNAL COUNT_SHI, COUNT_GE : STD_LOGIC_VECTOR(3 DOWNTO 0);SIGNAL COUNT_EN : STD_LOGIC;BEGIN    CO <=  set_hour OR COUNT_EN;    PROCESS(clk_to_minute, set_hour, reset)     BEGIN           IF reset = '0'      THEN COUNT_SHI <= "0000"; COUNT_GE <= "0000"; -- 有复位信号,则清除计数        ELSIF clk_to_minute'EVENT AND clk_to_minute = '1'   THEN                 IF COUNT_SHI = "0101" AND COUNT_GE  = "1001"   THEN                 COUNT_SHI <= "0000"; COUNT_GE <= "0000";  COUNT_EN <= '1';  -- 计数进位(信号量不是立即赋值,需等下一个时钟信号到来。)            ELSIF COUNT_GE < "1001"     THEN COUNT_GE <= COUNT_GE + 1; COUNT_EN <= '0';             ELSE COUNT_GE <= "0000";  -- 计数溢出则清零,并产生进位                IF COUNT_SHI < "1010"   THEN COUNT_SHI <= COUNT_SHI + 1;                  ELSE COUNT_SHI <= "0000";                  END IF;            END IF;        END IF;    END PROCESS;    DATOUT <= COUNT_SHI & COUNT_GE;  -- 数据输出END BHV;-----------------------------------------------------  -- 秒钟BCD60进制计数-----------------------------------------------------LIBRARY IEEE;USE IEEE.STD_LOGIC_1164.ALL;USE IEEE.STD_LOGIC_UNSIGNED.ALL;ENTITY SECOND_BCD_COUNT ISPORT(clk_to_second, reset, set_min : IN STD_LOGIC;                                CO : OUT STD_LOGIC;                              DATOUT : OUT STD_LOGIC_VECTOR(7 DOWNTO 0));END SECOND_BCD_COUNT;ARCHITECTURE BHV OF SECOND_BCD_COUNT ISSIGNAL COUNT_SHI, COUNT_GE : STD_LOGIC_VECTOR(3 DOWNTO 0);SIGNAL COUNT_EN : STD_LOGIC;BEGIN    CO <= set_min OR COUNT_EN;    PROCESS(clk_to_second, reset, set_min)      BEGIN   IF reset = '0'       THEN COUNT_SHI <= "0000"; COUNT_GE <= "0000"; -- 有复位信号,则清除计数    ELSIF clk_to_second'EVENT AND clk_to_second = '1'   THEN             IF COUNT_SHI = "0101" AND COUNT_GE  = "1001"   THEN             COUNT_SHI <= "0000"; COUNT_GE <= "0000";  COUNT_EN <= '1';  -- 计数进位(信号量不是立即赋值,需等下一个时钟信号到来。)        ELSIF COUNT_GE < "1001"     THEN COUNT_GE <= COUNT_GE + 1;  COUNT_EN <= '0';        ELSE COUNT_GE <= "0000";              IF COUNT_SHI < "1010"   THEN COUNT_SHI <= COUNT_SHI + 1;              ELSE COUNT_SHI <= "0000";              END IF;        END IF;    END IF;    DATOUT <= COUNT_SHI & COUNT_GE;  -- 数据输出    END PROCESS;END BHV;

3.数码管译码显示模块

-----------------------------------------------------  -- 数码管译码显示模块-----------------------------------------------------LIBRARY IEEE;USE IEEE.STD_LOGIC_1164.ALL;USE IEEE.STD_LOGIC_UNSIGNED.ALL;ENTITY SELTIME ISPORT(            SCAN_CLK : IN STD_LOGIC;  -- 扫描时钟输入      HOUR, MINUTE, SECOND : IN STD_LOGIC_VECTOR(7 DOWNTO 0);  -- 时间数据输入                      SEL : OUT STD_LOGIC_VECTOR(5 DOWNTO 0);  -- 位选信号输出                      SEG : OUT STD_LOGIC_VECTOR(7 DOWNTO 0));  -- 段选信号输出END SELTIME;ARCHITECTURE BHV OF SELTIME ISSIGNAL SCAN_COUNT : STD_LOGIC_VECTOR(2 DOWNTO 0);  -- 扫描计数 SIGNAL DAT : STD_LOGIC_VECTOR(3 DOWNTO 0);  BEGIN      -- 位选扫描进程     SCAN : PROCESS(SCAN_CLK) BEGIN        IF SCAN_CLK'EVENT AND SCAN_CLK = '1'   THEN             IF(SCAN_COUNT > "101")  THEN SCAN_COUNT <= "000";            ELSE SCAN_COUNT <= SCAN_COUNT + 1;            END IF;        END IF;        CASE SCAN_COUNT IS            WHEN "000" => DAT <= SECOND(3 DOWNTO 0);            WHEN "001" => DAT <= SECOND(7 DOWNTO 4);            WHEN "010" => DAT <= MINUTE(3 DOWNTO 0);            WHEN "011" => DAT <= MINUTE(7 DOWNTO 4);            WHEN "100" => DAT <= HOUR(3 DOWNTO 0);            WHEN "101" => DAT <= HOUR(7 DOWNTO 4);            WHEN  OTHERS => NULL;        END CASE;    END PROCESS SCAN;    -- 译码显示进程 共数码管编码    DECODE :    PROCESS(SCAN_COUNT) BEGIN        CASE DAT IS            WHEN "0000" => SEG<="11000000";             WHEN "0001" => SEG<="11111001";             WHEN "0010" => SEG<="10100100";             WHEN "0011" => SEG<="10110000";             WHEN "0100" => SEG<="10011001";             WHEN "0101" => SEG<="10010010";             WHEN "0110" => SEG<="10000010";             WHEN "0111" => SEG<="11111000";             WHEN "1000" => SEG<="10000000";             WHEN "1001" => SEG<="10010000";             WHEN OTHERS => SEG<="11111111";         END CASE;    END PROCESS DECODE;     -- 3-8译码    SEL <=  "111110" WHEN SCAN_COUNT = "000" ELSE               "111101" WHEN SCAN_COUNT = "001" ELSE               "111011" WHEN SCAN_COUNT = "010" ELSE               "110111" WHEN SCAN_COUNT = "011" ELSE               "101111" WHEN SCAN_COUNT = "100" ELSE               "011111" WHEN SCAN_COUNT = "101" ELSE               "111111";END BHV;

4.分配模块,晶振频率50MHz

-----------------------------------------------------  -- 分频模块-----------------------------------------------------LIBRARY IEEE;USE IEEE.STD_LOGIC_1164.ALL;USE IEEE.STD_LOGIC_UNSIGNED.ALL;ENTITY DEV ISPORT(                       CLK_50MHz : IN STD_LOGIC;    CLK_1Hz, CLK_5Hz, CLK_250Hz : OUT STD_LOGIC);END;ARCHITECTURE BHV OF DEV ISSIGNAL Q1 : INTEGER RANGE 0 TO 49999999;SIGNAL Q2 : INTEGER RANGE 0 TO 199999;SIGNAL Q3 : INTEGER RANGE 0 TO 9999999;BEGIN    PROCESS(CLK_50MHz) BEGIN        IF CLK_50MHz'EVENT AND CLK_50MHz = '1' THEN           -- 1Hz            IF Q1 < 25000000        THEN CLK_1Hz <= '0'; Q1 <= Q1 + 1;            ELSIF Q1 < 49999999     THEN CLK_1Hz <= '1'; Q1 <= Q1 + 1;            ELSE Q1 <= 0;            END IF;            -- 250Hz            IF Q2 < 100000      THEN CLK_250Hz <= '0'; Q2 <= Q2 + 1;            ELSIF Q2 < 199999       THEN CLK_250Hz <= '1'; Q2 <= Q2 + 1;             ELSE Q2 <= 0;            END IF;            -- 5Hz            IF Q3 < 5000000 THEN CLK_5Hz <= '0'; Q3 <= Q3 + 1;            ELSIF Q3 < 9999999  THEN CLK_5Hz <= '1'; Q3 <= Q3 + 1;             ELSE Q3 <= 0;            END IF;        END IF;    END PROCESS;END;

5.按键延时消抖模块(PS:这个很重要,网上借鉴的。。。~_~)

-----------------------------------------------------  -- 按键延时消抖模块-----------------------------------------------------LIBRARY IEEE;USE IEEE.STD_LOGIC_1164.ALL;USE IEEE.STD_LOGIC_UNSIGNED.ALL;ENTITY KEY_DELAY ISPORT(CLK, KEY_IN : IN STD_LOGIC;           KEY_OUT : OUT STD_LOGIC);END KEY_DELAY;ARCHITECTURE BHV OF KEY_DELAY ISBEGINPROCESS(CLK, KEY_IN) VARIABLE COUNT : INTEGER RANGE 0 TO 10;BEGIN    IF CLK'EVENT AND CLK = '1' THEN        IF KEY_IN = '0' THEN            IF COUNT < 10    THEN COUNT := COUNT + 1;            ELSE COUNT := COUNT;  -- 赋予变量的值使即刻生效的,在此后的代码中,此变量将使用新的变量值。            END IF;            IF COUNT = 9    THEN KEY_OUT <= '1';                ELSE KEY_OUT <= '0';                END IF;        ELSE COUNT := 0;            END IF;    END IF;END PROCESS;END BHV;

6.报时模块

-----------------------------------------------------  -- 报时模块-----------------------------------------------------LIBRARY IEEE;USE IEEE.STD_LOGIC_1164.ALL;USE IEEE.STD_LOGIC_UNSIGNED.ALL;ENTITY ALERT ISPORT(  CLK : IN STD_LOGIC;  -- 激励LED变化      M_IN : IN STD_LOGIC_VECTOR(7 DOWNTO 0);  -- 输入分钟显示数据        S_IN : IN STD_LOGIC_VECTOR(7 DOWNTO 0);  -- 输入秒钟显示数据     SPEAKER : OUT STD_LOGIC;  -- 蜂鸣器控制        LED : OUT STD_LOGIC_VECTOR(3 DOWNTO 0));  -- 流水灯END ALERT;ARCHITECTURE BHV OF ALERT ISSIGNAL SEL : STD_LOGIC_VECTOR(1 DOWNTO 0);SIGNAL COUNT : STD_LOGIC_VECTOR(2 DOWNTO 0);BEGIN      REG : PROCESS(CLK) BEGIN        IF CLK'EVENT AND CLK = '1'      THEN             IF COUNT < "111"    THEN COUNT <= COUNT + 1;            ELSE COUNT <= "000";             END IF;        END IF;    END PROCESS REG;    FLOW : PROCESS(COUNT, M_IN, S_IN) BEGIN        IF M_IN = "00000000"    AND S_IN < "00001001"   THEN  -- 整点闪烁            CASE COUNT IS                WHEN "000" => LED <="1000";                  WHEN "001" => LED <="0100";                  WHEN "010" => LED <="0010";                  WHEN "011" => LED <="0001";                WHEN "111" => LED <="1111";                 WHEN "101" => LED <="0000";                WHEN "110" => LED <="1111";                WHEN OTHERS => LED <="0000";            END CASE;        ELSE    LED <= "0000";        END IF;    END PROCESS FLOW;    BEEP : PROCESS( M_IN, S_IN) BEGIN        IF M_IN = "00000000"    AND S_IN < "0000010"    THEN  -- 整点报时          SPEAKER <= '0';        ELSE SPEAKER <= '1';        END IF;    END PROCESS BEEP;END BHV;    
0 0
原创粉丝点击