1

I am trying to make an elevator in VHDL, to be implemented on FPGA. It has 0-12 floors, it has buttons for up/down outside, depending on which direction you wish to go, and buttons inside. I am checking first if the outside buttons work, the implementation for inside being the same. Right now it compiles, but the simulation waveform crashes.

Library ieee; 
    use ieee.std_logic_1164.all; 
    use ieee.std_logic_unsigned.all;
    use ieee.numeric_std.all;

entity lift is
    port (
    CLK: in bit;                   --clock initialized by the waveform, for now
    iUP: in std_logic_vector (3 downto 0);                     --input from FPGA
    iDOWN: in std_logic_vector (3 downto 0);                   --output
    iBUTTON: in std_logic_vector (3 downto 0);                 --input from inside the elevator
    W: in BIT;                                                  --weight s
    DOOR: in BIT;                                               --door opened or not
    ETAJ: out std_logic_vector (12 downto 0):="0000000000001");    --output to LCD
end lift;

architecture mama of lift is
signal directie: bit := '1';                                     --direction of lift, 1 up / 0 down
signal pozitie: natural := 0;                                    --position of lift, 0-12
signal sus: bit;                                                 --up
signal jos: bit;                                                 --down
signal UP: std_logic_vector(12 downto 0) :="0000000000000";          --vector for the outside inputs that ask to go up
signal DOWN: std_logic_vector(12 downto 0) :="0000000000000";        --same as above, but down
begin     
    merge: process (UP, DOWN, pozitie)                      --process to determine if the lift goes up or down
    variable i : std_ulogic;                                --the vector with the outside inputs has 1 if the button is pressed, 0 otherwise
    variable j : std_ulogic;   
    begin
    for i in pozitie+1 to 12 loop
        if UP(i) = '1' then
            sus <= '1';
        end if;
    end loop;
    for j in pozitie-1 to 0 loop
        if DOWN(j) = '1' then
            jos <= '1';
        end if;
    end loop;
    end process merge;

    conv: process(iUP, iDOWN)                                              --converts input from binary to int 
    begin
        UP(to_integer(unsigned(iUP)))<='1';
        DOWN(to_integer(unsigned(iDOWN)))<='1';
    end process conv;

    moovit: process (UP, DOWN, iBUTTON)                              --the moving process 
    variable i : std_ulogic;
    begin
        if directie='1' then                                                   --if direction is up and it has to go up
            while sus='1' loop
                if CLK'EVENT and CLK='1' and UP(pozitie)='1' then
                    UP(pozitie)<='0';
                    DOWN(pozitie)<='0';
                end if;
                pozitie <= pozitie + 1;
            end loop;
        else
            while jos='1' loop
                if CLK'EVENT and CLK='1' and DOWN(pozitie)='1' then
                    DOWN(pozitie)<='0';
                    UP(pozitie)<='0';
                end if;
                pozitie <= pozitie - 1;
            end loop;
        end if;
    end process;
end mama;
Bogdan Marcu
  • 105
  • 5
  • 1
    Welcome to StackOverflow. What exactly your design should do and what does not work? How your testbench looks like? Please, provide [mcve] – Staszek May 12 '17 at 18:41
  • OK, so I have to make this elevator project. I described what it has to have/do above the code. I use simulation on waveform from ACTIVE-HDL. I am trying to implement outputs coming from outside the elevator. They come in 0 to 3 vectors, are switched to integers. Inside the architecture I have two vectors for the inputs from all the floors that want to go UP or DOWN. First process checks what direction to go, second converts the input and puts a '1' for the floor where it is an input, third is the moving process. Theoretically, it should be all fine, but on the waveform it isn't – Bogdan Marcu May 12 '17 at 18:42
  • Provide clarification by editing question. – Staszek May 12 '17 at 18:43
  • I edited above ^_^ – Bogdan Marcu May 12 '17 at 18:47
  • If you have waveform, the you should have testbench. Provide it. – Staszek May 12 '17 at 18:50
  • In process merge, variable declarations for i and j are not needed. A loop parameter includes an implicit declaration, a loop statement is an inner declarative region and these are wrong anyway. `for j in pozitie - 1 to 0 loop` is a null range for j when pozitie > 1, and will cause a run time error (a different run time error for pozitie = 0). That `to` should be `downto`. Ask a specific question, provide an MCVE. –  May 12 '17 at 21:17
  • I wrote something but it's too long so I put it in a pastebin here : https://pastebin.com/ZJyag62L – Bogdan Marcu May 13 '17 at 20:12
  • @BogdanMarcu it is not long. Just remove all the unnecessary empty lines... People often paste longer code fragments in StackOverflow. – JHBonarius May 15 '17 at 10:05

1 Answers1

3

There are many things in your code that are not compatible with synthesis. Or at least of which I am not sure if it will work. For instance

merge: process (UP, DOWN, pozitie)
[...]   
for i in pozitie+1 to 12 loop
    if UP(i) = '1' then

You're using a for loop with variable length. This is easy in a processor, but you are writing HDL (Hardware Description Language): how do you imagine using a variable amount of logic gates would work?

In this case you should use a comperator. E.g.:

if unsigned(iDOWN) < pozitie then
    jos <= '1';

Then look at you clocked process. You seem to know how to introduce a clock with CLK'EVENT and CLK='1'. But you put the statement inside if statements and even a while statement! Again: how would you expect that to be realized in hardware?

A normal clock synchronous process looks like this:

clk_process: process(clk)
begin
    if rising_edge(clk) then
        [synchronous statement]
    end if;
end process;

p.s. drop use ieee.std_logic_unsigned.all; if you are already using numeric_std.

JHBonarius
  • 10,824
  • 3
  • 22
  • 41