2
\$\begingroup\$

There are different ways to wait on a signal change in VHDL. In my testbench I need to wait on a signal but if it does not change in say 100us, then I must continue the test. How to do this?

\$\endgroup\$
0

3 Answers 3

1
\$\begingroup\$

If you are just looking for a change, using a wait with both an on signal and for timeout-value gets the job done:

wait on A for 100 us ; 

When you are looking for more interesting things, you can also use the until. For example, resume when Ready='1' at the rising edge of clock, but timeout if 100 clocks go by and the condition does not happen:

wait on Clk until rising_edge(Clk) and Ready='1' for 100 * TPeriod_Clk ; 

-- Check for ready not responding
assert rising_edge(Clk) and Ready='1' report "no ready.  DUT is not responding" severity FAILURE ;
```
\$\endgroup\$
4
  • \$\begingroup\$ Of course there's some risk when duplicating the condition between the wait and the subsequent assert... in this example the assertion can pass even though the wait was never satisfied and timed out. \$\endgroup\$
    – Ben Voigt
    Jul 28, 2023 at 15:06
  • \$\begingroup\$ @BenVoigt No. If Ready was not 1 when the wait wakes up, it will not be 1 during the assert. Signals only update when a process suspends and since this process uses a wait statement, that would take another wait statement inserted before the assert statement. The only thing this check can miss is that the wait timed out due to Clk not rising. If Clk did not rise, the test case is hopelessly dead and is unlikely to get far - so it is pointless to check for that or worry about it. \$\endgroup\$
    – Jim Lewis
    Jul 29, 2023 at 16:10
  • 1
    \$\begingroup\$ There are two ways for the wait to timeout but still pass the assert. First is if the clock is not running. Second is if Ready is high during part of the clock cycle, but not during the rising clock edge. \$\endgroup\$
    – Ben Voigt
    Jul 30, 2023 at 22:51
  • \$\begingroup\$ @BenVoigt Good point. In the general case, such as I proposed here, that would be a problem, and hence, I updated it. OTOH, in the verification components where I use this sort of code, the entire process maintains alignment to clock and the timeout is based on multiples of the clock period. As a result, the wait statement wakes up on the rising edge of clock - even when it wakes up due to timeout. \$\endgroup\$
    – Jim Lewis
    Aug 1, 2023 at 1:27
3
\$\begingroup\$

You can just combine a wait for with a wait until statement. For your example:

wait until your_bestie_signal`event for 100us;

This will return when an event is registered on the signal or 100 microseconds of simulation time have passed.

\$\endgroup\$
5
  • \$\begingroup\$ Wow its that simple? I wonder why none of my books or resources mention this. \$\endgroup\$
    – gyuunyuu
    Jul 29, 2019 at 13:03
  • 1
    \$\begingroup\$ @Quantum0xE7 Dunno, it's vaguely explained in my Doulos VHDL Golden Reference Guide and you can find some tutorials if you search for "vhdl wait until for", but honestly, I just remember reading the syntax in a SystemC test-bench tutorial where they mentioned that sc_core::wait(a, b) is equivalent to wait until a for b. \$\endgroup\$
    – DonFusili
    Jul 29, 2019 at 16:11
  • \$\begingroup\$ It's not combining them, one is a condition clause the other is a timeout clause. See IEEE Std 1076-2008 10.2 Wait statement. A condition is an expression providing a Boolean value. An explicit timeout clause provides a time expression, which for an implicit timeout clause is TIME'HIGH. Note the standard also requires a separator between an numeric literal and an identifier as in the answer's time expression (15.2). \$\endgroup\$
    – user8352
    Jul 29, 2019 at 16:58
  • \$\begingroup\$ A time expression isn't a lexical element and there is a -2008 lexical element (Bit string) where the lack of a separator can be ambiguous despite a couple of commercial implementations treating time expressions as lexical elements. \$\endgroup\$
    – user8352
    Jul 29, 2019 at 17:10
  • \$\begingroup\$ @user8352 Feel free to edit or provide a more correct answer, it's been years since I wrote a VHDL test, so I'm sure you're right. \$\endgroup\$
    – DonFusili
    Jul 30, 2019 at 7:57
1
\$\begingroup\$

Tested:

use IEEE.STD_LOGIC_1164.ALL;
use IEEE.Numeric_STD.ALL;

entity wwt is end entity; 

architecture bhv of wwt is
signal ts1, tm1, ts2, tm2 : std_logic := '0';
begin
tp1: process
  begin tm1 <= '1';
    ts1 <= '1' after 100 ns;
    wait until ts1 = '1' for 200 ns;
    ts1 <= '0' after 100 ns;
    wait until ts1 = '0' for 50 ns;
    tm1 <= '0';  wait for 100 ns;
  end process;
tp2: process
  begin tm2 <= '1';
    ts2 <= '1' after 100 ns;
    wait until ts2'event for 200 ns;
    ts2 <= '0' after 100 ns;
    wait until ts2'event for 50 ns;
    tm2 <= '0';  wait for 100 ns;
  end process;
end architecture bhv;

And all the waits are terminated by whatever occurs first (event, event+signal value, timeout). Note: wait until = ; means waiting until both: (1) 'event to occur; and (2) the signal value to match;

-- if the signal initially has the specified value, the wait don't recognize the condition to match, as there is no event then - e.g. a "sig <= '1'; wait until sig = '1' for 1 ms;" waits 1 ms.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.