📄 control.vhd
字号:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
--*******************************************************************************
entity control is
port(upone,uptwo,downtwo,downthree : in std_logic;--电梯外乘客的请求信号
one,two,three : in std_logic;--电梯内乘客的请求上或下至几层楼的信号
reset : in std_logic; --复位初始化开关
over,emergency,lock:in std_logic;--超重、紧急停运和上锁信号
clk : in std_logic; --时钟信2MHz
alarm,ovelight,locklight : out std_logic;--故障、超重及锁定提示灯
p : out integer range 1 to 3; --电梯当前位置
lightup,lightdown : out std_logic_vector(6 downto 0);
--lightup显示'u'则电梯在上升模式,
--lightdown显示'd'则电梯在下降模式;
arrive : out std_logic); --arrive为'1'时表明电梯到达楼层,并在开门状态
end;
--*******************************************************************************
architecture behave of control is
type states is (up1,up2,down1,down2,stop,dw1,dw2,dw3,dw4,dw5);
--states为电梯所处的各个状态
--up1表示电梯正在从第1层上升
--up2表示电梯正在从第2层上升
--down1表示电梯正在向第1层下降
--down2表示电梯正在向第2层下降
--stop表示电梯停止在某一层上
--dw1表示电梯开门的第一秒
--dw2表示电梯开门的第二秒
--dw3表示电梯开门的第三秒
--dw4表示电梯开门的第四秒,判断电梯的下一个状态
--dw5表示当电梯处于上升或下降状态时,如果没有相应的上升或下降请求信号,则转入
--此dw5状态,使其不再在上升或下降状态停留,而响应其它信号
signal state: states;
signal clear1,clear2,clear3,flag1,flag2,flag3,fl1,fl2,fl3: std_logic;
--这些都是标志位,控制电梯的状态转换
--flag1、flag2、flag3代表各层相应的请求信号
--clear1、clear2、clear3代表相应层的请求已经完成,可以接收新的任务
signal position : integer range 1 to 3; --电梯的当前停留位置
signal lup,ldown: std_logic_vector(6 downto 0);--与lightup和lightdown功能相同
signal arr : std_logic; --与arrive功能相同
signal ala,ov,loc : std_logic; --与alarm,ovlight,locklight功能相同
begin
k1:
process(clk)
variable cnt: integer range 1 to 2000000;
variable updown : std_logic; --此变量表明电梯处于上升或下降状态
begin
if(clk'event and clk ='1')then
if(upone='1' or one='1')then --一层有上楼请求
flag1<='1';
elsif clear1='1' then --一层的请求已完成
flag1<='0'; --当没有新请求信号则清零
end if;
if (uptwo='1' or downtwo = '1' or two = '1') then --二层有请求
flag2<='1';
elsif clear2 = '1' then --二层的请求已完成
flag2<='0'; --当没有新请求信号则二层清零
end if;
if (downthree= '1' or three = '1')then --三层有请求
flag3<='1';
elsif clear3 = '1' then --三层的请求已完成
flag3<='0'; --当没有新请求信号则三层清零
end if;
if(emergency='1') then
ala<='1';
elsif(over='1') then
ov<='1';
elsif(lock='1') then
loc<='1';
end if;
if cnt<2000000 then--通过计数2000000获得1s的时钟信号
cnt:=cnt+1; --计数信号小于20000000则加1
else
if reset = '1' then --复位时,电梯初值设置在一层,状态为stop
position<=1;
state<=stop;
ovelight<='0';--各状态指示灯均灭
locklight<='0';
alarm<='0';
lup<="1111111";
ldown<="1111111";
else
fl1<=flag1;
fl2<=flag2;
fl3<=flag3;
--fl1、fl2、fl3置'1'表示相应楼层有请求信号,并把相应的任务完成信号clear
--置'0',表示有新的任务等待完成
if(fl1='1')then
clear1<='0';
end if;
if(fl2='1')then
clear2<='0';
end if;
if(fl3='1')then
clear3<='0';
end if;
case state is --状态机描述
when up1 =>-------------up1:正在从一层上升
if fl2='0' then --若上升期间二层期间无请求,则直接上三层
clear1<='0';
clear3<='0';
state<=up2;
position<=2;
else
state<=stop;
position<=2;
fl2<='0'; --完成了对二层请求的响应;
clear2<='1';
end if;
when up2 =>--------------up2:正在从二层上升
clear1<='0';
clear2<='0';
state<=stop;
position<=3;
if position =2 then --如果电梯在第二层
position<=3; --那么下一个位置在第三层
fl3<='0'; --完成了对第三层请求的相应
clear3<='1';
elsif position =1 then --如果电梯在第一层
position<=2; --那么下一个位置在第二层
fl2<='0'; --二层的请求已经完成
clear2<='1';
end if;
when down1 => --正在向第一层下降
clear2<='0';
clear3<='0';
state<=stop; --下一状态是stop
if position=2 then --如果电梯在第二层
position<=1; --那么下一个位置在第一层
fl1<='0'; --一层的请求已经完成
clear1<='1';
elsif position =3 then
position<=2;
fl2<='0';
clear2<='1';
end if;
when down2 => --正在向第二层下降
--如果在下降期间,二层没有请求,就直接下到一层
if fl2 ='0' then
clear1<='0';
clear3<='0';
--下一状态转至down1,电梯将会再下降一层
state<=down1;
position<=2; --电梯的下一个位置在第二层
else
state<=stop; --若下降期间二层有请求,则在二层停下
position<=2; --位置转至二层
fl2<='0'; --完成了对二层请求的响应
clear2<='1';
end if;
when stop => --在停止状态
if(emergency='1' or over='1') then
state<=stop;
else
state<=dw1;--下一状态转至dw1,电梯会进入开门状态
arr<='1'; --arr置'1',表明电梯到达并开门
lup<="1111111"; --上升指示灯灭
ldown<="1111111";--下降指示灯灭
end if;
when dw1 => --在dw1状态时,等待1s
state<=dw2;--下一状态转至dw2
when dw2 =>
state<=dw3;
when dw3 =>
state<=dw4;
when dw4 =>
arr<='0'; --开门灯灭
if position=1 then --如果电梯在第一层
updown :='1'; --则进入上升模式
fl1<='0'; --一层的任务完成
clear1<='1';
if fl2='1' then --如果二层有请求
state<=up1; --先响应二层的请求,再响应上升一层的请求
arr<='0'; --维持灯熄灭状态
lup<="1000001"; --上升灯亮
elsif fl3='1' then --若三层有请求
state <=up1;
--响应完二层请求信号后,再响应第三层的请求
arr<='0';--开门灯维持熄灭状态
lup<="1000001";--上升灯亮
end if;
elsif position=3 then
updown :='0';--进入下降状态
fl3<='0'; --到达三层的任务已完成
clear3<='1';
if fl2='1' then --若二层有请求
state<=down2;
--先响应二层请求,再转入下降一层的状态
arr<='0';
ldown<="1000010";--下降灯亮
elsif fl1='1' then
state<=down2;
--响应完二层请求信号后再响应一层的请求
arr<='0';
ldown<="1000010";
end if;
elsif position =2 then
fl2<='0'; --到达二层的任务已经完成
clear2<='1';
if updown ='1' then
--当电梯处于上升状态,不响应一层的请求
if fl3='1' then
state<=up2;
arr<='0';
lup<="1000001";
else
state<=dw5;
--若三层无请求,就转至dw5状态
end if;
end if;
if updown = '0' then
--当处于下降状态,不响应三层的请求
if fl1='1' then
state<=down1;
arr<='0';
ldown<="1000010";
else
state<=dw5;
--若一层无请求,就转至dw5状态
end if;
end if;
end if;
when dw5 =>
--只要到了dw5的状态,无论原来处于上升或下降状态,对三层和一层的信号都可相响应
if fl3='1' then
state<=up2;
arr<='0';
lup<="1000001";
elsif fl1='1' then
state<=down1;
arr<='0';
ldown<="1000010";
end if;
end case;
cnt:=1;--进程完成一次全部的状态、条件判断并执行相应操作后,计数信号重置1
end if;
alarm<=ala;
ovelight<=ov;
locklight<=loc;
end if;
end if;
end process;
p<=position;--给输出信号赋值
lightup<=lup;
lightdown<=ldown;
arrive<=arr;
end;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -