0

I'm working on elevator code in VHDL and I have an issue with signal (przybycie) that shows elevator arrived to choosen floor. There is a code:

    library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.numeric_std.ALL;
use IEEE.std_logic_unsigned.ALL;




entity winda is
    port (clk : in std_logic;
--          przycisk1 : in std_logic; -- 000
--          przycisk2 : in std_logic; -- 001
--          przycisk3 : in std_logic; -- 010
--          przycisk4 : in std_logic; -- 011
            pietro : in std_logic_vector(2 downto 0); -- button
            alarm : in std_logic;
            numer_pietra : out std_logic_vector(2 downto 0);
            koniec : out std_logic);
end entity winda;


architecture winda_arch of winda is

type STANY is (otwarcie_drzwi,spoczynek, wybor_pietra, zamkniecie_drzwi, praca_windy, koniec_pracy);
signal stan, stan_nast: STANY;
signal licznik_pieter: std_logic_vector(2 downto 0) :="000";
signal drzwi: std_logic; -- 0 OTWARTE, 1 ZAMKNIETE
signal przybycie: std_logic :='0'; -- przybycie na wybrane pietro
signal otwarciozamkniecie: std_logic :='0'; -- sygnal otwierania/zamykania drzwi


begin

    reg:process(clk, alarm)
        begin
            if (alarm = '1') then
                stan <= spoczynek;
            elsif rising_edge(clk) then
                stan <= stan_nast;
            end if;
        end process reg;
        
        komb:process(clk, alarm, stan)
        begin
            stan_nast <= stan;
            case stan is
            
            when otwarcie_drzwi =>
                    stan_nast <= spoczynek;
            
            when spoczynek => 
                    stan_nast <= wybor_pietra;
                        
            when wybor_pietra =>
                if (pietro /= licznik_pieter) then
                        stan_nast <= zamkniecie_drzwi;
                        else
                            stan_nast <= wybor_pietra;
                        end if;
            when zamkniecie_drzwi =>
                    stan_nast <= praca_windy;
                        
            when praca_windy =>
                if (pietro = licznik_pieter) then
                    stan_nast <= koniec_pracy;
                else
                    stan_nast <= praca_windy;
                end if;
                
            when koniec_pracy =>
                        stan_nast <= otwarcie_drzwi;
                
            when others =>
            stan_nast <= spoczynek;
            
            
end case;
end process komb;


drzwi<= '1' when stan = praca_windy or stan = zamkniecie_drzwi or stan = koniec_pracy else '0';
otwarciozamkniecie <= '1' when stan = zamkniecie_drzwi or stan = otwarcie_drzwi else '0';


licznik:process(clk,alarm,przybycie,pietro,otwarciozamkniecie)
    begin
        if (alarm = '1' or drzwi = '0' or otwarciozamkniecie = '1') then
            przybycie <= '0';
        elsif (rising_edge(clk)) then
            if (stan = praca_windy) then
                if (licznik_pieter = pietro) then
                przybycie <= '1';   
            elsif ( licznik_pieter > pietro ) then
                przybycie <= '0';
                licznik_pieter <= licznik_pieter - "01";
            else
                przybycie <= '0';
                licznik_pieter <= licznik_pieter + "01";
            end if;
            end if;
        end if;
end process licznik;
    
koniec <= '1' when stan = koniec_pracy or stan = spoczynek else '0';
numer_pietra <= licznik_pieter when drzwi = '0' else "000";

end architecture winda_arch;

And there simulation: simulation picture

Problem is that "przybycie = '1'" should be one clock tact before ( just after licznik_pieter shows "2") how it should be

What is wrong with that code?

toolic
  • 57,801
  • 17
  • 75
  • 117
Saran12
  • 9
  • 1
  • Note the next state (stan nast) transaction from praca_windy to koniec coincidental with the falling edge of clk. You appear to have issues with the komb process sensitivity list (missing pietro, licznik_pieter). Provide a [mcve], here a testbench as the means to duplicate the problem. The asynchronous reset to przybycie in process licznik is combinatorial and can be subject to routing glitches in implementation as well as missing drzwi from the process sensitivity list. Consistent indentation would enhance readability. Note numer_pietra is wrong as well. – user16145658 Jun 09 '22 at 23:28
  • There are a couple more issues. You have your lift taking one clock to move between floors and if you're predicting arrival to przybycie you need to do it where the direction is known (you have increments and decrements for licznik_pieter). – user16145658 Jun 10 '22 at 03:52
  • @user16145658 numer_pietra is correct why is it wrong? Numer_pietra shows current lift floor after arriving. So I need a new input "direction" to make it working? But what then if i need to implement it on FPGA board, i wanted to control it just by buttons ( 1button - 1 floor) – Saran12 Jun 10 '22 at 08:58
  • No you don't need a direction, you already have that where either increment or decrement licznik_pieter. Provide a [mcve], add a testbench. – user16145658 Jun 11 '22 at 02:39

1 Answers1

0

licznik_pieter changes from "2" to "3" after the clock edge, because it is a clocked value.

przybycie cannot become '1' in the same clock cycle but must wait to the next clock edge, when the condition licznik_pieter = pietro is true at the time of the clock edge. (Exactly: a moment before that to satisfy the setup prerequisite.)

EDIT:

To "foresee" the equality one clock cycle earlier, you could for example write:

    if (licznik_pieter + "01" = pietro) then
        przybycie <= '1';

(Hope it works, I don't have any VHDL system ready.)

Or make it a combinatorial result, with the possibility of glitches.

But make sure that this meets all of your requirements and logic.

the busybee
  • 10,755
  • 3
  • 13
  • 30