Vhdl 为什么电梯在紧急状态下会卡死?

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

这是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.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;