SlideShare a Scribd company logo
1 of 16
Download to read offline
A Unique Functional Coverage Flow using SystemVerilog
                        and NTB

                                      Richard Raimi
                                          ARM, Inc
                                      rraimi@arm.com

                                  Dennis Strouphauer
                                       Synopsys, Inc
                                  dstroup@synopsys.com


                                         ABSTRACT

There are two constructs in SystemVerilog that support functional coverage: the covered
property and the covergroup. At ARM, Inc. in Austin, Texas, we wanted to use SystemVerilog
functional coverage on a next generation processor design; however, only the covered property
and not the covergroup was going to be supported by Synopsys in the time frame of our project.
Feeling that both were needed, we chose to write our functional coverage in SystemVerilog,
using both the covered property and the covergroup, and translate the SystemVerilog
covergroups to NTB / Vera ‘coverage_groups’, a similar, but not identical, construct. In this
way, we were able to train our team in SystemVerilog, use the code we wrote in the present, and
allow ourselves the option of reusing it in the future, when the covergroup would be fully
supported in VCS. In this paper, we describe this translation process, as well as the pros and
cons of functional coverage in both NTB / Vera and SystemVerilog.
Table of Contents

1.0       Introduction: Functional Coverage ....................................................................................3
2.0       Functional Coverage Constructs in SystemVerilog and Vera / NTB ................................3
2.1       NTB coverage_groups .......................................................................................................8
2.2       Bind Directives ..................................................................................................................9
3.0       SystemVerilog for Functional Coverage at ARM-Austin ...............................................10
3.1       Relating Design Components to Coverage Components.................................................11
3.2       Code Writing Standards...................................................................................................11
4.0       Translating SystemVerilog to NTB : The 'covermap' Translator ....................................12
5.0       Results and Performance..................................................................................................15



                                                       Table of Figures

Figure 1 : SVA Sequence...............................................................................................................4
Figure 2 : SVA Properties..............................................................................................................4
Figure 3 : SVA Assert and Cover ..................................................................................................5
Figure 4 : SVA Covergroup...........................................................................................................6
Figure 5 : SVA Covergroup Advanced..........................................................................................7
Figure 6 : NTB (Vera) coverage_group example ..........................................................................8
Figure 7 : SVA Bind ....................................................................................................................10
Figure 8 : Flow Diagram..............................................................................................................13




SNUG Boston 2005                                                     2                 A Unique Functional Coverage Flow
1.0 Introduction: Functional Coverage
Functional Coverage provides an indication of the thoroughness of the implementation of the
verification plan and can help answer questions such as how much of the design specification has
been exercised? and what actually happened during a test? As chip designs grow larger and
more complex with thousands of possible states and transitions, a comprehensive verification
environment must be created that minimizes wasted effort. Functional coverage is used as a
guide to direct the verification resources by identifying the tested and untested parts of the
design. When properly used, functional coverage can serve as a formal specification of a test
plan. In turn, the process of writing functional coverage can bring holes in a test plan to the
attention of verification personnel.

Functional coverage, because it is a measure of what is determined to be of interest and relevant,
must be manually specified by members of the design and verification team. It cannot be
extracted automatically from the design source code. This paper describes the use of the
SystemVerilog language to create functional coverage models for an ARM processor.

2.0 Functional Coverage Constructs in SystemVerilog and Vera / NTB
The constructs in SystemVerilog that are related to functional coverage are:

        1. sequences and properties
        2. covered properties and assertions
        3. covergroups

The sequence construct is a basic building block. A sequence is a description of temporal
behavior using logical and temporal operators of the SystemVerilog Assertion (SVA) language.
SVA is a subset of SystemVerilog, useful for describing behaviors that unfold over multiple time
steps.

In its simplest form a sequence can be just a Boolean expression, which is considered to be a
sequence of zero time steps. It is optional to define what constitutes a time step in a sequence.
A time step may be thought of as a directive indicating when to sample variables appearing in
the sequence. The ability to write a sequence without defining the meaning of a time step allows
reuse of a sequence in many different contexts, each with different definitions of time steps.
Labeling a sequence also facilitates reuse, as we will see below. A sequence has no defined truth
value, but there is a concept of a sequence being matched, meaning that the behavior of a design
unfolds as described in the sequence. Here, we also describe this as the sequence succeeding, or
successfully concluding. Figure 1 shows an example of a sequence describing a signal, req,
going high, and one time step later, a signal, ack, also going high.




SNUG Boston 2005                                3            A Unique Functional Coverage Flow
sequence s_1;
                    req ##1 ack
                  endsequence



                                    Figure 1 : SVA Sequence

A sequence can be reused, via its label, inside of a property. The body of a property is made up
of one or more sequences operated on by temporal operators or logic operators. The sequences
can be written explicitly in the property, meaning, one can form expressions with variables and
logic and temporal operators, or one can reuse sequences that are defined elsewhere via their
label. (At ARM, we always do the latter.) A property will have a time step, or sampling
definition. This is done using Verilog syntax, for example “@(posedge clk)”. If a sequence is
reused by referencing its label inside of a property, the sequence will take on the time step
definition of the property. Figure 2 shows how a sequence can be reused inside a property: we
show sequence s_1 from Figure 1 being reused inside properties p_1 and p_2. Note that
evaluation of a property can be subject to constraints. Both properties in Figure 2 will only be
evaluated if the signal, reset, is low.




                   property p_1;
                     @(posedge clk) disable iff (reset) s_1;
                   endproperty

                   property p_2;
                     @(posedge clk) disable iff (reset) s_1 |-> done;
                   endproperty




                                   Figure 2 : SVA Properties

Unlike a sequence, a SystemVerilog property does have a Boolean truth value. At its simplest, if
the body of a property is just a Boolean expression, the property is true on every time step in
which the expression is true. In more complicated properties, the property is true, at a given
sample point, when the mix of temporal and logical operators within it evaluates to true. For
example, if s is the label of a sequence, and o is a variable representing a design signal, then the
expression
    s |-> o


SNUG Boston 2005                                 4            A Unique Functional Coverage Flow
in the body of a property, where |-> is the implication operator, is true whenever:
        • s has not successfully concluded, or
        • s has successfully concluded, and at that same instant, signal o is high
As an aside, the fact that the implication operator evaluates to true when its left hand argument,
known as the antecedent, evaluates to false, is often confusing to people. This is called “vacuous
truth”, and must be taken into account when setting up a functional coverage and assertion based
verification system. For example, property p_2 in Figure 2 will be vacuously true at every
sample point at which sequence s_1 does not match. It would be desirable to have an
independent means of verifying that the property also was true a finite number of time when
sequence s_1 did match. Counting how often property p_1 is true accomplishes this.

Properties can be labeled, and, like sequences, they can be reused in a higher level context by
their label. In particular, properties can be the target of the SystemVerilog cover and assert
directives. When a cover directive is applied to a property, a count is generated of how often the
property is true at its sample intervals. This is known as a covered property. When an assert
directive is applied to a property, an error is signaled if the property is ever false at a sample
point. This is known as an assertion. Note that this allows reuse of sequences for both
functional coverage and assertions. Figure 3 shows cover and assert directives applied to the
properties of Figure 2, p_1 and p_2. Note that applying both these directives at the same time
solves the problem of vacuous truth for property p_2. If property p_2 is forever vacuously true,
the cover directive, c_1, will have a zero count. If, on the other hand, property p_2, and,
therefore, assertion a_2 is actually stressed, cover c_1 will have a positive, non-zero count, to the
extent that that occurs.



                    c_1: cover property (p_1);

                    a_2: assert property (p_2)



                                                                                                    

                                Figure 3 : SVA Assert and Cover

SystemVerilog covergroups, in contrast to sequences and properties, are primarily targeted
towards combinational logic. They are not part of the SVA subset of SystemVerilog.
SystemVerilog covergroups are closely related to the Vera ‘coverage_group’ construct that
preceded it. A covergroup will have a sampling, or time step definition, using the same syntax
as we saw previously with properties (e.g., @(posedge clk)).

The two main components of a covergroup are the coverpoint and the cross. A coverpoint is
defined relative to a signal of a particular width. The default behavior of a coverpoint is to
generate a counter for each possible permutation of the underlying signal’s values, up to some
preset limit. Thus, for example, a 3-bit wide signal would generate 8 counters, one for each


SNUG Boston 2005                                 5            A Unique Functional Coverage Flow
possible 0/1 permutation. These counters are referred to as bins. A cross generates counters for
the cross product of two or more coverpoints, meaning, counters for the occurrence of all
possible simultaneous hits to the bins of the underlying coverpoints. For example, if one
coverpoint is related to a 2-bit signal and another to a 3-bit signal, then the default behavior is to
create 4 bins for the first coverpoint and 8 for the second. The cross of both coverpoints would,
by default, create 32 distinct bins, one for each possible, simultaneous update to the bins of the
coverpoints. Figure 4 shows a covergroup like this, where coverpoints cp_1 and cp_2 are
defined from 2 and 3 bit signals, respectively, and a cross of these two coverpoints, cr_1,
generates 32 bins.



                       reg [1:0] two_bit_sig;
                       reg [2:0] three_bit_sig;

                       covergroup cg_1 @(posedge clk);
                          cp_1 : coverpoint two_bit_sig;
                          cp_2 : coverpoint three_bit_sig;
                          cr_1 : cross cp_1,cp_2;
                        endgroup




                                   Figure 4 : SVA Covergroup

