基于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
- 基于VHDL的数字钟设计
- 基于VHDL语言编写的多功能数字钟
- 基于VHDL设计的交通灯系统
- 基于VHDL的四路抢答器设计
- VHDL设计简单数字时钟
- EDA(VHDL)数字钟
- 基于VHDL语言的几种消抖电路的设计
- 基于VHDL的四路抢答器设计(程序)
- 基于VHDL的四路抢答器设计(程序)+注释
- 基于DE2的VHDL六层电梯控制程序设计
- EDA课设-基于VHDL的简易出租车计价器设计
- fpga的vhdl设计
- 状态机的VHDL设计
- 【VHDL】VHDL设计n的全加器
- 完整版 VHDL设计数字电子时钟
- 基于CPLD的数字钟设计(一)
- 基于CPLD的数字钟设计(二)
- 最近用VHDL语言写的数字钟
- 基于OpenCV 的美颜相机推送直播流
- 栈和队列-第3章-《数据结构题集》习题解析-整理
- Haroopad在linux打不开以及显示不了中文
- 文章标题
- 算法系列—堆排序
- 基于VHDL的数字钟设计
- Android dvm
- 插入排序
- linux系统编程之基础必备(四):C 标准库IO缓冲区和内核缓冲区的区别
- 第九周【项目二-对称矩阵压缩存储的实现与应用(2)】
- 环队列
- 第一章:介绍Django
- hunterliy小作品之 HunterMusic音乐播放器(Day3-自定义通知栏实现)
- 串口通信一次最多发送两个数据