详细设计及实现
根据要求,我们可以用典型时序状态机实现功能,共有六个大的状态,现设定:
S0: 四个方向的红灯全亮
S1: 东、西方向绿灯亮,南、北方向红灯亮
S2:东、西方向黄灯闪烁,南、北方向红灯亮
S3:东、西方向红灯亮,南、北方向绿灯亮
S4:东、西方向红灯亮,南、北方向黄灯闪烁
S5:东、西、南、北四个方向的红灯亮
整体控制状态图如下:
图1 整体功能状态机
此状态机是该设计的核心模块,由其控制着东、西、南、北方向的交通。仔细分析设计要求可知,东西方向交通灯状态变化相同,南北方向亦相同,故实际上只需控制两组交通灯,所以状态机有六个输出变量,分别控制东西、南北方向的红、绿、黄灯的亮灭状态。另外,状态机还有三个输入变量,分别为复位信号、紧急状况控制信号、时钟信号。
由于在vhdl语言中,同一个进程内只能有一个时钟,所以紧急信号宜以电平来触发。但实验要求通过单脉冲来控制紧急信号,为了解决这个矛盾,可以设计一个边沿触发的紧急信号发生器,当输入一个单脉冲时,输出电平为高,即进入紧急状态;再输入一单脉冲,输出电平为低,解除紧急状态。
为了控制各个状态持续的时间,需在状态机中设置计时装置。可将输入状态机的时钟信号的频率设计为1Hz,即一个脉冲周期为1s。由于实际试验中,给定的实验器材频率都很大,从Khz到MHz,在这里采用50MHz,这样就只需要计数器来分频。此外,复位信号利用高低电平来控制,当电平为高时,状态机保持东、西、南、北四个方向红灯均亮的状态,若为低则由初始状态进入状态循环。
综上所述,可得总体设计结构框图如下:
图2 总体设计结构框图
clk为输入时钟(用于计时,由计数器分频后提供);
reset为复位信号,与计数器的复位信号连接在一起,由一个电平开关控制;
hold为紧急信号(由紧急信号发生器控制);
输出变量red1、green1、yellow1控制东西方向红、绿、黄交通灯的亮灭状态;南北方向则由red2、green2、yellow2控制。
部分模块结构图如下:
图2 控制模块结构图
状态机
状态机用于控制十字路口交通灯的状态变化。此模块中我设计的是异步复位和异步等待(即进入紧急状态),复位信号是低电平有效,紧急信号是高电平有效。另外,为了控制各个状态的持续时间,此状态机中还设计了一个计数装置,用于计时。
状态SO持续时间为1s,由于输入状态机的时钟频率为1Hz,即一个脉冲持续时间为1s,所以在计数为0~1内状态机为S0状态。同理,在计数为1~31内,为S1状态;在计数为31~36内,为S2状态;S3状态所处的计数范围为36~56;S4状态所处的计数范围为56~61。
状态机部分代码如下:
ENTITY state_machine IS
PORT(
clk,reset_n,hold,clk_1hz,select_model: IN STD_LOGIC; --clk为50M时钟信号,hold为紧急信号,reset为复位信号
second_count_ge_out: OUT std_logic_vector(3 downto 0);--秒的个位
second_count_shi_out:OUT std_logic_vector(3 downto 0);--秒的十位
red1_out,green1_out,yellow1_out:OUT STD_LOGIC; --控制东西方向的交通灯
red2_out,green2_out,yellow2_out:OUT STD_LOGIC);--控制南北方向的交通灯
END;
ARCHITECTURE state_machine_function OF state_machine IS
TYPE states IS(s0,s1,s2,s3,s4);
SIGNAL next_state:states;
signal red1: std_logic;
signal red2: std_logic;
signal green1: std_logic;
signal green2: std_logic;
signal yellow1: std_logic;
signal yellow2: std_logic;
signal second_count_ge: std_logic_vector(3 downto 0);--秒的个位
signal second_count_shi: std_logic_vector(3 downto 0);--秒的十位
signal second_count_ge_reg: std_logic_vector(3 downto 0);--秒的个位
signal second_count_shi_reg: std_logic_vector(3 downto 0);--秒的十位
signal second_count_ge_model: std_logic_vector(3 downto 0);--秒的个位
signal second_count_shi_model: std_logic_vector(3 downto 0);--秒的十位
BEGIN
red1_out<= red1;
red2_out<= red2;
green1_out<= green1;
green2_out<= green2;
yellow1_out<= yellow1;
yellow2_out<= yellow2;
second_count_ge_out<=second_count_ge_reg;
second_count_shi_out<=second_count_shi_reg;
process(clk_1hz,reset_n)
begin
if(reset_n = '0')then
second_count_ge_reg<="0000";
second_count_shi_reg<="0000";
elsif(clk_1hz'event and clk_1hz = '1')then--上升沿触发
second_count_ge_reg<=second_count_ge;
second_count_shi_reg<=second_count_shi;
end if;
end process;
process(select_model)
begin
if(select_mode = '1')then--白天模式
second_count_ge_model1<="1001";--主干道30秒
second_count_shi_model1<="0010";
second_count_ge_model2<="1001";--次干道20秒
second_count_shi_model2<="0001";
else--夜晚模式
second_count_ge_model1<="1001";--主干道20秒
second_count_shi_model1<="0010";
second_count_ge_model2<="1010";--次干道10秒
second_count_shi_model2<="0000";
end if;
end process;
-- /**********************************************************/
-- //控制模块
-- //
-- /**********************************************************/
PROCESS(reset_n,hold,clk_1hz)
VARIABLE countnum:INTEGER RANGE 0 TO 61; --计数变量
BEGIN
IF(reset_n='0') THEN --复位
countnum:=0;
next_state<=s0;
red1<='1';green1<='0';yellow1<='0';
red2<='1';green2<='0';yellow2<='0';
second_count_ge <= "0001";--1
second_count_shi <= "0000";--0
ELSIF(hold='0') THEN --进入紧急状态
countnum:=0;
next_state<=next_state;
red1<='1';green1<='0';yellow1<='0';
red2<='1';green2<='0';yellow2<='0';
ElSIF(clk_1hz'event AND clk_1hz='1') THEN
IF(countnum>=60) THEN --循环后又回到S1状态
countnum:=1;
ELSE
countnum:=countnum+1; --计数加1
END IF;
CASE next_state IS
WHEN s0 => --东西、南北方向红灯均亮
red1<='1';green1<='0';yellow1<='0';
red2<='1';green2<='0';yellow2<='0';
if(second_count_ge = "0000")then
second_count_ge <= "0000";--0
else
second_count_ge <= second_count_ge - '1';
end if;
IF(countnum=1) THEN
next_state<=s1;
second_count_ge <= second_count_ge_model1;--9
second_count_shi <= second_count_shi_model1;--2
ELSIF(countnum>=0 AND countnum<1) THEN
next_state<=s0;
END IF;
WHEN s1 => --东西方向绿灯亮,南北方向红灯亮。东西方向通车,时间30S
red1<='0';green1<='1';yellow1<='0';
red2<='1';green2<='0';yellow2<='0';
if(second_count_ge = "0000")then
second_count_ge <= "1001";--
if(second_count_shi = "0000")then
second_count_shi <= "0000";--0
else
second_count_shi <= second_count_shi - '1';
end if;
else
second_count_ge <= second_count_ge - '1';
end if;
IF(countnum = 31) THEN
next_state<=s2;
second_count_ge <= "0100";--4
second_count_shi <= "0000";--0
ELSIF(countnum>=1 AND countnum<31) THEN
next_state <= s1;
END IF;
WHEN s2 => --东西方向黄灯亮,南北方向红灯亮,时间5s。
red1<='0';green1<='0';yellow1<='1';
red2<='1';green2<='0';yellow2<='0';
if(second_count_ge = "0000")then
second_count_ge <= "0000";--0
else
second_count_ge <= second_count_ge - '1';
end if;
IF(countnum=36) THEN
next_state<=s3;
second_count_ge <= second_count_ge_model2;--9
second_count_shi <= second_count_shi_model2;--1
ELSIF(countnum>=31 AND countnum<36) THEN
next_state<=s2;
END IF;
WHEN s3 => --东西方向红灯亮,南北方向绿灯亮,南北方向通车,时间20s。
red1<='1';green1<='0';yellow1<='0';
red2<='0';green2<='1';yellow2<='0';
if(second_count_ge = "0000")then
second_count_ge <= "1001";--9
if(second_count_shi = "0000")then
second_count_shi <= "0000";--0
else
second_count_shi <= second_count_shi - '1';
end if;
else
second_count_ge <= second_count_ge - '1';
end if;
IF(countnum=56) THEN
next_state<=s4;
second_count_ge <= "0100";--4
second_count_shi <= "0000";--0
ELSIF(countnum>=36 AND countnum<56) THEN
next_state<=s3;
END IF;
WHEN s4 => --东西方向红灯亮,南,北方向黄灯亮,时间5s。
red1<='1';green1<='0';yellow1<='0';
red2<='0';green2<='0';yellow2<='1';
if(second_count_ge = "0000")then
second_count_ge <= "0000";--0
else
second_count_ge <= second_count_ge - '1';
end if;
IF(countnum=1) THEN
next_state<=s1;
second_count_ge <= second_count_ge_model1;--9
second_count_shi <= second_count_shi_model1;--2
ELSIF(countnum>=56 AND countnum<61) THEN
next_state<=s4;
END IF;
END CASE;
END IF;
END PROCESS;
END state_machine_function;
状态机的波形图如下:
文章来源:https://www.toymoban.com/news/detail-856342.html
初始状态为四个方向的红灯全亮,时间1秒。然后东、西方向绿灯亮,南、北方向红灯亮。东、西方向通车,时间30秒。但在此过程中,有一个紧急的信号出现,所以在大概在6秒左右,出现紧急信号,东西南北方向红灯都亮。在11秒左右解除紧急信号,仿真图中恢复S1的状态。经验证,图中均符合题目要求。文章来源地址https://www.toymoban.com/news/detail-856342.html
到了这里,关于基于FPGA的交通信号灯设计(二)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!