"wait on" accepts a list of signals, and is released when any one of those signals has an event.
"wait until" accepts a Boolean expression. It automatically creates a "wait on" sensitivity list from all signals that participate in the expression; whenever one of those signals changes, it wakes up, tests the expression and releases if the expression is true. If the expression is false, "wait" goes back to sleep waiting for the next signal change.
You can also add a timeout using "wait for".
wait until Ack = '0';
is automatically re-written by VHDL as
wait on Ack until Ack = '0';
and therefore it's pointless to put the 'event test into the expression.
You could also (very usefully for a testbench) do
wait until Ack = '0' for 10 us;
and now the wait will time-out if Ack has not gone to zero within the specified timeout. Of course, this means that you need to test Ack when you come out of the wait:
wait until Ack = '0' for 10 us; assert Ack = '0' report "Timeout failure waiting for Ack='0'" severity ERROR;
If you provide an explicit "on" sensitivity list, then the automatic sensitivity list is not created:
wait until Ack = '0' and Ready = '1'; -- wakes up on every event on Ack or Ready
wait on Ack until Ack = '0' and Ready = '1'; -- doesn't wake up on Ready events, but only on Ack events
Finally, note that "wait until" is always edge-triggered. If the "until" condition is already true when you do the wait, it will NOT release immediately - it needs at least one signal transition to be released. So you may need something like this:
if Ack /= '0' then wait until Ack = '0'; end if;
if there's a risk that Ack might already be zero before you hit the wait statement.
Jonathan Bromley, Consultant
DOULOS - Developing Design Know-how