输入时钟信号为1KHz,所以首先使用分频器进行分频处理。
然后让数码管显示倒计时。
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
--因为实验箱的LED只有红和绿,所以黄灯就让红绿灯一起亮
Entity StreetLamp is
port(clk :in std_logic;
L1 : out std_logic_vector(1 downto 0);--东西方向灯
L2 : out std_logic_vector(1 downto 0);--南北方向灯
DS : out std_logic_vector(7 downto 0);--段选
WS : out std_logic_vector(7 downto 0)--位选
);
end StreetLamp;
architecture one of StreetLamp is
type FSM is (s0,s1,s2,s3,s4,s5,s6);
signal cst,next_state:FSM;
signal count,count1 : integer range 0 to 999;--输入1KHz,时钟为1MS,则通过计数将时钟转为1S
signal clk1,clk2 : std_logic;
signal cnt:integer:=0;
signal tmp,tmp1 ,data: std_logic_vector(7 downto 0);
signal sum : integer range 0 to 99;
begin
process(CLK)
begin
if clk'event and clk ='1' then
if count1 =4 then --用来给数码管扫描4ms
count1 <= 0;
clk2 <= '1';
else
count1 <= count1 + 1;
clk2 <= '0';
end if;
if count = 999 then
count <= 0;
sum <= sum +1;
if sum = 80 then
sum <= 0;
end if;
clk1 <= '1';--时钟频率为1Hz
else
count <= count + 1;
clk1 <= '0';
end if;
end if;
end process;
REG:process (clk1,sum)
begin
if clk1'event and clk1 = '1' then
cst <= next_state;
end if;
end process REG;
COM:process (cst,sum)
variable t1,t2,t3 : std_logic_vector(7 downto 0);
begin
case cst is
when s0 => L1 <= "01";
L2 <= "01";
if sum < 10 then next_state <= s0;
else next_state <= s1;
end if;
when s1 => L1 <= "10";
L2 <= "01";
if sum < 20 then
next_state <= s1;
else
next_state <= s2;
end if;
when s2 => L1 <= "11"; --黄灯=红绿灯全开
L2 <= "01";
if sum > 20 and sum < 40 then next_state <= s5;
else next_state <= s3;
end if;
when s3 => L1 <= "01";
L2 <= "10";
if sum > 40 and sum < 60 then next_state <= s3;
else next_state <= s4;
end if;
when s4 => L1 <= "01";
L2 <= "11";
if sum > 60 and sum < 80 then next_state <= s6;
else next_state <= s1;
end if;
when s5 => L1 <= "00";--为在s2状态下能让黄灯闪烁的一种交替状态
L2 <= "01";
if sum > 20 and sum < 40 then
next_state <= s2;
else next_state <= s3;
end if;
when s6 => L1 <= "01";--为载s4状态下能让黄灯闪烁的一种交替状态
L2 <= "00";
if sum > 60 and sum < 80 then
next_state <= s4;
else next_state <= s1;
end if;
end case;
end process COM;
process(clk1)
begin
if clk1'event and clk1 = '1' then
if tmp = 0 then
tmp <= "00001001";--十位赋值9
if tmp1 = 2 or tmp1 = 1 then
tmp1 <= tmp1 - 1;
else
tmp1 <= "00000001";
end if;
else
tmp <= tmp - 1;
end if;
end if;
end process;
process(clk2)--该进程的目的就是为了达到一种动态交替的效果
begin
if clk2'event and clk2 = '1' then
cnt <= cnt+1;------每1/1000秒的时间cnt+1,主要用于扫描数码管
if cnt = 2 then
cnt <= 0;
end if;
end if;
end process;
-------------------------------------------------------------
process(cnt)
begin
case cnt is
when 0 => WS <= "00000010";data <= tmp;--当cnt为0时亮倒数第二个数码管,来完成一个动态扫描的目的
when 1 => WS <= "00000001";data <= tmp1;
when others => null;
end case;
end process;
process (data)
begin
case data is
when "00000000" => DS <="11111100";--显示0
when "00000001" => DS <="01100000";--显示1
when "00000010" => DS <="11011010";--显示2
when "00000011" => DS <="11110010";--显示3
when "00000100" => DS <="01100110";--显示4
when "00000101" => DS <="10110110";--显示5
when "00000110" => DS <="10111110";--显示6
when "00000111" => DS <="11100000";--显示7
when "00001000" => DS <="11111110";--显示8
when "00001001" => DS <="11110110";--显示9
when others =>DS<="00000000";
end case;
end process;
end one;