一、设计任务
(一)采用 VHDL 语言,利用 Quartus 编程设计一个数字万年历,具有以下功能:
1、时、分、秒的功能设计与调试成功,用数码管显示;
2、月、日的功能设计与调试成功,用数码管显示;
3、年(含闰年)的功能设计与调试成功,用数码管轮流显示年、月、日、 时、分、秒;
4、可手动设置任意日期,包括年、月、日、时、分,按键不超过 4 个;
5、星期的功能设计与调试成功,用数码管轮流显示年、月、日、时、分、 秒、星期;
6、能进行闹钟设置以及秒表计时功能;
7、其他功能(按键消抖、节日提醒);
(二)利用开发板对设计的电路进行调试检验;
(三)总结电路设计结果。
二、系统设计

简述万年历设计方案及主要模块:
(一)计数器模块
(二)校时模块
(三)显示及显示方式切换模块
(四)顶层原理图
(五)引脚设定
(六)下载验证
三、模块的实现
(一)计数器模块
1、分、秒计数器
这两个模块都为60进制计数器,源程序的代码如下:
--秒/分 60bcd
--******************************
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_ARITH.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
--******************************
ENTITY COUNT_60BCD IS
PORT (CLK:IN STD_LOGIC;
jinwei:OUT STD_LOGIC;
Q :OUT STD_LOGIC_VECTOR(7 DOWNTO 0)
);
END COUNT_60BCD;
--******************************
ARCHITECTURE ABC OF COUNT_60BCD IS
SIGNAL QQ:STD_LOGIC_VECTOR(7 DOWNTO 0);
BEGIN
PROCESS (CLK)
BEGIN
IF CLK'EVENT AND CLK='1' THEN
IF QQ>="01011001" THEN QQ<="00000000";jinwei<='1';
ELSIF QQ(3 DOWNTO 0)>="1001" THEN
QQ(3 DOWNTO 0)<="0000";
QQ(7 DOWNTO 4)<=QQ(7 DOWNTO 4)+1;
jinwei<='0';
ELSE QQ<=QQ+1;
jinwei<='0';
END IF;
END IF;
END PROCESS;
Q<=QQ;
END ABC;
CLK表示时钟脉冲信号,CLR表示重置(清零),jinwei表示进位,Q表示输出。
当CLR设置为1表示清零,Q输出都为零。
当CLR设置为0表示未进行重置,当秒/分计数器计数到59时,等待CLK信号下一个脉冲上升沿到来时,输出jinwei产生一个输出脉冲,同时秒/分计数器再次从0开始计数(1分钟=60秒/1小时=60分钟)。
2、时计数器
该模块为24进制计数器,源程序的代码如下图:
--时 24bcd
--******************************
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_ARITH.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
--******************************
ENTITY hour_24bcd IS
PORT (CLK:IN STD_LOGIC;
jinwei:OUT STD_LOGIC;
Q :OUT STD_LOGIC_VECTOR(7 DOWNTO 0)
);
END hour_24bcd;
--******************************
ARCHITECTURE ABC OF hour_24bcd IS
SIGNAL QQ:STD_LOGIC_VECTOR(7 DOWNTO 0);
BEGIN
PROCESS (CLK)
BEGIN
IF CLK'EVENT AND CLK='1' THEN
IF QQ>="00100011" THEN --
QQ<="00000000";jinwei<='1';--进位
ELSIF QQ(3 DOWNTO 0)>="1001" THEN--bcd进位
QQ(3 DOWNTO 0)<="0000";
QQ(7 DOWNTO 4)<=QQ(7 DOWNTO 4)+1;
jinwei<='0';
ELSE QQ<=QQ+1;jinwei<='0';
END IF;
END IF;
END PROCESS;
Q<=QQ;
END ABC;
CLK表示时钟脉冲信号,CLR表示重置(清零),jinwei表示进位,Q表示输出。
当CLR设置为1表示清零,Q输出都为零。
当CLR设置为0表示未进行重置,当时计数器计数到23时,等待CLK信号下一个脉冲上升沿到来时,进位输出jinwei产生一个输出脉冲,同时时计数器再次从0开始计数(1天=24小时)。
3、日计数器
日计数器进制设定有四种不同的情况。若该月为大月(1,3,5,7,8,10,12)日计数器到31时才产生进位信号。若该月为小月(4,6,9,11)日计数器计数到30时就产生进位信号。若该月为闰年的2月,日计数器计数到29时就产生进位信号。若该月为平年的2月,日计数器计数到28时就产生进位信号。所以,日计数器需要输入判断信号is_leap_year,如果是闰年即is_leap_year为1则2月有29天,否则2月有28天。
日计数器的源程序代码如下图:
--日计数器 31bcd
--******************************
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_ARITH.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
use IEEE.NUMERIC_STD.ALL;
--******************************
ENTITY day_31 IS
PORT (clk :IN STD_LOGIC; --使能信号/重置信号
yue:in std_logic_vector(7 downto 0);--当前月份
is_leap_year:in std_logic;--闰年判断
jinwei:OUT STD_LOGIC;--满一个月则需要进位
Q :OUT STD_LOGIC_VECTOR(7 DOWNTO 0)--当前日期
);
END day_31;
--******************************
ARCHITECTURE ABC OF day_31 IS
SIGNAL QQ:STD_LOGIC_VECTOR(7 DOWNTO 0);
signal days_in_month :std_logic_vector(7 downto 0);
begin
process(yue, is_leap_year) --月份内的天数判断
begin
case yue is
when "00000001" | "00000011" |"00000101" | "00000111" | "00001000" | "00010000" | "00010010" =>--1 | 3 | 5 | 7 | 8 | 10 | 12
days_in_month <="00110001";--31
when "00000100" | "00000110" | "00001001" | "00010001" => --4 | 6 | 9 | 11
days_in_month <="00110000";--30
when "00000010" => --2月进行闰年判断
if is_leap_year = '1' then
days_in_month <= "00101001";--闰年的二月29天
else
days_in_month <= "00101000";--非闰年28天
end if;
when others =>days_in_month <= "00110001";--其他情况设置为31天
end case;
end process;
-- 日期计数逻辑
process(clk,days_in_month)
begin
if clk'event and clk='1' then
IF QQ>=days_in_month THEN QQ<="00000001";jinwei<='1';--满一个月进位
ELSIF QQ(3 DOWNTO 0)>="1001" THEN --由于bcd,个位慢9进位
QQ(3 DOWNTO 0)<="0000";
QQ(7 DOWNTO 4)<=QQ(7 DOWNTO 4)+1;
jinwei<='0';
ELSE QQ<=QQ+1;
jinwei<='0';
end if;
end if;
end process;
Q<=QQ;
END ABC;
CLK表示时钟脉冲信号,is_leap_year判断闰年,rst重置,yue表示月,jinwei表示进位,Q表示输出。
当rst设置为0表示未进行重置,is_leap_year为0即不是闰年,yue=“00000010”即2月,Q输出到28时,输出jinwei产生一个进位输出脉冲,同时日计数器再次从1开始计数。
当rst设置为1表示重置(清零),Q输出清零同时日计数器再次从1开始计数。
4、月计数器
该模块为十二进制计数器,代码如下:
--月 12bcd
--******************************
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_ARITH.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
--******************************
ENTITY COUNT_12 IS
PORT (CLK:IN STD_LOGIC;
jinwei:OUT STD_LOGIC;
Q :OUT STD_LOGIC_VECTOR(7 DOWNTO 0)
);
END COUNT_12;
--******************************
ARCHITECTURE ABC OF COUNT_12 IS
SIGNAL QQ:STD_LOGIC_VECTOR(7 DOWNTO 0);BEGIN
PROCESS(CLK)
BEGIN
IF CLK'EVENT AND CLK='1' THEN
IF QQ>="00010010" THEN --有十二月,所以到十二进位
QQ<="00000000";jinwei<='1';--进位
ELSIF QQ(3 DOWNTO 0)>="1001" THEN--bcd进位
QQ(3 DOWNTO 0)<="0000";
QQ(7 DOWNTO 4)<="0001";
jinwei<='0';
ELSE QQ<=QQ+1;jinwei<='0';
END IF;
END IF;
END PROCESS;
Q<=QQ;
END ABC;
CLK表示时钟脉冲信号,CLR表示重置(清零),jinwei表示进位,Q表示输出。
当CLR设置为1表示清零,Q输出都为零。当CLR设置为0表示未进行重置,当月计数器计数到11时,等待CLK信号下一个脉冲上升沿到来时,输出jinwei产生一个输出脉冲,同时秒/分计数器再次从0开始计数(1年=12个月)。
5、年计数器
该模块由两部分组成,一个代表年的低位(后两位),另一个表示年的高位(前两位),代码相同,都是100进制,如下:
--年 100进制计数器
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
--********************************
entity COUNT_100BCD is
port (
CLK : in std_logic;
Q : out std_logic_vector(7 downto 0);
TCN :out std_logic
);
end COUNT_100BCD;
--***************************************
architecture abc of COUNT_100BCD is
signal QQ : std_logic_vector(7 downto 0):="00100000";
beginprocess(CLK)
begin
if CLK'EVENT AND CLK='1' then -- 上升沿触发
if QQ >="10011001" then
QQ<="00000000" ; TCN<='1';
ELSIF QQ(3 DOWNTO 0) >="1001" THEN
QQ(3 downto 0) <="0000"; -- 将低四位清零
QQ(7 downto 4) <=QQ(7 downto 4)+1; -- 高四位加一
TCN<='0';
else
QQ <=QQ+1; -- 否则正常加一
TCN<='0';
end if;
end if;
end process;
Q <= QQ; -- 输出信号
end abc;
CLK表示时钟脉冲信号,Q表示输出,TCN为进位。Q输出到99时,输出TCN产生一个进位输出脉冲,同时年计数器再次从0开始计数。
6、闰年判断
代码如下:
--判断当前年份是否是闰年
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
--********************************
entity RUNNIAN is
Port (
NIAN : in STD_LOGIC_VECTOR(15 downto 0); -- 输入的BCD数,前8位为年份的十进制表示(假设范围足够处理所需年份)
RUN : out STD_LOGIC -- 输出‘1’表示闰年
);
end RUNNIAN;
--*************************************
architecture Behavioral of RUNNIAN is
begin
process(NIAN)
variable yearDec : integer; -- 用于存储转换后的十进制年份
begin
-- 将BCD编码的年份转换为十进制
yearDec := CONV_INTEGER(NIAN(15 downto 12)) * 1000 +
CONV_INTEGER(NIAN(11 downto 8)) * 100 +
CONV_INTEGER(NIAN(7 downto 4)) * 10 +
CONV_INTEGER(NIAN(3 downto 0));
-- 判断是否为闰年
if (yearDec mod 4 = 0 and yearDec mod 100 /= 0) or (yearDec mod 400 = 0) then
RUN <= '1';
else
RUN <= '0';
end if;
end process;
end Behavioral;
NIAN表示年RUN表示闰年例如:NIAN“0010000000100100”=2024是闰年即RUN=1,
NIAN=“0010000000100011”不是闰年
(二)校时模块
1、调整时间
调整时间源程序代码,如下 :
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_ARITH.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;ENTITY MENU_TZ IS
PORT( CLK, RESET : IN std_logic;
X : OUT std_logic;
Y : OUT std_logic_vector( 5 downto 0)
);
END MENU_TZ;ARCHITECTURE abc OF MENU_TZ IS
signal Q1 :std_logic_vector( 2 downto 0):="000";
SIGNAL Y1 :STD_LOGIC_VECTOR(5 DOWNTO 0) :="111111";
SIGNAL X1 :STD_LOGIC;
BEGIN
PROCESS (CLK, RESET)
BEGIN
IF RESET = '1' THEN --清零
Q1 <= "000";
Y1 <= "111111";
ELSIF CLK'EVENT AND CLK='1' THEN -- 确保在时钟上升沿检查复位信号
CASE Q1 IS
WHEN "000" => Q1 <= "001"; Y1 <= "111111";
WHEN "001" => Q1 <= "010"; Y1 <= "111110";--年高位
WHEN "010" => Q1 <= "011"; Y1 <= "111101";--年低位
WHEN "011" => Q1 <= "100"; Y1 <= "111011";--月
WHEN "100" => Q1 <= "101"; Y1 <= "110111";--天
WHEN "101" => Q1 <= "110"; Y1 <= "101111";--时
WHEN "110" => Q1 <= "000"; Y1 <= "011111";--分
WHEN OTHERS => Q1 <= "000"; Y1 <= "111111";
END CASE;
END IF;
END PROCESS;
Y<=Y1;
end abc;
CLK表示时钟脉冲信号,RESET表示重置,Y调整时间
2、二选一数据选择器
选择前一个计数器进位的脉冲或者是手动调整时间的脉冲,程序如下:
--切换计数器时钟信号,实现正常计时或调整时间
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;entity MUX2 is
Port (
X1, X2 : in STD_LOGIC; -- 两个数据输入
A : in STD_LOGIC; -- 选择信号,'0'选择X1,'1'选择X2
Y : out STD_LOGIC -- 输出信号,选择的输入数据
);
end MUX2;architecture Behavioral of MUX2 is
begin
Y <= X1 when A = '0' else X2; -- ‘0’>X1;'1'>X2
end Behavioral;
(三)
1、共阴极七位数码管
--8421码的共阴极七位数码管的显示译码器
--******************************
LIBRARY IEEE;
USE IEEE. STD_LOGIC_1164.ALL;
USE IEEE. STD_LOGIC_ARITH.ALL;
USE IEEE. STD_LOGIC_UNSIGNED. ALL;
--********************************
entity seven_segment_decoder is
Port ( CLK : IN STD_LOGIC;
A,B,C,D,E,F : in STD_LOGIC_VECTOR (3 downto 0);
LED_SEG : OUT STD_LOGIC_VECTOR(6 DOWNTO 0); --段控制信号输出
LED_SCAN : OUT STD_LOGIC_VECTOR(5 DOWNTO 0) --位控制信号输出
);
end seven_segment_decoder;
--*******************************
architecture ABC of seven_segment_decoder is
signal F1,F2,F3,F4,F5,F6 : std_logic_vector(6 downto 0);
SIGNAL CNT_4 : STD_LOGIC_VECTOR(2 DOWNTO 0);
BEGIN
PROCESS(CLK)
BEGIN
IF CLK'EVENT AND CLK = '1' THEN
IF CNT_4 /= "101" THEN
CNT_4 <= CNT_4 + 1;
else
CNT_4 <="000";
END IF;END IF;
END PROCESS;
--***********************************
PROCESS(CNT_4)
BEGINCASE CNT_4 IS
WHEN "000" =>LED_SEG<=F1; LED_SCAN<="111110";
WHEN "001" =>LED_SEG<=F2; LED_SCAN<="111101";
WHEN "010" =>LED_SEG<=F3; LED_SCAN<="111011";
WHEN "011" =>LED_SEG<=F4; LED_SCAN<="110111";
WHEN "100" =>LED_SEG<=F5; LED_SCAN<="101111";
WHEN "101" =>LED_SEG<=F6; LED_SCAN<="011111";
WHEN OTHERS=>NULL;
END CASE;END PROCESS;
--***********************************
process(A,B,C,D,E,F)
begin
case A is
WHEN "0000"=>F1<="0111111";
WHEN "0001"=>F1<="0000110";
WHEN "0010"=>F1<="1011011";
WHEN "0011"=>F1<="1001111";
WHEN "0100"=>F1<="1100110";
WHEN "0101"=>F1<="1101101";
WHEN "0110"=>F1<="1111101";
WHEN "0111"=>F1<="0000111";
WHEN "1000"=>F1<="1111111";
WHEN "1001"=>F1<="1101111";
when others => F1 <= "0000000"; -- 关闭所有段(全亮,如果是共阳极则需要取反)
end case;
case B is
WHEN "0000"=>F2<="0111111";
WHEN "0001"=>F2<="0000110";
WHEN "0010"=>F2<="1011011";
WHEN "0011"=>F2<="1001111";
WHEN "0100"=>F2<="1100110";
WHEN "0101"=>F2<="1101101";
WHEN "0110"=>F2<="1111101";
WHEN "0111"=>F2<="0000111";
WHEN "1000"=>F2<="1111111";
WHEN "1001"=>F2<="1101111";
when others => F2 <= "0000000"; -- 关闭所有段(全亮,如果是共阳极则需要取反)
end case;
case C is
WHEN "0000"=>F3<="0111111";
WHEN "0001"=>F3<="0000110";
WHEN "0010"=>F3<="1011011";
WHEN "0011"=>F3<="1001111";
WHEN "0100"=>F3<="1100110";
WHEN "0101"=>F3<="1101101";
WHEN "0110"=>F3<="1111101";
WHEN "0111"=>F3<="0000111";
WHEN "1000"=>F3<="1111111";
WHEN "1001"=>F3<="1101111";
when others => F3 <= "0000000"; -- 关闭所有段(全亮,如果是共阳极则需要取反)
end case;
case D is
WHEN "0000"=>F4<="0111111";
WHEN "0001"=>F4<="0000110";
WHEN "0010"=>F4<="1011011";
WHEN "0011"=>F4<="1001111";
WHEN "0100"=>F4<="1100110";
WHEN "0101"=>F4<="1101101";
WHEN "0110"=>F4<="1111101";
WHEN "0111"=>F4<="0000111";
WHEN "1000"=>F4<="1111111";
WHEN "1001"=>F4<="1101111";
when others => F4 <= "0000000"; -- 关闭所有段(全亮,如果是共阳极则需要取反)
end case;
case E is
WHEN "0000"=>F5<="0111111";
WHEN "0001"=>F5<="0000110";
WHEN "0010"=>F5<="1011011";
WHEN "0011"=>F5<="1001111";
WHEN "0100"=>F5<="1100110";
WHEN "0101"=>F5<="1101101";
WHEN "0110"=>F5<="1111101";
WHEN "0111"=>F5<="0000111";
WHEN "1000"=>F5<="1111111";
WHEN "1001"=>F5<="1101111";
when others => F5 <= "0000000"; -- 关闭所有段(全亮,如果是共阳极则需要取反)
end case;
case F is
WHEN "0000"=>F6<="0111111";
WHEN "0001"=>F6<="0000110";
WHEN "0010"=>F6<="1011011";
WHEN "0011"=>F6<="1001111";
WHEN "0100"=>F6<="1100110";
WHEN "0101"=>F6<="1101101";
WHEN "0110"=>F6<="1111101";
WHEN "0111"=>F6<="0000111";
WHEN "1000"=>F6<="1111111";
WHEN "1001"=>F6<="1101111";
when others => F6 <= "0000000"; -- 关闭所有段(全亮,如果是共阳极则需要取反)
end case;
end process;
end ABC;
2、万年历所有的显示
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_ARITH.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;ENTITY WNL IS
PORT (
CLK : IN STD_LOGIC;
QM : IN STD_LOGIC_VECTOR(7 DOWNTO 0);--秒
QF : IN STD_LOGIC_VECTOR(7 DOWNTO 0);--分
QS : IN STD_LOGIC_VECTOR(7 DOWNTO 0);--时
QR : IN STD_LOGIC_VECTOR(7 DOWNTO 0);--日
QY : IN STD_LOGIC_VECTOR(7 DOWNTO 0);--月
QN : IN STD_LOGIC_VECTOR(15 DOWNTO 0); -- 年 注意QN为16位向量
QW : IN STD_LOGIC_VECTOR(7 DOWNTO 0);--星期
QMB:IN STD_LOGIC_VECTOR(7 DOWNTO 0);--秒表
QMBF:IN STD_LOGIC_VECTOR(7 DOWNTO 0);--秒表分钟
DATA_1 : OUT STD_LOGIC_VECTOR(3 DOWNTO 0);
DATA_2 : OUT STD_LOGIC_VECTOR(3 DOWNTO 0);
DATA_3 : OUT STD_LOGIC_VECTOR(3 DOWNTO 0);
DATA_4 : OUT STD_LOGIC_VECTOR(3 DOWNTO 0);
DATA_5 : OUT STD_LOGIC_VECTOR(3 DOWNTO 0);
DATA_6 : OUT STD_LOGIC_VECTOR(3 DOWNTO 0)
);
END;ARCHITECTURE ONE OF WNL IS
SIGNAL cnt : INTEGER RANGE 0 TO 3 := 0; -- 用于计数状态切换
BEGIN
PROCESS(CLK)
BEGIN
IF CLK'EVENT AND CLK='1' THEN
cnt <= cnt + 1;
IF cnt = 3 THEN -- 每三个时钟周期切换一次状态
cnt <= 0;
END IF;
END IF;
END PROCESS;
PROCESS(cnt)
begin
case cnt is
when 0 =>
DATA_1 <= QM(3 DOWNTO 0);
DATA_2 <= QM(7 DOWNTO 4);
DATA_3 <= QF(3 DOWNTO 0);
DATA_4 <= QF(7 DOWNTO 4);
DATA_5 <= QS(3 DOWNTO 0);
DATA_6 <= QS(7 DOWNTO 4);
WHEN 1 =>
DATA_1 <= QW(3 DOWNTO 0);
DATA_2 <= "0000";
DATA_3 <= QR(3 DOWNTO 0);
DATA_4 <= QR(7 DOWNTO 4);
DATA_5 <= QY(3 DOWNTO 0);
DATA_6 <= QY(7 DOWNTO 4);
WHEN 2 =>
DATA_4 <= QN(15 DOWNTO 12);
DATA_3 <= QN(11 DOWNTO 8);
DATA_2 <= QN(7 DOWNTO 4);
DATA_1 <= QN(3 DOWNTO 0);
DATA_5 <= "0000";
DATA_6 <= "0000";
WHEN 3 =>
DATA_1 <= QMB(3 DOWNTO 0);
DATA_2 <= QMB(7 DOWNTO 4);
DATA_3 <= QMBF(3 DOWNTO 0);
DATA_4 <= QMBF(7 DOWNTO 4);
DATA_5 <= "0000";
DATA_6 <= "0000";
END CASE;
END PROCESS;
END ARCHITECTURE ONE;
(四)其他功能
1、秒表
-- 功能 : 秒表计时
--*******************************************************************
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
--*******************************************************************
entity MB is
port (
-- STOP : in std_logic;
STAR : in std_logic;
CLR : in std_logic;
CLK : in std_logic;
TCN : out std_logic;--进位
CLR2 : out std_logic;--清零
Q : out std_logic_vector(7 downto 0)
);
end MB;
--*******************************************************************
architecture abc of MB is
signal QQ : std_logic_vector(7 downto 0);
signal c2 : std_logic;
beginprocess(CLK,CLR,STOP,STAR)
begin
IF STAR='1'THEN
IF CLR='1'THEN QQ<="00000000";c2<='1';
ELSif STOP='0'THEN
IF CLK'EVENT AND CLK='1' then
IF QQ >="01011001"
then QQ<="00000000";TCN<='1'; -- 计数到59时
ELSIF QQ(3 DOWNTO 0) >="1001" THEN
QQ(3 downto 0) <="0000"; -- 将低四位清零
QQ(7 downto 4) <=QQ(7 downto 4)+1; -- 高四位加一
else
QQ <=QQ+1; -- 否则正常加一
TCN<='0';
END IF;
end IF;
end if;
END IF;
end process;
CLR2 <= c2;
Q <= QQ; -- 输出信号
end abc;
2、节日
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;ENTITY JIERI IS
PORT (
EN : IN STD_LOGIC;
Y_IN : IN STD_LOGIC_VECTOR(7 DOWNTO 0);
R_IN : IN STD_LOGIC_VECTOR(7 DOWNTO 0);
TIME_ON : OUT STD_LOGIC -- 节日结果输出,当达到设定时间后输出高电平,且一直保持,直到关上闹钟开关
);
END JIERI;ARCHITECTURE Behavioral OF JIERI IS
BEGIN
PROCESS (EN, Y_IN, R_IN)
BEGIN
IF EN = '1' THEN -- 当节日开关打开时
IF ((R_IN = "00101001") AND (Y_IN = "00000010")) OR
((R_IN = "00100101") AND (Y_IN = "00010010")) OR
((R_IN = "00000001") AND (Y_IN = "00000110")) THEN
-- 检查是否为特定的时间点
TIME_ON <= '0'; -- 如果是设定的时间点,则输出高电平,表示触发
ELSE
TIME_ON <= '1'; -- 不是设定时间点,输出低电平
END IF;
ELSE
TIME_ON <= '1'; --关闭时,始终输出低电平
END IF;
END PROCESS;
END Behavioral;
3、闹钟
--闹钟
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;ENTITY NAOZHONG IS
PORT (
EN : IN STD_LOGIC; -- EN相当于闹钟开关,高电平打开
S_IN : IN STD_LOGIC_VECTOR(7 DOWNTO 0);
F_IN : IN STD_LOGIC_VECTOR(7 DOWNTO 0);
TIME_ON : OUT STD_LOGIC -- 闹钟结果输出,当达到设定时间后输出高电平,且一直保持,直到关上闹钟开关
);
END NAOZHONG;ARCHITECTURE Behavioral OF NAOZHONG IS
BEGIN
PROCESS (EN, S_IN, F_IN)
BEGIN
IF EN = '1' THEN -- 当闹钟开关打开时
IF ((S_IN = "00100011") AND (F_IN = "01011001")) OR
((S_IN = "00100001") AND (F_IN = "00010010")) OR
((S_IN = "00000001") AND (F_IN = "00000110")) THEN
-- 检查是否为特定的时间点
TIME_ON <= '1'; -- 如果是设定的时间点,则输出高电平,表示闹钟触发
ELSE
TIME_ON <= '0'; -- 不是设定时间点,输出低电平
END IF;
ELSE
TIME_ON <= '0'; -- 闹钟关闭时,始终输出低电平
END IF;
END PROCESS;
END Behavioral;
四、总体架构
以上就是所有,有其他问题可以私信或者在评论区发,我看到了就会回,演示视频在b站【基于fpga的数字万年历成果展示-哔哩哔哩】 https://b23.tv/BTH5XRh
全部项目:通过网盘分享的文件:FPGA万年历.zip
链接: https://pan.baidu.com/s/1_S4DO16g2B6ifID-WwZAnw?pwd=a9vx 提取码: a9vx