Procedure exit on global signal

A

ALuPin

Hi newsgroup users,

I am trying to implement the following in my VHDL testbench:

Within a process (without sensitivity list) I call a procedure "wait_delay".
In the most test cases the signal 't_order_burst_data' gets high when
the procedure is left again.
But there are also some cases where it gets high while the loop
in the procedure is busy. I want the procedure to abort then.
But how can I make the signal 't_order_burst_data' visible for the procedure
all the time ?

I would be very thankful for any suggestions.


procedure wait_delay ( signal clock : std_logic;
signal order_burst_data_in : std_logic) is
variable i : natural;
begin
for i in 0 to 4 loop
exit when order_burst_data_in='1';
wait until rising_edge(clock);
end loop;
end wait_delay;
....

process
begin
wait until rising_edge(t_clk);
for m in 0 to 10 loop
wait until rising_edge(t_clk);
wait until t_order_burst_data='1';
wait_delay(t_clk,
t_order_burst_data);
end loop;
t_continue <= '1';
wait;
end process;
 
J

Jonathan Bromley

Hi newsgroup users,

I am trying to implement the following in my VHDL testbench:

Within a process (without sensitivity list) I call a procedure "wait_delay".
In the most test cases the signal 't_order_burst_data' gets high when
the procedure is left again.
But there are also some cases where it gets high while the loop
in the procedure is busy. I want the procedure to abort then.
But how can I make the signal 't_order_burst_data' visible for the procedure
all the time ?

Write it in Verilog and use "disable" :)

Seriously... this is a common problem. The only solution I know of
is to do a simultaneous wait for all the things that could possibly
affect the waiting. VHDL's "wait on" (dynamic sensitivity list)
makes this easy, but processing the signal changes can be a little
messy.
procedure wait_delay ( signal clock : std_logic;
signal order_burst_data_in : std_logic) is
variable i : natural;
begin
for i in 0 to 4 loop
exit when order_burst_data_in='1';
wait until rising_edge(clock);
end loop;
end wait_delay;

In this case you have only one "wait" so it's quite easy to fix:

OuterLoop: for i in 0 to 4 loop
while not rising_edge(clock) loop
wait on clock, order_burst_data;
exit OuterLoop when order_burst_data_in='1';
end loop;
end loop; -- OuterLoop


Or perhaps you prefer this version:

for i in 0 to 4 loop
wait until (order_burst_data = '1') or rising_edge(clock);
exit when order_burst_data_in='1';
end loop;

Personally I find the first version easier to think about
and to maintain, but it's only a matter of choice.

In general it's a smart move to ensure that processes of this kind
have only one "wait" in them, centralising the waiting so that you
can be sure not to miss anything. This kind of trick works nicely
for resets, interrupts, aborts and similar asynchronous stuff.
--
Jonathan Bromley, Consultant

DOULOS - Developing Design Know-how
VHDL, Verilog, SystemC, Perl, Tcl/Tk, Verification, Project Services

Doulos Ltd. Church Hatch, 22 Market Place, Ringwood, BH24 1AW, UK
Tel: +44 (0)1425 471223 mail:[email protected]
Fax: +44 (0)1425 471573 Web: http://www.doulos.com

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

Duane Clark

ALuPin said:
Hi newsgroup users,

I am trying to implement the following in my VHDL testbench:

Within a process (without sensitivity list) I call a procedure "wait_delay".
In the most test cases the signal 't_order_burst_data' gets high when
the procedure is left again.
But there are also some cases where it gets high while the loop
in the procedure is busy. I want the procedure to abort then.
But how can I make the signal 't_order_burst_data' visible for the procedure
all the time ?

I would be very thankful for any suggestions.


procedure wait_delay ( signal clock : std_logic;
signal order_burst_data_in : std_logic) is
variable i : natural;
begin
for i in 0 to 4 loop
exit when order_burst_data_in='1';
wait until rising_edge(clock);
end loop;
end wait_delay;

Have you tried:
wait until rising_edge(clock) or order_burst_data_in='1';
 
J

Jim Lewis

nospam,
Another post from a truly prolific information leech bought to you by
Google.
Prolific. Perhaps.

A leech? I don't agree with this. I don't consider those
who post their code and sometimes their simulation results
when they ask a question to be leech.

Of course you are entitled to your own opinion and can
always create a filter to remove the person from your
viewing consideration.

If you consider the exact issue in this case. The
solution required the full use of the wait statement
(Jonathan Bromley's second solution):

for i in 0 to 4 loop
wait until (order_burst_data = '1') or rising_edge(clock);
exit when order_burst_data_in='1';
end loop;


I think the author (AluPin) put enough consideration and
the solution was difficult enough that I feel your
comment is unjustified.

Regards,
Jim Lewis

P.S.
It would be polite and civil if both of you would
put a by-line with your real name.
--
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Jim Lewis
Director of Training mailto:[email protected]
SynthWorks Design Inc. http://www.SynthWorks.com
1-503-590-4787

Expert VHDL Training for Hardware Design and Verification
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
M

Mike Treseler

I'm glad that Google now has free web-based
newsgroup service with reasonably quick posting.
At work, I no longer have access to a real news server.

As for the original posting, it was a good,
on-topic question that provoked an illuminating
posting from Mr Bromley. This group is hardly overloaded
with questions in any case.

-- Mike Treseler
 
J

Jim Lewis

Or perhaps you prefer this version:
for i in 0 to 4 loop
wait until (order_burst_data = '1') or rising_edge(clock);
exit when order_burst_data_in='1';
end loop;

Or take it one step further:
wait until order_burst_data = '1' for 5 * tperiod_Clk ;

Where tperiod_Clk = period of clock.
This will wake up in 5 clocks or when order_burst_data = '1'.
Note, you do need to be careful how you setup clock when you
start using "wait for" that is multiples of tperiod_Clk.

One way to avoid issues is to make sure the wait for
is not a multiple of clock and re-align with clock:

wait until order_burst_data = '1' for 5 * tperiod_Clk - 2 ns ;
wait until rising_edge(Clock) ;
-- wait until Clock = '1' ; -- alternate to rising_edge but not identical

The "2 ns" is assumed to be << tperiod_Clk. I often
use a propagation delay constant instead of a literal.


Wait in any of the above forms is a very fundamental
part of testbenches.

Cheers,
Jim
--
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Jim Lewis
Director of Training mailto:[email protected]
SynthWorks Design Inc. http://www.SynthWorks.com
1-503-590-4787

Expert VHDL Training for Hardware Design and Verification
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
G

Guest

Jim Lewis said:
nospam,
Prolific. Perhaps.

A leech? I don't agree with this. I don't consider those
who post their code and sometimes their simulation results
when they ask a question to be leech.

If you care to check the OPs posting history on Google you will find 10
pages of posts. If you inspect them you will find perhaps two or three
posts to threads which the OP did not originate with a question.

These are the first line of each post in the first page

Hello, does someone know
Hi @ all, is it possible to
Some additional question:
3.what is the advantages and disadvantages of
Some additional thing: "Differential" is the wrong expression. I need
LIBRARY ieee; USE ieee.std_logic_1164.all; LIBRARY work;
Hi, is the following CAM-implementation synthezisable?
hi how do i detect a state change of a signal
Hi, I have a question
Hi everybody, How can I put

Notice a pattern?

Information leech seems an appropriate term for someone who asks but never
answers questions.

My recent observation is that it is an appropriate term for the majority of
people accessing technical groups via google.

Google users seem to regard usenet as a free consultancy service and as
long as there are enough suckers who bother to read and contribute to their
threads it will work for them.
Of course you are entitled to your own opinion and can
always create a filter to remove the person from your
viewing consideration.

I am currently kill filing the majority of Google posters, I wish it could
be automated. If you don't want to see usenet turn into a wasteland of
unanswered questions I suggest you do the same.
 
J

Jonathan Bromley

Or take it one step further:
wait until order_burst_data = '1' for 5 * tperiod_Clk ;

Where tperiod_Clk = period of clock.

Brilliant for wait-with-timeout, but...
This will wake up in 5 clocks or when order_burst_data = '1'.
Note, you do need to be careful how you setup clock when you
start using "wait for" that is multiples of tperiod_Clk.

Indeed; the timeout will probably expire in the same delta
cycle that *schedules a change* on the clock. A recipe
for disaster and race conditions.
One way to avoid issues is to make sure the wait for
is not a multiple of clock and re-align with clock:

wait until order_burst_data = '1' for 5 * tperiod_Clk - 2 ns ;
wait until rising_edge(Clock) ;
-- wait until Clock = '1' ; -- alternate to rising_edge but not identical

I can't say I like this very much. It takes us back to the OP's
problem - there is a window of time in which the wait is insensitive
to "order_burst_data" (I think I got that signal name wrong in my
post, but whatever...). A dead time of 2 ns is just as bad as
a dead time of several microseconds. Always remember the first
mantra of concurrent programming:

Never confuse the unlikely with the impossible.

Of course we can fix this...
wait until order_burst_data = '1' for 5 * tperiod_Clk - 2 ns ;
wait until order_burst_data = '1' or rising_edge(Clock) ;
but this justifies my case for keeping only one wait statement
in such a process: the various conditions now need to be replicated
in all the wait statements. It's a mess, hard to write, hard to
maintain and hard to understand.
--
Jonathan Bromley, Consultant

DOULOS - Developing Design Know-how
VHDL, Verilog, SystemC, Perl, Tcl/Tk, Verification, Project Services

Doulos Ltd. Church Hatch, 22 Market Place, Ringwood, BH24 1AW, UK
Tel: +44 (0)1425 471223 mail:[email protected]
Fax: +44 (0)1425 471573 Web: http://www.doulos.com

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

Jim Lewis

I can't say I like this very much. It takes us back to the OP's
problem - there is a window of time in which the wait is insensitive
to "order_burst_data" (I think I got that signal name wrong in my
post, but whatever...). A dead time of 2 ns is just as bad as
a dead time of several microseconds. Always remember the first
mantra of concurrent programming:

Never confuse the unlikely with the impossible.

Right because the unlikely always seems to happen within the
first second of plugging in the board.

Point taken, for this problem, it would be much better to wake
up a simulation resolution time step before clock. A function
(named Sim_Resolution) is being added to std.standard in VHDL-200X.

I also fell into my normal testbench mode of keeping everything
synched up to the reference clock for the interface.

OOPS I temporarily ignored ApuPin's issue waking on
order_burst_data as it violates one of my testbench
rules - always stay aligned with your reference clock
(unless waking up to handle errors).

It's a mess, hard to write, hard to maintain and hard to understand.

Using wait in this manner is fairly common testbench stuff.
It stays easy if you can shy away from the asynchronous
stuff and avoid race conditions. However, avoiding race
conditions is a simple procedural issue.

Cheers,
Jim
--
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Jim Lewis
Director of Training mailto:[email protected]
SynthWorks Design Inc. http://www.SynthWorks.com
1-503-590-4787

Expert VHDL Training for Hardware Design and Verification
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 

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

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,482
Members
44,901
Latest member
Noble71S45

Latest Threads

Top