Signal Transition detection - wait until... or if construct

M

MJ

Hello,

I have a question about "if (....)" and "wait until ..." usage in
testbenches.

I want to wait for a start pulse from the DUT in the testbench to do
some other things.
Process_A does not work. Ready1 is never set.
Process_B works. Why? What is wrong?

Here is are the two processes:

Process_A : process
begin
ready1 <= '0';
if (rising_edge(transfer_start)) then
-- do something ...
ready1 <= '1';
wait for c_clock_cycle;
ready1 <= '0';
end if;
wait;
end process;

Process_B : process
begin
ready2 <= '0';
wait until rising_edge(transfer_start);
-- do something ...
ready2 <= '1';
wait for c_clock_cycle;
ready2 <= '0';
wait;
end process;
 
Joined
Feb 7, 2008
Messages
4
Reaction score
0
Hello MJ,

For the process A and B, you don't use a sensitivity list. If you use this method, only "wait" statement will work. Indeed, the "wait" statement will wait for an event on transfer_start and so, doesn't need to include transfer_start in the sensivity list . For the "if" statement, you need to use a sensitivity list :
Process_A : process(transfer_start)
begin
ready1 <= '0';
if (rising_edge(transfer_start)) then
....
end process;
Else the process isn't executed...

Mathieu
 
J

Jonathan Bromley

Hello,

I have a question about "if (....)" and "wait until ..." usage in
testbenches.

I want to wait for a start pulse from the DUT in the testbench to do
some other things.
Process_A does not work. Ready1 is never set.
Process_B works. Why? What is wrong?

Process_A executes at time zero, and again at regular intervals
because of the "wait for c_clock_cycle" delay. At each execution,
you test rising_edge(transfer_start). This expression is true
only in the exact delta cycle in which transfer_start goes from
low to high (0->1). It isn't going to happen - or, at least,
it isn't going to happen reliably.

Process_B stalls at the "wait until" statement. "wait until"
creates a sensitivity list from all signals mentioned in its
expression - in your case, simply transfer_Start. On *any*
transition of transfer_start, the sensitivity list is tripped
and the expression evaluated. If it's true, the wait is
released; if not, the wait goes back to sleep until the next
transition. Consequently you will asynchronously detect, and
execute on, the rising edge of transfer_start.

If you want to wait until transfer_start has a SYNCHRONOUS
rising edge - in other words, it was zero on the previous
clock event, but it's 1 on the current event- then you need
to store the old value yourself, and do an explicit comparison.
In a testbench, this works well:

procedure synch_await_rise (signal clock, control: std_logic);
variable old_control: std_logic := control;
begin
loop
wait until rising_edge(clock);
exit when control = '1' and old_control = '0';
old_control := control;
end loop;
end;
Here is are the two processes:

Process_A : process
begin
ready1 <= '0';
if (rising_edge(transfer_start)) then
-- do something ...
ready1 <= '1';
wait for c_clock_cycle;
ready1 <= '0';
end if;
wait;
end process;

Process_B : process
begin
ready2 <= '0';
wait until rising_edge(transfer_start);
-- do something ...
ready2 <= '1';
wait for c_clock_cycle;
ready2 <= '0';
wait;
end process;
--
Jonathan Bromley, Consultant

DOULOS - Developing Design Know-how
VHDL * Verilog * SystemC * e * Perl * Tcl/Tk * Project Services

Doulos Ltd., 22 Market Place, Ringwood, BH24 1AW, UK
(e-mail address removed)
http://www.MYCOMPANY.com

The contents of this message may contain personal views which
are not the views of Doulos Ltd., unless specifically stated.
 
P

Paul Uiterlinden

MJ said:
Hello,

I have a question about "if (....)" and "wait until ..." usage in
testbenches.

I want to wait for a start pulse from the DUT in the testbench to do
some other things.
Process_A does not work. Ready1 is never set.
Process_B works. Why? What is wrong?

Here is are the two processes:

Process_A : process
begin
ready1 <= '0';
if (rising_edge(transfer_start)) then
-- do something ...
ready1 <= '1';
wait for c_clock_cycle;
ready1 <= '0';
end if;
wait;
end process;

Jonathan said:
On Sun, 10 Feb 2008 23:07:21 -0800 (PST), MJ <[email protected]>

Process_A executes at time zero, and again at regular intervals
because of the "wait for c_clock_cycle" delay. At each execution,
you test rising_edge(transfer_start). This expression is true
only in the exact delta cycle in which transfer_start goes from
low to high (0->1). It isn't going to happen - or, at least,
it isn't going to happen reliably.


It is not going to happen at all, because transfer_start is not in the
sensitivity list, nor is there a wait on this signal.

What will happen is: Process_A is executed at time zero. Signal ready1 will
be driven '0', and because at time zero there will be no rising edge on
transfer start, the condition of the 'if' will be false. Hence the wait
statement is executed and the process will fall asleep for ever.

If the OP wants to use an 'if', he should add transfer_start to the
sensitivity list, so the process is woken up on each event on this signal:

Process_A : process(transfer_start)
begin
ready1 <= '0';
if (rising_edge(transfer_start)) then
-- do something ...
ready1 <= '1';
wait for c_clock_cycle;
ready1 <= '0';
end if;
end process;

A wait statement is not needed and not allowed if you use a sensitivity
list.

The only difference with Process_B is that Process_B will work only for one
rising edge on transfer_start. After it has driven ready2 low, the process
will be suspended for ever (by the wait statement without arguments).
Subsequent events on transfer_start will have no effect.
 
M

MJ

Thank you for your help.

There is much I have to learn.
I will study again the "process" chapter in vhdl documentation.

Kind Regards

Markus
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top