赞
踩
根据要求,我们可以用典型时序状态机实现功能,共有六个大的状态,现设定:
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;
状态机的波形图如下:
初始状态为四个方向的红灯全亮,时间1秒。然后东、西方向绿灯亮,南、北方向红灯亮。东、西方向通车,时间30秒。但在此过程中,有一个紧急的信号出现,所以在大概在6秒左右,出现紧急信号,东西南北方向红灯都亮。在11秒左右解除紧急信号,仿真图中恢复S1的状态。经验证,图中均符合题目要求。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。