If one does not constrain the generation of bins, a combinatorial explosion could quickly result.
Fortunately, SystemVerilog has a great many ways of specifying constraints. One can put guard
conditions on coverpoints and crosses, so that they are updated only when the guards hold. One
can apply guards more finely, putting them directly on specific, user-defined bins. One can
restrict the range of values of a bin via user-defined bins, and one can label particular ranges as
ignorable or illegal. The illegal designation acts much like an assertion, in that it causes the
simulator to post an error if a value in the specified range is hit. In general, constraining
covergroups involves some method of not allowing SystemVerilog to automatically generate the
number of bins it would otherwise generate by default. This often involves creating bins
explicitly. The bins keyword is used to create explicit bins on either coverpoints or crosses, as is
shown in Figure 5, below. Note that the square bracket operator, ‘[]’, will generate individual
bins for each number in its range. Thus, the definition of bins c of coverpoint cp_1, Figure 5,
will generate 3 bins, one each for the values 200, 201 and 202. In contrast, the definition of bins
a of coverpoint cp_1 will generate only a single bin, for all of the 65 distinct values in its range.
With bins a, it will be impossible to know how many times the individual values in the range
were hit. If this information is needed, the ‘[]’ operator must be used.



SNUG Boston 2005                                  6            A Unique Functional Coverage Flow
reg [10:0] v_a;
                        reg [1:0] v_b;

                        covergroup cg_2 @(posedge clk);
                           cp_1: coverpoint v_a {
                             bins a = { [0:63],65 };
                             bins b[] = { [127:150], [148:191] };
                             bins c[] = { 200, 201, 202 } iff (!reset) ;
                             bins d = { [1000:2000] };
                             illegal_bins bad_vals = { [2001: 2047] }; }
                          cp_2: coverpoint v_b;
                          cr_1 : cross cp_1, cp_2 {
                             bins b_cr = binsof(cp_1.b) && binsof(cp_2); }
                        endgroup




                            Figure 5 : SVA Covergroup Advanced

Bins definitions for crosses are more complicated than those for coverpoints. This is because, in
a cross, one is crossing all combinations of defined bins for the coverpoints, and one needs a
mechanism to choose these combinations. SystemVerilog has a binsof operator for this purpose.
The argument of the binsof operator can be either a coverpoint, in which case all defined bins for
that coverpoint are meant, or a coverpoint bin, in which case only that bin is selected. One can
use a limited set of logic operators on binsof expressions, to further refine one’s selections. To
explain this, consider the following cross bins definition shown in figure 5:

       • The cross is labeled cr_1
       • The cross operates on coverpoints cp_1 and cp_2
       • The cross has a single, user defined bin, b_cr
       • The first binsof operator selects a single bin, b, within the coverpoint cp_1. Other
       bins defined for cp_1 are ignored.
       • The second binsof operator selects all bins of coverpoint cp_2. This coverpoint will
       have 4 automatically generated bins, since it is 2 bits wide and the user had not defined
       any explicit bins for it.
       • The && operator will cause the cross bin, b_cr, to be updated only when the specific
       bin b in coverpoint cp_1 is hit, and a valid bin (any) within cp_2 is also hit.




SNUG Boston 2005                                7           A Unique Functional Coverage Flow
2.1 NTB coverage_groups

In figure 6, we show how one would write an NTB coverage_group that has the same semantics,
but slightly different syntax, as the SystemVerilog covergroup of Figure 5. Note that the NTB
sample is roughly equivalent to the SystemVerilog coverpoint. In addition, we show an NTB
interface block, which is the means we used to connect to design signals in NTB. The NTB
m_state construct, used in the cp_1 sample point, has a similar role to the SystemVerilog []
operator, in that it creates an individual bin for every value in its range.


      interface cg_if {
        input clk CLOCK hdl_node "`design_module.clk";
        input reset INPUT_EDGE INPUT_SKEW hdl_node "`DESIGN_PATH.reset";
        input [10:0] v_a INPUT_EDGE INPUT_SKEW hdl_node "`DESIGN_PATH.va";
        input [1:0] v_b INPUT_EDGE INPUT_SKEW hdl_node "`DESIGN_PATH.vb";
      }

      coverage_group cg_2 {
        sample_event = @(posedge cg_if.clk);
        sample cp_1 (ex_sysvlog_if.v_a)
        {
          state a (0:63,65);
          m_state b (127:150], [148:191]);
          m_state c (200:202) if (!cg_if.reset );
          state d (1000:2000);
          bad_state bad_vals (2001:2047);
         }
        sample cp_2 (cg_if.v_b);
        cross cr_1 (cp_1,cp_2)
        {
          state b_cr ( (( (cp_1 >= 127) && (cp_1 <= 191) ) ) && (( (cp_2 >= 0) && (cp_2 <= 3) ) ));
        }
      }




                            Figure 6 : NTB (Vera) coverage_group example




SNUG Boston 2005                              8           A Unique Functional Coverage Flow
2.2 Bind Directives

Sampling of signals in SystemVerilog is made simple by the bind directive. Bind directives
cause one module to be instantiated within another, without having to explicitly alter the code of
either. This facilitates a strict separation between a design’s implementation code and its
verification code, whether the latter is code for functional coverage, for testbench modeling, or
any other purpose.

The first three fields of the bind directive are as follows:

       1. The name of the module or instance that is the target of the binding
       2. The name of the module that is being bound to the target module, and
       3. The instance name of the module being bound

After these three fields there follows a port list, with the same syntax as for a normal, Verilog
module instantiation. Figure 7 illustrates this. There, we show a module with functional
coverage code, cover_mod. It contains a single covergroup, cg_sig, which uses signals local to
cover_mod. But, these signals are actually connected to those of a design module, design_mod,
which is not shown. A bind directive (note that it is defined outside of module scope) makes this
connection. The signal names in the port list are those local to the design module. They are
connected to the inputs of the coverage module, cover_mod, in order of appearance. Similar to
the rules for traditional Verilog instantiations, we also could have used dot operator connections
in the port list. These are safer, being less error prone, but for brevity, we chose to not to show
them.

When the bind directive is executed during compile time, the bound module is instantiated
directly below the target module or instance. Since the target may be named by its module or
instance name, there are really two types of bindings. If module binding is used, an instance of
the bound module is placed below each instance of the target module. If instance binding is
used, an instance of the bound module is placed below only one, particular instance of the target
module. Usually, for functional coverage, there is no need for module binding, as coverage is
generally written for modules that are rather high up in the hierarchy and have only one instance.

Signals in the target instance are bound to inputs in the bound module through the bind port list.
Thus, the bound module has access to any and all signals in the scope of the target instance,
simply by putting them in the port list, which makes sampling of design signals for functional
coverage rather easy. The hierarchical path to the coverage module instance also makes clear
which parts of the design are being covered, because the design instance whose signals are being
sampled is placed immediately above the coverage module instance in the hierarchy. Thus, if
one adopts a naming convention that makes it easy to recognize coverage modules, one can
know which design modules they are sampling simply by reading the hierarchical path name of
the coverage module.




SNUG Boston 2005                                   9           A Unique Functional Coverage Flow
module cover_mod (clk, reset, enable, sig1, sig2, sig3);
         input clk;
         input reset;
         input enable;
         input [1:0] sig1;
         input [2;0] sig2;
         input [3:0] sig3;

        covergroup cg_sig @(posedge clk)
          cp_1 : coverpoint sig1 iff (!reset && enable);
          cp_2 : coverpoint sig2 iff (!reset && enable);
          cp_3 : coverpoint sig3 iff (!reset && enable);
          cr_1 : cross sig1,sig2,sig3;
        endgroup
        endmodule

        bind design_mod cover_mod u_cover_mod (d_clk, d_rst, d_en, d_sig1, d_sig2, d_sig3);




                                     Figure 7 : SVA Bind

3.0 SystemVerilog for Functional Coverage at ARM-Austin
At ARM in Austin, we debated several choices for a functional coverage vehicle for our current
project, the design of a next generation, high performance ARM core. In the end, we decided on
SystemVerilog as implemented in Synopsys’ VCS. We were motivated by the fact that
SystemVerilog was an emerging standard that would eventually have wide vendor support, and
that it was being integrated at no extra cost into VCS. We also liked the fact that, via its
sequence and property constructs, with the associated cover and assert directives, one could
reuse SystemVerilog functional coverage code for assertions, and visa-versa. In addition,
SystemVerilog supported coverage of permutations of values of bit-vectors, through its
covergroup construct. This was extremely important to us, and, it turns out, the overwhelming
majority of our coverage bins ended up coming from covergroups. None of the other, competing
functional coverage vehicles had the same degree of support for all these aspects of functional
coverage. SystemVerilog stood out in this regard.

However, we had to deal with the problem that SystemVerilog support was being put into VCS
incrementally, and not all coverage constructs we wanted to use were available yet. The most
important one that was missing was the covergroup. However, at the suggestion of Synopsys,
we decided this could be overcome via a translator. Synopsys was building up support for NTB,
the natively compiled version of Vera now being bundled with VCS, at the same time as it was
building up support for SystemVerilog,. The NTB / Vera coverage_group construct was very


SNUG Boston 2005                              10           A Unique Functional Coverage Flow
similar to that of the SystemVerilog covergroup and was immediately available in VCS. We
decided translating between the two was feasible. We created a translator and called it
covermap. With covermap, we were able to train our team in the use of SystemVerilog in the
present, while building up a body of code that could be reused in the future, when SystemVerilog
would be fully supported. In the meantime, covermap would insure (hopefully) that our
functional coverage code executed with the expected functionality of SystemVerilog.

3.1 Relating Design Components to Coverage Components
As part of our functional coverage methodology, we mandated that:
        • Functional coverage code be written inside of standard, Verilog modules, as opposed
        to newer SystemVerilog constructs such as program blocks or classes. This allowed our
        hierarchy to be composed of similar structures, and we did not have a strong need for the
        other structures, as they were more targeted towards testbenches and we were using an all
        Verilog testbench.
        • Bind directives be used to create a one-to-one relationship between a coverage
        module and a design module. This facilitated our post-processing tools relating the
        sampled modules to the modules doing the sampling.
        • Only standard Verilog reg and wire variables be used in coverage modules. While
        other constructs were available in SystemVerilog and had some advantages, this kept the
        coverage modules as similar, in coding style, to the design modules as possible.
        • Local variables be allowed in coverage modules, but bracketed between formatted
        comments. This allowed the covermap translator to recognize them easily. The local
        variables were used to form Boolean expressions, or, quite often, complicated state
        machines from sampled, design variables. This, in turn, simplified the task of functional
        coverage. For example, bus signals were used to create state machines that kept track of
        transaction histories, and, in turn, functional coverage was written in terms of these
        histories.
In our configuration management structure there is a directory for each distinct unit of our
design. We made a subdirectory under each such unit directory, for functional coverage files.
We initiated a naming convention where the file names for functional coverage files reused the
names of the design modules they were covering, with an added “_sysvlog.v” suffix. We created
a small Perl script that found all such files with these suffixes, whenever we compiled a
simulation model with functional coverage, and put them in a file list for the VCS compiler.

3.2 Code Writing Standards

For covered properties, we mandated that all coverage code writers would use the sequence
construct to describe temporal behavior, and that all sequences would be labeled for reuse. We
then created covered properties by labeling the property, and applying a cover directive to that
label. We created assertions from sequences in a similar manner, using the assert directive.
Within assertions, a sequence would typically occur as the antecedent of an implication.
Assertions and covered properties work synergistically, in that the covered property measures
how often the design has been stressed, while the assertion monitors for correct behavior
whenever the stress is applied. As stated above, “vacuous truth” is a problem in a verification
system. Using our methodology, if an assertion never fired (which is desired) one could easily


SNUG Boston 2005                               11           A Unique Functional Coverage Flow
ascertain, from looking at hit total for the related covered property, whether that was because it
was never stressed, i.e., whether its left hand side, the antecedent, had never been true.

For covergroups, we supported most of the constructs that are in the current SystemVerilog 3.1a
LRM; except for transition coverage (no one felt a strong need for it).

For all coverage constructs, we mandated a naming convention. For example, covered property
names would begin with “c_”, covergroups with “cg_”, coverpoints with “cp_”, etc. This
facilitated easy recognition of an item’s type in our output, when a coverage bin was listed using
its full hierarchical path. In that case, with these conventions it was easy to see that it was, for
example, a bin within a cross within a covergroup, and to know which design module’s signals
were being sampled.

We also utilized a priority labeling system, with each covered property and each coverage bin
allowed to have a separate priority. We allowed three levels:
        1. L1. Meaning, important enough that it must be hit in top level simulations
        2. L2. Meaning, desirable to hit at top level, but acceptable if hit only in unit level
        simulation (where it is easier to generate specific input sequences)
        3. L3: Meaning, desirable to hit at any level, but not required
Use of anything but L1 coverage was discouraged, and had to be justified. L3 coverage was
used only rarely, and had to be rigorously justified. Usually, it was used as a temporary holding
place for coverage points that were new and not thoroughly tested.

We implemented the priority labeling system through formatted comments containing a coverage
item’s name and its priority level. The covermap translator then applied that label to that item
and to all items below it in the coverage hierarchy, unless the label was contradicted by a
specific directive found for an item lower down. The highest element in the coverage hierarchy
for any Verilog module was the module itself, the next highest were individual covered
properties and covergroups, and, within a covergroup, coverpoints and crosses were next highest,
with the lowest level being the bins of coverpoints and crosses.

4.0 Translating SystemVerilog to NTB : The 'covermap' Translator
The main task of the covermap translator is to read in SystemVerilog files, find covergroup
constructs, and translate these to NTB coverage_group constructs. But, it performs many other
useful tasks, as well, for example enforcing our priority labeling system described above. The
translator would signal an error if a coverage item did not have an associated priority label.

Each file read in by covermap is expected to contain a single, Verilog module definition, and one
or more SystemVerilog bind directives. The Verilog coverage module may contain one or more
of the following:

   •   SVA sequence and property definitions
   •   SVA covered property and assertion declarations
   •   SystemVerilog covergroup definitions and instantiations



SNUG Boston 2005                                 12           A Unique Functional Coverage Flow
•    Local variable definitions, and Verilog code (including tasks and functions) utilizing
        these

When covermap translates ‘n’ SystemVerilog input files, it will produce 2n + 1 output files, of
the following type:

   •    ‘n’ files with all the original SVA covered properties and assertions, and with all Verilog
        code utilizing local variables, but with covergroups and their instantiations commented
        out
   •    ‘n’ NTB files holding NTB coverage_groups derived from the original SystemVerilog
        covergroups
   •    A “master” NTB file holding a program block

NTB begins execution in a program block, a construct somewhat similar to the ‘main’ function
in C. There must be at most only one such block in any body of NTB code. All the NTB
coverage_groups must be instantiated in this program block, even if they are defined in separate
files. covermap facilitates this by generating include directives within the master NTB file for
all the separate NTB files.

The following diagram illustrates the functional coverage flow:



                                               Test Stimulus
       Original SV                                 Files               Verilog Design
       Files                                                                Files



                                            NTB Files                    Compile and
                                                                         Sim Scripts
                 covermap
                 translator
                                            SV Files
                                                                   NTB        SVA



       DB Init                        DB                             Post processing
       File                           Viewer                           Programs




                                    Figure 8 : Flow Diagram


SNUG Boston 2005                                13             A Unique Functional Coverage Flow
In this flow, we start with hand coded SystemVerilog files. As covermap reads in these files, it
stores information in a set of C++ classes that give it a picture of the coverage hierarchy. It then
traverses this hierarchy down to individual coverage bins and prints out a list of all these bins in
a database initialization file (“DB Init File”). This file is used to initialize an SQL database used
by an HTML viewer for coverage results. Along with the hit counts for each bin, the database
stores a reference to the test names that hit it, and Perl scripts operate on the database to generate
a minimized suite of tests that can hit all the coverage points. In addition to using this SQL
database and HTML viewer for functional coverage, we track pass / fail numbers on regression
suites and track progress of the debug effort, with it, as well. One of the most important reasons
for creating our own means of post processing functional coverage results was to integrate those
results with this type of information coming from our simulations, so that, within one viewing
tool, we could track all pertinent aspects of our project’s progress.

In the normal translation flow, the original SystemVerilog files are translated into 2 types of
files: (1) NTB files holding coverage_groups, and (2) SystemVerilog files holding all the
original code except that related to covergroups. When the Verilog from the design is compiled
for simulation, these files are compiled in as well.

As covermap translates, it changes names of coverage items in order to transmit information on
design hierarchy into NTB data. Since NTB coverage_groups are instantiated in the NTB
program block, which is in the testbench, no information is readily available in output files as to
the design blocks being sampled by a coverage_group. covermap is able to recreate the
hierarchical path that would have existed had the NTB coverage_group been a SystemVerilog
covergroup. It encodes this information in a new name for the NTB coverage_group. In turn,
post processing scripts are able to parse this name, and show the user where the coverage items
are in relation to the design hierarchy.

As test stimulus is loaded and simulations are run, two different types of coverage databases are
formed: SVA and NTB. The SVA database holds hit counts for covered properties, while the
NTB database holds the same for the bins created by NTB coverage_groups. Special scripts and
programs then read these databases, and reformat the data to make it suitable for the HTM
database viewer (“DB Viewer”). This requires anticipating the names VCS / NTB will apply to
automatically generated coverage_group bins.

When the coverage files are translated, the resulting set of NTB and SVA files are compiled with
the code for the design and testbench. During covermap’s translation, the user may obtain two
types of optional output:
    • statistics on the distribution of properties and covergroups through the design hierarchy,
       as well as a breakdown within the covergroups on the quantities of bins in each member
       coverpoint or cross, and
    • an initialization file for loading our SQL coverage database, listing the hierarchical path
       to each coverage bin of all the covergroup coverpoints and crosses, as well as the
       hierarchical path to each covered property.
Great care is taken that the names of bins coverpoint and cross bins correspond to what will be
generated after simulation. For instance, NTB has certain naming conventions for auto-
generated bins, and certain formatting requirements for fields within names. We take care to


SNUG Boston 2005                                 14            A Unique Functional Coverage Flow
produce names consistent with those in our SQL initialization file, because we will use string
matching to compare names of bins hit in simulation to those in the initialization file.

After simulations have concluded, functional coverage data exists in two separate sets of files,
one for NTB coverage_groups and one for SVA covered properties. We then transform this data
for our SQL / HTML viewer. In our post process scripts, we label it as L1, L2 and L3 priority
level. The covermap translator enables this by prepending the priority level to the translated
name of the coverage item. We run scripts that use the Tcl SVA API (application programming
interface) to extract the covered properties that were hit, and the number of hits for each. We run
a C program that utilizes Synopsys new UCAPI (Unified Coverage API) library, to read out the
same information for the NTB coverage_group members. The UCAPI is a relatively new library
intended to be a single interface through which all the various types of coverage formats in use
by Synopsys may be read.

5.0 Results and Performance
At this point, we are still in the midst of our design project, and while we have written most of
our intended coverage code, we have not written all of it. At the unit level, our functional
coverage is well above 90%, and it is approaching that for top level.

One important issue is the cost of functional coverage, i.e., how much it reduces simulation
performance. Of course, this will be in proportion to the size of the functional coverage code
base relative to the design code. There is no universally accepted way to measure the size of a
body of functional coverage code. We feel the most appropriate way is to count coverage bins,
in other words, to determine how many separate events are being monitored. When we expand
our code, we currently generate around 100,000 coverage bins; but, among these there can be a
wide variance in simulation time. A simple coverpoint bin, where the coverpoint hasn’t any
complex sampling guards, would be very quick to simulate, since it can be implemented with
efficient, integer operations. A covered property (which can be considered to implement a “bin”,
if we understand that to mean a counter of how often the property was hit), on the other hand,
could be very costly to simulate, since it may describe a very complex sequence of events, the
tracking of which requires a large overhead. However, the vast majority of our coverage bins
come from covergroups.

