数字钟设计 用VHDL语言实现 你怎么做的
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
entity dongtai is
port(clk,rest:in std_logic;
seg,led:out std_logic_vector(7 downto 0));
end dongtai;
architecture action of dongtai is
signal counter,counter2,counter3,counter4,counter5,counter7,counter8,counter9:integer:=0;
signal counter1:std_logic_vector(7 downto 0);
begin
clock:process
variable tmp,tmp1,count,count2,count3,count4,count5,count7,count8,count9:integer:=0;
begin
wait until clk='1';
tmp:=tmp+1;
tmp1:=tmp1+1;
if(tmp1=50000000)then
count2:=count2+1;
counter2<=count2;
tmp1:=0;------111
if(count2=10)then
count2:=0;
count3:=count3+1;
counter3<=count3;---222
if(count3=6)then
count3:=0;
count4:=count4+1;
counter4<=count4;---444
if(count4=10)then
count4:=0;
count5:=count5+1;
counter5<=count5;---555
if(count5=6)then
count5:=0;
count7:=count7+1;
counter7<=count7;----777
if(count7=10)then
count7:=0;
count8:=count8+1;
counter8<=count8;----8888
if(count8>3)then
count8:=0;
end if;
end if;
end if;
end if;
end if;
end if;
end if;
if(count8=2 and count7=3 and count5=5 and count4=9 and count3=5 and count2=9 )then
tmp:=0;
tmp1:=0;
count:=0;
count2:=0;
count3:=0;
count4:=0;
count5:=0;
count7:=0;
count8:=0;
count9:=0;
counter<=0;
counter2<=0;
counter3<=0;
counter4<=0;
counter5<=0;
counter7<=0;
counter8<=0;
counter9<=0;
end if;
if(tmp=250)then
count:=count+1;
counter<=count;
tmp:=0;
if(count=8)then
count:=0;
end if;
end if;
end process clock;
scan:process(counter)
variable tmp:std_logic_vector(7 downto 0);
begin
case counter is
when 1=>tmp:="11111110";
when 2=>tmp:="11111101";
when 3=>tmp:="11111011";
when 4=>tmp:="11110111";
when 5=>tmp:="11101111";
when 6=>tmp:="11011111";
when 7=>tmp:="10111111";
when 8=>tmp:="01111111";
when others=>tmp:="11111111";
end case;
seg<=tmp;
counter1<=tmp;
end process scan;
yima:process(counter1,counter2,counter3,counter4,counter5,counter7,counter8)
variable tmp:std_logic_vector(7 downto 0);
begin
case counter1 is
when "11111110"=>
case counter2 is -------111
when 0 =>tmp:="11000000";
when 1 =>tmp:="11111001";
when 2 =>tmp:="10100100";
when 3 =>tmp:="10110000";
when 4 =>tmp:="10011001";
when 5 =>tmp:="10010010";
when 6 =>tmp:="10000010";
when 7 =>tmp:="11111000";
when 8 =>tmp:="10000000";
when 9 =>tmp:="10010000";
when others=>tmp:="11000000";
end case;
when "11111101"=>
case counter3 is -----222
when 0 =>tmp:="11000000";
when 1 =>tmp:="11111001";
when 2 =>tmp:="10100100";
when 3 =>tmp:="10110000";
when 4 =>tmp:="10011001";
when 5 =>tmp:="10010010";
when others=>tmp:="11000000";
end case;
when "11111011"=>
case counter2 is ----333
when 0 =>tmp:="11111111";
when 1 =>tmp:="10111111";
when 2 =>tmp:="11111111";
when 3 =>tmp:="10111111";
when 4 =>tmp:="11111111";
when 5 =>tmp:="10111111";
when 6 =>tmp:="11111111";
when 7 =>tmp:="10111111";
when 8 =>tmp:="11111111";
when 9 =>tmp:="10111111";
when others=>tmp:="11111111";
end case;
when "11110111"=>
case counter4 is ----444
when 0 =>tmp:="11000000";
when 1 =>tmp:="11111001";
when 2 =>tmp:="10100100";
when 3 =>tmp:="10110000";
when 4 =>tmp:="10011001";
when 5 =>tmp:="10010010";
when 6 =>tmp:="10000010";
when 7 =>tmp:="11111000";
when 8 =>tmp:="10000000";
when 9 =>tmp:="10010000";
when others=>tmp:="11000000";
end case;
when "11101111"=>
case counter5 is ----555
when 0 =>tmp:="11000000";
when 1 =>tmp:="11111001";
when 2 =>tmp:="10100100";
when 3 =>tmp:="10110000";
when 4 =>tmp:="10011001";
when 5 =>tmp:="10010010";
when others=>tmp:="11000000";
end case;
when "11011111"=>
case counter2 is ----666
when 0 =>tmp:="11111111";
when 1 =>tmp:="10111111";
when 2 =>tmp:="11111111";
when 3 =>tmp:="10111111";
when 4 =>tmp:="11111111";
when 5 =>tmp:="10111111";
when 6 =>tmp:="11111111";
when 7 =>tmp:="10111111";
when 8 =>tmp:="11111111";
when 9 =>tmp:="10111111";
when others=>tmp:="11111111";
end case;
when "10111111"=>
if(counter8<2)then
case counter7 is ----777
when 0 =>tmp:="11000000";
when 1 =>tmp:="11111001";
when 2 =>tmp:="10100100";
when 3 =>tmp:="10110000";
when 4 =>tmp:="10011001";
when 5 =>tmp:="10010010";
when 6 =>tmp:="10000010";
when 7 =>tmp:="11111000";
when 8 =>tmp:="10000000";
when 9 =>tmp:="10010000";
when others=>tmp:="11000000";
end case;
end if;
if(counter8=2)then
case counter7 is ----777
when 0 =>tmp:="11000000";
when 1 =>tmp:="11111001";
when 2 =>tmp:="10100100";
when 3 =>tmp:="10110000";
when others=>tmp:="11000000";
end case;
end if;
when "01111111"=>
case counter8 is ----888
when 0 =>tmp:="11000000";--0
when 1 =>tmp:="11111001";--1
when 2 =>tmp:="10100100";--2
when others=>tmp:="11000000";
end case;
when others=>tmp:="11111111";
end case;
led<=tmp;
end process yima;
end action;
比较长!但比较好理解吧!
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
--------------------------------------------------------------------
entity digital is
port( Clk : in std_logic; --时钟输入
Rst : in std_logic; --复位输入
S1,S2 : in std_logic; --时间调节输入
led : out std_logic_vector(3 downto 0); --整点输报时输出
spk : out std_logic;
Display : out std_logic_vector(6 downto 0); --七段码管显示输出
SEG_SEL : buffer std_logic_vector(2 downto 0) --七段码管扫描驱动
);
end digital;
--------------------------------------------------------------------
architecture behave of digital is
signal Disp_Temp : integer range 0 to 15;
signal Disp_Decode : std_logic_vector(6 downto 0);
signal SEC1,SEC10 : integer range 0 to 9;
signal MIN1,MIN10 : integer range 0 to 9;
signal HOUR1,HOUR10 : integer range 0 to 9;
signal Clk1kHz : std_logic;--数码管扫描时钟
signal Clk1Hz : std_logic;--时钟计时时钟
signal led_count : std_logic_vector(2 downto 0);
signal led_display : std_logic_vector(3 downto 0);
signal spkcout : std_logic;
begin
PROCESS(clk) --产生1hz信号
variable cnt : INTEGER RANGE 0 TO 49999999; --产生1Hz时钟的分频计数器
BEGIN
IF clk='1' AND clk'event THEN
IF cnt=49999999 THEN cnt:=0;
ELSE
IF cnt<25000000 THEN clk1hz<='1';
ELSE clk1hz<='0';
END IF;
cnt:=cnt+1;
END IF;
END IF;
end process;
PROCESS(clk) --产生1hz信号
variable cnt1 : INTEGER RANGE 0 TO 49999; --产生1KHz时钟的分频计数器
BEGIN
IF clk='1' AND clk'event THEN
IF cnt1=49999 THEN cnt1:=0;
ELSE
IF cnt1<25000 THEN clk1khz<='1';
ELSE clk1khz<='0';
END IF;
cnt1:=cnt1+1;
END IF;
END IF;
end process;
process(Clk1Hz,Rst)
begin
if(Rst='0') then --系统复位
SEC1<=0;
SEC10<=0;
MIN1<=0;
MIN10<=0;
HOUR1<=0;
HOUR10<=0;
elsif(Clk1Hz'event and Clk1Hz='1') then --正常运行
if(S1='0') then --调节小时
if(HOUR1=9) then
HOUR1<=0;
HOUR10<=HOUR10+1;
elsif(HOUR10=2 and HOUR1=3) then
HOUR1<=0;
HOUR10<=0;
else
HOUR1<=HOUR1+1;
end if;
elsif(S2='0') then --调节分钟
if(MIN1=9) then
MIN1<=0;
if(MIN10=5) then
MIN10<=0;
else
MIN10<=MIN10+1;
end if;
else
MIN1<=MIN1+1;
end if;
elsif(SEC1=9) then
SEC1<=0;
if(SEC10=5) then
SEC10<=0;
if(MIN1=9) then
MIN1<=0;
if(MIN10=5) then
MIN10<=0;
if(HOUR1=9) then
HOUR1<=0;
HOUR10<=HOUR10+1;
elsif(HOUR10=2 and HOUR1=3) then
HOUR1<=0;
HOUR10<=0;
else
HOUR1<=HOUR1+1;
end if;
else
MIN10<=MIN10+1;
end if;
else
MIN1<=MIN1+1;
end if;
else
SEC10<=SEC10+1;
end if;
else
SEC1<=SEC1+1;
end if;
end if;
end process;
process(Clk)--整点报时
begin
if(Clk1hz'event and Clk1hz='1') then
if(MIN10=5 and MIN1=9 and SEC10=5 and sec1>3) then --在59分55秒开始提示
led_Count<=led_Count+1; spkcout<=not spkcout;
else
led_count<="000";
spkcout<='0';
end if;
spk<=spkcout;
end if;
end process;
process(led_count)--整点报时LED灯的闪烁
begin
case (led_count) is
when "000"=>led_display<="0000";
when "001"=>led_display<="1111";
when "010"=>led_display<="0111";
when "011"=>led_display<="0011";
when "100"=>led_display<="0001";
when "101"=>led_display<="1111";
when others=>led_display<="0000";
end case;
led<=led_display;
end process;
process(SEG_SEL)
begin
case (SEG_SEL+1) is
when "111"=>Disp_Temp<=HOUR10;
when "110"=>Disp_Temp<=HOUR1;
when "101"=>Disp_Temp<=10;
when "100"=>Disp_Temp<=MIN10;
when "011"=>Disp_Temp<=MIN1;
when "010"=>Disp_Temp<=10;
when "001"=>Disp_Temp<=SEC10;
when "000"=>Disp_Temp<=SEC1;
end case;
end process;
process(Clk1khz)
begin
if(Clk1khz'event and Clk1khz='1') then --扫描累加
SEG_SEL<=SEG_SEL+1;
Display<=Disp_Decode;
end if;
end process;
process(Disp_Temp) --显示转换
begin
case Disp_Temp is
when 0=>Disp_Decode<="0111111"; --0
when 1=>Disp_Decode<="0000110"; --1
when 2=>Disp_Decode<="1011011"; --2
when 3=>Disp_Decode<="1001111"; --3
when 4=>Disp_Decode<="1100110"; --4
when 5=>Disp_Decode<="1101101"; --5
when 6=>Disp_Decode<="1111101"; --6
when 7=>Disp_Decode<="0000111"; --7
when 8=>Disp_Decode<="1111111"; --8
when 9=>Disp_Decode<="1101111"; --9
when 10=>Disp_Decode<="1000000"; ---
when others=>Disp_Decode<="0000000"; --全灭
end case;
end process;
end behave;
源代码如下 自己把各个模块打好包 下面有个图 自己看看
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY TZKZQ IS
PORT(KEY: IN STD_LOGIC_VECTOR(1 DOWNTO 0); --按键信号
CLK_KEY: IN STD_LOGIC; --键盘扫描信号
MAX_DAYS:IN STD_LOGIC_VECTOR(4 DOWNTO 0); --本月最大天数
SEC_EN,MIN_EN,HOUR_EN,DAY_EN,MON_EN,YEAR_EN,WEEK_EN:OUT STD_LOGIC; --异步并行置位使能
HOUR_CUR:IN STD_LOGIC_VECTOR(4 DOWNTO 0);
MIN_CUR,SEC_CUR:IN STD_LOGIC_VECTOR(5 DOWNTO 0);
YEAR_CUR:IN STD_LOGIC_VECTOR(6 DOWNTO 0);
MON_CUR :IN STD_LOGIC_VECTOR(3 DOWNTO 0);
DAY_CUR :IN STD_LOGIC_VECTOR(4 DOWNTO 0);
WEEK_CUR:IN STD_LOGIC_VECTOR(2 DOWNTO 0);
SEC,MIN:BUFFER STD_LOGIC_VECTOR(5 DOWNTO 0);
HOUR:BUFFER STD_LOGIC_VECTOR(4 DOWNTO 0);
DAY :BUFFER STD_LOGIC_VECTOR(4 DOWNTO 0);
MON :BUFFER STD_LOGIC_VECTOR(3 DOWNTO 0);
YEAR:BUFFER STD_LOGIC_VECTOR(6 DOWNTO 0);
WEEK:BUFFER STD_LOGIC_VECTOR(2 DOWNTO 0));
END ENTITY TZKZQ;
ARCHITECTURE ART OF TZKZQ IS
TYPE STATETYPE IS (NORMAL,SEC_SET,MIN_SET,HOUR_SET,DAY_SET,MON_SET,
YEAR_SET,WEEK_SET);
SIGNAL MODE:STATETYPE;
BEGIN
PROCESS(KEY,CLK_KEY)
BEGIN
IF CLK_KEY'EVENT AND CLK_KEY='1' THEN
IF KEY="01" THEN
SEC_EN<='1';MIN_EN<='1';HOUR_EN<='1';
DAY_EN<='1';MON_EN<='1';YEAR_EN<='1';
WEEK_EN<='1';
CASE MODE IS
WHEN NORMAL => MODE<=SEC_SET;SEC<=SEC_CUR;SEC_EN<='0';
WHEN SEC_SET => MODE<=MIN_SET;MIN<=MIN_CUR;SEC_EN<='1';MIN_EN<='0';
WHEN MIN_SET => MODE<=HOUR_SET;HOUR<=HOUR_CUR;MIN_EN<='1';HOUR_EN<='0';
WHEN HOUR_SET=> MODE<=DAY_SET;DAY<=DAY_CUR;HOUR_EN<='1';DAY_EN<='0';
WHEN DAY_SET => MODE<=MON_SET;MON<=MON_CUR;DAY_EN<='1';MON_EN<='0';
WHEN MON_SET => MODE<=YEAR_SET;YEAR<=YEAR_CUR; MON_EN<='1';
YEAR_EN<='0';
WHEN YEAR_SET => MODE<=WEEK_SET;WEEK<=WEEK_CUR;YEAR_EN<='1';WEEK_EN<='0';
WHEN WEEK_SET => MODE<=NORMAL;
END CASE;
ELSIF KEY="10" THEN --如果按下调整键,则自加
CASE MODE IS
WHEN SEC_SET => SEC_EN<='0';
--异步并行置位使能有效
IF SEC="111011" THEN SEC<="000000";
--如果秒计数到59,返回到0重新计数
ELSE SEC<=SEC+1; --否则继续计数
END IF;
WHEN MIN_SET => MIN_EN<='0';
IF MIN="111011" THEN MIN<="000000";
ELSE MIN<=MIN+1;
END IF;
WHEN HOUR_SET=> HOUR_EN<='0';
IF HOUR="11000" THEN HOUR<="00000";
ELSE HOUR<=HOUR+1;
END IF;
WHEN DAY_SET => DAY_EN<='0';
IF DAY=MAX_DAYS THEN DAY<="00001";
ELSE DAY<=DAY+1;
END IF;
WHEN WEEK_SET=> WEEK_EN<='0';
IF WEEK="111" THEN WEEK<="001";
ELSE WEEK<=WEEK+1;
END IF;
WHEN OTHERS=>NULL;
END CASE;
END IF;
END IF;
END PROCESS;
END ARCHITECTURE ART;
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY CNT60 IS
PORT(LD: IN STD_LOGIC;
CLK: IN STD_LOGIC;
DATA: IN STD_LOGIC_VECTOR(5 DOWNTO 0);
NUM: BUFFER STD_LOGIC_VECTOR(5 DOWNTO 0);
CO: OUT STD_LOGIC);
END ENTITY CNT60;
ARCHITECTURE ART OF CNT60 IS
BEGIN
PROCESS(CLK,LD) IS
BEGIN
IF(LD='0') THEN
NUM<=DATA;
ELSIF CLK'EVENT AND CLK='1' THEN
IF NUM="111011" THEN --59
NUM<="000000";CO<='1';
ELSE
NUM<=NUM+1;CO<='0';
END IF;
END IF;
END PROCESS;
END ARCHITECTURE ART;
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY CNT60 IS
PORT(LD: IN STD_LOGIC;
CLK: IN STD_LOGIC;
DATA: IN STD_LOGIC_VECTOR(5 DOWNTO 0);
NUM: BUFFER STD_LOGIC_VECTOR(5 DOWNTO 0);
CO: OUT STD_LOGIC);
END ENTITY CNT60;
ARCHITECTURE ART OF CNT60 IS
BEGIN
PROCESS(CLK,LD) IS
BEGIN
IF(LD='0') THEN
NUM<=DATA;
ELSIF CLK'EVENT AND CLK='1' THEN
IF NUM="111011" THEN --59
NUM<="000000";CO<='1';
ELSE
NUM<=NUM+1;CO<='0';
END IF;
END IF;
END PROCESS;
END ARCHITECTURE ART;
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY CNT24 IS
PORT(LD: IN STD_LOGIC;
CLK: IN STD_LOGIC;
DATA: IN STD_LOGIC_VECTOR(4 DOWNTO 0);
NUM: BUFFER STD_LOGIC_VECTOR(4 DOWNTO 0);
CO: OUT STD_LOGIC);
END ENTITY CNT24;
ARCHITECTURE ART OF CNT24 IS
BEGIN
PROCESS(CLK,LD) IS
BEGIN
IF(LD='0') THEN
NUM<=DATA;
ELSIF CLK'EVENT AND CLK='1' THEN
IF NUM="11000" THEN --24
NUM<="00000";CO<='1';
ELSE
NUM<=NUM+1;CO<='0';
END IF;
END IF;
END PROCESS;
END ARCHITECTURE ART;
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY CNT30 IS
PORT(LD:IN STD_LOGIC;
CLK:IN STD_LOGIC;
NIAN:IN STD_LOGIC_VECTOR(6 DOWNTO 0);
YUE :IN STD_LOGIC_VECTOR(3 DOWNTO 0);
DATA:IN STD_LOGIC_VECTOR(4 DOWNTO 0);
NUM:BUFFER STD_LOGIC_VECTOR(4 DOWNTO 0);
MAX_DAYS:OUT STD_LOGIC_VECTOR(4 DOWNTO 0);
CO:OUT STD_LOGIC);
END ENTITY CNT30;
ARCHITECTURE ART OF CNT30 IS
SIGNAL TOTAL_DAYS:STD_LOGIC_VECTOR(4 DOWNTO 0);
BEGIN
PROCESS(CLK,LD) IS
VARIABLE IS_RUNNIAN:STD_LOGIC;
BEGIN
CASE NIAN IS
WHEN "0000000" => IS_RUNNIAN:='1'; --0
WHEN "0000100" => IS_RUNNIAN:='1'; --4
WHEN "0001000" => IS_RUNNIAN:='1'; --8
WHEN "0001100" => IS_RUNNIAN:='1'; --12
WHEN "0010000" => IS_RUNNIAN:='1'; --16
WHEN "0010100" => IS_RUNNIAN:='1'; --20
WHEN "0011000" => IS_RUNNIAN:='1'; --24
WHEN "0011100" => IS_RUNNIAN:='1'; --28
WHEN "0100000" => IS_RUNNIAN:='1'; --32
WHEN "0100100" => IS_RUNNIAN:='1'; --36
WHEN "0101000" => IS_RUNNIAN:='1'; --40
WHEN "0101100" => IS_RUNNIAN:='1'; --44
WHEN "0110000" => IS_RUNNIAN:='1'; --48
WHEN "0110100" => IS_RUNNIAN:='1'; --52
WHEN "0111000" => IS_RUNNIAN:='1'; --56
WHEN "0111100" => IS_RUNNIAN:='1'; --60
WHEN "1000000" => IS_RUNNIAN:='1'; --64
WHEN "1000100" => IS_RUNNIAN:='1'; --68
WHEN "1001000" => IS_RUNNIAN:='1'; --72
WHEN "1001100" => IS_RUNNIAN:='1'; --76
WHEN "1010000" => IS_RUNNIAN:='1'; --80
WHEN "1010100" => IS_RUNNIAN:='1'; --84
WHEN "1011000" => IS_RUNNIAN:='1'; --88
WHEN "1011100" => IS_RUNNIAN:='1'; --92
WHEN "1100000" => IS_RUNNIAN:='1'; --96
WHEN OTHERS => IS_RUNNIAN:='0';
END CASE;
CASE YUE IS
WHEN "0001" => TOTAL_DAYS<="11111"; --1
WHEN "0011" => TOTAL_DAYS<="11111"; --3
WHEN "0101" => TOTAL_DAYS<="11111"; --5
WHEN "0111" => TOTAL_DAYS<="11111"; --7
WHEN "1000" => TOTAL_DAYS<="11111"; --8
WHEN "1010" => TOTAL_DAYS<="11111"; --10
WHEN "1100" => TOTAL_DAYS<="11111"; --12
WHEN "0100" => TOTAL_DAYS<="11110"; --4
WHEN "0110" => TOTAL_DAYS<="11110"; --6
WHEN "1001" => TOTAL_DAYS<="11110"; --9
WHEN "1011" => TOTAL_DAYS<="11110"; --11
WHEN "0010" =>
IF (IS_RUNNIAN='1') THEN
TOTAL_DAYS<="11101";
ELSE
TOTAL_DAYS<="11100";
END IF;
WHEN OTHERS=>NULL;
END CASE;
IF(LD='0') THEN
NUM<=DATA;
ELSIF CLK'EVENT AND CLK='1' THEN
MAX_DAYS<=TOTAL_DAYS;
IF NUM=TOTAL_DAYS THEN --99
NUM<="00001";CO<='1';
ELSE
NUM<=NUM+1;CO<='0';
END IF;
END IF;
END PROCESS;
END ARCHITECTURE ART;
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY CNT7 IS
PORT(LD: IN STD_LOGIC;
CLK: IN STD_LOGIC;
DATA: IN STD_LOGIC_VECTOR(2 DOWNTO 0);
NUM: BUFFER STD_LOGIC_VECTOR(2 DOWNTO 0));
END ENTITY CNT7;
ARCHITECTURE ART OF CNT7 IS
BEGIN
PROCESS(CLK,LD) IS
BEGIN
IF(LD='0') THEN
NUM<=DATA;
ELSIF CLK'EVENT AND CLK='1' THEN
IF NUM="111" THEN --7
NUM<="000";
ELSE
NUM<=NUM+1;
END IF;
END IF;
END PROCESS;
END ARCHITECTURE ART;
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY CNT12 IS
PORT(LD: IN STD_LOGIC;
CLK: IN STD_LOGIC;
DATA: IN STD_LOGIC_VECTOR(3 DOWNTO 0);
NUM: BUFFER STD_LOGIC_VECTOR(3 DOWNTO 0);
CO: OUT STD_LOGIC);
END ENTITY CNT12;
ARCHITECTURE ART OF CNT12 IS
BEGIN
PROCESS(CLK,LD) IS
BEGIN
IF(LD='0') THEN
NUM<=DATA;
ELSIF CLK'EVENT AND CLK='1' THEN
IF NUM="1100" THEN --12
NUM<="0000";CO<='1';
ELSE
NUM<=NUM+1;CO<='0';
END IF;
END IF;
END PROCESS;
END ARCHITECTURE ART;
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY CNT99 IS
PORT(LD: IN STD_LOGIC;
CLK: IN STD_LOGIC;
DATA: IN STD_LOGIC_VECTOR(6 DOWNTO 0);
NUM: BUFFER STD_LOGIC_VECTOR(6 DOWNTO 0));
END ENTITY CNT99;
ARCHITECTURE ART OF CNT99 IS
BEGIN
PROCESS(CLK,LD) IS
BEGIN
IF(LD='0') THEN
NUM<=DATA;
ELSIF CLK'EVENT AND CLK='1' THEN
IF NUM="1100011" THEN --12
NUM<="0000000";
ELSE
NUM<=NUM+1;
END IF;
END IF;
END PROCESS;
END ARCHITECTURE ART;
EDA设计——多功能数字钟
由于实验室cpld芯片为 ACEC1K EP1K10TC100-3 内部资源不是很丰富,故设计时应考虑节省系统资源开销,采用原理图互联,自顶向下方式设计方便快捷、可读性好,但芯片之间互联必然会增加系统内部数据寄存器。故在设计之初,就考虑到用编程方法实现。本设计采用VHDL语言编写, 整个系统共用一个程序语言描述,在最大程度上 实现了数据的共用。经过最后编译,调试,下载测试完成后,达到了实验要求
电路接口:
alarm——蜂鸣器接口
row[3,2,1,0]——矩阵键盘行
col[3,2,1,0]——矩阵键盘列
sel[2,1,0]——数码管为选接口
sg[6,5,4,3,2,1,0]——数码管断码接口
clk——接1024hz信号
代码如下
VhdL代码及解释:
library ieee;
use ieee.std_logic_1164.all ;
use ieee.std_logic_unsigned.all;
entity eda_clk9 is
port( clk : in std_logic ;--时钟输入
alarm : out std_logic;--闹钟输出
row : inout std_logic_vector(3 downto 0);--矩阵键盘行输入
col : inout std_logic_vector(3 downto 0);--矩阵键盘列输出
sel : out std_logic_vector(2 downto 0);--显示位选码输出
sg : out std_logic_vector(6 downto 0));--显示段码输出
end entity eda_clk9;
architecture one of eda_clk9 is
signal clk_1:std_logic ;--500hz信号
signal clk_2:std_logic ;--100hz信号
signal alarm_flag :std_logic ;--闹钟标志位
signal stat : std_logic_vector(2 downto 0) ;--状态标志向量
signal buff0,buff1,buff2,buff3,buff4,buff5,buff6,buff7 :
std_logic_vector(3 downto 0);--显示缓冲
signal input0,input1,input2,input3,input4,input5 :
std_logic_vector(3 downto 0);--输入缓冲
signal keyr,keyc : std_logic_vector(3 downto 0);--键盘行列缓存
signal kcount : std_logic_vector(2 downto 0);--键盘程序计数
signal kflag1,kflag2 : std_logic;--键盘标志信号
signal key_val : std_logic_vector(3 downto 0) ;--键盘缓存
signal kf : std_logic ;--键值赋值标志
signal keyflag : std_logic ;--按键信号
signal input_n : integer range 7 downto 0;--输入计数
signal dis_word : std_logic_vector(3 downto 0);--显示缓存
signal dis_n : std_logic_vector(2 downto 0);--显示计数
signal clk_count: std_logic_vector(8 downto 0);--时钟计数
signal fp500 : std_logic_vector(4 downto 0);--500hz分频中介变量
signal fp100 : std_logic_vector(6 downto 0);--100hz分频中介变量
signal clk_sec_1 : std_logic_vector(3 downto 0);--时钟各位
signal clk_sec_2 : std_logic_vector(3 downto 0);
signal clk_min_1 : std_logic_vector(3 downto 0);
signal clk_min_2 : std_logic_vector(3 downto 0);
signal clk_hou_1 : std_logic_vector(3 downto 0);
signal clk_hou_2 : std_logic_vector(3 downto 0);
signal alarm_sec_1 : std_logic_vector(3 downto 0);--闹钟各位
signal alarm_sec_2 : std_logic_vector(3 downto 0);
signal alarm_min_1 : std_logic_vector(3 downto 0);
signal alarm_min_2 : std_logic_vector(3 downto 0);
signal alarm_hou_1 : std_logic_vector(3 downto 0);
signal alarm_hou_2 : std_logic_vector(3 downto 0);
signal stop_mil_1 : std_logic_vector(3 downto 0);--秒表各位
signal stop_mil_2 : std_logic_vector(3 downto 0);
signal stop_sec_1 : std_logic_vector(3 downto 0);
signal stop_sec_2 : std_logic_vector(3 downto 0);
signal stop_min_1 : std_logic_vector(3 downto 0);
signal stop_min_2 : std_logic_vector(3 downto 0);
signal stop_fg : std_logic ;
begin
input_1 : process(clk_1) --记录按键过程中时间
begin
if(clk_1'event and clk_1='1')
then kcount<=kcount+1;--上升沿加一
end if;
end process input_1;
input_2 : process(clk_1) --两次扫描键盘判断是否按键
begin
if(clk_1'event and clk_1='1') then--上升沿触发
if(kcount=0) then
row<="1111";--全盘扫描
col<="0000";
elsif(kcount=1) then
keyr<=row;--读行扫描信号
elsif(kcount=2) then
row<="0000";--再次扫描
col<="1111";
elsif(kcount=3) then
keyc<=col;--读列三秒信号
end if;
end if;
end process input_2;
input_3: process(clk_1) --设置按键标志位
begin
if(clk_1'event and clk_1='1') then--上升沿触发
if(kcount=4 and keyr="1111") then--第四时钟,无按键
kflag1<='0';--清标志位
elsif(kcount=4) then
kflag1<='1';--置标值为
end if;
kflag2<=kflag1;--缓存
end if;
end process input_3;
input_4 : process(clk_1) --判断按键,计算键码,设置按键信号
variable temp : std_logic_vector(3 downto 0) ;--定义中间计算缓存变量
begin
if(clk_1'event and clk_1='1') then
if(kcount=5 and kflag1='1' and kflag2='0') then --有按键
temp:= "0000" ;--计算缓存清零
case keyc is--键盘行值
when "1110" => temp :=temp ;
when "1101" => temp :=temp + 1;
when "1011" => temp :=temp + 2;
when "0111" => temp :=temp + 3;
when others =>null;
end case;
case keyr is--键盘列值
when "1110" => temp:=temp ;
when "1101" => temp:=temp+4;
when "1011" => temp:=temp+8;
when "0111" => temp:=temp+12;
when others => null;
end case;
kf <= '1';--置按键信号为
key_val<=temp;
else kf <= '0';--清按键信号为
end if;
if kf = '1'--按键成功赋值后产生一按键标志脉冲keyflag
then keyflag <= '1' ;
kf <='0';
else keyflag <= '0';
end if;
end if;
end process input_4 ;
input_5: process(keyflag) --循环六次来输入时间,闹钟初值
begin
if keyflag'event and (keyflag = '1') then
if stat(1) = '1' and key_val <10 then--判断为按键状态,且按键为数值键
input_n<=input_n+1;
case input_n is--分别对应输入次数存入不同的输入缓冲
when 0 => input0<=key_val;
when 1 => input1<=key_val;
when 2 => input2<=key_val;
when 3 => input3<=key_val;
when 4 => input4<=key_val;
when 5 => input5<=key_val;
when others => input_n <= 0;--为下次输入做准备
end case;
else input_n <= 0 ;--为输入做准备
input0 <= "1011" ;--显示“--------”
input1 <= "1011" ;
input2 <= "1011" ;
input3 <= "1011" ;
input4 <= "1011" ;
input5 <= "1011" ;
end if;
end if;
end process input_5 ;
dis_1 : process(clk_1)--此进程为显示buff0~7的值在数码管上,显示方式为逐位扫描显示。
variable dis_word : std_logic_vector(3 downto 0);
begin
if clk_1'event and clk_1 = '1' then --上升沿触发
dis_n <= dis_n +1 ; --下一次显示下一位数码
case dis_n is --根据显示位数取对应的位的数值
when "000" => dis_word := buff0 ;
when "001" => dis_word := buff1 ;
when "010" => dis_word := buff2 ;
when "011" => dis_word := buff3 ;
when "100" => dis_word := buff4 ;
when "101" => dis_word := buff5 ;
when "110" => dis_word := buff6 ;
when "111" => dis_word := buff7 ;
when others => null ;
end case ;
sel <= dis_n;--送出按位显示的位选信号
case dis_word is--对应数值译码
when "0000" => sg <= "0111111";
when "0001" => sg <= "0000110";
when "0010" => sg <= "1011011";
when "0011" => sg <= "1001111";
when "0100" => sg <= "1100110";
when "0101" => sg <= "1101101";
when "0110" => sg <= "1111101";
when "0111" => sg <= "0000111";
when "1000" => sg <= "1111111";
when "1001" => sg <= "1101111";
when "1010" => sg <= "1110111";
when "1011" => sg <= "1000000";
when "1100" => sg <= "0111001";
when "1101" => sg <= "1011110";
when "1110" => sg <= "1111001";
when "1111" => sg <= "1110001";
when others =>null;
end case ;
end if;
end process dis_1;
dis_2 : process (stat) --根据系统状态显示不同的内容
begin
case stat is
when "000" =>--显示时间状态
buff7 <= clk_sec_1;
buff6 <= clk_sec_2;
buff4 <= clk_min_1;
buff3 <= clk_min_2;
buff1 <= clk_hou_1;
buff0 <= clk_hou_2;
buff2 <= "1011";
buff5 <= "1011";
when "001" =>--显示闹钟状态
buff7 <= alarm_sec_1;
buff6 <= alarm_sec_2;
buff4 <= alarm_min_1;
buff3 <= alarm_min_2;
buff1 <= alarm_hou_1;
buff0 <= alarm_hou_2;
buff2 <= "1011";
buff5 <= "1011";
when "010" |"011" =>--输入状态显示
buff7 <= input5;
buff6 <= input4;
buff4 <= input3;
buff3 <= input2;
buff1 <= input1;
buff0 <= input0;
when "100" =>--秒表显示状态
buff7 <= stop_mil_1;
buff6 <= stop_mil_2;
buff4 <= stop_sec_1;
buff3 <= stop_sec_2;
buff1 <= stop_min_1;
buff0 <= stop_min_2;
buff2 <= "1011";
buff5 <= "1011";
when others => null ;
end case ;
end process dis_2;
clock:process (clk_1)--时钟进程
begin
if clk_1'event and clk_1='1' then --上升沿触发
if clk_count = 500 --500hz分频后得1hz
then clk_count <= "000000000";
else clk_count <= clk_count + 1;
end if;
if stat = "010" and input_n >5 then --若在调时状态,且输入5次后
clk_hou_2 <= input0 ;--将输入缓冲中的值放如计时初值中
clk_hou_1 <= input1 ;
clk_min_2 <= input2 ;
clk_min_1 <= input3 ;
clk_sec_2 <= input4 ;
clk_sec_1 <= input5 ;
elsif clk_count = 0 then --达到一秒后,秒位加一
clk_sec_1 <= clk_sec_1 + 1;
elsif clk_sec_1 = "1010" then --如果秒位为10清零
clk_sec_1 <= "0000";
clk_sec_2 <= clk_sec_2 +1 ; --同时秒的十位加一
elsif clk_sec_2 = "0110" then --如果秒十位为6
clk_min_1 <= clk_min_1 +1; --分钟个位加一
clk_sec_2 <= "0000";
elsif clk_min_1 = "1010" then --分个位为10时清零
clk_min_1 <= "0000";
clk_min_2 <= clk_min_2 +1 ; --分十位加一
elsif clk_min_2 = "0110" then --分十位为6时
clk_hou_1 <= clk_hou_1 +1; --小时个位加一
clk_min_2 <= "0000"; --分钟十为清零
elsif clk_hou_1 = "1010" then --小时个位为10清零
clk_hou_1 <= "0000";
clk_hou_2 <= clk_min_2 +1 ; --小时十为加一
elsif clk_hou_2 = "0010" and clk_hou_1 = "0100" then--达到24点时小时清零
clk_hou_1 <= "0000";
clk_hou_2 <= "0000";
elsif (clk_sec_2 > 5) or (clk_min_2 > 5) or (clk_hou_2 > 2) or ( (clk_hou_2 = 2 )and (clk_hou_1 > 3))
then clk_sec_1 <= "0000"; --设定时间非法时,设置为默认时间初值00:00:00
clk_sec_2 <= "0000";
clk_min_1 <= "0000";
clk_min_2 <= "0000";
clk_hou_1 <= "0000";
clk_hou_2 <= "0000";
end if;
end if;
end process clock;
naozhong_1 : process (clk_sec_1)
begin
if (clk_sec_1 = alarm_sec_1) and (clk_sec_2 = alarm_sec_2) and (clk_min_1 = alarm_min_1) and (clk_min_2 = alarm_min_2) and (clk_hou_1 = alarm_hou_1) and (clk_hou_2 = alarm_hou_2)
then alarm_flag <='1'; --时间到达闹钟时置闹钟位
elsif key_val = "1111" then --按闹钟设定15号键时关闭闹钟
alarm_flag <= '0';
end if;
end process naozhong_1 ;
naozhong_2 :process (clk_1)
begin--闹钟鸣叫进程
if alarm_flag = '1' then --没按关闭键
if clk_count < 200 then --长鸣
alarm <= '1';
elsif clk_count <300 then
alarm <= '0';
elsif clk_count <350 then--短鸣
alarm <= '1';
elsif clk_count <400 then
alarm <= '0';
elsif clk_count <450 then--短鸣
alarm <= '1';
else alarm <= '0';
end if;
else alarm <= '0';
end if;
end process naozhong_2 ;
main : process(keyflag)
begin--主控状态进程
if keyflag'event and keyflag = '1' then--有按键就触发
if input_n >5 then
stat <= "000" ; --若按键达到5次,则必从设定状态返回到时间显示状态
else case key_val is
when "1011" => stop_fg <= not (stop_fg) ; --秒表操作
when "1100" => stat <= "000"; -- 显示时间
when "1101" => stat <= "001"; -- 显示闹钟
when "1110" => stat <= "010"; -- 设定时间
when "1111" => stat <= "011"; -- 设定闹钟
when "1010" => stat <= "100"; -- 开启秒表
when others => null;
end case;
end if;
if stat = "011" and input_n >5 then --闹钟设定赋输入的初值
alarm_hou_2 <= input0 ;
alarm_hou_1 <= input1 ;
alarm_min_2 <= input2 ;
alarm_min_1 <= input3 ;
alarm_sec_2 <= input4 ;
alarm_sec_1 <= input5 ;
elsif (alarm_sec_2 > 5) or (alarm_min_2 > 5) or (alarm_hou_2 > 2) or ( (alarm_hou_2 = 2 )and (alarm_hou_1 > 3))
then alarm_hou_2 <= "0000"; --设定闹钟的时间非法时清零
alarm_hou_1 <= "0000";
alarm_min_2 <= "0000";
alarm_min_1 <= "0000";
alarm_sec_2 <= "0000";
alarm_sec_1 <= "0000";
end if;
end if;
end process main;
fengping : process (clk)
begin --12khz的时钟分频
if clk'event and clk = '1' then
if fp500 ="10111" then --计算为24 = 11000
fp500 <= "00000"; --500hz分频
clk_1 <= '1';
else
fp500 <= fp500 + 1;
clk_1 <= '0';
end if;
if fp100 = "1101001" then --计算为1201 = 1111000
fp100 <= "0000000"; --100hz分频
clk_2 <= '1';
else
fp100 <=fp100 + 1;
clk_2 <= '0';
end if;
end if;
end process fengping ;
stop : process (clk_2)
begin --秒表进程
if clk_2'event and (clk_2 = '1') then --上升沿触发
if stop_fg = '1' and stat(2) = '1' then--按键开始且为秒表状态
if stop_mil_1 = "1010" then--毫秒个位为10时清零
stop_mil_1 <= "0000" ;
else stop_mil_1 <= stop_mil_1 + 1;--否则加一
end if;
if stop_mil_2 = "1010" then--毫秒十位为10时清零
stop_mil_2 <= "0000";
elsif stop_mil_1 = "1010" then--由于信号延迟,毫秒个位为10时进位
stop_mil_2 <= stop_mil_2 + 1;
end if;
if stop_sec_1 = "1010" then--秒进位
stop_sec_1 <= "0000" ;
elsif stop_mil_2 = "1010" then
stop_sec_1 <= stop_sec_1 + 1;
end if;
if stop_sec_2 = "0110" then
stop_sec_2 <= "0000" ;
elsif stop_sec_1 = "1010" then
stop_sec_2 <= stop_sec_2 + 1;
end if;
if stop_min_1 = "1010" then--分进位
stop_min_1 <= "0000" ;
elsif stop_sec_2 = "1010" then
stop_min_1 <= stop_min_1 + 1;
end if;
if stop_min_2 = "1010" then
stop_min_2 <= "0000" ;
elsif stop_min_1 = "1010" then
stop_min_2 <= stop_min_2 + 1;
end if;
elsif not (stat(2) = '1') then--如果为其他状态各位清零
stop_mil_1 <= "0000";
stop_mil_2 <= "0000";
stop_sec_1 <= "0000";
stop_sec_2 <= "0000";
stop_min_1 <= "0000";
stop_min_2 <= "0000";
end if;
end if;
end process stop ;
end architecture one;
参考文献:
1.EDA技术实用教程.潘松、黄继业主编.科学出版社.2002
是设置初始时钟吗,有一个CLK的引脚可以用.
言炭尤诺: library ieee;use ieee.std_logic_1164.all;use ieee.std_logic_arith.all;use ieee.std_logic_unsigned.all;entity...
无极县13076058214: 用VHDL语言设计一个电子时钟 - ?
言炭尤诺: library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; entity shuzizhong is port(clk,,clk1,set,change,s1,s2,s3:in std_logic; second1,second2,minite1,minite2,hour1,hour2:out std_logic_vector(3 downto 0); Light:out std_logic_vector...
无极县13076058214: VHDL电子时钟设计 - ?
言炭尤诺: 基于CPLD的VHDL语言数字钟(含秒表)设计 利用一块芯片完成除时钟源、按键、扬声器和显示器(数码管)之外的所有数字电路功能.所有数字逻辑功能都在CPLD器件上用VHDL语言实现.这样设计具有...
无极县13076058214: 用VHDL语言设计一个12小时数字钟,用数码管现实时分秒,实现整点报时功能?
言炭尤诺: 一个12进制计数器+一个60进制计数器+一个60进制计数器 当分/秒计数器输出达到整点报时状态是输出报时信号. 如果要代码的话,找我Q Q 聊
无极县13076058214: 急急急急急急!!!!!有会用VHDL语言实现数字钟的...帮忙!!!!!!!! - ?
言炭尤诺: 这个很简单,我有现成的工程,你只要重新锁定管教即可.需要的话 留个q 传你
无极县13076058214: 高分求 基于VHDL语言设计的数字时钟 - ?
言炭尤诺: -------------------程序(.vhd文件)如下--------------------------- library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; ---- Uncomment the following library declaration if instantiating ...
无极县13076058214: 基于VHDL语言的数字钟的层次化设计 - ?
言炭尤诺: 此数字钟是以24小时制记时,当到整点时会报时一分钟,按下清零键时也会报时一分钟.主要元件有计数器,分频器,报时器,选择器和译码器等.控制逻辑主要是用来实现计数和清零.基本方框图如下:留下邮箱,给你把正文发过去.
无极县13076058214: 急:EDA用VHDL语言设计多功能数字时钟...要求外加控制信号1HZ,可整点报时.?
言炭尤诺: 用一个计50000的计数器,当计数器为0的时候,计数器为50000,输出反向. 那么输出就是1Hz
无极县13076058214: 急!!!在QUARTUS II中使用VHDL语言设计分为时、分、秒三个模块的数字钟 - ?
言炭尤诺: 这个跟三个VHDL文件没有关系.你建立波形文件后需要再次编译,如果没有成功继续编译.还是只有一个模块,你把你总的实现功能,就是用到元件例化的那个vhdl设置为顶层文件试一试,再编译一次.
无极县13076058214: 基于FPGA技术的数字时钟万年历设计 - ?
言炭尤诺: 【实验目的】: 设计一个24小时制数字钟,要求能显示时,分,秒,并且可以手动调整时和分 【试验中所用器材】: 开发环境MAX—PLUSII,ZY11EDA13BE 试验系统, VHDL 语言. 【设计原理】 数字钟的主体是计数器,它记录并显示接收到...