Search code examples
vhdl

Wait statement to be synthesizable


I have this problem with the VHDL synthesis. I read in multiple articles that the "wait" statement is synthesizable if I only use one "wait until"/process, so that's what I did. So I tried to make a counter which shows at what floor I am (my project consists of an elevator in Logic Design), and it should open the doors for 5 seconds at floors which were ordered. The problem is with the wait statement. I don't know what to replace it to make it work in ISE too.

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;

entity counter is
    port(clk1: in std_logic;
    enable2:in std_logic;
    input_mux: in std_logic;
    dir: in std_logic;
    reset,s_g,s_u: in std_logic;
    q_open: out std_logic;
    q: out std_logic_vector(3 downto 0));
end counter;

architecture c1 of counter is 

signal flag: std_logic:='0';

component test 
port(clock: in std_logic;
a: in std_logic_vector(3 downto 0);
notify: out std_logic);
end component;    

begin
delay: test port map(clk1,"0101",flag);
process
    variable temp:std_logic_vector(3 downto 0):="0000";
    variable q_open_var:std_logic:='0';
    begin
    if (enable2='1') then
         if (s_g='1' and s_u='1') then 
             if (RESET='1') then 
                 temp:="0000";
             elsif (CLK1'EVENT and CLK1='1') then
                  if (DIR='1') then 
                      temp:=temp+1;
                  elsif(DIR='0') then 
                      temp:=temp-1;
                  end if;
             end if;
        end if;
    end if; 
    if (input_mux='1') then 
        q_open_var:='1';
        q_open<=q_open_var;
        wait until (flag'event and flag='1');
        q_open_var:='0';
    end if;
    q<=temp;
    q_open<=q_open_var;
wait on clk1, reset;
end process;
end c1;

Solution

  • Although this structure is supported, you pushed over the limit of what is supported. The synthesis tool must generate registers from what you code. A register does have a clock and a reset input, but the synthesis tool does not know the words clk1 and reset. I.e. is you write

    wait on clk1, reset;
    

    The tool will not know what the reset is, nor what the clock is. Actually, both signals are considered clock triggers.

    But you design is more problematic, as you have if-statements before the asynchronous reset and clock trigger. Although clock-gating is supported, you probably did not intend it.

    Then there is a /second/ clock trigger in you statement: wait until (flag'event and flag='1');. I don't know what you are doing there, but how would you imagine this being realized in hardware?

    You should really stick to standard/advised coding style for predictable behavior. I.e.

    library ieee;
    use ieee.numeric_std.all;
    
    [...]
        signal temp : unsigned(3 downto 0) := (others => '0');
    begin
        temp_proc: process(clk1, reset)
            variable q_open_var : std_logic := '0';
        begin
        if rising_edge(clk1) then
            if enable2='1' and s_g='1' and s_u='1' then 
                if dir = '1' then
                    temp <= temp + 1;
                elsif dir = '0' then
                    temp <= temp - 1;
                end if;
            end if;
        end if;
        if reset = '1' then
            temp <= (others => '0');
        end if;
    end process;
    
    q <= std_logic_vector(temp);
    

    (I left out the q_open part, as it is unclear what you want. Make a SEPARATE process for that, as it is not dependent on reset)

    p.s. I like the five lines of end if; the most ;) Please use proper indenting next time. And use 'elsif' not 'else if'.