Right now, we are experiencing slowdowns of 300% to 450% in top level simulations with
functional coverage. In other words, if a simulation takes, say, 100 CPU seconds to simulate,
using a simulation model compiled without functional coverage code, it will take between 300 to
450 CPU seconds to simulate when our functional coverage code is compiled in. This is just the
simulation time, and does not include any post processing time for analyzing results. When
considering these numbers, it should be borne in mind that the testbench for our full design (as
opposed to our unit level testbenches) is an all Verilog testbench, using only a very few PLI
calls. For many users of functional coverage, they will be adding functional coverage to the
already existing overhead of a testbench in a specialized language, such as NTB / Vera. In this
case, the effect of functional coverage may not seem as large. Ours is a rather unusual case,
allowing one to see the overhead of functional coverage relative to a rather pure body of
traditional Verilog code (note that in our design and testbench we are not using SystemVerilog


SNUG Boston 2005                                15            A Unique Functional Coverage Flow
constructs, only in our functional coverage files, and much of our testbench is written in
synthesizable Verilog).

We have attempted to analyze these slowdowns, with help from Synopsys R&D teams. One
major aspect, which cannot be resolved quickly, is that much of the work VCS does to analyze
functional coverage is still being done through function calls into libraries. While this is quite
normal, it obviously would be better if the function call overhead could be eliminated. VCS gets
much of its speedup on regular Verilog code from transforming it into natively compiled
constructs. Synopsys plans to eventually do all functional coverage work in a native compile as
well, and this is where the largest performance gains are expected. Until then, performance
improvements must come from incremental sources.

One workaround we are investigating is compiling only those coverage items that have not been
sufficiently hit. The idea is to create a feedback loop between the coverage results database and
the covermap translator. The translator would inspect a list of coverage items hit to date on a
specific version of the design, and not translate those that have been sufficiently hit.

While the reduced performance we have experienced is a major problem, we do not consider this
a defect specific to SystemVerilog or VCS, we suspect that slowdowns like this are common
throughout the industry. Since use of functional coverage is only now starting to spread, the
problem may not be widely recognized; but, it is certainly important. It is obviously desirable to
do functional coverage; but, at the same time it is very costly. Design teams are facing the
difficult choice of having to split their resources between simulating the design, which is their
primary means of finding bugs, and tracking whether their simulations are effective, through
functional coverage. Given the current performance problems of functional coverage, it is
tempting to skip it in favor doing more simulation. Synopsys must work hard to eliminate the
need for this tradeoff, by boosting the performance of functional coverage.




SNUG Boston 2005                                16           A Unique Functional Coverage Flow

More Related Content

What's hot

Introduction to System verilog
Introduction to System verilog Introduction to System verilog
Introduction to System verilog Pushpa Yakkala
 
Challenges in Using UVM at SoC Level
Challenges in Using UVM at SoC LevelChallenges in Using UVM at SoC Level
Challenges in Using UVM at SoC LevelDVClub
 
Uvm presentation dac2011_final
Uvm presentation dac2011_finalUvm presentation dac2011_final
Uvm presentation dac2011_finalsean chen
 
UVM Methodology Tutorial
UVM Methodology TutorialUVM Methodology Tutorial
UVM Methodology TutorialArrow Devices
 
Session 6 sv_randomization
Session 6 sv_randomizationSession 6 sv_randomization
Session 6 sv_randomizationNirav Desai
 
System verilog control flow
System verilog control flowSystem verilog control flow
System verilog control flowPushpa Yakkala
 
Efficient Methodology of Sampling UVM RAL During Simulation for SoC Functiona...
Efficient Methodology of Sampling UVM RAL During Simulation for SoC Functiona...Efficient Methodology of Sampling UVM RAL During Simulation for SoC Functiona...
Efficient Methodology of Sampling UVM RAL During Simulation for SoC Functiona...Sameh El-Ashry
 
SystemVerilog Assertions verification with SVAUnit - DVCon US 2016 Tutorial
SystemVerilog Assertions verification with SVAUnit - DVCon US 2016 TutorialSystemVerilog Assertions verification with SVAUnit - DVCon US 2016 Tutorial
SystemVerilog Assertions verification with SVAUnit - DVCon US 2016 TutorialAmiq Consulting
 
System verilog important
System verilog importantSystem verilog important
System verilog importantelumalai7
 
SOC Verification using SystemVerilog
SOC Verification using SystemVerilog SOC Verification using SystemVerilog
SOC Verification using SystemVerilog Ramdas Mozhikunnath
 
Introduction about APB Protocol
Introduction about APB ProtocolIntroduction about APB Protocol
Introduction about APB ProtocolPushpa Yakkala
 
verification_planning_systemverilog_uvm_2020
verification_planning_systemverilog_uvm_2020verification_planning_systemverilog_uvm_2020
verification_planning_systemverilog_uvm_2020Sameh El-Ashry
 
Basics of Functional Verification - Arrow Devices
Basics of Functional Verification - Arrow DevicesBasics of Functional Verification - Arrow Devices
Basics of Functional Verification - Arrow DevicesArrow Devices
 
Random stability in systemVerilog and UVM based testbench
Random stability in systemVerilog and UVM based testbenchRandom stability in systemVerilog and UVM based testbench
Random stability in systemVerilog and UVM based testbenchKashyap Adodariya
 

What's hot (20)

Introduction to System verilog
Introduction to System verilog Introduction to System verilog
Introduction to System verilog
 
Challenges in Using UVM at SoC Level
Challenges in Using UVM at SoC LevelChallenges in Using UVM at SoC Level
Challenges in Using UVM at SoC Level
 
Uvm presentation dac2011_final
Uvm presentation dac2011_finalUvm presentation dac2011_final
Uvm presentation dac2011_final
 
UVM Methodology Tutorial
UVM Methodology TutorialUVM Methodology Tutorial
UVM Methodology Tutorial
 
UVM TUTORIAL;
UVM TUTORIAL;UVM TUTORIAL;
UVM TUTORIAL;
 
Session 6 sv_randomization
Session 6 sv_randomizationSession 6 sv_randomization
Session 6 sv_randomization
 
System verilog control flow
System verilog control flowSystem verilog control flow
System verilog control flow
 
system verilog
system verilogsystem verilog
system verilog
 
Efficient Methodology of Sampling UVM RAL During Simulation for SoC Functiona...
Efficient Methodology of Sampling UVM RAL During Simulation for SoC Functiona...Efficient Methodology of Sampling UVM RAL During Simulation for SoC Functiona...
Efficient Methodology of Sampling UVM RAL During Simulation for SoC Functiona...
 
Ch 6 randomization
Ch 6 randomizationCh 6 randomization
Ch 6 randomization
 
axi protocol
axi protocolaxi protocol
axi protocol
 
Ovm vs-uvm
Ovm vs-uvmOvm vs-uvm
Ovm vs-uvm
 
SystemVerilog Assertions verification with SVAUnit - DVCon US 2016 Tutorial
SystemVerilog Assertions verification with SVAUnit - DVCon US 2016 TutorialSystemVerilog Assertions verification with SVAUnit - DVCon US 2016 Tutorial
SystemVerilog Assertions verification with SVAUnit - DVCon US 2016 Tutorial
 
System verilog important
System verilog importantSystem verilog important
System verilog important
 
SOC Verification using SystemVerilog
SOC Verification using SystemVerilog SOC Verification using SystemVerilog
SOC Verification using SystemVerilog
 
AMBA_APB_pst
AMBA_APB_pstAMBA_APB_pst
AMBA_APB_pst
 
Introduction about APB Protocol
Introduction about APB ProtocolIntroduction about APB Protocol
Introduction about APB Protocol
 
verification_planning_systemverilog_uvm_2020
verification_planning_systemverilog_uvm_2020verification_planning_systemverilog_uvm_2020
verification_planning_systemverilog_uvm_2020
 
Basics of Functional Verification - Arrow Devices
Basics of Functional Verification - Arrow DevicesBasics of Functional Verification - Arrow Devices
Basics of Functional Verification - Arrow Devices
 
Random stability in systemVerilog and UVM based testbench
Random stability in systemVerilog and UVM based testbenchRandom stability in systemVerilog and UVM based testbench
Random stability in systemVerilog and UVM based testbench
 

Viewers also liked

Finding Bugs Faster with Assertion Based Verification (ABV)
Finding Bugs Faster with Assertion Based Verification (ABV)Finding Bugs Faster with Assertion Based Verification (ABV)
Finding Bugs Faster with Assertion Based Verification (ABV)DVClub
 
The Verification Methodology Landscape
The Verification Methodology LandscapeThe Verification Methodology Landscape
The Verification Methodology LandscapeDVClub
 
Functial Verification Tutorials
Functial Verification TutorialsFunctial Verification Tutorials
Functial Verification Tutorialsguestbcfac5
 
Aldec overview 2011-10 revised
Aldec overview 2011-10 revisedAldec overview 2011-10 revised
Aldec overview 2011-10 revisedPrateek Chopra
 
System Verilog 2009 & 2012 enhancements
System Verilog 2009 & 2012 enhancementsSystem Verilog 2009 & 2012 enhancements
System Verilog 2009 & 2012 enhancementsSubash John
 
Timing Analysis
Timing AnalysisTiming Analysis
Timing Analysisrchovatiya
 
System Verilog Tutorial - VHDL
System Verilog Tutorial - VHDLSystem Verilog Tutorial - VHDL
System Verilog Tutorial - VHDLE2MATRIX
 
Code coverage & tools
Code coverage & toolsCode coverage & tools
Code coverage & toolsRajesh Kumar
 
Fifo first in first out powerpoint ppt slides.
Fifo first in first out powerpoint ppt slides.Fifo first in first out powerpoint ppt slides.
Fifo first in first out powerpoint ppt slides.SlideTeam.net
 
First In, First Out (FIFO); Last In, Last Out (LIFO)
First In, First Out (FIFO); Last In, Last Out (LIFO)First In, First Out (FIFO); Last In, Last Out (LIFO)
First In, First Out (FIFO); Last In, Last Out (LIFO)UNowAcademics
 

