Vhdl 为什么电梯在紧急状态下会卡死?
这是7层电梯的vhdl代码 编码被封装为3种状态s0=不移动,s1=向上移动,s2=向下移动 如果处于s0,则应根据下一个正边缘上的所需地板或称为地板,在向上/向下移动后等待2个周期。 问题是电梯卡在s1状态 谁能帮我一下吗Vhdl 为什么电梯在紧急状态下会卡死?,vhdl,Vhdl,这是7层电梯的vhdl代码 编码被封装为3种状态s0=不移动,s1=向上移动,s2=向下移动 如果处于s0,则应根据下一个正边缘上的所需地板或称为地板,在向上/向下移动后等待2个周期。 问题是电梯卡在s1状态 谁能帮我一下吗 -- Cad Project -- Project Name : Elevator -- Date : 18\12\2013 library IEEE; use ieee.std_logic_1164.all; use ieee.std_logic_arith.al
-- Cad Project
-- Project Name : Elevator
-- Date : 18\12\2013
library IEEE;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
--Entity Decleration
entity Elevator is
port (call, clk, press : in std_logic;
-- Call To Call The Elevator ,press if a key is pressrd from the pannel inside the elevator .
Desire_floor, Call_Floor : in std_logic_vector (2 downto 0);
-- Desired_floor is the floor number choosed from inside the elevator .
-- called_floor is the floor number that the "Call" Key has been pressed from .
weight : in std_logic;
Door_open_close, Move_up, move_down, OverWeight : out std_logic;
-- Door_open_close is 1 when opened ,0 when closed .
-- OverWeight is 1 when the weight is over 500 KG.
Current_Floor : buffer std_logic_vector (2 downto 0) := "000";
temp1_state, temp2_state : buffer std_logic_vector (1 downto 0);
o1, o2, o3, o4, o5, o6, o7 : out std_logic_vector (2 downto 0));
end;
--architecture Decleration
architecture Elevator of Elevator is
type state is (s0, s1, s2);
--s0 state represents no move ,s1 state represents move up ,s2 state represents move down .
signal current_state : state := s0;
signal next_state : state;
signal Desired_floor, Called_Floor : std_logic_vector (2 downto 0);
signal X : std_logic := '0'; -- X is a signal used to restart the timer or to resume it's count.
signal counter : std_logic_vector (2 downto 0); -- Timer befor closing/opening the doors "timer".
signal counter2 : std_logic_vector (2 downto 0) := "000"; -- Timer for the elevator to move up or down.
signal temp1, temp2, temp3, temp4, temp5 : std_logic_vector (2 downto 0);
begin
P1 : process (clk , weight, x)
variable s11 : std_logic_vector (2 downto 0) := "000";
-- Variable insted of the counter signal -->to have the direct assigment
begin
if (weight = '1') then
OverWeight <= '1';
current_state <= s0;
elsif (clk'event and clk = '1') then
if (x = '1') then -- if X equals to 1 that means restart the timer.
s11 := "000";
elsif (x = '0') then -- if X equals 0 then count up "keep counting ".
s11 := s11+1;
end if;
current_state <= next_state;
counter <= s11;
OverWeight <= '0';
end if;
counter <= s11;
o5 <= counter;
end process P1;
P2 : process (clk) -- this process if for the 2nd timer.
variable s4 : std_logic_vector (2 downto 0) := "000";
-- Variable insted of the counter2 signal -->to have the direct assigment
begin
if (rising_edge(clk)) then
if (press = '1') then
Desired_floor <= Desire_floor;
if (Current_Floor < Desired_floor) then
s4 := s4 +1;
elsif (Current_Floor > Desired_floor) then
s4 := s4 -1;
end if;
counter2 <= s4;
elsif (call = '1') then
Called_Floor <= Call_Floor;
if (Current_Floor < Called_Floor) then
s4 := s4 +1;
elsif (Current_Floor > Called_Floor) then
s4 := s4 -1;
end if;
end if;
end if;
counter2 <= s4;
o1 <= counter2;
o2 <= Desired_floor;
o3 <= Called_Floor;
counter2 <= s4;
--Desired_floor<=Desire_floor;
end process P2;
P3 : process (counter, current_state)
begin
case current_state is
when s0 =>
if(counter < "001") then
x <= '0';
Current_Floor <= Current_Floor;
next_state <= s0;
temp1_state <= "00";
else
if (press = '1') then
if(Desired_floor > Current_Floor) then
next_state <= s1;
temp2_state <= "01";
elsif (Desired_floor < Current_Floor) then
next_state <= s2;
temp2_state <= "10";
end if;
else
if (call = '1') then
if (Called_Floor > Current_Floor) then
next_state <= s1;
temp2_state <= "01";
elsif (Called_Floor < Current_Floor) then
next_state <= s2;
temp2_state <= "10";
end if;
end if;
end if;
x <= '1';
end if;
Door_open_close <= '1';
Move_up <= '0';
move_down <= '0';
Current_Floor <= counter2;
temp1_state <= "00";
when s1 =>
temp1 <= (Desired_floor - Current_Floor);
temp2 <= (Called_Floor-Current_Floor);
o4 <= temp1;
if ((temp1 /= "000") or (temp2 /= "000")) then
next_state <= s1;
temp2_state <= "01";
Current_Floor <= counter2;
elsif (((Desired_floor-Current_Floor) = "000")or ((Called_Floor-Current_Floor) = "000")) then
next_state <= s0;
temp2_state <= "00";
end if;
Door_open_close <= '0';
Move_up <= '1';
move_down <= '0';
Current_Floor <= counter2;
x <= '1';
temp1_state <= "01";
when s2 =>
temp3 <= (Current_Floor-Desired_floor);
temp4 <= (Current_Floor-Called_Floor);
if ((temp3 /= "000") or (temp4 /= "000")) then
next_state <= s2;
temp2_state <= "10";
Current_Floor <= counter2;
elsif (((Current_Floor-Desired_floor) = "000") or ((Called_Floor-Current_Floor) = "000")) then
next_state <= s0;
temp2_state <= "00";
end if;
Door_open_close <= '0';
Move_up <= '0';
move_down <= '1';
Current_Floor <= counter2;
x <= '1';
temp1_state <= "10";
end case;
end process P3;
end;
**********************************
——Cad项目
--工程名称:电梯
--日期:2013年12月18日
图书馆IEEE;
使用ieee.std_logic_1164.all;
使用ieee.std_logic_arith.all;
使用ieee.std_logic_unsigned.all;
--实体减容
实体电梯是
端口(呼叫、时钟、按键:在标准逻辑中;
--Call要呼叫电梯,请按电梯内面板上的按键。
欲望层、呼叫层:标准逻辑向量(2到0);
--所需楼层是从电梯内部选择的楼层编号。
--called_floor是按下“Call”(呼叫)键的楼层号码。
权重:在标准逻辑中;
门打开或关闭、向上移动、向下移动、超重:超出标准逻辑;
--门打开时为1,门关闭时为0。
--体重超过500公斤时超重为1。
当前楼层:缓冲区标准逻辑向量(2到0):=“000”;
temp1_状态、temp2_状态:缓冲区标准逻辑向量(1到0);
o1,o2,o3,o4,o5,o6,o7:输出标准逻辑向量(2到0);
结束;
--建筑失能
电梯的结构是
类型状态为(s0、s1、s2);
--s0状态表示不移动,s1状态表示向上移动,s2状态表示向下移动。
信号电流_状态:状态:=s0;
信号下一个_状态:状态;
所需信号_-floor,称为_-floor:std_-logic_-vector(2到0);
信号X:std_逻辑:='0';--X是用于重新启动计时器或恢复其计数的信号。
信号计数器:标准逻辑向量(2到0);--关闭/打开车门前的计时器“计时器”。
信号计数器2:std_逻辑_向量(2到0):=“000”——电梯向上或向下移动的计时器。
信号temp1、temp2、temp3、temp4、temp5:std_逻辑_向量(2到0);
开始
P1:过程(时钟、重量、x)
变量s11:std_逻辑_向量(2到0):=“000”;
--变量替代计数器信号-->进行直接分配
开始
如果(重量='1'),则
超重看起来只有当用户按下“按”时,楼层计数器才会增加。
解释
如果我们还没有到达所需的楼层,那么当前楼层
由计数器2
temp1 <= (Desired_floor - Current_Floor);
o4 <= temp1;
if ((temp1 /= "000")) then
next_state <= s1;
temp2_state <= "01";
Current_Floor <= counter2;
(顺便提一下,为什么要将s4
分配给counter2
三次?)
s4
仅在断言press
时更改。所以,只有当有人按下按钮时,你的电梯才会向上或向下移动
一般性意见
您的流程敏感度列表到处都是!您的灵敏度列表应该是clock
或clock,reset
。异步进程(敏感度列表中没有时钟的进程)确实有它们的位置,但除非绝对必要,否则我通常会避免它们。当一切都是严格同步的时候,我发现在我的头脑中想象时间行为要容易得多
P1 : process (clk , weight, x) <- BAD
P2 : process (clk) <- GOOD
P3 : process (counter, current_state) <- OKAY
P4 : process (temp6, clk) <- BAD
如果它与以前不同,完全可以理解,但要清理这些内容,无论代码的接收端是谁,都不需要阅读。您需要正确缩进代码-否则了解vhdl的人可能不会看itRead关于单进程还是双进程状态机的内容。之后,即使您决定坚持使用不太容易的2进程版本,您也可能已经找到了一些问题所在。
if (rising_edge(clk)) then
if (press = '1') then
if (Current_Floor < Desired_floor) then
s4 := s4 +1;
elsif (Current_Floor > Desired_floor) then
s4 := s4 -1;
end if;
counter2 <= s4; <-
end if;
end if;
counter2 <= s4; <-
o1 <= counter2;
o2 <= Desired_floor;
counter2 <= s4; <-
P1 : process (clk , weight, x) <- BAD
P2 : process (clk) <- GOOD
P3 : process (counter, current_state) <- OKAY
P4 : process (temp6, clk) <- BAD
if (temp6'event and temp6 = '1')then
--if ( current_state =s0 ) then
Desired_floor <= Desire_floor;
else
Desired_floor <= Desired_floor;
end if;
Desired_floor <= Desired_floor;