Horizons Feb 09
Horizons Feb 09
Horizons Feb 09
in HDL-based testbenches. more Our feature article for this issue comes from our
friends at Contemporary Verification Consultants, a Questa Vanguard partner located in India.
In “Achieving a Higher Quality Design through Questa,” they present a case study detailing
the advantages of many of the advanced verification techniques discussed in previous issues
of Verification Horizons. The article shows how constrained-random In our Partners’ Corner, you’ll find the third and last installment of
stimulus, functional coverage, and the SystemVerilog DPI, particularly Doulos’ “A Practical Guide to OVM” series (see the June and October
as supported by Questa , were used to more efficiently create a 2008 issues for parts one and two). This part of the guide shows
more robust verification environment than the previous directed-test how to get started writing sequences in OVM 2.0. I’d like to take this
environment. Their focus on functional coverage allowed them to opportunity to thank John Aynsley and all our friends at Doulos for
exercise many more scenarios beyond what the designers could contributing this valuable multi-part guide. We conclude this issue with
code by hand, thus exposing many issues early in the process that our Consultants’ Corner article, contributed by Mentor’s European
had been missed in the previous design. The more robust verification Verification Practice Consulting group, on using the SystemVerilog
environment resulted in a higher quality product using a much more “bind” construct to provide a low-risk migration path to incorporate
predictable, and less risky, process. advanced verification techniques in HDL-based testbenches.
Our next two articles deal with minimizing the risks associated with So, in winter in New England, it’s important to stay warm and be
verifying the increasing complexity of your designs. In “Reduce the thankful for friendly neighbors and family to help in times of need. In a
Risk of Expensive Post-Silicon Debug,” you’ll see how our 0-In CDC stormy economy, it’s even more important to protect yourself from the
product can accurately model the metastability inherent in your multi- “cold” of risk in your verification process. Remember that we here at
clock designs — you know, those intermittent bugs that usually show Mentor Graphics will be ready with a “chainsaw” and a “pickup” to help
up only in the lab. The article shows you how those bugs can now be you weather the storm.
found and eliminated as part of your RTL verification step. Next we So now it’s time to sit by the fire, grab a cup of hot chocolate,
look at another type of synchronization in “Mitigate Multi-Processor and settle in to enjoy this latest issue of Verification Horizons.
Synchronization Risks with Processor Driven Verification.” The article
discusses the requirements for an effective multi-processor verification
environment, especially in synchronizing the processors with each
other and providing a powerful non-intrusive debug environment that Respectfully submitted,
shows each processor and all of the hardware together. You’ll see how
Questa Codelink™ makes it easier to debug and verify such a complex Tom Fitzpatrick
SoC design. Verification Technologist
Mentor Graphics
Another area where many of our customers are looking to reduce
risk is when moving to the Open Verification Methodology (OVM)
from their current legacy Verification Methodology Manual (VMM)
environments. While they recognize the advantages of the OVM (as
discussed in previous Verification Horizons articles), there are times
when an engineering team is reluctant to replace or rewrite legacy
VMM components, so interoperability has become a critical issue. In
December, Mentor Graphics released an open-source interoperability
library to address this problem (see http://www.ovmworld.org/
contributions-details.php?id=30). “Reusing Legacy VMM VIP in OVM
Environments” gives an overview of this solution, which addresses
the requirements set out by the Accellera Verification IP Technical
Subcomittee.
2
Table of Contents Verification Horizons
is a publication of Mentor Graphics
Corporation, all rights reserved.
Page 5... Achieving
Higher
Editor:
Quality Design through Questa Tom Fitzpatrick
by Ajeetha Kumari, CEO and V. Govind Bagath Singh, Verification Lead, CVC
Program Manager:
Rebecca Granquist
Page 11... Reduce
the Risk Senior Writer:
of Expensive Post Silicon Debug Todd Burkholder
by Rindert Schutten, Senior Marketing Manager, Mentor Graphics
Wilsonville Worldwide Headquarters
Partner’s Corner:
Consultant’s Corner:
Page 27... Are
You in a “bind”
with Advanced Verification?
by Virginie Mallez, Mark Peryer, Andy Walton, and Paul Williams,
Verification Practice, Mentor Consulting (Europe)
3
“The current economic
climate is as inhospitable
as a New England winter,
so to survive we have to
“bundle up” and try to
keep warm. In business
terms, that means keep
going as best we can
while minimizing our
exposure to risks.”
4
Achieving Higher Quality Design through Questa
by Ajeetha Kumari, CEO and V. Govind Bagath Singh, Verification Lead, CVC
The design and verification of a complex image processing system The functionality of the block is best explained with the following
consisting of various image enhancement techniques is a very figures. In these two sample images, the LHS one shows the defects
challenging and daunting task. The sheer complexity of algorithms and (marked in BOLD for ease-of-identification) and the RHS is the
their wide range of applications mean that there are many different corrected image. The defective locations shown are only indicative
scenarios and corner cases to verify and also to ensure that the with the real life ones being more dense and wide spread.
system is behaving correctly. Traditionally such designs have been
verified with mostly directed tests and teams have been successful Original image with defects Expected, corrected image
in doing so. However, with more complex systems being designed (from CCD)
with shrinking time-to-market, this approach doesn’t scale up. The
complexity factor requires more powerful verification technologies
while the time-to-market pressure involves managing and mitigating
risks. Recent advances in Higher Level Verification techniques aim
to address these challenges. However a raw set of features such as
constraints, coverage, assertions etc. alone don’t appeal directly to
such design teams as they are left to ponder which one to use where.
This is where a tailored verification approach based on proven and
robust verification platform fits in.
In this paper we share our recent experience of verifying an image
correction algorithm block using sophisticated verification techniques
offered by SystemVerilog along with robust and easy-to-use
verification platform - Questa.
DUT description
An image captured via CCD sensor contains known defects
and a piece of hardware attempts to correct these errors on the
fly. The defects may appear anywhere in the picture and the CCD
manufacturers provide a list of known-bad-pixel locations along with
the CCD. Depending on the quality and the cost of the CCD, the
defect density varies. Several algorithms exist to correct such defects Previous DV approach
with almost all of them involving replacing the defective pixel with a In the previous project, a similar verification was done using
“computed” value. The complexity of the algorithm varies depending Verilog based testbench with the image being fed in as input and the
on the expected defect density profiles. Whereas a previous defects fed in via testcases. Code coverage was used to measure the
generation design used a simple algorithm that looked at adjacent implementation level completeness. It worked and found design errors;
pixels, the new design involved a more sophisticated one that involves the kind of defect density profiles that were simulated was directly
four adjacent pixels and four diagonal pixels. Care should be taken dependent on the creativity of the verification engineer. The directed
to use only good pixels from the neighbourhood while computing a tests missed critical corner cases as they tend to revolve around a few
replacement value; for instance if there are two adjacent rows with known weak areas where defects were more likely. With no access to
defective pixels, the computation should skip immediate row values unlimited DV resources, the designs were taped-out after a rigorous
and those shall not be used in the computation. series of directed test runs. The resultant designs met a class of
applications such as casual photography, but the quality of design was
5
below acceptable standards for some other target applications, • Constrained- random is not easy to measure/visualize/track
such as professional photography. • Teams need to analyze new metrics, probably learn new
coverage analysis tools
• Integration difficulties of previous generation C-Verilog
The DV scrutiny
interface – PLI
The DV team along with the system architects did a methodical
scrutiny of the DV process to find areas for improvement for the
As a QVP member, CVC addressed these concerns by doing a
next project. As a valued QVP (Questa Vanguard Partner) member
quick demo of the Questa verification platform and SystemVerilog.
and SystemVerilog based verification services provider, CVC (www.
The key takeaways of that demo were:
noveldv.com) was invited to the review. During the scrutiny process the
following key observations were made:
• Questa’s solver is indeed robust and provides a wider distribution to
cover various corner cases. When augmented with a well-crafted
• The defect density profiles verified were limited to the
functional coverage model, the randomness can be measured and
DV engineer’s imaginations/timelines.
progress indicators can be quickly generated.
• Reliance on single metric of implementation coverage
• The functional coverage analysis in Questa is nearly the same as
masked certain spatial defect occurrences.
the code/implementation coverage metric that the teams were
• Lack of self-checking ability caused inefficiencies
familiar with. Intuitively laid out coverage results made most of the
in the entire process leading to several golden files,
analysis self explanatory.
at times stagnant from previous runs.
• A few members wanted to take the combination to the next level
by the ability to combine implementation coverage with functional
The DV team wanted to look at ways to improve the quality coverage. With Questa’s advanced Unified Coverage DB
standards and mitigate the risk in the new project that involved even capabilities this was achievable (though yet to be deployed).
more complex algorithm for correction. • SystemVerilog’s DPI is a higher abstraction, functional-level
interface than detailed signal-level one. This meant that the system
The DV Savior architect’s C-golden reference model can directly be reused during
the simulation phase to qualify the test run as PASS/FAIL.
With the key weak areas identified, the CVC team was tasked
with quickly coming up with solutions to address the issues. One
additional requirement enforced was that any new approach should
be widely usable and deployable across the Design and Verification Revamped DV savoir faire
team. The teams were quite familiar with ModelSim and hence they Adopting Functional Coverage
preferred a GUI that’s as friendly (or better). After a careful analysis
Our team added functional coverage on existing design and
of the DV scrutiny results, CVC suggested a modern verification
showed why the code coverage alone (used in previous project)
approach involving three new technologies to address the previous
was not sufficient and how it missed some important corner cases
shortcomings:
and scenarios. One of the characteristics of an image processing
block is its data centric, computation heavy implementation. The old
• Apply constrained-random technique to create verification was focused only on getting all the computation logic
the defect density profiles intact, but it overlooked the spatial occurrence of the defects at various
• Add functional coverage on top of code coverage possible spots. There were many directed defects inserted and verified
• Build a self-checking mechanism via SystemVerilog DPI but the verification completeness was only as good as the individual
creativity of scenarios. Unfortunately code coverage, which showed full
While some of the DV team members quickly appreciated the new coverage for all the computational elements such as adders, shifters
proposal, others were apprehensive about the potential added risks etc doesn’t truly reveal functional holes, which were missed. Once the
such as:
6
functional coverage mindset was introduced the designers and micro- problem. A few useful tips for the early constraint users are:
architects came up with interesting coverage goals. The table shows a
few of them. • Use –solvefaildebug flag
Coverage aspect Cover expression Comments Preview with vsim command line.
Two consecutive Bad_ pixel_loc Computation should This prints extended debug
rows of defects ignore “known bad information regarding constraint
pixels” and use the conflicts and also tries to create
“corrected values” a reduced testcase to understand
or skip the bad row the constraint model in isolation.
Intersecting Bad_ pixel_loc Intersections get • As the model grows bigger,
defect rows & corrected twice using the command line option may
columns not be the most preferred mechanism.
This is especially true where multiple
Is every pixel Bad_ pixel_loc X Ensure that the folks are concurrently developing parts
location marked image_dimension correction algorithm of testbench code. Questa provides
as defective (Cross) can handle defects a nice attribute that can be in-lined in
(across sim at any location the randomize() call that provides
runs) solver debug for selected parts
of testbench alone.
As the samples above indicate, functional coverage brings in
higher abstraction than low-level implementation coverage; one could
appreciate the “visualness” in the defect pixel location. SystemVerilog
provided the necessary language hooks to capture such advanced
coverage goals at a higher level of abstraction. Questa provides an
intuitive, easy to comprehend view of the coverage results very similar
to its code coverage analysis, which made the verification engineers
feel at home while analyzing new, more complex information. As One of the significant benefits of adopting a constrained random
the team became more and more familiar with functional coverage, testbench is the ease of adding additional tests compared to a
they learned how much more useful it is to digest and analyze the traditional, directed testbench. With the old testbench setup, every
information it provided vis-a-vis the raw data that code coverage used time a new testcase is needed, the de-facto approach is to copy-paste
to provide. the old test and tweak the defect density profiles. With constrained
random testing there are very significant changes:
Exploiting constraint solver capabilities
The next challenge was to ensure the full set of coverage goals was • First of all, using different random seeds is very likely to create
achieved in a reasonable time frame. While the textbook definition of different defect density profiles. In Questa one can use the
constraints tends to project as if constraints shall be used to model all vsim –sv_seed option to pass a different seed. With this,
stimuli, our team took a rather pragmatic approach. We used the raw the same SystemVerilog test code creates different “density
image inputs and used constraints to randomize the defect locations profiles”. This is very powerful as it eliminates the need to
and their density. With the powerful solver engine in Questa, very maintain several tests in the old setup.
interesting defect density profiles were randomly generated and fed • While using the random seed is a good option, the ROI (Return
to the DUT. Such profiles are very hard, if not impossible, for directed on Investment) of running several seeds tends to taper off at
testcase writers to conceive and code. As with any new technology, some point. This is not a bad sign, but rather an indication of how
early users of constraint-random verification are prone to make errors constrained the state space is. SystemVerilog provides various
in their constraint models. Questa comes with a nice, easy-to-use ways to alter the state space targeted by constrained random
solver debug interface that points quickly to the source code level generation such as:
7
- Turn constraint blocks ON/OFF are randomly generated, the path to achieving coverage is to focus/
- Inline constraints to further shrink the state space constrain “around” the goals more than “exactly on the goals”. A Few
- Layered constraints to override base class constraints etc. guidelines to keep in mind while closing in coverage holes are:
8
The choice of 2-state data type
across the boundary is a conscious one
as the reference model is at a higher
level of abstraction, unaware of X/Z of
hardware. We used SystemVerilog’s
$isunknown system function at the
boundary and simple assertions to
catch any violations of this assumption.
The C-side function prototype looked
like:
Questa’s DPI integration capabilities
ensured that the checker integration is
smooth. Once we generate a shared
object file, vsim –sv_lib is all that is
needed to integrate it.
Questa provides an integrated
C-debugger that is very handy during
the debug phase of this project. It is
much like standard GDB for C but with
a tighter integration to traditional HDL
The real challenge in using DPI is to find the right mapping of SV to debug windows. This made the RTL
C datatypes. In this project we used static, unpacked arrays across the team and the Verification team feel at home while debugging foreign
SV-C boundary and the mapping was done as follows: language. For the System team to debug the reference model, CVC
demonstrated a nice way to quickly focus on C-code without having to go
behind several HDL/SV lines of code. This feature is called “Auto BP” in
SV datatype C-datatype Questa’s C-debug flow. When enabled, it sets breakpoints automatically
bit [31:0] pixel_in const svBitVecVal* pixel_in at every SV-C boundary call without the user having to know the location
[0:307200] of files, libraries etc. Below is a screenshot of how Questa quickly takes
int no_of_bad_ pixel const int no_of_bad_ pixel the user to the relevant C-entry point after “Auto BP”.
bit [18:0] bad_ pixel[0:99] const svBitVecVal*
bad_ pixel Summary
Putting it all together, the functional coverage, constraint-random
generation and the DPI were the key
SystemVerilog features that proved vital
for achieving a higher quality design.
The power of functional coverage
enabled the micro-architects to capture
more stringent quality requirements as
executable verification goals that were
previously handled in ad-hoc manner.
The combined strengths of code and
functional coverage used together
resulted in finding more design errors
than with the previous approach of
9
relying on code coverage alone. Adoption of constrained random
generation brought down the number of directed tests significantly
and also enabled the team to achieve tougher verification goals in a
shorter span of time. Clearly the old approach doesn’t scale up well
to rising demands of higher quality designs. Finally the debug of a
failing simulation run got accelerated multi-fold by the reuse of the
C-reference model and Questa’s well integrated debug solution. As
a near future enhancement the team is exploring extending the DPI
integration to every pixel level computation to isolate issues very close
to their occurrence.
Needless to say the language is only as powerful as an
implementation and its ease of use. Questa has excellent support for
the IEEE 1800 SystemVerilog standard and its intuitive debug and
analysis capabilities make advanced verification fun indeed!
About CVC
CVC (Contemporary Verification Consultants Pvt. Ltd.
http://www.noveldv.com) is a high end DV Startup
Company focused on THE most challenging aspect in
today’s semiconductor industry - Functional Verification. We have all it
takes to make the functional verification of your ASIC/SoC successful
- be it:
10
Reduce the Risk of Expensive Post Silicon Debug
by Rindert Schutten, Senior Marketing Manager, Mentor Graphics
A 2007 study by Far West research found that less than 30 percent that it takes an unpredictable amount of time for the output to settle.
of ASIC designs have first silicon success, and the majority of these Moreover, the logic value that the output will ultimately settle to cannot
flawed chips have functional flaws. Hence over 70 percent of all be predicted.
ASICs—and anecdotal evidence suggest that for FPGAs this number To account for this behavior, designers need to use dedicated
is much higher—require extensive debugging in the lab, often referred design structures, called synchronizers, to make sure that these
to as post-silicon debug. metastable signals do not contaminate the rest of the design. In
Post-silicon debug is hard and expensive. It requires expensive other words, synchronizers confine the scope of metastable signals
instrumentation, and observability (when compared to simulation) is to the internals of the synchronizers. There are various kinds of
strongly impaired, because only a few of the thousands of important synchronizers. A basic synchronizer is a 2DFF, as shown in figure
internal signals are directly accessible during normal chip operations. 1. For most implementation libraries, a 2DFF synchronizer reduces
As a result, post-silicon debug is often a labor intensive process. the probability that its output will become metastable to practically 0
There is, however, a category of bugs that are even harder to find (in the lifetime of the device). In [1] more background information on
and debug post silicon than “regular” functional bugs. These bugs metastability is given. 
manifest themselves intermittently and are not repeatable. These
bugs seem to appear randomly, sometimes, for example, they only
appear (or disappear) after the chip has warmed up. Other times they
seem to happen every now and then in a completely random fashion.
These bugs behave this way because they are caused by stochastic
events deep inside the silicon. Locating and exterminating these
bugs—compared to regular, repeatable functional bugs—is even more Fig. 1. An example of a simple 2DFF synchronizer circuit. The red
daunting, and a lengthy, unpredictable post-silicon debug process bars represent the setup/hold window around the positive clock edges.
is almost a given. A large set of bugs in this category originate from In general, tx should not change value within this window. However, in
faultily designed clock domain crossings. asynchronous multi-clock designs, this will happen. When it does, you
Clock domain crossings are present in many chips because can not accurately predict when rx will change value.
today’s chips (both ASIC and FPGA) increasingly require a set of
asynchronous clock domains, and the communication between Irrespective of which synchronizers you use, the basic non-
these clock domains, the clock domain crossings (CDC), have to determinism resulting from metastability is not eliminated. In fact,
be designed very carefully to ensure consistent, correct behavior in all synchronizers, while doing a good job of containing metastable
silicon. Errors in the design of these CDCs are typically not found signals, exhibit non-deterministic delays. This means that, when
during simulation, and therefore, if bugs are present, they escape to metastability conditions on the first flip-flop are present, you cannot
silicon, causing the tremendous headache of debugging intermittent accurately predict at what cycle, in the receiving clock domain, a value
bugs post-silicon. This article explains how to eliminate these bugs change will be propagated.
from appearing in silicon in the first place, drastically reducing the risk
These metastability effects are not modeled by regular RTL or gate-
of an unpredictable, and lengthy, post-silicon debug process.
level simulations. At best, what a simulation can do is check whether
When data is transferred from one clock domain to the other setup/hold violations are present and produce an X on the output;
designers cannot avoid violating the basic design rule that says “thou virtually X-ing out the complete simulation, so the functional impact of
shall not violate setup/hold conditions for flip-flops.” Indeed, this rule the non-determinism on the delay can not be analyzed. Static timing
goes on, explaining if you change the input data while inside the set does not help either. The best it can do is warn the user that a timing
and hold window around the clock edge of a flip-flop the result is non- violation occurs. Since this violation cannot be eliminated (because the
deterministic. In fact, the output signal will be metastable, meaning
11
two clock domains are asynchronous by design), the best the designer it creates a behavioral metastability model for each CDC that, when
can do is suppress the warning. So other solutions are needed to linked into the simulator, mimics accurately the metastability behavior
analyze the impact of this non-determinism introduced by CDC signals as it happens in silicon.
and prevent bugs from escaping to silicon. Although many errors are caught by this thorough analysis process,
the more intricate CDC bugs can be revealed only through thorough
simulation with CDC assertions and behavioral metastability models
included in that simulation.
During the simulation phase, designers use their existing
testbenches that they have used to verify the functional behavior of the
design. By including the CDC assertions and behavioral metastability
models, they automatically get a coverage report that shows how
well their existing testbenches exercise the corner cases required to
expose CDC bugs. It is fairly common that the initial coverage they
achieve is low, meaning that the tests were not designed to create
these corner cases. So it is typical that extra tests are required to
create them. In doing so, bugs are often exposed and, consequently,
fixed before the design is committed to silicon.
Debugging in the simulation phase of the 0-In CDC verification
Fig. 2. The first step in comprehensive CDC verification is an
solution falls back on the regular debugging environment that comes
analysis step. In this step all CDCs are found and checked. During
with the simulator. Once you have reached your target coverage goals
this step the CDC protocol assertions and behavioral metastability
on the CDC assertions and behavioral metastability models, you are
models are generated as well. These assertions and models are then
done and have substantially reduced the risk of CDC bugs slipping into
subsequently used in step 2 — simulation. By analyzing the coverage
your silicon, dramatically lowering the risk of an expensive post-silicon
results, designers will typically add new tests to reach the required
debug phase for your product.
coverage goals.
12
For many products, schedule predictability is very important.
Clearly, missing bugs during the verification process decreases
schedule predictability. However, one class of bugs specifically, the
bugs related to clock domain crossings, can throw a wrench into an
otherwise carefully crafted schedule for product launch, because
these bugs manifest themselves as intermittent bugs in hardware and
are extremely hard to find and debug in a post-silicon, on the bench,
debugging process. The 0-In CDC verification solution is focused on
finding and fixing these bugs before tapeout or before the RTL code
is downloaded into the FPGA to, if not eliminate, drastically reduce the
probability of these bugs entering your silicon in the first place. More
information on comprehensive CDC verification can be found in [2].
13
Mitigate Multi-Processor Synchronization
Risks with Processor-Driven Verification
by Marc Bryan, Product Marketing Manager, System-Level Engineering Division, Mentor Graphics
Multi-processor synchronization techniques are extensions of • Message passing between processors is not deterministic.
well established single processor, multi-threaded, software based • The multi-processor system is susceptible to race conditions.
synchronization techniques. These multi-processor synchronization • Priorities cannot be used to mutually exclude operations on
techniques require a high level of concurrent visibility of both hardware separate processors.
and processor instruction logic. The risks of effective verification •Neither cooperative multi-threading nor disabling interrupts
of multi-processor synchronization hardware and processor instruction can ensure data integrity in shared memory.
logic can be best mitigated using a processor driven verification
methodology and supporting tools. The stimulus must come from the In a multi-processor system, synchronization requires both hardware
processor in conjunction with the system level test bench. Debug tools and instructions running on the processor. Locked bus cycles for a
must be non-intrusive and provide concurrent visibility of the hardware single processor’s exclusive use of the bus, hardware semaphores
and processor state of all processors in a multi-processor design. for synchronizing access to shared system resources, and other
inter-processor synchronization hardware support the synchronization
What is so hard about processor instructions in the operating system. Naturally, the
multi-processor synchronization? synchronization hardware and processor instructions must be bug
free to ensure proper and reliable synchronization between the cores.
Although the design challenges of multi-processor synchronization
Synchronization bugs are transient, sometimes non-deterministic, and
could fill multiple issues of Verification Horizons or a whole book, let’s
generally infrequent. Problems typically occur in a tiny window of time
take a quick look at the problem to see the acute need for flawless
when instructions on two or more processors execute a co-incident
functionality of the hardware and software synchronization logic.
action such as updating a list pointer or a shared buffer size.
There are various, well established techniques used to synchronize
Engineers are always ready for a challenge, but the project and
multiple threads running on a single processor. These are built into
product risks of not effectively verifying the hardware and processor
multi-threaded operating systems today.
instruction synchronization logic in a multi-processor system are
significantly greater than those in a single processor system. It may not
• Message passing between threads is deterministic by proper be possible to use processor code to work around a hardware defect
construction of the operating system. in the multi-processor synchronization hardware logic that gets into
• Priorities are used to mutually exclude threads from one another. your silicon.
•If the threads are cooperating effectively and mutual exclusion or
So, mitigating the multi-processor synchronization verification risk is
interrupt masking is used, the threads preserve the data integrity
essential for the success of your project and product.
of shared memory and avoid deadlock.
14
we must ensure that the state
changes of the semaphore and
the read/write operations produce
the correct values in order to
prevent deadlock or corrupted
I/O. Deadlock could occur if
both the CPU and the DSP read
the hardware semaphore and
received the value indicating
that the semaphore is in use.
Corrupted I/O could occur if
both the CPU and the DSP read
the hardware semaphore and
received the value indicating that
the semaphore is available.
Multi-processor
synchronization
verification
and debug
Figure 1 100% correlated multi-processor debug
and waveform views in Questa Codelink
requirements
Now that we’ve looked at the problem and risks, let’s take a look at
the requirements to solve the problems and mitigate the risks.
From the programmer’s view, a processor must first acquire the
Processor Driven Verification
hardware semaphore before accessing the I/O. Each processor
executes a single read instruction of the hardware semaphore followed The verification stimulus to the hardware needs to match the
by a test of the semaphore value. If the processor sees that the behavior and timing of activity generated by the processor. The best
semaphore is set, then the processor continues on to execute the I/O way to do this is drive the stimulus from the processor by executing
procedure. Once the I/O work is done by the processor, the processor processor instructions on a fully functional processor model. The
executes a single write instruction to the hardware semaphore to clear instructions can be simple directed tests, diagnostics, device drivers,
it and make it available to other processors in the system. or complete test benches written in C or assembly.
From the hardware engineer’s view, the hardware semaphore logic Please see the Processor Driven Verification article in volume 4,
contains an atomic, uninterruptible read-modify-write operation so that issue 3 of Verification Horizons for a more in-depth discussion of
when the semaphore is read by any processor, the semaphore will processor driven verification.
become set only if is already clear. It is possible to avoid additional bus In the hardware semaphore shared resource example, we need a
overhead by processors executing spin-lock instruction sequences set of processor tests running on all of the processors which exercise
while trying to gain access to the hardware semaphore. The hardware the hardware semaphore logic including individual and concurrent
semaphore logic can keep track of the processors requesting the reads and writes of the hardware semaphore across the system bus
semaphore and provide an interrupt to the next waiting processor by both processors. Because the CPU and DSP are likely running
when the semaphore is cleared. at different clock speeds, these tests will need to coordinate their
We must verify that the hardware semaphore logic works correctly concurrent execution by flags in the dual ported memory. So, before
with the processor instructions controlling access to the shared I/O we can verify the hardware semaphore logic, we must also verify the
resource. Since the hardware semaphore is also a shared resource, concurrent accesses by both processors to the dual ported RAM.
15
Non-Intrusive Debug Is this enough?
Because multi-processor synchronization is highly dependent on the So far, so good. We’ve got stimulus coming from instructions
timing relationships between hardware and processor instructions, the running on the processors and established the key debug
debug tool for hardware and processor instructions must not disturb requirements to view the processor activity on all cores concurrently
the timing. If the debug tool disturbs the timing relationships, the tool without changing the timing relationships.
may inadvertently mask certain bugs. These bugs, which disappear or
change characteristics when one attempts to study them, are known However, non-intrusive, concurrent, multi-core debug of processor
as “Heisenbugs”. driven tests is necessary, but not sufficient for effective debug of
multi-processor synchronization. These tools provide the necessary
In our shared I/O resources hardware semaphore example, the processor instruction and register views. To complete the debug
timing of signals on the bus and in the hardware semaphore logic solution one also needs the view of the hardware logic. The complete
must not be disrupted by our debug tool. When both the CPU and solution requires full processor instruction debug completely correlated
DSP attempt to access the hardware semaphore for the shared I/O to the hardware inter-processor synchronization logic.
resource, there will be bus contention and arbitration. We need to
be able to see the undisturbed signals at the bus interface of the In the hardware semaphore example, we must be able to see the
hardware semaphore in order to verify that the bus arbitration logic register and instruction state of both processors correlated directly with
does not cause problems with the hardware semaphore. For example, the signals in the hardware semaphore logic.
if there are concurrent reads of the hardware semaphore, we need to This solution exists today in the Questa Codelink product.
verify that the hardware semaphore logic correctly sets the semaphore
for the processor that was granted access to the hardware semaphore
Questa Codelink
and correctly returns the set/available value to that processor.
Likewise, we need to verify that when the other processor’s read Questa Codelink provides full software debug visibility and run
executes that the hardware semaphore correctly returns the clear/ control of RTL and gate level processor models including registers,
unavailable value. memory, source and disassembly code, variables, and the stack. The
processor debug views are available concurrently for each processor
Unfortunately debug monitors (such as a resident RTOS process
in a homogeneous or heterogeneous multi-processor design.
communicating with a software debugger), inserting “break”
instructions, and some JTAG connections alter the real time execution The processor debug views are 100% correlated with the
and timing of the system. waveforms in Questa. The processor run controls include run (forward
and backward), stop, step (forward and backward), and breakpoints.
Non-intrusive debug solutions include on-chip trace modules such
as the ARM Embedded Trace Macrocell and the MIPS PDTrace, This combination of processor debug views and run controls
software simulation in a RTL or gate level logic simulator, or complete enables the easy correlation of inter-processor synchronization events
logic emulators. All of these provide some level of support for with the hardware and processor instruction synchronization logic.
memory and register state changes plus an initial state for memory Questa Codelink is non-intrusive and requires no hardware or
and registers. From the initial state and the log of changes, the software changes. It runs with the same fully functional processor
programmer’s view of the state of the processors can be reconstructed model you already have in your design.
for any point in time (within the time range of the log/trace).
Although Questa Codelink provides interaction with the RTL and
Concurrent Visibility of All Processors gate level simulator while the simulation is running, this is generally
Naturally, one must be able to see the state of all processors at not efficient due to the length of time required to wait before viewing
the same time in order to have a complete view of the processors. In the execution of a few instructions on the processor. Questa Codelink
our shared I/O resource hardware semaphore example, we must be facilitates efficiency in your verification process by enabling post-
able to the concurrent programmer’s views (primarily registers and simulation debug. During simulation time Questa Codelink logs
instructions) of both the CPU and the DSP. changes in the processor’s general purpose registers. The logging
16
process has less than a 1% impact on simulation time. This small delay
is more than made up by the time savings of the highly interactive,
post-simulation debug when the verification engineer can quickly
step forward and backwards through the processor instructions and
hardware waveforms and set hardware and software breakpoints as
needed. One can traverse the log of a 15 hour simulation in 5 seconds.
Turning to our hardware semaphore example, we would use the
completely synchronized processor register, memory, instruction
views with the hardware semaphore logic waveform views to provide
full visibility to every bus access of the hardware semaphore. Both
the processor debug and hardware waveform views are needed for
hardware semaphore accesses by any or all of the processors that
are executing the processor driven test bench. Furthermore, if our
hardware semaphore logic queues semaphore requests and provides
processor interrupts when the semaphore is granted to a processor,
we can use Codelink to view the interrupt control logic signals of each
of the processors and the processor register and instructions during
the execution of the interrupt handling routines.
Conclusion
Functional verification of multi-processor synchronization hardware
logic and processor instructions is most effective using processor
driven tests and non-intrusive debug tools that provide concurrent
visibility of the hardware and processor state of all processors in a
multi-processor design. The risks of not discovering multi-processor
synchronization bugs are greater than undiscovered bugs in single
processor, multi-threaded, software synchronization. The Questa
Codelink product mitigates these risks by providing all the required
verification and debug features for verifying multi-processor
synchronization.

17
Reusing Legacy VMM VIP in OVM Environments
OVM/VMM Interoperability and Migration
by Tom Fitzpatrick & Adam Erickson, Verification Technologists, Mentor Graphics
Overview
• Encapsulated Model: The details of the legacy library (in this case,
The Open Verification Methodology (OVM) provides users with VMM) must be hidden from the user of the integrated VIP. The
a proven methodology for creating modular, reusable verification OVM wrapper will be implemented according to the interconnected
components and testbenches that accelerate the verification task. model, which requires knowledge of VMM; however users of the
With more than 12,000 downloads and 5200 users on ovmworld.org, OVM-wrapped component will only use OVM.
the OVM has taken the industry by storm since its open-source
release just over a year ago. Having been architected specifically to To be considered a successful integration of legacy VMM
encourage (enable/support) reuse from the block to system levels and in an OVM environment, it must be possible for the OVM user to
from project to project, the OVM provides the ideal level of flexibility instantiate, control, and augment the functionality of the unmodified
and automation to simplify the creation of verification intellectual VMM component2 from the OVM testbench. Specifically, it must
property (VIP). Clearly, verification teams who have taken a look be possible to:
at the OVM have liked what they’ve seen.
1. Instantiate the VMM component in an OVM environment (or
Even users of the older Verification Methodology Manual (VMM)
component) and have it run with its phases synchronized to the
have shown substantial interest in OVM. This led to the forming of
appropriate OVM phases.
Accellera’s Verification Intellectual Property Technical Subcommittee
2. Extract transactions from the VMM environment to be converted
(VIP-TSC), chartered with standardizing a solution that enables
and passed to OVM components for scoreboarding, coverage, or
interoperability between OVM and VMM. In response to the VIP-
other analysis.
TSC’s approval of a set of interoperability requirements, Mentor
3. Configure the VMM component from an OVM environment or test.
Graphics released an open-source OVM/VMM interoperability
4. Specify additional transaction sequences in OVM, utilizing existing
library to meet these requirements. The library includes a set of new
VMM transactors.
OVM-based components and classes to handle synchronization
and communication between the OVM and VMM. It also includes The remainder of this article will discuss how the OVM/VMM
an enhanced version of the open-source VMM release to provide interoperability library addresses these requirements.
IEEE 1800 compliance and additional infrastructure that supports
interoperability1. It also includes an extensive set of examples and
HTML-based documentation. Phase Synchronization
Both OVM and VMM support the basic concept of “phases,” but
each has its own specific set of phase methods. In order for IP from
Integration Requirements
the two libraries to work together, the appropriate phases from each
The VIP-TSC approved a set of interoperability requirements on must be called at the appropriate point relative to the other. Ideally, this
December 3rd, 2008. The solution described here includes a library alignment should be transparent to the user. The interoperability library
and methodology that meets or exceeds these requirements. The VIP- introduces a new component, the ovm_vmm_env, which serves as a
TSC requirements describe two levels of interoperability: proxy to allow the OVM phase controller to control the phasing of VMM
environments by registering the VMM phase methods as additional
• Interconnected Model: The VIP integrator must take into account
custom phases in the default phase list. The relative phasing is shown
that the underlying VIP comes from two different libraries.
in Figure 1, with OVM phases shown in green and VMM phases shown
Successful integration thus requires knowledge of both OVM and
in pink.
VMM. This is the level of interoperability at which the requirements
were specified. 
18
initial
run_test(“test”);
endmodule
1) module example_02_add_ovm_sb;
function void build(); Along with the vmm_env class, we instantiate an OVM scoreboard
env = new(); component in the build method. Then, in the OVM connect() method,
endfunction
endclass
we create a VMM callback object (line 12–13) that converts the
vmm_data transaction into an ovm_transaction and writes it to the
19
scoreboard. This callback is then appended to the VMM’s master Encapsulating Legacy
driver (line 15), which was created as part of the build process.
VMM Components in OVM
In the end_of_elaboration() method, we can similarly configure the
The requirements specified by the VIP-TSC deal primarily with the
VMM generator (line 18). This is important because, unlike OVM, VMM
interconnected model, where the integrator must be aware of both the
components can only be configured after they have been built. Note
OVM and VMM use-models in order to make them work together. In
also that the vmm_env class’ gen_cfg() method will have been called
the previous example, the integrator is actually the test writer, since all
prior to its build() method being called, as part of the OVM phasing
VMM details are visible at the “top level” of the testbench. However,
mechanism.
part of the reuse advantage of the OVM comes from its built-in
The data conversion is accomplished via a user-defined convert() notion of hierarchy, in which any component, including ovm_env and
method inside the callback object. An example of the conversion from ovm_test, may be instantiated by any other component. The flexible
a vmm_data type (apb_rw) to a corresponding ovm_transaction type architecture of OVM ensures that the phasing is handled automatically
(ovm_apb_rw) is shown here: throughout the hierarchy.
With this in mind, the question of incorporating legacy VMM VIP
function ovm_apb_rw convert(apb_rw from, into an OVM-based testbench becomes even more straightforward,
ovm_apb_rw to=null); allowing the VMM legacy components to be wrapped in an OVM
if (to == null)
convert = new;
component and thus appearing to the test writer as if the testbench
else is completely OVM. All that is needed is to take the VMM-specific
convert = to; pieces of the system shown above and incorporate them in a wrapper
case (from.cmd)
component, which is extended from the same ovm_vmm_env proxy
apb_rw::READ: convert.cmd = ovm_apb_rw::RD;
apb_rw::WRITE: convert.cmd = ovm_apb_rw::WR; component discussed above. Consider:
endcase
convert.addr = from.addr;
convert.data = from.data; 1) module example_07_ovm_atomic_gen;
convert.set_transaction_id(from.data_id);
convert.set_sequence_id(from.scenario_id); 2) class ovm_apb_env extends
ovm_vmm_env_wrapper_noname #(tb_env);
endfunction
the system wherever such conversion is needed. There may also be 7) function new (string name=”ovm_apb_env”,
an analogous convert method to convert from OVM back to VMM. 8) ovm_component parent=null);
9) super.new(name,parent);
Additional OVM stimulus may be added and connected to the VMM
10) atomic_gen_port = new(“inject_export”,this);
driver via its vmm_channel pointer. Because the communication 11) endfunction
semantics of the vmm_channel are slightly different than for OVM
TLM-based components, the Interoperability library also includes a 12) virtual function void build();
13) super.build(); // builds underlying vmm_env
set of adapters that present the OVM interface on one side and the 14) atomic_gen = new(“vmm_atomic_gen_adapter”,this,env.gen);
VMM interface on the other. The adapter set allows OVM components, 15) get_config_int(“num_trans”,num_trans);
including sequencers and drivers, to be connected to VMM channels 16) env.gen.stop_after_n_insts = num_trans;
17) endfunction
and to VMM atomic or scenario generators (via the inject() and inject_
obj() methods, respectively). The full set of adapters can be seen by 18) virtual function void connect();
downloading the library. 19) ovm_apb_master_convert_cb cb;
20
end_of_elaboration can now be done in the wrapper’s build() method
20) super.connect();
directly. To the test writer, the configuration parameter is now set using
21) cb = new(ap);
22) env.mst.append_callback(cb); the set_config_int() method (line 39), as it would be for any OVM
23) inject_export.connect(atomic_gen.blocking_put_export); component. The wrapper calls get_config_int() as part of its build()
24) endfunction (line 14) and then uses that information to reach down into the VMM
25) endclass
environment to set the parameter, according to the VMM guidelines.
26) class env extends ovm_component; The wrapper also provides appropriate ports and exports to allow
other OVM components in the top-level environment to connect to
27) ovm_apb_env apb_env;
28) ovm_random_stimulus #(ovm_apb_tr) producer; it as needed. In this case, there is a stimulus injector export (line 3),
29) ovm_apb_sb #(ovm_apb_rw) sb; // OVM component which provides an interface (line 23) for an OVM stimulus generator
to drive additional stimulus into the vmm_env (line 39). It also shows
30) function new (string name, ovm_component parent=null);
an analysis_port (line 4) to which the converter callback writes
31) super.new(name,parent);
32) endfunction transactions (lines 21-22), allowing additional analysis components,
such as the scoreboard (line 29), to be connected (line 40) as to any
33) virtual function void build(); OVM component.
34) apb_env = new(“apb_env”,this);
35) producer = new(“producer”,this);
36) sb = new(“sb”,this);//could use the factory
37) endfunction
Conclusion
Using the wrapper approach it is now possible to take any vmm_env
38) virtual function void connect();
class — indeed, any vmm_xactor — and wrap it in an OVM component
39) producer.blocking_put_port.connect(inject_export);
40) apb_env.ap.connect(sb.analysis_export); to hide any VMM-specific details about the underlying VIP. Using
41) endfunction the interoperability library, it is only necessary for the wrapper writer
to understand the VMM enough to instantiate the proper converter
42) virtual task run();
objects, do the necessary data conversions and configuration calls,
43) producer.generate_stimulus();
44) endtask and make the appropriate ports and/or exports visible in the wrapper.
Once that is done, the rest of the team can reuse the VMM VIP as
45) endclass if it were simply an OVM component, according to all of the OVM
46) initial begin
guidelines.
47) set_config_int(“*.apb_env”,”num_trans”,5); The interoperability library presented here thus provides
48) run_test(“env”);
49) end
a low-risk migration path from your legacy VMM VIP to a fully
OVM-based environment. Once the VMM is wrapped, the flexibility
50) endmodule of the OVM makes it a simple exercise to replace the underlying
VMM with an OVM implementation (either ported or acquired from
some other source) of the same functionality. Rather than having
The ovm_vmm_env_wrapper_noname component is an extension to start over from scratch, the user can manage the risk of moving
of ovm_vmm_env and includes the virtual methods for controlling the from legacy VMM environments to take advantage of all the superior
phasing of the vmm_env, which is specified as a parameter (line 2). benefits of the OVM.
This wrapper class includes much of the same functionality discussed
in the previous interconnected example, with a few important 1
All enhancements to the VMM library are transparent to the user.
differences.
First, because the wrapper component is now the parent 2
VMM environments (vmm_env) and/or transactors (vmm_xactor,
of the vmm_env class it instantiates, we have a bit more flexibility vmm_subenv) may be reused via this approach. Unless otherwise
regarding when to call particular phasing methods. Upon completion specified, the term “component” will be used to refer to “a piece of
of super.build() on line 12, we are guaranteed that the underlying VIP,” regardless of what specific VMM class is used to implement
vmm_env class is built, so the configuration setting previously done in the VIP.
21
A Practical Guide to OVM—Part 3
by John Aynsley, CTO, Doulos
INTRODUCTION a design under test (or DUT). The stimulus generated by sequencers
can range from a simple stream of random transactions to a highly
This is the third and final article of a series aimed at helping you structured sequence representing a set of nested protocols.
get started with OVM in a simple, practical way. The emphasis of the
series has been on the steps you need to take to write working code. Here is the transaction class that appeared in previous articles,
updated for use with the OVM 2.0 sequencer class:
In the previous two articles we explored the overall structure of an
OVM class-based verification environment and saw how to assemble
OVM verification components, run tests, and reconfiguring the class my_transaction extends ovm_sequence_item;
verification environment. In this final article we explore sequences and rand int addr;
sequencers, which are the main tools used to generate structured test rand int data;
stimulus. rand bit r0w1;
The previous article was published just as version 2.0 of the function new (string name = “”,
OVM class library was being released. One of the most important ovm_sequencer_base sequencer = null,
innovations in OVM 2.0 was the revision and improvement of ovm_sequence_base parent_seq = null);
the sequence classes. This article describes the new, improved super.new(name);
sequences available in OVM 2.0. endfunction: new
The code you see in this article will run with OVM-2.0, and can be constraint c_addr { addr >= 0; addr < 256; }
downloaded from the Doulos website at www.doulos.com/knowhow. constraint c_data { data >= 0; data < 256; }
`ovm_object_utils_begin(my_transaction)
A very simple Sequencer `ovm_field_int(addr, OVM_ALL_ON + OVM_DEC)
`ovm_field_int(data, OVM_ALL_ON + OVM_DEC)
The role of the sequencer in OVM is to generate a stream of `ovm_field_int(r0w1, OVM_ALL_ON + OVM_BIN)
transactions that can be fed into a downstream component, which `ovm_object_utils_end
could itself be another sequencer or a driver. You may remember
from the previous articles that a driver is a verification component endclass: my_transaction
that converts an abstract transaction into a series of pin wiggles on
22
It is important that the user-defined transaction class extends The macro `ovm_update_sequence_lib_and_item, adds three
ovm_sequence_item: this allows the transaction to be generated standard sequences to the sequence library. These are:
by a sequencer. It is also important to use the correct constructor
arguments, which are different from those of other OVM classes. • ovm_simple_sequence, which consists of a single item of the
We will now give a line-by-line description of the code for a very given transaction type.
simple sequencer so that you can start using sequencers right away: • ovm_random_sequence, which selects and executes a series
of sequences from the array, but excluding ovm_exhaustive_
class my_sequencer extends ovm_sequencer #(my_transaction);
sequence and ovm_random_sequence itself. By default, this
only leaves ovm_simple_sequence. The number of sequences
is determined by the count property of the ovm_sequencer class,
A sequencer is a class derived from ovm_sequencer and and defaults to a random number between 1 and 10.
specialized to generate transactions of a particular type, which in this • ovm_exhaustive_sequence, which selects and executes every
example is my_transaction. sequence in the array once, but excluding ovm_random_
sequence and ovm_exhaustive_sequence itself. Again,
`ovm_sequencer_utils(my_sequencer)
this only leaves ovm_simple_sequence unless further
sequences have been added.
`ovm_update_sequence_lib_and_item(my_transaction)
endfunction : new class my_test extends ovm_test;
...
endclass : my_sequencer virtual function void build;
super.build();
Each sequencer has an associated sequence library, which holds all set_config_int(“*.m_sequencer”, “count”, 10);
...
of the sequences which can be generated by that particular sequencer.
The macro `ovm_update_sequence_lib_and_item populates this
sequence library with an initial set of sequences, based on the type of The set_config_int call sets the count property of the sequencer to
the transaction my_transaction. The sequence library is actually an control precisely how many transactions are generated by the default
array of sequences from which sequences are selected to be run one- sequence ovm_random_sequence. The sequencer is chosen using
at-a-time. a string that represents the OVM hierarchical name of the component
and can contain wildcards.
23
the driver The driver communicates with the sequencer using the seq_item_
port, which is a pre-defined port specifically for making a connection
The transactions generated by a sequencer get passed either to
to an upstream ovm_sequencer. This part of the code is a bit tricky,
another sequencer or to a driver. A driver is a component that injects
because the port is not defined in the my_driver class itself but is
the stimulus represented by the transaction into the design-under-test
defined in the base class (or superclass) ovm_driver and is inherited
by wiggling pins. A user-defined driver class follows the same pattern
by my_driver. It appears as if seq_item_port is being used without
as other OVM components, so we do not need to explain it line-by-
being declared, because the declaration itself is in the source code of
line. Here is the complete source code for a simple driver component
the OVM class library.
suitable for connection to my_sequencer.
The driver calls two methods of the seq_item_port: get_next_
item to pull the next transaction from the sequencer, and item_done
class my_driver extends ovm_driver #(my_transaction); to tell the sequencer that it has finished with the transaction.
virtual dut_if m_dut_if;
Sequences
`ovm_component_utils (my_driver)
The ovm_sequencer is not restricted to generating single
function new(string name, ovm_component parent); transactions. The next step is to introduce a user-defined sequence,
super.new(name, parent);
and add it to the sequence library of the sequencer. Whereas a
endfunction: new
sequencer is a component, a sequence relates a set of data items
function void build; (transactions and other sequences) and includes code to generate
super.build(); them in the proper order. A user-defined sequence extends the class
endfunction : build
ovm_sequence:
virtual task run;
repeat(10)
begin class my_sequence_1 extends ovm_sequence #(my_transaction);
my_transaction tx;
#27 `ovm_sequence_utils(my_sequence_1, my_sequencer)
// seq_item_port is built into ovm_driver:
seq_item_port.get_next_item(tx); my_transaction seq_item;
24
sequence of my_sequencer. Alternatively, my_sequence_1 may be Another more flexible way to start sequences is using the sequence
selected manually using one of several possible methods, described selection and execution methods. Sequence execution can be
below. controlled from within a user-defined sequence class or from the test:
25
CONCLUSIONS
class my_env extends ovm_env;
In this article we have seen simple examples of using the ovm_
`ovm_component_utils(my_env) sequence and ovm_sequencer classes, but this is just the beginning.
These two classes can be used to build nested, hierarchical and
my_sequencer m_sequencer; layered sequences in many forms, sufficient to model typical layered
my_driver m_driver;
protocol stacks.
function new( string name = “”, ovm_component parent = null ); In this series of articles we have examined the rudiments of building
super.new(name, parent);
an OVM verification environment from a practical viewpoint. You can
endfunction: new
find the source code for these examples together with online tutorials
virtual function void build; and further hints and tips at www.doulos.com/knowhow, and you can
super.build(); download the OVM class library itself from www.ovmworld.org.
m_sequencer = my_sequencer::type_id::create(“m_sequencer”, this);
m_driver = my_driver::type_id::create(“m_driver”, this);
endfunction: build
endclass: my_env
26
Are You in a “bind” with Advanced Verification?
by Virginie Mallez, Mark Peryer, Andy Walton, and Paul Williams,Verification Practice, Mentor Consulting (Europe)
The first eight years of the 21st century have seen leading Adding SystemVerilog code into an existing Verilog or VHDL DUT
companies in our industry adopting new methodologies for verifying consists of three separate issues, for clarity it is important to keep
their designs. These companies publish papers highlighting these separate –
considerable benefits gained by implementing advanced verification
technologies such as functional requirements tracking, Coverage • Firstly, mixed languages. This is a capability of Questa allowing
Driven Verification (CDV), Assertion Based Verification (ABV), formal a component written in one language to be instantiated in a
verification, constrained random stimulus, and most recently, the Open structural design written in another language. You cannot mix
Verification Methodology (OVM). And yet, a significant number of SystemVerilog language constructs (such as covergroups) directly
customers continue to use HDL based testbench methods developed into VHDL code, because that would violate the VHDL syntax
in the 1990’s or earlier. Why is this? rules. You can only instantiate a design unit into another, for
The most common reason for keeping to traditional verification example, a SystemVerilog module into a VHDL structural design
practices is the lack of an obvious migration path to allow risk free where the VHDL was expecting to find an entity/architecture
adoption of new approaches. In this article we describe a useful instantiated.
approach which has provided a migration path for many customers • The role of bind is simply to add an instantiation of code to an
who are beginning to adopt advanced verification techniques. The existing design unit (anywhere in the hierarchy) without touching
solution presented is the combination of Questa’s Multilanguage the original code. It does this by appending the extra code to an
support, and the Verilog bind mechanism. existing design unit during elaboration. The end result is the same
as instantiating a SystemVerilog module directly into the source
file. Bind itself does not provide any multi-language capabilities,
Understanding how bind works
but can be used with the multi-language Questa capabilities
We have seen that SystemVerilog provides advanced verification described above to instantiate a SystemVerilog design unit into a
capabilities. Now we show the role of bind in a multi-language VHDL or Verilog hierarchical design.
environment.
27
• Design code should be kept separate from verification code. The “bind” statement can be in any compilation-unit available during
The principle being that a means of measurement should not elaboration. For example, the bind statement, the target module
influence the thing that is being measured. It is possible to add and the module to be bound can all be in separate files.
SystemVerilog verification constructs such as covergroups directly Note that bind does not add any functionality to the SystemVerilog
into Verilog RTL code, but the result will be unsynthesiseable. language; it simply allows a more convenient way to insert assertion
code into an existing module without editing the source file. Also note
Using a combination of bind and multi-language support we can that it is not restricted to binding modules of assertions. Any code
insert verification capabilities such as covergroups and assertions can be bound, and modules, interfaces and program blocks can all
into existing HDL code. We can even add pre-prepared verification be inserted using bind, subject to the rules that would apply were the
components (such as an AMBA MVC verification IP or assertion based blocks instantiated directly.
monitors from the Questa Verification Library (QVL)) to any point in There are two forms of bind, the first, is to bind to all instances of
our Verilog or VHDL design without touching the original source code. a modules so that the new code will be added to every instance. The
We will now describe how this capability is used, starting with the second is to bind to a specific instance, where code is added only to
simple case of using bind in a pure Verilog environment, and then that instance. The syntax for this is as follows:
adding the complexity of multi-language.
bind t1.dut.u1 my_assertions uassert (.sig(my_var));
The mechanics of using bind with Verilog
bind indicates that a design unit (Verilog module, interface, or
program block) is to be instantiated immediately before the end of It is also possible to bind to multiple instances of a specified module
a specified module or interface. Given a SystemVerilog module (mod) using the following syntax:
containing assertions:
bind mod:t1.dut.u1, t1.dut.u2, t1.dut.u3
module my_assertions(input logic sig); my_assertions uassert (.sig(my_var));
property …
endmodule : my_assertions
module mod;
logic my_var; bind \ent(a) my_assertions uass2 (my_var);
initial …
endmodule : mod
:
:
bind mod my_assertions uassert (.sig(my_var));
28
Bind across levels of hierarchy
We have seen how the combination of bind and Questa
multi-language support gives the ability to add advanced
SystemVerilog modules to any component or instance
in an HDL design. However, when binding modules into
VHDL designs we are restricted to only access signals
that are local to that specific component, or instance of
that component. There are often cases where we need to
monitor signals across multiple levels of VHDL hierarchy;
for example, coverage of the interaction of two parts of
the design, or an assertion that is deactivated by a reset
applied at a parent level of hierarchy or sampled on a
Note that the escape token (\) used before the ent(a) is required in clock in another part of the design.
the bind statement above to allow the Verilog compiler to parse the As an example, the following SystemVerilog code fragment counts
VHDL architecture reference. Also note that no spaces are allowed in the number of clock cycles where a state machine is in the wait state.
this identifier e.g. “\myent ( myarch )” is illegal.
In exactly the same way as shown in Verilog, it is possible bind to a
covergroup wait_cover @(posedge clk);
specific instance of a VHDL design unit as follows: wait_count: coverpoint wait_count iff (encode_enable == 1)
{
bins counter_zero = {0};
bind tst.dut.u1 my_assertions uass3 (my_var); bins counter_one = {1};
bins counter_ok = {[2:7]};
bins counter_over = {[8:1023]};
There is no direct equivalent of the verilog multiple instance bind bins counter_problem = {[1024:$]};
command, therefore binding to multiple (but not all) instances of a }
component would be written as: endgroup
The SystemVerilog wrapper that makes the bind is either In the diagram to the right SystemVerilog binding has been used
instantiated within the hierarchy of a SystemVerilog testbench, or the to insert ‘signal grabbers’ into the VHDL design. These grabbers are
wrapper can be added as a top level at the simulator command line as SystemVerilog modules and as such as able to write hierarchical
follows: references (see next section) between the sub-design and a top level
SV Interface. Coverage is then performed at the top level where all
required information has been made available by the grabbers.
vsim design sva_binding
29
References to instances If the source file was edited and the instantiation added instead of
being bound, the $unit namespace would be visible.
created using bind
• The order in which bind statements are elaborated is not defined,
It is legal to use references to and into bound components. A and consequently it is not legal to rely on bind order.
common example of this is to group all signals of interest in a sublevel • bind components cannot contain further bind statements.
of the DUT into a SystemVerilog Interface. This Interface can then
be referenced hierarchically from a top level testbench. For example
group all signals on an AHB bus together into a SystemVerilog
Interface using bind, and then refer in the testbench to a covergroup in Using bind to take advantage of
that interface (e.g. dut.alu_sub.axi_bind.data_coverage) or to a task in advanced verification
that interface (dut.alu_sub.axi_bind.writeData(errorInjectedByte)). Bind can be used to bind SystemVerilog assertions and covergroups
to RTL code without having to make any changes to the design code.
Bind Restrictions This means that development teams can easily start to use
Since bind is the equivalent to inserting code into a source module, assertions alongside their traditional testbench, gradually building
all restrictions that would apply when instantiating a component still from simple debug assertions to sophisticated protocol monitors as
apply. For example: their fluency improves. It also means that they can take advantage
of covergroups to get functional coverage information from their
traditional test benches.
• The instance name must be unique in the target module. Thus, it
is not possible to bind a component using an instance name that is Our experience is that once the power of these two methodologies
already used in the target module. Also, multiple bind statements is grasped, and then there is a natural progression towards wanting
to the same module must not use the same instance name as to improve stimulus generation using advanced techniques such as
each other. (VHDL & Verilog language rule) constrained random.
• A component cannot be bound into a program block. (SV rule)
• Only an interface can be bound into an interface. (SV rule) Summary
bind is a simple and effective way to incorporate verification code
In addition, there are a number of bind-specific restrictions:
into existing RTL designs. The bind statement contains a specification
of where a component is to be bound – i.e. all instances of a
• Since the binding only occurs at elaboration time, there is no component; specific instances of a component; or a specific instance;
visibility of compilation-unit scope ($unit) to the bound module. and the instantiation that is to be incorporated at the specified location
in the hierarchy:
30
NOTES:
31
Editor: Tom Fitzpatrick
Program Manager: Rebecca Granquist
Senior Writer: Todd Burkholder
Subscribe:
http://www.mentor.com/horizons
32