Viewers also liked (14)

Doulos coverage-tips-tricks
Doulos coverage-tips-tricksDoulos coverage-tips-tricks
Doulos coverage-tips-tricks
 
Code coverage
Code coverageCode coverage
Code coverage
 
Finding Bugs Faster with Assertion Based Verification (ABV)
Finding Bugs Faster with Assertion Based Verification (ABV)Finding Bugs Faster with Assertion Based Verification (ABV)
Finding Bugs Faster with Assertion Based Verification (ABV)
 
The Verification Methodology Landscape
The Verification Methodology LandscapeThe Verification Methodology Landscape
The Verification Methodology Landscape
 
Functial Verification Tutorials
Functial Verification TutorialsFunctial Verification Tutorials
Functial Verification Tutorials
 
Aldec overview 2011-10 revised
Aldec overview 2011-10 revisedAldec overview 2011-10 revised
Aldec overview 2011-10 revised
 
System Verilog 2009 & 2012 enhancements
System Verilog 2009 & 2012 enhancementsSystem Verilog 2009 & 2012 enhancements
System Verilog 2009 & 2012 enhancements
 
Timing Analysis
Timing AnalysisTiming Analysis
Timing Analysis
 
System Verilog Tutorial - VHDL
System Verilog Tutorial - VHDLSystem Verilog Tutorial - VHDL
System Verilog Tutorial - VHDL
 
Code coverage & tools
Code coverage & toolsCode coverage & tools
Code coverage & tools
 
FIFO Design
FIFO DesignFIFO Design
FIFO Design
 
Verilog HDL
Verilog HDLVerilog HDL
Verilog HDL
 
Fifo first in first out powerpoint ppt slides.
Fifo first in first out powerpoint ppt slides.Fifo first in first out powerpoint ppt slides.
Fifo first in first out powerpoint ppt slides.
 
First In, First Out (FIFO); Last In, Last Out (LIFO)
First In, First Out (FIFO); Last In, Last Out (LIFO)First In, First Out (FIFO); Last In, Last Out (LIFO)
First In, First Out (FIFO); Last In, Last Out (LIFO)
 

Similar to System Verilog Functional Coverage

systemverilog-interview-questions.docx
systemverilog-interview-questions.docxsystemverilog-interview-questions.docx
systemverilog-interview-questions.docxssuser1c8ca21
 
A Formal Executable Semantics Of Verilog
A Formal Executable Semantics Of VerilogA Formal Executable Semantics Of Verilog
A Formal Executable Semantics Of VerilogTracy Morgan
 
SystemVerilog-20041201165354.ppt
SystemVerilog-20041201165354.pptSystemVerilog-20041201165354.ppt
SystemVerilog-20041201165354.pptravi446393
 
Re usable continuous-time analog sva assertions
Re usable continuous-time analog sva assertionsRe usable continuous-time analog sva assertions
Re usable continuous-time analog sva assertionsRégis SANTONJA
 
Postdoc symposium - A Logic Meta-Programming Foundation for Example-Driven Pa...
Postdoc symposium - A Logic Meta-Programming Foundation for Example-Driven Pa...Postdoc symposium - A Logic Meta-Programming Foundation for Example-Driven Pa...
Postdoc symposium - A Logic Meta-Programming Foundation for Example-Driven Pa...ICSM 2011
 
A Logic Meta-Programming Foundation for Example-Driven Pattern Detection in O...
A Logic Meta-Programming Foundation for Example-Driven Pattern Detection in O...A Logic Meta-Programming Foundation for Example-Driven Pattern Detection in O...
A Logic Meta-Programming Foundation for Example-Driven Pattern Detection in O...Coen De Roover
 
Qtp interview questions
Qtp interview questionsQtp interview questions
Qtp interview questionsRamu Palanki
 
Qtp interview questions
Qtp interview questionsQtp interview questions
Qtp interview questionsRamu Palanki
 
Components in real time systems
Components in real time systemsComponents in real time systems
Components in real time systemsSaransh Garg
 
System Structure for Dependable Software Systems
System Structure for Dependable Software SystemsSystem Structure for Dependable Software Systems
System Structure for Dependable Software SystemsVincenzo De Florio
 
safety assurence in process control
safety assurence in process controlsafety assurence in process control
safety assurence in process controlNathiya Vaithi
 
Relational Database Management System
Relational Database Management SystemRelational Database Management System
Relational Database Management Systemsweetysweety8
 
What is the difference between struts 1 vs struts 2
What is the difference between struts 1 vs struts 2What is the difference between struts 1 vs struts 2
What is the difference between struts 1 vs struts 2Santosh Singh Paliwal
 
A Verified Modern SAT Solver
A Verified Modern SAT SolverA Verified Modern SAT Solver
A Verified Modern SAT SolverKatie Naple
 
Performance tesing coding standards & best practice guidelines v1
Performance tesing coding standards & best practice guidelines v1Performance tesing coding standards & best practice guidelines v1
Performance tesing coding standards & best practice guidelines v1Argos
 
Using a Formal Property Checker for Simulation Coverage Closure
Using a Formal Property Checker for Simulation Coverage Closure Using a Formal Property Checker for Simulation Coverage Closure
Using a Formal Property Checker for Simulation Coverage Closure DVClub
 
Programming topics. syed arslan rizvi
Programming topics. syed arslan rizviProgramming topics. syed arslan rizvi
Programming topics. syed arslan rizviSyed Arslan Rizvi
 
Elastic Morocco Meetup Nov 2020
Elastic Morocco Meetup Nov 2020Elastic Morocco Meetup Nov 2020
Elastic Morocco Meetup Nov 2020Anna Ossowski
 
2010 bristol q1_formal-property-checkers
2010 bristol q1_formal-property-checkers2010 bristol q1_formal-property-checkers
2010 bristol q1_formal-property-checkersObsidian Software
 

Similar to System Verilog Functional Coverage (20)

systemverilog-interview-questions.docx
systemverilog-interview-questions.docxsystemverilog-interview-questions.docx
systemverilog-interview-questions.docx
 
A Formal Executable Semantics Of Verilog
A Formal Executable Semantics Of VerilogA Formal Executable Semantics Of Verilog
A Formal Executable Semantics Of Verilog
 
SystemVerilog-20041201165354.ppt
SystemVerilog-20041201165354.pptSystemVerilog-20041201165354.ppt
SystemVerilog-20041201165354.ppt
 
Re usable continuous-time analog sva assertions
Re usable continuous-time analog sva assertionsRe usable continuous-time analog sva assertions
Re usable continuous-time analog sva assertions
 
Postdoc symposium - A Logic Meta-Programming Foundation for Example-Driven Pa...
Postdoc symposium - A Logic Meta-Programming Foundation for Example-Driven Pa...Postdoc symposium - A Logic Meta-Programming Foundation for Example-Driven Pa...
Postdoc symposium - A Logic Meta-Programming Foundation for Example-Driven Pa...
 
A Logic Meta-Programming Foundation for Example-Driven Pattern Detection in O...
A Logic Meta-Programming Foundation for Example-Driven Pattern Detection in O...A Logic Meta-Programming Foundation for Example-Driven Pattern Detection in O...
A Logic Meta-Programming Foundation for Example-Driven Pattern Detection in O...
 
Qtp interview questions
Qtp interview questionsQtp interview questions
Qtp interview questions
 
Qtp interview questions
Qtp interview questionsQtp interview questions
Qtp interview questions
 
Components in real time systems
Components in real time systemsComponents in real time systems
Components in real time systems
 
System Structure for Dependable Software Systems
System Structure for Dependable Software SystemsSystem Structure for Dependable Software Systems
System Structure for Dependable Software Systems
 
safety assurence in process control
safety assurence in process controlsafety assurence in process control
safety assurence in process control
 
Relational Database Management System
Relational Database Management SystemRelational Database Management System
Relational Database Management System
 
What is the difference between struts 1 vs struts 2
What is the difference between struts 1 vs struts 2What is the difference between struts 1 vs struts 2
What is the difference between struts 1 vs struts 2
 
A Verified Modern SAT Solver
A Verified Modern SAT SolverA Verified Modern SAT Solver
A Verified Modern SAT Solver
 
Performance tesing coding standards & best practice guidelines v1
Performance tesing coding standards & best practice guidelines v1Performance tesing coding standards & best practice guidelines v1
Performance tesing coding standards & best practice guidelines v1
 
Using a Formal Property Checker for Simulation Coverage Closure
Using a Formal Property Checker for Simulation Coverage Closure Using a Formal Property Checker for Simulation Coverage Closure
Using a Formal Property Checker for Simulation Coverage Closure
 
Programming topics. syed arslan rizvi
Programming topics. syed arslan rizviProgramming topics. syed arslan rizvi
Programming topics. syed arslan rizvi
 
Elastic Morocco Meetup Nov 2020
Elastic Morocco Meetup Nov 2020Elastic Morocco Meetup Nov 2020
Elastic Morocco Meetup Nov 2020
 
Bound and Checked
Bound and CheckedBound and Checked
Bound and Checked
 
2010 bristol q1_formal-property-checkers
2010 bristol q1_formal-property-checkers2010 bristol q1_formal-property-checkers
2010 bristol q1_formal-property-checkers
 

System Verilog Functional Coverage

  • 1. A Unique Functional Coverage Flow using SystemVerilog and NTB Richard Raimi ARM, Inc rraimi@arm.com Dennis Strouphauer Synopsys, Inc dstroup@synopsys.com ABSTRACT There are two constructs in SystemVerilog that support functional coverage: the covered property and the covergroup. At ARM, Inc. in Austin, Texas, we wanted to use SystemVerilog functional coverage on a next generation processor design; however, only the covered property and not the covergroup was going to be supported by Synopsys in the time frame of our project. Feeling that both were needed, we chose to write our functional coverage in SystemVerilog, using both the covered property and the covergroup, and translate the SystemVerilog covergroups to NTB / Vera ‘coverage_groups’, a similar, but not identical, construct. In this way, we were able to train our team in SystemVerilog, use the code we wrote in the present, and allow ourselves the option of reusing it in the future, when the covergroup would be fully supported in VCS. In this paper, we describe this translation process, as well as the pros and cons of functional coverage in both NTB / Vera and SystemVerilog.
  • 2. Table of Contents 1.0 Introduction: Functional Coverage ....................................................................................3 2.0 Functional Coverage Constructs in SystemVerilog and Vera / NTB ................................3 2.1 NTB coverage_groups .......................................................................................................8 2.2 Bind Directives ..................................................................................................................9 3.0 SystemVerilog for Functional Coverage at ARM-Austin ...............................................10 3.1 Relating Design Components to Coverage Components.................................................11 3.2 Code Writing Standards...................................................................................................11 4.0 Translating SystemVerilog to NTB : The 'covermap' Translator ....................................12 5.0 Results and Performance..................................................................................................15 Table of Figures Figure 1 : SVA Sequence...............................................................................................................4 Figure 2 : SVA Properties..............................................................................................................4 Figure 3 : SVA Assert and Cover ..................................................................................................5 Figure 4 : SVA Covergroup...........................................................................................................6 Figure 5 : SVA Covergroup Advanced..........................................................................................7 Figure 6 : NTB (Vera) coverage_group example ..........................................................................8 Figure 7 : SVA Bind ....................................................................................................................10 Figure 8 : Flow Diagram..............................................................................................................13 SNUG Boston 2005 2 A Unique Functional Coverage Flow
  • 3. 1.0 Introduction: Functional Coverage Functional Coverage provides an indication of the thoroughness of the implementation of the verification plan and can help answer questions such as how much of the design specification has been exercised? and what actually happened during a test? As chip designs grow larger and more complex with thousands of possible states and transitions, a comprehensive verification environment must be created that minimizes wasted effort. Functional coverage is used as a guide to direct the verification resources by identifying the tested and untested parts of the design. When properly used, functional coverage can serve as a formal specification of a test plan. In turn, the process of writing functional coverage can bring holes in a test plan to the attention of verification personnel. Functional coverage, because it is a measure of what is determined to be of interest and relevant, must be manually specified by members of the design and verification team. It cannot be extracted automatically from the design source code. This paper describes the use of the SystemVerilog language to create functional coverage models for an ARM processor. 2.0 Functional Coverage Constructs in SystemVerilog and Vera / NTB The constructs in SystemVerilog that are related to functional coverage are: 1. sequences and properties 2. covered properties and assertions 3. covergroups The sequence construct is a basic building block. A sequence is a description of temporal behavior using logical and temporal operators of the SystemVerilog Assertion (SVA) language. SVA is a subset of SystemVerilog, useful for describing behaviors that unfold over multiple time steps. In its simplest form a sequence can be just a Boolean expression, which is considered to be a sequence of zero time steps. It is optional to define what constitutes a time step in a sequence. A time step may be thought of as a directive indicating when to sample variables appearing in the sequence. The ability to write a sequence without defining the meaning of a time step allows reuse of a sequence in many different contexts, each with different definitions of time steps. Labeling a sequence also facilitates reuse, as we will see below. A sequence has no defined truth value, but there is a concept of a sequence being matched, meaning that the behavior of a design unfolds as described in the sequence. Here, we also describe this as the sequence succeeding, or successfully concluding. Figure 1 shows an example of a sequence describing a signal, req, going high, and one time step later, a signal, ack, also going high. SNUG Boston 2005 3 A Unique Functional Coverage Flow
  • 4. sequence s_1; req ##1 ack endsequence Figure 1 : SVA Sequence A sequence can be reused, via its label, inside of a property. The body of a property is made up of one or more sequences operated on by temporal operators or logic operators. The sequences can be written explicitly in the property, meaning, one can form expressions with variables and logic and temporal operators, or one can reuse sequences that are defined elsewhere via their label. (At ARM, we always do the latter.) A property will have a time step, or sampling definition. This is done using Verilog syntax, for example “@(posedge clk)”. If a sequence is reused by referencing its label inside of a property, the sequence will take on the time step definition of the property. Figure 2 shows how a sequence can be reused inside a property: we show sequence s_1 from Figure 1 being reused inside properties p_1 and p_2. Note that evaluation of a property can be subject to constraints. Both properties in Figure 2 will only be evaluated if the signal, reset, is low. property p_1; @(posedge clk) disable iff (reset) s_1; endproperty property p_2; @(posedge clk) disable iff (reset) s_1 |-> done; endproperty Figure 2 : SVA Properties Unlike a sequence, a SystemVerilog property does have a Boolean truth value. At its simplest, if the body of a property is just a Boolean expression, the property is true on every time step in which the expression is true. In more complicated properties, the property is true, at a given sample point, when the mix of temporal and logical operators within it evaluates to true. For example, if s is the label of a sequence, and o is a variable representing a design signal, then the expression s |-> o SNUG Boston 2005 4 A Unique Functional Coverage Flow
  • 5. in the body of a property, where |-> is the implication operator, is true whenever: • s has not successfully concluded, or • s has successfully concluded, and at that same instant, signal o is high As an aside, the fact that the implication operator evaluates to true when its left hand argument, known as the antecedent, evaluates to false, is often confusing to people. This is called “vacuous truth”, and must be taken into account when setting up a functional coverage and assertion based verification system. For example, property p_2 in Figure 2 will be vacuously true at every sample point at which sequence s_1 does not match. It would be desirable to have an independent means of verifying that the property also was true a finite number of time when sequence s_1 did match. Counting how often property p_1 is true accomplishes this. Properties can be labeled, and, like sequences, they can be reused in a higher level context by their label. In particular, properties can be the target of the SystemVerilog cover and assert directives. When a cover directive is applied to a property, a count is generated of how often the property is true at its sample intervals. This is known as a covered property. When an assert directive is applied to a property, an error is signaled if the property is ever false at a sample point. This is known as an assertion. Note that this allows reuse of sequences for both functional coverage and assertions. Figure 3 shows cover and assert directives applied to the properties of Figure 2, p_1 and p_2. Note that applying both these directives at the same time solves the problem of vacuous truth for property p_2. If property p_2 is forever vacuously true, the cover directive, c_1, will have a zero count. If, on the other hand, property p_2, and, therefore, assertion a_2 is actually stressed, cover c_1 will have a positive, non-zero count, to the extent that that occurs. c_1: cover property (p_1); a_2: assert property (p_2) Figure 3 : SVA Assert and Cover SystemVerilog covergroups, in contrast to sequences and properties, are primarily targeted towards combinational logic. They are not part of the SVA subset of SystemVerilog. SystemVerilog covergroups are closely related to the Vera ‘coverage_group’ construct that preceded it. A covergroup will have a sampling, or time step definition, using the same syntax as we saw previously with properties (e.g., @(posedge clk)). The two main components of a covergroup are the coverpoint and the cross. A coverpoint is defined relative to a signal of a particular width. The default behavior of a coverpoint is to generate a counter for each possible permutation of the underlying signal’s values, up to some preset limit. Thus, for example, a 3-bit wide signal would generate 8 counters, one for each SNUG Boston 2005 5 A Unique Functional Coverage Flow
  • 6. possible 0/1 permutation. These counters are referred to as bins. A cross generates counters for the cross product of two or more coverpoints, meaning, counters for the occurrence of all possible simultaneous hits to the bins of the underlying coverpoints. For example, if one coverpoint is related to a 2-bit signal and another to a 3-bit signal, then the default behavior is to create 4 bins for the first coverpoint and 8 for the second. The cross of both coverpoints would, by default, create 32 distinct bins, one for each possible, simultaneous update to the bins of the coverpoints. Figure 4 shows a covergroup like this, where coverpoints cp_1 and cp_2 are defined from 2 and 3 bit signals, respectively, and a cross of these two coverpoints, cr_1, generates 32 bins. reg [1:0] two_bit_sig; reg [2:0] three_bit_sig; covergroup cg_1 @(posedge clk); cp_1 : coverpoint two_bit_sig; cp_2 : coverpoint three_bit_sig; cr_1 : cross cp_1,cp_2; endgroup Figure 4 : SVA Covergroup If one does not constrain the generation of bins, a combinatorial explosion could quickly result. Fortunately, SystemVerilog has a great many ways of specifying constraints. One can put guard conditions on coverpoints and crosses, so that they are updated only when the guards hold. One can apply guards more finely, putting them directly on specific, user-defined bins. One can restrict the range of values of a bin via user-defined bins, and one can label particular ranges as ignorable or illegal. The illegal designation acts much like an assertion, in that it causes the simulator to post an error if a value in the specified range is hit. In general, constraining covergroups involves some method of not allowing SystemVerilog to automatically generate the number of bins it would otherwise generate by default. This often involves creating bins explicitly. The bins keyword is used to create explicit bins on either coverpoints or crosses, as is shown in Figure 5, below. Note that the square bracket operator, ‘[]’, will generate individual bins for each number in its range. Thus, the definition of bins c of coverpoint cp_1, Figure 5, will generate 3 bins, one each for the values 200, 201 and 202. In contrast, the definition of bins a of coverpoint cp_1 will generate only a single bin, for all of the 65 distinct values in its range. With bins a, it will be impossible to know how many times the individual values in the range were hit. If this information is needed, the ‘[]’ operator must be used. SNUG Boston 2005 6 A Unique Functional Coverage Flow
  • 7. reg [10:0] v_a; reg [1:0] v_b; covergroup cg_2 @(posedge clk); cp_1: coverpoint v_a { bins a = { [0:63],65 }; bins b[] = { [127:150], [148:191] }; bins c[] = { 200, 201, 202 } iff (!reset) ; bins d = { [1000:2000] }; illegal_bins bad_vals = { [2001: 2047] }; } cp_2: coverpoint v_b; cr_1 : cross cp_1, cp_2 { bins b_cr = binsof(cp_1.b) && binsof(cp_2); } endgroup Figure 5 : SVA Covergroup Advanced Bins definitions for crosses are more complicated than those for coverpoints. This is because, in a cross, one is crossing all combinations of defined bins for the coverpoints, and one needs a mechanism to choose these combinations. SystemVerilog has a binsof operator for this purpose. The argument of the binsof operator can be either a coverpoint, in which case all defined bins for that coverpoint are meant, or a coverpoint bin, in which case only that bin is selected. One can use a limited set of logic operators on binsof expressions, to further refine one’s selections. To explain this, consider the following cross bins definition shown in figure 5: • The cross is labeled cr_1 • The cross operates on coverpoints cp_1 and cp_2 • The cross has a single, user defined bin, b_cr • The first binsof operator selects a single bin, b, within the coverpoint cp_1. Other bins defined for cp_1 are ignored. • The second binsof operator selects all bins of coverpoint cp_2. This coverpoint will have 4 automatically generated bins, since it is 2 bits wide and the user had not defined any explicit bins for it. • The && operator will cause the cross bin, b_cr, to be updated only when the specific bin b in coverpoint cp_1 is hit, and a valid bin (any) within cp_2 is also hit. SNUG Boston 2005 7 A Unique Functional Coverage Flow
  • 8. 2.1 NTB coverage_groups In figure 6, we show how one would write an NTB coverage_group that has the same semantics, but slightly different syntax, as the SystemVerilog covergroup of Figure 5. Note that the NTB sample is roughly equivalent to the SystemVerilog coverpoint. In addition, we show an NTB interface block, which is the means we used to connect to design signals in NTB. The NTB m_state construct, used in the cp_1 sample point, has a similar role to the SystemVerilog [] operator, in that it creates an individual bin for every value in its range. interface cg_if { input clk CLOCK hdl_node "`design_module.clk"; input reset INPUT_EDGE INPUT_SKEW hdl_node "`DESIGN_PATH.reset"; input [10:0] v_a INPUT_EDGE INPUT_SKEW hdl_node "`DESIGN_PATH.va"; input [1:0] v_b INPUT_EDGE INPUT_SKEW hdl_node "`DESIGN_PATH.vb"; } coverage_group cg_2 { sample_event = @(posedge cg_if.clk); sample cp_1 (ex_sysvlog_if.v_a) { state a (0:63,65); m_state b (127:150], [148:191]); m_state c (200:202) if (!cg_if.reset ); state d (1000:2000); bad_state bad_vals (2001:2047); } sample cp_2 (cg_if.v_b); cross cr_1 (cp_1,cp_2) { state b_cr ( (( (cp_1 >= 127) && (cp_1 <= 191) ) ) && (( (cp_2 >= 0) && (cp_2 <= 3) ) )); } } Figure 6 : NTB (Vera) coverage_group example SNUG Boston 2005 8 A Unique Functional Coverage Flow
  • 9. 2.2 Bind Directives Sampling of signals in SystemVerilog is made simple by the bind directive. Bind directives cause one module to be instantiated within another, without having to explicitly alter the code of either. This facilitates a strict separation between a design’s implementation code and its verification code, whether the latter is code for functional coverage, for testbench modeling, or any other purpose. The first three fields of the bind directive are as follows: 1. The name of the module or instance that is the target of the binding 2. The name of the module that is being bound to the target module, and 3. The instance name of the module being bound After these three fields there follows a port list, with the same syntax as for a normal, Verilog module instantiation. Figure 7 illustrates this. There, we show a module with functional coverage code, cover_mod. It contains a single covergroup, cg_sig, which uses signals local to cover_mod. But, these signals are actually connected to those of a design module, design_mod, which is not shown. A bind directive (note that it is defined outside of module scope) makes this connection. The signal names in the port list are those local to the design module. They are connected to the inputs of the coverage module, cover_mod, in order of appearance. Similar to the rules for traditional Verilog instantiations, we also could have used dot operator connections in the port list. These are safer, being less error prone, but for brevity, we chose to not to show them. When the bind directive is executed during compile time, the bound module is instantiated directly below the target module or instance. Since the target may be named by its module or instance name, there are really two types of bindings. If module binding is used, an instance of the bound module is placed below each instance of the target module. If instance binding is used, an instance of the bound module is placed below only one, particular instance of the target module. Usually, for functional coverage, there is no need for module binding, as coverage is generally written for modules that are rather high up in the hierarchy and have only one instance. Signals in the target instance are bound to inputs in the bound module through the bind port list. Thus, the bound module has access to any and all signals in the scope of the target instance, simply by putting them in the port list, which makes sampling of design signals for functional coverage rather easy. The hierarchical path to the coverage module instance also makes clear which parts of the design are being covered, because the design instance whose signals are being sampled is placed immediately above the coverage module instance in the hierarchy. Thus, if one adopts a naming convention that makes it easy to recognize coverage modules, one can know which design modules they are sampling simply by reading the hierarchical path name of the coverage module. SNUG Boston 2005 9 A Unique Functional Coverage Flow
  • 10. module cover_mod (clk, reset, enable, sig1, sig2, sig3); input clk; input reset; input enable; input [1:0] sig1; input [2;0] sig2; input [3:0] sig3; covergroup cg_sig @(posedge clk) cp_1 : coverpoint sig1 iff (!reset && enable); cp_2 : coverpoint sig2 iff (!reset && enable); cp_3 : coverpoint sig3 iff (!reset && enable); cr_1 : cross sig1,sig2,sig3; endgroup endmodule bind design_mod cover_mod u_cover_mod (d_clk, d_rst, d_en, d_sig1, d_sig2, d_sig3); Figure 7 : SVA Bind 3.0 SystemVerilog for Functional Coverage at ARM-Austin At ARM in Austin, we debated several choices for a functional coverage vehicle for our current project, the design of a next generation, high performance ARM core. In the end, we decided on SystemVerilog as implemented in Synopsys’ VCS. We were motivated by the fact that SystemVerilog was an emerging standard that would eventually have wide vendor support, and that it was being integrated at no extra cost into VCS. We also liked the fact that, via its sequence and property constructs, with the associated cover and assert directives, one could reuse SystemVerilog functional coverage code for assertions, and visa-versa. In addition, SystemVerilog supported coverage of permutations of values of bit-vectors, through its covergroup construct. This was extremely important to us, and, it turns out, the overwhelming majority of our coverage bins ended up coming from covergroups. None of the other, competing functional coverage vehicles had the same degree of support for all these aspects of functional coverage. SystemVerilog stood out in this regard. However, we had to deal with the problem that SystemVerilog support was being put into VCS incrementally, and not all coverage constructs we wanted to use were available yet. The most important one that was missing was the covergroup. However, at the suggestion of Synopsys, we decided this could be overcome via a translator. Synopsys was building up support for NTB, the natively compiled version of Vera now being bundled with VCS, at the same time as it was building up support for SystemVerilog,. The NTB / Vera coverage_group construct was very SNUG Boston 2005 10 A Unique Functional Coverage Flow
  • 11. similar to that of the SystemVerilog covergroup and was immediately available in VCS. We decided translating between the two was feasible. We created a translator and called it covermap. With covermap, we were able to train our team in the use of SystemVerilog in the present, while building up a body of code that could be reused in the future, when SystemVerilog would be fully supported. In the meantime, covermap would insure (hopefully) that our functional coverage code executed with the expected functionality of SystemVerilog. 3.1 Relating Design Components to Coverage Components As part of our functional coverage methodology, we mandated that: • Functional coverage code be written inside of standard, Verilog modules, as opposed to newer SystemVerilog constructs such as program blocks or classes. This allowed our hierarchy to be composed of similar structures, and we did not have a strong need for the other structures, as they were more targeted towards testbenches and we were using an all Verilog testbench. • Bind directives be used to create a one-to-one relationship between a coverage module and a design module. This facilitated our post-processing tools relating the sampled modules to the modules doing the sampling. • Only standard Verilog reg and wire variables be used in coverage modules. While other constructs were available in SystemVerilog and had some advantages, this kept the coverage modules as similar, in coding style, to the design modules as possible. • Local variables be allowed in coverage modules, but bracketed between formatted comments. This allowed the covermap translator to recognize them easily. The local variables were used to form Boolean expressions, or, quite often, complicated state machines from sampled, design variables. This, in turn, simplified the task of functional coverage. For example, bus signals were used to create state machines that kept track of transaction histories, and, in turn, functional coverage was written in terms of these histories. In our configuration management structure there is a directory for each distinct unit of our design. We made a subdirectory under each such unit directory, for functional coverage files. We initiated a naming convention where the file names for functional coverage files reused the names of the design modules they were covering, with an added “_sysvlog.v” suffix. We created a small Perl script that found all such files with these suffixes, whenever we compiled a simulation model with functional coverage, and put them in a file list for the VCS compiler. 3.2 Code Writing Standards For covered properties, we mandated that all coverage code writers would use the sequence construct to describe temporal behavior, and that all sequences would be labeled for reuse. We then created covered properties by labeling the property, and applying a cover directive to that label. We created assertions from sequences in a similar manner, using the assert directive. Within assertions, a sequence would typically occur as the antecedent of an implication. Assertions and covered properties work synergistically, in that the covered property measures how often the design has been stressed, while the assertion monitors for correct behavior whenever the stress is applied. As stated above, “vacuous truth” is a problem in a verification system. Using our methodology, if an assertion never fired (which is desired) one could easily SNUG Boston 2005 11 A Unique Functional Coverage Flow
  • 12. ascertain, from looking at hit total for the related covered property, whether that was because it was never stressed, i.e., whether its left hand side, the antecedent, had never been true. For covergroups, we supported most of the constructs that are in the current SystemVerilog 3.1a LRM; except for transition coverage (no one felt a strong need for it). For all coverage constructs, we mandated a naming convention. For example, covered property names would begin with “c_”, covergroups with “cg_”, coverpoints with “cp_”, etc. This facilitated easy recognition of an item’s type in our output, when a coverage bin was listed using its full hierarchical path. In that case, with these conventions it was easy to see that it was, for example, a bin within a cross within a covergroup, and to know which design module’s signals were being sampled. We also utilized a priority labeling system, with each covered property and each coverage bin allowed to have a separate priority. We allowed three levels: 1. L1. Meaning, important enough that it must be hit in top level simulations 2. L2. Meaning, desirable to hit at top level, but acceptable if hit only in unit level simulation (where it is easier to generate specific input sequences) 3. L3: Meaning, desirable to hit at any level, but not required Use of anything but L1 coverage was discouraged, and had to be justified. L3 coverage was used only rarely, and had to be rigorously justified. Usually, it was used as a temporary holding place for coverage points that were new and not thoroughly tested. We implemented the priority labeling system through formatted comments containing a coverage item’s name and its priority level. The covermap translator then applied that label to that item and to all items below it in the coverage hierarchy, unless the label was contradicted by a specific directive found for an item lower down. The highest element in the coverage hierarchy for any Verilog module was the module itself, the next highest were individual covered properties and covergroups, and, within a covergroup, coverpoints and crosses were next highest, with the lowest level being the bins of coverpoints and crosses. 4.0 Translating SystemVerilog to NTB : The 'covermap' Translator The main task of the covermap translator is to read in SystemVerilog files, find covergroup constructs, and translate these to NTB coverage_group constructs. But, it performs many other useful tasks, as well, for example enforcing our priority labeling system described above. The translator would signal an error if a coverage item did not have an associated priority label. Each file read in by covermap is expected to contain a single, Verilog module definition, and one or more SystemVerilog bind directives. The Verilog coverage module may contain one or more of the following: • SVA sequence and property definitions • SVA covered property and assertion declarations • SystemVerilog covergroup definitions and instantiations SNUG Boston 2005 12 A Unique Functional Coverage Flow
  • 13. Local variable definitions, and Verilog code (including tasks and functions) utilizing these When covermap translates ‘n’ SystemVerilog input files, it will produce 2n + 1 output files, of the following type: • ‘n’ files with all the original SVA covered properties and assertions, and with all Verilog code utilizing local variables, but with covergroups and their instantiations commented out • ‘n’ NTB files holding NTB coverage_groups derived from the original SystemVerilog covergroups • A “master” NTB file holding a program block NTB begins execution in a program block, a construct somewhat similar to the ‘main’ function in C. There must be at most only one such block in any body of NTB code. All the NTB coverage_groups must be instantiated in this program block, even if they are defined in separate files. covermap facilitates this by generating include directives within the master NTB file for all the separate NTB files. The following diagram illustrates the functional coverage flow: Test Stimulus Original SV Files Verilog Design Files Files NTB Files Compile and Sim Scripts covermap translator SV Files NTB SVA DB Init DB Post processing File Viewer Programs Figure 8 : Flow Diagram SNUG Boston 2005 13 A Unique Functional Coverage Flow
  • 14. In this flow, we start with hand coded SystemVerilog files. As covermap reads in these files, it stores information in a set of C++ classes that give it a picture of the coverage hierarchy. It then traverses this hierarchy down to individual coverage bins and prints out a list of all these bins in a database initialization file (“DB Init File”). This file is used to initialize an SQL database used by an HTML viewer for coverage results. Along with the hit counts for each bin, the database stores a reference to the test names that hit it, and Perl scripts operate on the database to generate a minimized suite of tests that can hit all the coverage points. In addition to using this SQL database and HTML viewer for functional coverage, we track pass / fail numbers on regression suites and track progress of the debug effort, with it, as well. One of the most important reasons for creating our own means of post processing functional coverage results was to integrate those results with this type of information coming from our simulations, so that, within one viewing tool, we could track all pertinent aspects of our project’s progress. In the normal translation flow, the original SystemVerilog files are translated into 2 types of files: (1) NTB files holding coverage_groups, and (2) SystemVerilog files holding all the original code except that related to covergroups. When the Verilog from the design is compiled for simulation, these files are compiled in as well. As covermap translates, it changes names of coverage items in order to transmit information on design hierarchy into NTB data. Since NTB coverage_groups are instantiated in the NTB program block, which is in the testbench, no information is readily available in output files as to the design blocks being sampled by a coverage_group. covermap is able to recreate the hierarchical path that would have existed had the NTB coverage_group been a SystemVerilog covergroup. It encodes this information in a new name for the NTB coverage_group. In turn, post processing scripts are able to parse this name, and show the user where the coverage items are in relation to the design hierarchy. As test stimulus is loaded and simulations are run, two different types of coverage databases are formed: SVA and NTB. The SVA database holds hit counts for covered properties, while the NTB database holds the same for the bins created by NTB coverage_groups. Special scripts and programs then read these databases, and reformat the data to make it suitable for the HTM database viewer (“DB Viewer”). This requires anticipating the names VCS / NTB will apply to automatically generated coverage_group bins. When the coverage files are translated, the resulting set of NTB and SVA files are compiled with the code for the design and testbench. During covermap’s translation, the user may obtain two types of optional output: • statistics on the distribution of properties and covergroups through the design hierarchy, as well as a breakdown within the covergroups on the quantities of bins in each member coverpoint or cross, and • an initialization file for loading our SQL coverage database, listing the hierarchical path to each coverage bin of all the covergroup coverpoints and crosses, as well as the hierarchical path to each covered property. Great care is taken that the names of bins coverpoint and cross bins correspond to what will be generated after simulation. For instance, NTB has certain naming conventions for auto- generated bins, and certain formatting requirements for fields within names. We take care to SNUG Boston 2005 14 A Unique Functional Coverage Flow
  • 15. produce names consistent with those in our SQL initialization file, because we will use string matching to compare names of bins hit in simulation to those in the initialization file. After simulations have concluded, functional coverage data exists in two separate sets of files, one for NTB coverage_groups and one for SVA covered properties. We then transform this data for our SQL / HTML viewer. In our post process scripts, we label it as L1, L2 and L3 priority level. The covermap translator enables this by prepending the priority level to the translated name of the coverage item. We run scripts that use the Tcl SVA API (application programming interface) to extract the covered properties that were hit, and the number of hits for each. We run a C program that utilizes Synopsys new UCAPI (Unified Coverage API) library, to read out the same information for the NTB coverage_group members. The UCAPI is a relatively new library intended to be a single interface through which all the various types of coverage formats in use by Synopsys may be read. 5.0 Results and Performance At this point, we are still in the midst of our design project, and while we have written most of our intended coverage code, we have not written all of it. At the unit level, our functional coverage is well above 90%, and it is approaching that for top level. One important issue is the cost of functional coverage, i.e., how much it reduces simulation performance. Of course, this will be in proportion to the size of the functional coverage code base relative to the design code. There is no universally accepted way to measure the size of a body of functional coverage code. We feel the most appropriate way is to count coverage bins, in other words, to determine how many separate events are being monitored. When we expand our code, we currently generate around 100,000 coverage bins; but, among these there can be a wide variance in simulation time. A simple coverpoint bin, where the coverpoint hasn’t any complex sampling guards, would be very quick to simulate, since it can be implemented with efficient, integer operations. A covered property (which can be considered to implement a “bin”, if we understand that to mean a counter of how often the property was hit), on the other hand, could be very costly to simulate, since it may describe a very complex sequence of events, the tracking of which requires a large overhead. However, the vast majority of our coverage bins come from covergroups. Right now, we are experiencing slowdowns of 300% to 450% in top level simulations with functional coverage. In other words, if a simulation takes, say, 100 CPU seconds to simulate, using a simulation model compiled without functional coverage code, it will take between 300 to 450 CPU seconds to simulate when our functional coverage code is compiled in. This is just the simulation time, and does not include any post processing time for analyzing results. When considering these numbers, it should be borne in mind that the testbench for our full design (as opposed to our unit level testbenches) is an all Verilog testbench, using only a very few PLI calls. For many users of functional coverage, they will be adding functional coverage to the already existing overhead of a testbench in a specialized language, such as NTB / Vera. In this case, the effect of functional coverage may not seem as large. Ours is a rather unusual case, allowing one to see the overhead of functional coverage relative to a rather pure body of traditional Verilog code (note that in our design and testbench we are not using SystemVerilog SNUG Boston 2005 15 A Unique Functional Coverage Flow
  • 16. constructs, only in our functional coverage files, and much of our testbench is written in synthesizable Verilog). We have attempted to analyze these slowdowns, with help from Synopsys R&D teams. One major aspect, which cannot be resolved quickly, is that much of the work VCS does to analyze functional coverage is still being done through function calls into libraries. While this is quite normal, it obviously would be better if the function call overhead could be eliminated. VCS gets much of its speedup on regular Verilog code from transforming it into natively compiled constructs. Synopsys plans to eventually do all functional coverage work in a native compile as well, and this is where the largest performance gains are expected. Until then, performance improvements must come from incremental sources. One workaround we are investigating is compiling only those coverage items that have not been sufficiently hit. The idea is to create a feedback loop between the coverage results database and the covermap translator. The translator would inspect a list of coverage items hit to date on a specific version of the design, and not translate those that have been sufficiently hit. While the reduced performance we have experienced is a major problem, we do not consider this a defect specific to SystemVerilog or VCS, we suspect that slowdowns like this are common throughout the industry. Since use of functional coverage is only now starting to spread, the problem may not be widely recognized; but, it is certainly important. It is obviously desirable to do functional coverage; but, at the same time it is very costly. Design teams are facing the difficult choice of having to split their resources between simulating the design, which is their primary means of finding bugs, and tracking whether their simulations are effective, through functional coverage. Given the current performance problems of functional coverage, it is tempting to skip it in favor doing more simulation. Synopsys must work hard to eliminate the need for this tradeoff, by boosting the performance of functional coverage. SNUG Boston 2005 16 A Unique Functional Coverage Flow