📄 jiaotongdeng_mealy2.vhd
字号:
--交通灯控制程序
--功能:
-- 东西方向交通灯循环显示为:
-- 绿灯亮45s,黄灯亮5s,左拐灯亮15s,黄灯亮5s,红灯亮40s,黄灯亮5s
-- 南北方向交通灯循环显示为:
-- 红灯亮65s,黄灯亮5s,绿灯亮20s,黄灯亮5s,左拐灯亮15s,黄灯亮5s
--由于实验板条件有限,只有8个指示灯,故简化指示灯为东西方向4个,南北方向4个
--指示灯从左到右依次为绿灯,黄灯,左拐灯,红灯
--作者:hb8421
--器件:LC4128
--晶振:2MHz
--实验板:LC4128实验板
--创立时间:2007年5月18日16:24:49
--结束时间:
--总结:对于变量,一定要设置范围,且要越小越好,节省器件资源,
--否则会编译正常(编译与器件无关),布线不正常(布线与器件有关)。
--使用变量方式,占用资源严重!
--使用状态机模式,占用资源少。
--使用时钟使能信号,而不是时钟分频信号作为驱动。
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY jiaotongdeng_mealy2 IS
GENERIC(
-- CONSTANT CLK_COUNTER :integer :=1000;--分频用
CONSTANT CLK_COUNTER :integer :=1;--仿真用
CONSTANT EAST_GREEN :integer :=15;--定时
CONSTANT EAST_YELLOW :integer :=5;
CONSTANT EAST_LEFT :integer :=15;
CONSTANT EAST_RED :integer :=40;
CONSTANT SOUTH_GREEN :integer :=15;
CONSTANT SOUTH_YELLOW :integer :=5;
CONSTANT SOUTH_LEFT :integer :=15;
CONSTANT SOUTH_RED :integer :=40
);
PORT
(
clk : IN STD_LOGIC;
rst_n : IN STD_LOGIC;
east_light : OUT STD_LOGIC_VECTOR(3 DOWNTO 0);
south_light : OUT STD_LOGIC_VECTOR(3 DOWNTO 0)
);
END ;
--
ARCHITECTURE arch1 OF jiaotongdeng_mealy2 IS
SIGNAL clkdiv_en : STD_LOGIC;--1Hz,时钟使能信号
SIGNAL int_east_light :STD_LOGIC_VECTOR(3 DOWNTO 0);
SIGNAL int_south_light :STD_LOGIC_VECTOR(3 DOWNTO 0);
type state_type is (s1,s2,s3,s4,s5,s6);--自定义数据类型
SIGNAL state_east:state_type; --东西方向状态
SIGNAL state_south:state_type; --南北方向状态
BEGIN
--P1 PROCESS
--分频,把2MHz晶振分成1Hz
--clkdiv1k=clk_sys/number1/2=20000000/1000/2=1000 Hz
--clkdiv=clkdiv1k/number2=1000/1000=1 Hz
P1: PROCESS(clk)
VARIABLE clk_cnter1 :INTEGER RANGE 0 TO 1005;
VARIABLE clk_cnter1k :INTEGER RANGE 0 TO 1005;
BEGIN
IF clk'event AND clk='1' THEN
clk_cnter1k:=clk_cnter1k+1;
IF (clk_cnter1k = CLK_COUNTER) THEN
clk_cnter1:=clk_cnter1+1;
IF (clk_cnter1 = CLK_COUNTER) THEN
clkdiv_en<='1'; --使能
clk_cnter1 :=0;
ELSE
clkdiv_en<='0';
END IF;
clk_cnter1k :=0;
END IF;
END IF;
END PROCESS;
--控制东西方向交通灯
P2: PROCESS(clk)
VARIABLE cnter1 :integer range 0 to 50;
BEGIN
IF rising_edge(clk) THEN
IF rst_n='0' THEN
state_east<=s1;
cnter1:=0;
ELSIF clkdiv_en='1' THEN
cnter1:=cnter1+1;
END IF;
case state_east is
when s1=> if cnter1>=EAST_GREEN then --时长大于绿灯亮
state_east<=s2; --转换为状态S2
cnter1:=0;
end if;
when s2=> if cnter1>=EAST_YELLOW then --时长大于黄灯亮
state_east<=s3; --转换为状态S3
cnter1:=0;
end if;
when s3=> if cnter1>=EAST_LEFT then --时长大于左拐灯亮
state_east<=s4; --转换为状态S4
cnter1:=0;
end if;
when s4=> if cnter1>=EAST_YELLOW then --时长大于黄灯亮
state_east<=s5; --转换为状态S5
cnter1:=0;
end if;
when s5=> if cnter1>=EAST_RED then --时长大于红灯亮
state_east<=s6; --转换为状态S6
cnter1:=0;
end if;
when s6=> if cnter1>=EAST_YELLOW then --时长大于黄灯亮
state_east<=s1; --转换为状态S1
cnter1:=0;
end if;
end case;
END IF;
END PROCESS;
--内部东西输出
P3: PROCESS(clk)
begin
IF rising_edge(clk) THEN
IF rst_n='0' THEN
int_east_light<="1111";
ELSE
case state_east is
when s1 =>int_east_light<="0111";--绿灯亮
when s2 =>int_east_light<="1011";--黄灯亮
when s3 =>int_east_light<="1101";--左拐灯亮
when s4 =>int_east_light<="1011";--黄灯亮
when s5 =>int_east_light<="1110";--红灯亮
when s6 =>int_east_light<="1011";--黄灯亮
end case;
END IF;
END IF;
end process;
--控制南北方向交通灯
P4: PROCESS(clk)
VARIABLE cnter1 :integer range 0 to 50;
BEGIN
IF rising_edge(clk) THEN
IF rst_n='0' THEN
state_south<=s1;
cnter1:=0;
ELSIF clkdiv_en='1' THEN
cnter1:=cnter1+1;
END IF;
case state_south is
when s1=> if cnter1>=SOUTH_RED then --时长大于红灯亮
state_south<=s2; --转换为状态S2
cnter1:=0;
end if;
when s2=> if cnter1>=SOUTH_YELLOW then --时长大于黄灯亮
state_south<=s3; --转换为状态S3
cnter1:=0;
end if;
when s3=> if cnter1>=SOUTH_GREEN then --时长大于绿灯亮
state_south<=s4; --转换为状态S4
cnter1:=0;
end if;
when s4=> if cnter1>=SOUTH_YELLOW then --时长大于黄灯亮
state_south<=s5; --转换为状态S5
cnter1:=0;
end if;
when s5=> if cnter1>=SOUTH_LEFT then --时长大于左拐灯亮
state_south<=s6; --转换为状态S6
cnter1:=0;
end if;
when s6=> if cnter1>=SOUTH_YELLOW then --时长大于黄灯亮
state_south<=s1; --转换为状态S1
cnter1:=0;
end if;
end case;
END IF;
end process;
--内部南北输出
P5:PROCESS(clk)
BEGIN
IF rising_edge(clk) THEN
IF rst_n='0' THEN
int_south_light<="1111";
ELSE
case state_south is
when s1 =>int_south_light<="1110";--红灯亮
when s2 =>int_south_light<="1011";--黄灯亮
when s3 =>int_south_light<="0111";--绿灯亮
when s4 =>int_south_light<="1011";--黄灯亮
when s5 =>int_south_light<="1101";--左拐灯亮
when s6 =>int_south_light<="1011";--黄灯亮
end case;
END IF;
END IF;
END PROCESS;
--输出
PROCESS(clk)
BEGIN
IF RISING_EDGE(clk) THEN
east_light<=int_east_light;
south_light<=int_south_light;
END IF;
END PROCESS;
END arch1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -