Question on variables in a procedure....

W

wpiman@aol.com

Guest
I have a gut feeling that this has to do with variables being created
and destroyed- but perhaps someone can explain it properly for me.

I am writing a TB and have a procedure which simply wiggles some lines
based off of times passed to it..

Say...
procedure timingGeneration(
timeAtoB, timeBtoC, timeAtoA, (all times)
a,b,c (all outputs)...

This is just a simple loop. I call it concurrently.

In this procedure I declare a variable (std_logic) called AtoA_Done. I
am trying to set this variable up to fire when A goes active with a
delay on it.

AtoA_Done := '1' AFTER timeAtoA; -- Causes problems- doesn't compile
also
AtoA_Done := '0', '1' AFTER timeAtoA; -- Didn't work either


I then do all the other transitions and at the end of the loop
perform...

WAIT UNTIL AtoA_Done = '1';

This should all work just fine for me- but I cannot seem to get by the
fact that the variable cannot be assigned with a delay.

Is this doable? I can't declare local signals.
 
wpiman@aol.com wrote:

Say...
procedure timingGeneration(
timeAtoB, timeBtoC, timeAtoA, (all times)
a,b,c (all outputs)...

This is just a simple loop. I call it concurrently.
If you want the procedure to produce delays,
call it from a main process with no sensitivity list.

See procedure handshake_cycle in the testbench link here:
http://home.comcast.net/~mike_treseler/


-- Mike Treseler
 
AtoA_Done := '1' AFTER timeAtoA; -- Causes problems- doesn't >compile
also
AtoA_Done := '0', '1' AFTER timeAtoA; -- Didn't work either
Signal assignments assign waveforms to signals, not to variables. You
cannot use AFTER in variable assignments (at least up to VHDL'93). Als,
varibles do not generate events, so you can wait until <condition
containing variable>, but not assume that the wait is triggered when
the variable changes.

Hubble.
 
wpiman,
Please use your name in the future as it feels more polite.

In your example, you are calling a subprogram concurrently.
The objects you want to drive to the design under test
are signals. By default, all inputs to a subprogram are
constant class and all outputs are variables. To make your
outputs signals, you need to specify the class on the
interface to the subprogram:

procedure timingGeneration(
constant timeAtoB, timeBtoC, timeAtoA, (all times)
signal a,b,c (all outputs)...

Although this solves your problem, the same problem can be
solved with a simple process. So I would not bother with
using a subprogram in this manner.


In general, a testbench needs to create a sequence of
waveforms, or interface actions. One way to do
this write a procedure that creates one interface sequence
and call it multiple times from a process. For example:

TestCpuProc : process
begin
wait until nReset = '0' ; -- system entered reset
wait until rising_edge(Clk) and nReset = '1' ; -- system exiting reset
wait until rising_edge(Clk) ; -- some systems take several clks to exit reset
wait until rising_edge(Clk) ; -- some systems take several clks to exit reset
wait until rising_edge(Clk) ; -- some systems take several clks to exit reset
CpuWrite(parm1, parm2, parm3) ;
CpuRead (parm1, parm2, parm3) ;
CpuWrite(parm1, parm2, parm3) ;
. . .

wait for 10 * tperiod_Clk ;
report "Test Done" severity failure ;
end process ;


For each set of unique waveforms I need to create, I create one
procedure call. Hence for a simple CPU, I start by creating
CpuRead and CpuWrite procedures and then build from there.

When setting up procedures in this manner, use signals for:
All IO to/from architecture (ie: Design Under Test, Clk)
Any object name used in a wait statement
Any object name using a signal attribute ('event)

Use variables for:
Outputs that go to the process
For example: ErrorCount or Value read

Use constants for:
Any input value that does not change during the execution of the subprogram
Note constants can be computed at run time from an expression
Note also that signal and variables are a simple form of an expression.


This ought to get you started.

Cheers,
Jim

I have a gut feeling that this has to do with variables being created
and destroyed- but perhaps someone can explain it properly for me.

I am writing a TB and have a procedure which simply wiggles some lines
based off of times passed to it..

Say...
procedure timingGeneration(
timeAtoB, timeBtoC, timeAtoA, (all times)
a,b,c (all outputs)...

This is just a simple loop. I call it concurrently.

In this procedure I declare a variable (std_logic) called AtoA_Done. I
am trying to set this variable up to fire when A goes active with a
delay on it.

AtoA_Done := '1' AFTER timeAtoA; -- Causes problems- doesn't compile
also
AtoA_Done := '0', '1' AFTER timeAtoA; -- Didn't work either


I then do all the other transitions and at the end of the loop
perform...

WAIT UNTIL AtoA_Done = '1';

This should all work just fine for me- but I cannot seem to get by the
fact that the variable cannot be assigned with a delay.

Is this doable? I can't declare local signals.

--
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Jim Lewis
Director of Training mailto:Jim@SynthWorks.com
SynthWorks Design Inc. http://www.SynthWorks.com
1-503-590-4787

Expert VHDL Training for Hardware Design and Verification
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
<i>Signal assignments assign waveforms to signals, not to variables.
You
cannot use AFTER in variable assignments (at least up to VHDL'93). Als,
varibles do not generate events, so you can wait until &lt;condition
containing variable&gt;, but not assume that the wait is triggered when
the variable changes. </i>&lt;p&gt;Ok- that is a good way to say it- I think
I was trying to cheat by having a sequential statement (the procedure
in this case) spawn a separate thread if you will (the delay on the
signal)- then having the sequential statement wait on the thread to
complete. I could probably get away with this in a process within the
body of the testbench concurrent to the main process. I will see if I
can do it in a scalable way.
 

Welcome to EDABoard.com

Sponsor

Back
Top