我对始终发出的 vhdl 实体的输出有疑问U
。我查看了各种论坛,但找不到解决方案。
该项目是一个 5 层的电梯,必须等待 5 秒才能关上门,10 秒才能到达下一个到达目标的飞机。使用 Logisim (v 2.13.22) 和 ghdl (v 0.29.1)。
有谁知道问题可能是什么?提前致谢
这是我制作的vhdl代码。
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity Elevator is
Port (
clk : in std_logic;
rst : in std_logic;
rstPorta : in std_logic;
rstMotore : in std_logic;
zero : in std_logic;
one : in std_logic;
two : in std_logic;
three : in std_logic;
four : in std_logic;
upEngine : out std_logic;
downEngine : out std_logic;
ledReady: out std_logic;
ledUp: out std_logic;
ledDown: out std_logic;
ledDoorOpen: out std_logic;
ledDoorClosed: out std_logic;
ledBusy: out std_logic;
ledUsable: out std_logic;
doorOpenEngine : out std_logic;
doorCloseEngine : out std_logic;
cntPiano : out std_logic_vector(4 downto 0)
);
end Elevator;
architecture Ascensore of Elevator is
type state_type is (s0,s1,s2,s3,s4);
signal current_s,next_s: state_type;
signal cf, df: std_logic_vector(3 downto 0); -- vettore a 4 bit
signal countPorta: std_logic_vector(2 downto 0); -- vettore a 3 bit
signal countMotore: std_logic_vector(3 downto 0); -- vettore a 4 bit
begin
-- Questo processo modifica il segnale countPorta in modo tale da segnalare il tempo rimanente prima della chiusura della porta
process (clk,rstPorta)
begin
if (rstPorta='1') then countPorta <= "000"; -- Condizione di bypass della porta, apre la porta senza tempi d'attesa, per casi di emergenza
elsif (clk'event and clk='1') then
if (countPorta = "100") then countPorta <= "011";
elsif (countPorta = "011") then countPorta <= "010";
elsif (countPorta = "010") then countPorta <= "001";
else countPorta <= "000";
end if;
end if;
end process;
-- Questo processo modifica il segnale countMotore in modo tale da segnalare il tempo necessario all'arrivo al piano successivo
process (clk,rstMotore)
begin
if (rstMotore='1') then countMotore <= "0000"; -- Condizione di bypass del motore, ferma lo spostamento in casi di emergenza
elsif (clk'event and clk='1') then
if (countMotore = "1001") then countMotore <= "1000";
elsif (countMotore = "1000") then countMotore <= "0111";
elsif (countMotore = "0111") then countMotore <= "0110";
elsif (countMotore = "0110") then countMotore <= "0101";
elsif (countMotore = "0101") then countMotore <= "0100";
elsif (countMotore = "0100") then countMotore <= "0011";
elsif (countMotore = "0011") then countMotore <= "0010";
elsif (countMotore = "0010") then countMotore <= "0001";
else countMotore <= "0000";
end if;
end if;
end process;
-- Questo processo serve a controllare le chiamate dell ascensore nei vari piani
process (clk,rst)
begin
-- si inizializza ascensore considerando che esso parta dal piano 0 in una condizione priva di richieste esterne (stato 3)
if (rst='1') then
df <= "0000";
cf <= "0000";
upEngine <= '1';
downEngine <= '1';
ledReady <= '1';
ledUp <= '1';
ledDown <= '1';
ledDoorOpen <= '1';
ledDoorClosed <= '1';
ledBusy <= '1';
ledUsable <= '1';
doorOpenEngine <= '1';
doorCloseEngine <= '1';
current_s <= s3;
end if;
-- verifica se vi sono state richieste nei vari piani ad ogni ciclo di clock assegnando a df (desired floor) il piano della richiesta
if (clk'event and clk='1') then
if (zero = '1') then df <= "0000";
elsif (one = '1') then df <= "0001";
elsif (two = '1') then df <= "0010";
elsif (three = '1') then df <= "0011";
elsif (four = '1') then df <= "0100";
end if;
-- lo stato corrente corrisponde allo stato successivo
current_s <= next_s;
end if;
end process;
-- Processo Ascensore
process (current_s, cf, df, clk)
begin
if (clk'event and clk='1') then
case current_s is
-- STATO 0: fase di salita ascensore fino a che il piano desiderato non e' uguale al piano corrente
when s0 =>
if(cf < df) then
upEngine <= '1';
-- se il motore non e' ancora arrivato al piano resta nello Stato 0
if((countMotore= "1001") or (countMotore= "1000") or (countMotore= "0111") or (countMotore= "0110") or (countMotore= "0101") or (countMotore= "0100") or (countMotore = "0011") or (countMotore = "0010") or (countMotore = "0001"))
then then next_s <= s0;
end if;
-- se sono passati 10 sec, siamo arrivati al piano. cf verra' aumentato
if(countMotore = "0000") then
if (cf = "0000") then cf <= "0001";
elsif (cf = "0001") then cf <= "0010";
elsif (cf = "0010") then cf <= "0011";
elsif (cf = "0011") then cf <= "0100";
end if;
end if;
-- se il piano desiderato e' > del corrente fai un altro ciclo dello Stato 0
if(cf < df) then
next_s <= s0;
end if;
-- se il piano desiderato e' = al corrente vai nello Stato 2
if(cf = df) then
ledUp <= '0';
upEngine <= '0';
next_s <= s2;
countPorta <= "100";
end if;
end if;
-- STATO 1: fase di discesa ascensore fino a che il piano desiderato non e' uguale al piano corrente
when s1 =>
if(cf > df) then
downEngine <= '1';
-- se il motore non e' ancora arrivato al piano resta nello Stato 1
if((countMotore= "1001") or (countMotore= "1000") or (countMotore= "0111") or (countMotore= "0110") or (countMotore= "0101") or (countMotore= "0100") or (countMotore = "0011") or (countMotore = "0010") or (countMotore = "0001")) then
elsif(countMotore = "0000") then next_s <= s1;
end if;
-- se sono passati 10 sec, siamo arrivati al piano. cf verra' diminuito
if(countMotore = "0000") then
if (cf = "0100") then cf <= "0011";
elsif (cf = "0011") then cf <= "0010";
elsif (cf = "0010") then cf <= "0001";
elsif (cf = "0001") then cf <= "0000";
else cf <= cf;
end if;
end if;
-- se il piano desiderato e' < del corrente fai un altro ciclo dello Stato 1
if (cf > df) then
next_s <= s1;
end if;
-- se il piano desiderato e' = al corrente vai nello Stato 2
if(cf = df) then
ledDown <= '0';
downEngine <= '0';
next_s <= s2;
countPorta <= "100";
end if;
end if;
-- STATO 2: fase di apertura della porta nel piano desiderato
when s2 =>
if(countPorta = "000") then next_s <= s3;
else next_s <= s2;
end if;
-- STATO 3: ascensore in attesa di richieste con porta aperta
when s3 =>
doorOpenEngine <= '1';
doorCloseEngine <= '0';
ledDoorOpen <= '1';
ledDoorClosed <= '0';
ledReady <= '1';
ledUp <= '0';
ledDown <= '0';
ledBusy <= '0';
ledUsable <= '1';
if(cf = df) then
next_s <= s3;
end if;
if ((cf<df) or (cf>df)) then
countPorta <= "100";
next_s <= s4;
end if;
-- STATO 4: fase di chiusura della porta e selezione dello stato successivo per la salita (Stato 0) o discesa (Stato 1) dell'ascensore
when s4 =>
if((countPorta = "100") or (countPorta = "011") or (countPorta = "010") or (countPorta = "001")) then
next_s <= s4;
elsif((countPorta = "000") and (cf<df)) then
doorOpenEngine <= '0';
doorCloseEngine <= '1';
ledDoorOpen <= '0';
ledDoorClosed <= '1';
ledReady <= '0';
ledUp <= '1';
ledDown <= '0';
ledBusy <= '1';
ledUsable <= '0';
countMotore <= "1001";
next_s <= s0;
elsif((countPorta = "000") and (cf>df)) then
doorOpenEngine <= '0';
doorCloseEngine <= '1';
ledDoorOpen <= '0';
ledDoorClosed <= '1';
ledReady <= '0';
ledUp <= '0';
ledDown <= '1';
ledBusy <= '1';
ledUsable <= '0';
countMotore <= "1001";
next_s <= s1;
end if;
end case;
end if;
end process;
end Ascensore;