[PLI] cbValueChange callback behavior at time 0

  • Thread starter Guenter Dannoritzer
  • Start date
G

Guenter Dannoritzer

Guest
Hello,

I have a question about the correct cbValueChange behavior for a
callback at simulation time 0.

I use the $my_monitor system task from the Sutherland PLI handbook. The
system task is called at simulation time 0 in the following way:


addbit i1 (a, b, ci, sum, co);

initial
$my_monitor(i1);

So there is an instance of the addbit module that is passed to the
$my_monitor system task and what the system task does is it iterates
over all nets of the passed instance and registers a cbValueChange call
back for each.

Now the Verilog code is running some stimulus to this instance that
looks like this:

initial
begin
#2 a = 0; b = 0; ci = 0;
#10 a = 1;
#10 a = 0;
#10 b = 1;
#10 a = 1;
#10 $finish;
end

The interesting part about this is that the first assignment is done at
time #2, so at time 0 there is no assignment from the Verilog code.
However, the simulator will assign the value 'x' to the nets at time 0.

My question is now, how should the cbValueChange callbacks behave, when
'x' is assigned to nets at time 0?

I tested this with Cver and Aldec Riviera and both have the first
callback happen at time #2.

Here the output from Riviera:

VPI: Adding monitors to all nets in module addbit:
VPI:
VPI: At time 2.00: my_monitor_test.i1.ci = 0
VPI: At time 2.00: my_monitor_test.i1.b = 0
VPI: At time 2.00: my_monitor_test.i1.a = 0
VPI: At time 2.00: my_monitor_test.i1.n3 = 0
VPI: At time 2.00: my_monitor_test.i1.n1 = 0
VPI: At time 2.00: my_monitor_test.i1.n2 = 0
VPI: At time 2.00: my_monitor_test.i1.co = 0
VPI: At time 2.00: my_monitor_test.i1.sum = 0
VPI: At time 12.00: my_monitor_test.i1.a = 1
VPI: At time 12.00: my_monitor_test.i1.n1 = 1
VPI: At time 12.00: my_monitor_test.i1.sum = 1

Now when I add a $monitor system task and monitor the signals, I get a
signal change to 'x' shown at time 0.

I also ran a similar PLI example with the latest development snapshot of
Icarus Verilog and it did cause a cbValueChange callback to happen at
time 0.

Now my question is, in respect to Cver and Riviera, they must register
the cbValueChange callbacks after the net assignment happened in the
current time step, so they will not cause a callback when a value
changes in the time step when the registration happened.

In the Sutherland book I did not really find any information how this
callback behavior should be in the time step the callback got registered.

Does anyone know what the exact behavior should be? Specific at time 0?

Thanks for your help.

Cheers,

Guenter
 
On Aug 21, 4:23 am, Guenter Dannoritzer <kratfkryk...@spammotel.com>
wrote:
The interesting part about this is that the first assignment is done at
time #2, so at time 0 there is no assignment from the Verilog code.
However, the simulator will assign the value 'x' to the nets at time 0.

My question is now, how should the cbValueChange callbacks behave, when
'x' is assigned to nets at time 0?
I would not expect a value change at time zero. I would not expect
the nets to be assigned 'x' at time zero; I would expect them to be
considered to have been 'x' since before the simulation started.
Consider, if assigning 'x' creates a value change at time zero, what
value did the net have before the assignment of 'x'? It must have had
a value other than 'x', if you expect a value change callback from
assigning 'x'.

Even if there were a change to 'x' at time zero, I still would not
expect it to be visible to this system task. The callbacks will not
be established until the system task is called. That will not happen
until the initial block executes. And the nets will be 'x' before the
initial block executes. Note that a call to $display in the initial
block would show the nets to be 'x' already, so why would you expect
this PLI system task to see anything different?

Now when I add a $monitor system task and monitor the signals, I get a
signal change to 'x' shown at time 0.
You are not seeing a signal change. $monitor always dumps the current
values at the time it is called, whether any of them have changed or
not, before it starts waiting for them to change. This gives you a
starting value in your output, so that you get all values from that
time forward, instead of waiting for the first change. If you called
$monitor at time 1, when nothing changes, you would still get the
values at time 1 dumped.

If you want $my_monitor to behave the same way as $monitor, you could
make it do the same thing.
 
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

sharp@cadence.com wrote:
| On Aug 21, 4:23 am, Guenter Dannoritzer <kratfkryk...@spammotel.com>
| wrote:
|> The interesting part about this is that the first assignment is done at
|> time #2, so at time 0 there is no assignment from the Verilog code.
|> However, the simulator will assign the value 'x' to the nets at time 0.
|>
|> My question is now, how should the cbValueChange callbacks behave, when
|> 'x' is assigned to nets at time 0?
|
| I would not expect a value change at time zero. I would not expect
| the nets to be assigned 'x' at time zero; I would expect them to be
| considered to have been 'x' since before the simulation started.
| Consider, if assigning 'x' creates a value change at time zero, what
| value did the net have before the assignment of 'x'? It must have had
| a value other than 'x', if you expect a value change callback from
| assigning 'x'.

It is a little more complicated then that in practice for a variety
of reasons. First, the initial value for "reg" is defined to be 'x',
even if it is assigned a constant at time 0. So reg variables should
always start out as X, and that x should be propagated through any
logic that it feeds.

The "wire" is defined to be 'z' when unconnected, but has no explicitly
defined initial value. Icarus Verilog uses a value of 'z' so that the
initial pre-time-0 propagation of driven x values is not impacted by
the not-yet-calculated wire. Wires take on the settled value quickly.
That is typically 'x', but isn't necessarily. To wit:

~ reg foo;
~ wire bar = foo === 1'bx;

The "initial" value for bar should be 1, but in general the only way
to know that is to propagate defined initial values until events run
out. So you might see a transition from [xz] to 1 if you get your
valuechange callback in real early.

All this talk about wires (nets) which are *different* from variables
is because Guenther's example (the parts that he didn't post) has
lots of wires, and those are the bits that have confusing behavior.
While variables (reg) are well defined to start at 'x', wires are
not explicitly defined to start with anything, although an initial
value of 'z' is pretty convenient for getting things right.

And how 'bout this fun example:

~ reg foo;
~ wire bar
~ not #5 (bar, foo);

With Icarus Verilog, bar will be 'z' until time-5. That fits nicely
with the argument above.

- --
Steve Williams "The woods are lovely, dark and deep.
steve at icarus.com But I have promises to keep,
http://www.icarus.com and lines to code before I sleep,
http://www.picturel.com And lines to code before I sleep."
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.4-svn0 (GNU/Linux)
Comment: Using GnuPG with SUSE - http://enigmail.mozdev.org

iD8DBQFIvKAPrPt1Sc2b3ikRAsLLAKCoYwd2R77rjl0js+nVuBGPdFOSawCeKOeO
I7zK4cHRgB3aJsPT0YjtK0s=
=R+hj
-----END PGP SIGNATURE-----
 

Welcome to EDABoard.com

Sponsor

Back
Top