📄 elerun.vhd
字号:
--设计一个6层电梯控制器。电梯控制器是按照乘客的要求自动上、下的装置。
--1、每层电梯入口处设置上下请求开关,电梯内设有顾客到达层次的停站请求开关。
--2、设有电梯所处位置指示装置以及电梯运行模式(上升或者下降)指示装置。
--3、电梯每秒升降一层楼。
--4、电梯到达有停站请求的楼层,经过1秒电梯门打开,开门4秒后,电梯门关闭(开门指示灯灭),电梯继续运行,直至执行完最后一个请求信号后停留在当前层。
--5、电梯能记忆电梯内外所有请求信号,并按照电梯运行规则按顺序响应,每个请求信号保留至有电梯响应后消除。
--6、电梯运行规则:当电梯上升时,只响应比电梯所在位置高的上楼请求信号,由下而上逐个执行,直到最后一个上楼请求执行完毕;
--如果高层有下楼请求,则直接升到下楼请求的最高楼层,然后进入下降模式。当电梯处于下降模式时与上升正好相反
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
entity elerun is
port (
clk: in std_logic; --电梯时钟
alarm: in std_logic;
reset: in std_logic; --异步置位按键
fuplight: in std_logic_vector (6 downto 1);--电梯外部上升请求指示灯
fdnlight: in std_logic_vector (6 downto 1);--电梯外部下降请求指示灯
stlight: in std_logic_vector (6 downto 1);--电梯内部各层请求指示灯
position: out integer range 1 to 6; --电梯位置指示
doorlight: out std_logic; --电梯门开关指示灯
clearup:out std_logic;--用于清除上升请求指示灯的信号
cleardn:out std_logic;--用于清除下降请求指示灯的信号
yanshi:in std_logic;
tiqian: in std_logic;
udsig: buffer std_logic_vector(7 downto 0) --电梯升降指示
);
end elerun;
architecture sixflift of elerun is
type lift_state is
(stopon1,dooropen,doorclose,doorwait1,doorwait2,doorwait3,doorwait4,doorwait5,doorwait6,up,down,stop);
signal mylift: lift_state;
signal pos: integer range 6 downto 1;
signal udflag : std_logic;
signal posreg : integer range 1 to 6;
signal one: std_logic_vector (6 downto 1);
begin
process(reset,clk) --控制电梯状态的进程
begin
if (reset = '1' or alarm = '1') then
mylift <= stopon1;
clearup <= '1';
cleardn <= '1';
else
if (clk 'event and clk = '1') then
case mylift is
when stopon1 =>
doorlight <= '0';
posreg <= 1;
mylift <= doorwait1;
clearup <= '0';
cleardn <= '0';
udsig <= "00000010";
when doorwait1 =>
if tiqian = '1' then
mylift <= doorclose;
elsif yanshi = '1' then
mylift <= doorwait1;
else
mylift <= doorwait2;
end if;
clearup <= '0';
cleardn <= '0';
when doorwait2 =>
if tiqian = '1' then
mylift <= doorclose;
elsif yanshi = '1' then
mylift <= doorwait1;
else
mylift <= doorwait3;
end if;
clearup <= '0';
cleardn <= '0';
when doorwait3 =>
if tiqian = '1' then
mylift <= doorclose;
elsif yanshi = '1' then
mylift <= doorwait1;
else
mylift <= doorwait4;
end if;
clearup <= '0';
cleardn <= '0';
when doorwait4 =>
if tiqian = '1' then
mylift <= doorclose;
elsif yanshi = '1' then
mylift <= doorwait1;
else
mylift <= doorwait5;
end if;
clearup <= '0';
cleardn <= '0';
when doorwait5 =>
if tiqian = '1' then
mylift <= doorclose;
elsif yanshi = '1' then
mylift <= doorwait1;
else
mylift <= doorwait6;
end if;
clearup <= '0';
cleardn <= '0';
when doorwait6 =>
mylift <= doorclose;
cleardn <= (not udflag);
clearup <= udflag;
when doorclose =>
doorlight <= '0';
clearup <= '0';
cleardn <= '0';
if posreg = 6 then
if (stlight = "000000" and fuplight = "000000" and fdnlight = "000000") then
mylift <= doorclose;
udsig <= "00000010";
elsif stlight > "000000" or fdnlight > "000000" or fuplight > "000000" then
mylift <= down;
udsig<="01111010";
udflag <= '1';
end if;
elsif posreg = 1 then
if (stlight = "000000" and fuplight = "000000" and fdnlight = "000000") then
mylift <= doorclose;
udsig <= "00000010";
elsif stlight > "000000" or fdnlight > "000000" or fuplight > "000000" then
mylift <= up;
udsig<="01111100";
udflag <= '0';
end if;
else
if (stlight = "000000" and fuplight = "000000" and fdnlight = "000000") then
mylift <= doorclose;
udsig <= "00000010";
elsif stlight >= (one + one) or fuplight >= (one + one) or fdnlight >= (one + one) then
mylift <= up;
udsig<="01111100";
udflag <= '0';
elsif (stlight + stlight) <= one or (fuplight + fuplight) <= one or (fdnlight + fdnlight) <= one then
mylift <= down;
udsig<="01111010";
udflag <= '1';
else
mylift <= doorclose;
end if;
end if;
when up =>
clearup <= '0';
cleardn <= '0';
if posreg < 6 and (stlight(posreg) = '1' or fuplight(posreg) = '1' or (stlight = "000000" and fdnlight(posreg) = '1'))
then mylift <= stop;
if (stlight = "000000" and fdnlight(posreg) = '1' and fuplight = "000000") then
udflag <= '1';
end if;
elsif posreg = 6 and (stlight(posreg) = '1' or fuplight(posreg) = '1' or ( fuplight = "000000" and fdnlight(posreg) = '1'))
then mylift <= stop;
elsif posreg = 6 and ( fdnlight > "000000" or fuplight > "000000") then
mylift <= stop;
else
mylift <= up;
udsig<="01111100";
udflag <= '0';
if posreg<6 then
posreg <= (posreg+1);
end if;
end if;
when down =>
clearup <= '0';
cleardn <= '0';
if posreg > 1 and (stlight(posreg) = '1' or fdnlight(posreg) = '1' or ( stlight = "000000" and fuplight(posreg) = '1' ))
then mylift <= stop;
if (stlight = "000000" and fuplight(posreg) = '1' and fdnlight = "000000") then
udflag <= '0';
end if;
elsif posreg = 1 and (stlight(posreg) = '1' or fdnlight(posreg) = '1' or ( fdnlight = "000000" and fuplight(posreg) = '1'))
then mylift <= stop;
elsif posreg = 1 and ( fdnlight > "000000" or fuplight > "000000") then
mylift <= stop;
else
mylift <= down;
udsig<="01111010";
udflag <= '1';
if posreg>1 then
posreg <= (posreg-1);
end if;
end if;
when stop =>
mylift <= dooropen;
clearup <= '0';
cleardn <= '0';
when dooropen =>
doorlight <= '1';
clearup <= '0';
cleardn <= '0';
mylift <= doorwait1;
when others =>
mylift <= doorwait1;
clearup <= '0';
cleardn <= '0';
end case;
end if;
end if;
end process ;
position <= posreg;
process(clk,posreg)
begin
if clk 'event and clk = '1' then
case posreg is
when 1 => one <= "000001";
when 2 => one <= "000010";
when 3 => one <= "000100";
when 4 => one <= "001000";
when 5 => one <= "010000";
when 6 => one <= "100000";
end case;
end if;
end process ;
end ;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -