In the previous tutorial we learned the main differences between signals and variables. We learned that signals have a broader scope than variables, which are only accessible within one process. So how can we use signals for communication between several processes?

We have already learned to use wait; to wait infinitely, and wait for to wait for a specific amount of time. There exist two more types of wait statements in VHDL.

This blog post is part of the Basic VHDL Tutorials series.

The Wait On statement will pause the process until one of the specified signals change:

wait on <signal_name1>, <signal_name2> ...;

The Wait Until statement will pause until an event causes the condition to become true:

wait until <condition>;

In fact, Wait On, Wait Until, and Wait For can be combined:

wait on <signal_name1> until <condition> for <time_value>;

This example will pause for 10 nanoseconds, or until signal1 changes and signal2 is equal to signal3:

wait on signal1 until signal2 = signal3 for 10 ns;

Exercise

In this video tutorial, we will learn how to use the Wait On and Wait Until statements for inter-process communication in VHDL:

The final code we created in this tutorial:

entity T07_WaitOnUntilTb is
end entity;
 
architecture sim of T07_WaitOnUntilTb is
 
    signal CountUp   : integer := 0;
    signal CountDown : integer := 10;
 
begin
 
    process is
    begin
 
        CountUp   <= CountUp + 1;
        CountDown <= CountDown - 1;
        wait for 10 ns;
 
    end process;
 
    process is
    begin
 
        wait on CountUp, CountDown;
        report "CountUp=" & integer'image(CountUp) &
            " CountDown=" & integer'image(CountDown);
 
    end process;
 
    process is
    begin
 
        wait until CountUp = CountDown;
        report "Jackpot!";
 
    end process;
 
 
end architecture;

The output to the simulator console when we pressed the run button in ModelSim:

VSIM 2> run
# ** Note: CountUp=1 CountDown=9
#    Time: 0 ns  Iteration: 1  Instance: /t07_waitonuntiltb
# ** Note: CountUp=2 CountDown=8
#    Time: 10 ns  Iteration: 1  Instance: /t07_waitonuntiltb
# ** Note: CountUp=3 CountDown=7
#    Time: 20 ns  Iteration: 1  Instance: /t07_waitonuntiltb
# ** Note: CountUp=4 CountDown=6
#    Time: 30 ns  Iteration: 1  Instance: /t07_waitonuntiltb
# ** Note: CountUp=5 CountDown=5
#    Time: 40 ns  Iteration: 1  Instance: /t07_waitonuntiltb
# ** Note: Jackpot!
#    Time: 40 ns  Iteration: 1  Instance: /t07_waitonuntiltb
# ** Note: CountUp=6 CountDown=4
#    Time: 50 ns  Iteration: 1  Instance: /t07_waitonuntiltb
# ** Note: CountUp=7 CountDown=3
#    Time: 60 ns  Iteration: 1  Instance: /t07_waitonuntiltb
# ** Note: CountUp=8 CountDown=2
#    Time: 70 ns  Iteration: 1  Instance: /t07_waitonuntiltb
# ** Note: CountUp=9 CountDown=1
#    Time: 80 ns  Iteration: 1  Instance: /t07_waitonuntiltb
# ** Note: CountUp=10 CountDown=0
#    Time: 90 ns  Iteration: 1  Instance: /t07_waitonuntiltb
# ** Note: CountUp=11 CountDown=-1
#    Time: 100 ns  Iteration: 1  Instance: /t07_waitonuntiltb

Need the Questa/ModelSim project files?

Let me send you a Zip with everything you need to get started in 30 seconds

How does it work?

Tested on Windows and Linux Loading Gif.. How it works

Analysis

The first process increments the CountUp counter and decrements the CountDown counter. They are updated simultaneously. Although the signal assignments of the two signals are on different lines in the process, assigned signal values only become effective when the program hits a Wait statement. The process performs this operation at the start of the simulation, and then every 10 nanoseconds.

The second process’ first line is wait on CountUp, CountDown;. The program will wait at this line until one or both of the signals change. As we can see from the printout, this happens at 0 ns simulation time when the counters are changed for the first time, and every time they change after that.

The third process’ first line is wait until CountUp = CountDown;. The program will wake up every time one of the two signals change, just like the first process did. But it will only continue if the expression evaluates to true, otherwise it will go back to sleep. As we can see from the printout, “Jackpot!” is only printed once, at 40 ns when both counters have the same value.

Takeaway

  • Wait On will wait until one of the signals change
  • Wait Until will wake up if one of the signals change, but will only continue if the expression is true
  • Wait On, Wait Until and Wait For can be combined

Go to the next tutorial »

Similar Posts

9 Comments

  1. Hello Jonas. I’m loving your tutorials for vhdl so far.
    I have a question about though. could your explain why did you create multiple processes?

    1. Hi Giorgi,

      Nice to hear from you!

      The first process is solely for changing the counter signals. It provides input to the other processes.

      The other two “wait” statements each have their own processes because that’s the only way they could both be waiting at the same time. I wanted to show how “wait on” and “wait until” works, and also introduce you to some of the parallel features of VHDL.

      It’s just a demo, the code doesn’t do anything useful. Although, it is common to have multiple processes waiting on the same signal. For example on the clock signal.

  2. HI Jonas, this is just part of my project
    the Quartus II gives me an error when I try to use …Wait for…
    Error (10533): VHDL Wait Statement error at DE0_TOP.vhd(105): Wait Statement must contain condition clause with UNTIL keyword

    this is part of a test equipment system I inherited for my shop and only have the file (quartus diagram) and the FPGA, I’m new using these devices, electronic engineer but never use it before, really desperate to get it running, can you help me?

    architecture Structural of DE0_TOP is
        -- Signal Declarations
    begin
        -- Set default output states
        process is
        begin
    
            -- 7-SEG Display
            HEX0_D <= "0010010"; -- S
            HEX0_DP <= '1';
            HEX1_D <= "0001000"; -- A
            HEX1_DP <= '1';
            HEX2_D <= "0001100"; -- P
            HEX2_DP <= '1';
            HEX3_D <= "0001000"; -- A
            HEX3_DP <= '1';
    
            wait for (500 ms);
        end process;
    
        process is
        begin
            HEX0_D <= "1000000"; -- 0
            HEX0_DP <= '1';
            HEX1_D <= "1000000"; -- 0
            HEX1_DP <= '1';		  --DP
            HEX2_D <= "0001110"; -- F
            HEX2_DP <= '0';
            HEX3_D <= "1000110"; -- C
            HEX3_DP <= '1'; 
        end process;
    
    1. Hello Julio,

      I think your DE0_TOP module is not really the top module of your design. The code looks more like part of a testbench. The wait for (500 ms); line is not synthesizable.

      And the second process won’t compile because it lacks a sensitivity list or a Wait statement. Every process must have either a sensitivity list or a Wait statement.

      Maybe you should check out my article and video about it:
      https://vhdlwhiz.com/sensitivity-list/

      Finally, it may be that you are trying to synthesize the testbench in Quartus. Setting the testbench as the top module is a typical newbie error that will produce such errors.

  3. Hello Jonas,
    Great tutorial, thanks for putting all this together.
    Quick question; after running simulation, in the output to the sim console, I only get this:

    # ** Note: CountUp=1CountDown=9
    # Time: 0 ps Iteration: 1 Instance: /t07_waitonuntiltb

    Only one iteration.
    Regards,

    1. It looks like the simulation is still starting because we can see the first printout at 0 ps. Are you running the simulation for long enough? More than 0 ps?

      Try to start the simulation from the command prompt and run it for 100 ns like this:
      vsim work.t07_waitonuntiltb

      run 100 ns

Leave a Reply

Your email address will not be published. Required fields are marked *