SV programs - Re: Does Modelsim ASE support SystemVerilog?

D

David Rogoff

Guest
Jonathan Bromley wrote:
On Thu, 19 Aug 2010 23:33:59 +0200, Petter Gustad wrote:

it could be because I tried to use a program as
top level.

OK. The reason I never met this was that I just don't
use programs any more - they had their place in earlier
versions of SV, but they're just syntactic noise now.
Turn the program into a module instead.
Please elaborate!
 
On Fri, 20 Aug 2010 11:27:23 -0700, David Rogoff wrote:

had their place in earlier
versions of SV, but they're just syntactic noise now.
Turn the program into a module instead.

Please elaborate!
heh. How long do you have?

Programs, and their much more useful partner-in-crime
the clocking block, were inherited by SV from the Vera
testbench automation language. Programs (or, more
precisely, THE program because you could have only one)
were the means to encapsulate all the clever testbench
stuff, isolating it from the DUT and its associated
wiring, clock generators and suchlike.

Bear in mind that TB automation tools like Vera and
Specman would typically hook to Verilog through a
PLI-based interface. That imposed some interesting
restrictions on timing, particularly when you try
to drive and sample clock-synchronous signals.
That is where the trouble all starts...

Anyways: history aside, programs were always intended
to encapsulate the testbench parts of SV. But the way
they were specified gave them really bizarre timing
semantics. Let's start at the beginning...

A Verilog simulation, on reaching a moment in simulated
time when something will happen ( a "timeslot"),
starts work on a complicated dance in which...
- code that was put to sleep by #N time delays, such
as clock generators, executes
- that causes signals to update, which in its turn will
trip "@(signal)" sensitivities, causing other code
to be readied for execution
- and so on, until all the code that's ready to execute
has had a chance to do so.
That was the "Active" region of the Verilog scheduler.
However, some of that code has also made nonblocking
assignments using <=. When ALL activity in the Active
region has finished, the simulator moves on and processes
the Non Blocking Assignment (NBA) region of the scheduler.
This updates all the signals that had updates scheduled
for this moment in time using <=. That, in its turn,
usually causes other @(sig) controls to trip, and
fires up a whole new round of Active processing.

And so we go on, until there is nothing at all left to
do in the current timeslot - all activity has gone
quiet, and there's nothing due to happen until some
future timeslot (thanks to #N delays again). Now,
before we move on to some future timeslot, Verilog
gives PROGRAM BLOCKS a chance to execute.

Consequently, if you arrange a program block to execute
on a clock edge using @(posedge clk), which is the
usual deal, you have the strange and unhappy situation
that your testbench sees the settled just-after-clock
values of flipflops, because it doesn't start executing
until all DUT activity at that clock edge has finished.
But it has the advantage that any signals you *drive*
from the program will certainly not race with RTL code
executing at that clock edge.

(Disclaimer: It's a lot more complicated than that.
I thought the edited highlights would be better.)

So, what does a program block do if it wishes to
look at the PRE-CLOCK versions of signals, same
as typical RTL code would expect to see? It can't,
unless it enlists the help of a CLOCKING BLOCK which
allows you to sample signal values as they were just
before the clock edge.

Got all that? Thought so. Thanks for your attention.
Now, let's move on....

Unfortunately the definition of all this stuff in
early versions of SV was not as clear and precise
as it might have been. A huge amount of work was
done (I and others bear the scars to this day) to
try to straighten it out. In the process of
clearing up the LRM definition, various changes
and clarifications got added and the net result
is that you can now use clocking blocks not only
from a program, but also from code in an ordinary
module, and you will get predictable well-behaved
timing from your testbench either way.

Overwhelmingly, this stuff is of interest only
to incurable LRM wonks. Soon after the committee
discussions reached a conclusion, I joyfully added
a bunch of information on this to the Doulos course
material (I was working there at the time); everyone
absolutely hated it, and we took it out again soon
afterwards. The conclusions are clear, though...
- program blocks are a waste of syntax
- testbench code goes in modules like anything else
- clocking blocks are a Very Good Thing for clarifying
the time relationships between a clocked testbench
and a clocked DUT, and avoiding testbench/design
race conditions; use them

Finally, one word of caution: If you use a clocking
block to link testbench to design code, PLEASE be
careful how you trigger testbench activity.
NEVER, NEVER make the testbench sensitive to
@(posedge clk)
Instead, use a clocking block
clocking TestCB @(posedge clk); ...
and then trigger your TB from the clocking:
@(TestCB) do_testbench_stuff;
And, in your testbench, be sure NEVER to look
at synchronous DUT signals directly; instead,
use the clocking block to sample and drive.
Explaining why this is so would take way, way
too long, and you're all asleep already :)
--
Jonathan Bromley
 
Jonathan Bromley <spam@oxfordbromley.plus.com> writes:

afterwards. The conclusions are clear, though...
- program blocks are a waste of syntax
- testbench code goes in modules like anything else
- clocking blocks are a Very Good Thing for clarifying
the time relationships between a clocked testbench
and a clocked DUT, and avoiding testbench/design
race conditions; use them
Thank you for some great advice. I've been away from SystemVerilog
doing VHDL for a couple years. Reading your message I realise that I
have more to pick up than I expected.

//Petter
--
..sig removed by request.
 

Welcome to EDABoard.com

Sponsor

Back
Top