VHDL有限状态机(单进程,双进程)交通灯示例

Finite State Machine有限状态机

它的逻辑流程图是:

注意!“当前状态”和“下一状态”的位置,我们将在下文的交通灯示例中理解。

设计要求:

--我们要设计一个十字路口的交通灯,就两个按钮,东西方向一个(sensor2),南北方向一个(sensor)。流程就是,东西方向为红灯,南北在走人,
--这时候东西方向的人想过马路,按下sensor2,然后红变绿,东西走,南北停。然后南北的人想过马路,按下sensor,灯就由绿变黄再变红。
--整体上这个逻辑不是很严谨,放在这里只是举个例子。

下图为状态流程图:

我把注释写在代码中了,请参悟下文的代码。本实验用的是ModelSim软件,VHDL语言。他一般有两个文件,一个是硬件配置文件(df.vhd)用来写你设计的硬件的结构的。第二个是硬件测试文件(testbench,也就是tb.vhd),是用来设置仿真参数,用来仿真的。补充:因为本实验只用了状态机,所以就是一个硬件配置文件。但是,在往后的综合实验中,我们会用状态机与寄存器等其他硬件综合使用,所以要单独把状态机拿出来进行配置(df_state.vhd),这个就相当于库函数,然后在主函数(df.vhd)中再多写一行:

USE work.state_machine_package.all

进行调用,所以,它相当于三个文件了。

就是写上文的下行即可。

不多墨迹了,见代码(df.vhd)

--我们要设计一个十字路口的交通灯,就两个按钮,东西方向一个(sensor2),南北方向一个(sensor)。流程就是,东西方向为红灯,南北在走人,
--这时候东西方向的人想过马路,按下sensor2,然后红变绿,东西走,南北停。然后南北的人想过马路,按下sensor,灯就由绿变黄再变红。
--整体上这个逻辑不是很严谨,放在这里只是举个例子。

-- single Process FSM 单进程的有限状态机
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_SIGNED.ALL;

Entity Traffic_light is
	port(sensor : in std_logic;
		sensor2: in std_logic;
		 rst	: in std_logic;
		 clk	: in std_logic;
		 red_light: out std_logic;
		 green_light: out std_logic;
		 yellow_light : out std_logic
		);
end entity;

Architecture one_process of  Traffic_light is		--结构设定,one_process是本process的名字,一般情况下,状态机我们用一个process就够了
	type statetype is (red,green,yellow)           --type 是状态(圆圈),有多少个圆圈,括号里就写多少个名字;它们三个的功能就像HIGH/LOW一样,表示状态
	signal state : statetype;						--这里只设置了一个叫“state”的信号,它既不是输入也不是输出,表示的只是当前信号的状态
	
begin
-- synchronous reset
	process(clk,rst)
	begin
		if rising_edge (clk) then    --CLK 上升沿触发
			red_light <= '1';
			green_light <= '0';     --这是初始设置,红灯状态
			yellow_light <= '0';
			if rst= '0' then
				state <= red;   	--如果RST复位键没有触发,那么就把红灯状态给当前状态;也可以理解为保存红灯亮
			else
			case state is			--注意!!!state状态设定这里只能用case,不能用if
				when red =>			--若为状态红灯
				    red_light <= '1';
					yellow_light <= '0';
					green_light <= '0';
					if sensor = '1' then		--如果按钮sensor被按下(1),那么
						state <= green;			--将绿灯亮的状态给”当前状态“
						green_light <= '1';     --绿灯亮,红灯灭
						red_light <= '0';
						
					else
						state <= red;			--否则的话,红灯给“当前状态”,也就是保持的意思
					end if;						--不要忘了end if
				when green => 		--若状态为绿灯
				 if sensor2 = '1' then			--如果按钮2,sensor2被按下,那么
					state <= yellow;			--把黄灯亮的状态给“当前状态”
					yellow_light <= '1';		--黄灯亮,绿灯灭
					green_light <= '0';
				 else 							--否则保持绿灯亮
					state <= green;
				end if;
				
				when yellow =>		--若状态为黄灯
					state <= red;				--因为黄灯的下一步肯定是变红灯,所以在这就把红灯状态给“当前状态”
					red_light <= '1';			--红灯亮,黄灯灭
					yellow_light <= '0';
			end case;
			end if;
		end if;
	end process;
end one_process;

差不多懂了吧?上文的测试代码我就不写了,有兴趣的同学可以自己测试。

下面是双进程结构代码,还是以上文相同的状态逻辑流程图为例。


library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_SIGNED.ALL;

entity Traffic_light is
end entity;

	
Architecture dual_process_B of  Traffic_light is		
	type statetype is (red,green,yellow)           
	signal current_state, next_state : statetype; --请看我画的流程图,在这我定义两个状态(当前状态,下一状态)
	
begin

	decoding: process(current_state, sensor)
	begin
		red_light <= '1'; --开始是红灯亮
		green_light <= '0';
		yellow_light <= '0';
		case current_state is --当前状态设置
			when red =>					--若为红灯状态,若检测到开关1按下,则把“绿灯亮”给下一状态
				if sensor = '1' then
					next_state <= green;
				end if;								--若没按开关,那就保持红灯
				red_light <= '1';	
			when green =>				--若为绿灯状态,把黄灯给下一状态,并点亮绿灯
				next_state <= yellow;		--(逻辑不严谨,为了简单的举例才这么写的,具体流程图请见上文的手画的状态逻辑流程图)
				green_light <= '1';
					
			when yellow =>			--若为黄灯状态,下一状态为红灯,且黄灯点亮
				next_state <= red;
				yellow_light <= '1';
		end case;
	end process;
	
	state_register: process(clk,rst)--设置时钟进程
	begin
		if rising_edge (clk) then		--上升沿触发
			if rst = '1' then
				current_state <= red;		--等复位键置1,就红灯亮(开始仿真)
			else
				current_state <= next_state;	--否则就继续循环等待
			end if;
		end if;
	end process;

end dual_process_B;

这是我的课堂笔记,题目是老师随便的,他说逻辑有错的,我改对了。放到这就是加深理解的,学VHDL就应该多悟,多写,抄我代码没有任何意义,随便抄,您开心就好。

  • 5
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值