System Verilog configurable coverage model in an OVM setup – concept of reusability

By Parag Goel & Sakshi Bajaj

With the advent of a new era in verification technology based on an advanced HVL like System Verilog, the concept of random stimulus based verification was born, to verify today’s multi‐million gate designs. In concept, every verification engineer fancies the idea of random stimuli driven verification, but as is rightly said – “Everything comes with a cost” and the cost here is a big concern that haunts the life of every verification engineer:

  • How do I close my verification?
  • When can I say I am done?

To answer such questions, System Verilog as a language came up with the concept of functional coverage that is much more accurate of a measure compared to the traditional code coverage techniques. We concentrate mainly on this SV feature in our write‐up, adding one more dimension to it - configurability.

Methodology like OVM has brought in the concept of reusability of environment/agent (mainly consisting of driver/monitor/sequencer) across projects. But, on the other hand, a user tends to create a coverage model that is usually coupled very tightly to the specifications of the given project. In the process, he/she ends up writing a separate coverage model for every project, compromising the reusability aspect and violating the Methodology mantra! Keeping above limitation in view, we would like to present the user with one possible solution – configurable and reusable coverage model, sighting AMBA AXI protocol as the case study for discussion.

Why configurable coverage model???

“To minimize wasted effort, coverage is used as a guide for directing verification resources by identifying tested and untested portions of the design.” - IEEE Standard for System Verilog (IEEE Std 1800‐2009)

This quote from LRM[2], explains the intent of functional coverage. But the crux of this paper lies in the configurability of any given coverage model. Configurability is the key to re‐usability for any setup. All our current day methodologies have brought in the concept of reusability of the agents such as BFM’s and monitors across projects. In the same project, an engineer also creates a coverage model in order to provide the management with a picture of the verification activity status. However it’s as per the given project specifications. Thus an engineer end up in writing a separate coverage model per project while re‐using the rest.

However, verification environments created from reusability perspective need to be meticulously designed to take care of coverage model reusability as well! So our main focus is on the coverage model that could be configured and re‐used. AMBA – AXI is one of the most commonly used protocols in industry for communication amongst the SOC peripherals. Thus we chose this protocol for our case study.

System Verilog coverage constructs – Key to configurability

System Verilog provides a very fast & convenient method to describe the functional coverage for any given setup with the help of pre‐defined constructs. A brief overview shall be a good starting point.

A covergroup is user‐defined type like a class, which defines a coverage model. Composed of a number of sub‐elements including the following:  

  • Coverpoint - Describes a particular type of coverage event, how it will be counted as well as one or more bins to organize the count
  • Cross ‐ Defines a new coverage event by “combining” two or more existing coverpoints or variables
  • Bin - A coverage event counting mechanism, automatically or user‐defined
  • Options ‐ Certain built‐in options that helps to gain better controllability over the collection of coverage numbers.

Figure 1 depicts a brief overview. The main highlight of paper lies in the wise usage of the coverage/coverpoint/cross point OPTIONS, METHODS & BINS provided in the language. Let us brief on few important among them.

Firstly, the important coverage options:

  1. per_instance: Each instance contributes to the overall information for the covergroup type. When true, coverage information for this covergroup instance is tracked well.
  2. at_least: Minimum number of hits for each bin. A bin with a hit count less than this number is not considered covered. Say for example, if we want a particular coverpoint/bin to be hit a minimum of 5 times before user gains a confidence on the same, user should specify option.at_least=5
  3. weight: If set at the covergroup level, it specifies the weight of this covergroup for computing the overall coverage. If set at coverpoint (or cross) level, it specifies the weight of a coverpoint (or cross) for computing the coverage.
  4. goal: Specifies the target goal for a covergroup. If the user‐specified goal, say 50 percent for that given coverpoint/bin, then this shall account towards 100 percent coverage calculation.
  5. auto_bin_max: Maximum number of automatically created bins when no bins are explicitly defined for a coverpoint. 

Figure 1: System Verilog coverage constructs ‐ overview.

All the options can be specified for instance‐specific or type specific coverage calculation. But language restricts that type_option must be a constant parameter and does not allow variable for the same. The only configurations provided are goal, weight, strobe &comment.

There is a key difference between type and instance coverage. The instance coverage would give us coverage of each individual instance created while type coverage is a sum of all instances. Type coverage has many limitations which are described in later part of the paper.

Coverage methods are what we would discuss next.

  1. sample(): Controls the triggering of a covergroup.
  2. get_coverage(): Calculates type coverage number (0‐100)
  3. get_inst_coverage(): Calculates the coverage number (0‐100) of a specific instance on which it is invoked.

Since these methods can be called procedurally at any point of time, gives the user an additional flexibility to control the collection of coverage for a defined covergroup as well as get the coverage numbers in any of the agents in your OVM setup say, a score‐board etc.

Now let’s look into a little detail of bins:

[open_range_list] specification ‐one of the important features in the bin definition that enables the user to control the number of bins created in case the user has explicitly defined the bins, since the option auto_bin_max doesn’t work in this case. Another point that we have utilized is the order of precedence that the language imposes on the illegal/ignore/normal bin definition.

The priority order is as:

  1. illegal_bins: doesn’t account towards overall coverage, issues an error
  2. ignore_bins: doesn’t account towards overall coverage
  3. bins: are user‐defined/automatically created collectors which count towards the overall coverage numbers

“The default specification is associated with each of the above bins. It defines a bin that is associated with none of the defined value bins. The default bin catches the values of the coverage point that do not lie within any of the defined bins. However, the coverage calculation for a coverage point shall not take into account the coverage captured by the default bin. The default bin is also excluded from cross coverage.”

Overview of the AXI setup

As shown in Figure 2, we have built our coverage model in an OVM‐based setup. Utilization of OVM’s TLM communication to build the hierarchy run‐time helps a user in the placement of the components as required and also provides ease‐of‐communication amongst the components. As evident, all the regular components of the VIP are placed inside an agent wrapper. For the visibility of the collected transaction we utilize analysis port-export connection to establish a link between the bus monitor and the score-board as well as the coverage collector. The main reason for this structure is that both these components are coded by a user as per project specific requirements.

Figure 2: Overview of the AXI setup.

But later, with the introduction of the generic coverage model, we were able to shift this coverage collector inside the agent itself. Still it follows the same TLM connection along with an enable/disable switch attached to its connection in the connect() phase of OVM. This is the first level of control for the coverage model, as we don’t start focusing on the coverage numbers right from the start of the project, hence we need to keep it disabled until we gain first cut confidence on the design as well as the verification environment setup.

Classification of the coverage model – AXI Protocol as an example

As we rely mainly on our coverage definition for verification closure, so a comprehensive coverage model definition is required. Towards this end, a modular coverage model divided into four sections as shown below would yield great results.

But this modular coverage classification can still be considered generic in the sense that every protocol can be categorized under these same four sections.

  • Transaction coverage: coverage definition on the user‐controlled parameters usually defined in the transaction class & controlled through sequences.
  • Error coverage: coverage definition on the pre‐defined error injection scenarios.
  • Protocol coverage: (AXI Handshake coverage) this is protocol specific. In case of AXI, it is mainly for coverage on the handshake signals i.e. READY & VALID on all the five channels.
  • Flow coverage: This is again protocol specific and for AXI it covers various features like outstanding, inter‐leaving, write data before write address etc.

Consolidating all the above four models in a modular & easily controllable fashion was the next task. The figure below describes how it was done in an OVM setup.

Following are the basic requirements to model these four coverage models:

  1. Interface
  2. Transaction collected
  3. Configuration class

Let’s see how we get each one of them in detail. As depicted in Figure 3, for getting the transactions collected by bus monitor into the Main coverage class, we established a basic port‐export TLM connection with the Main coverage class. This transaction is in turn passed to the write/read transaction coverage model class, again via a TLM communication channel.

For coverage models other than transaction coverage model, an interface connection is required such that it is shared across the Bus monitor as well as the individual coverage models. This was achieved via connection package as shown in Figure 3. For more details see  System Verilog + OVM: Mitigating verification Challenges and Maximizing Reusability [1].

Lastly, a very crucial input required is the configuration class, which in our case is specific for coverage definition only. This configuration class is passed and utilized via set_config_*/get_config_* configuration utility of OVM. The configuration is set by the user in the main coverage class and from there it is passed via same utility further below to the respective coverage models as depicted in Figure 3.

Figure 3: Coverage model - OVM setup.

Note: As per the SV LRM, since the covergroup(s) can be created only in the class constructor, we should have the configuration object available from the user in the class constructor itself, despite the fact that we use OVM set/get configuration methods usually in the build() phase of an OVM setup. We shall talk more about this in the later section of the paper.

The main coverage class is a class that serves as a basic control point for the remaining coverage models. Listing 1 depicts the first level of configurability based on whether the user wishes to enable/disable a coverage model as a whole, in the build() phase of the OVM.

Listing 1: Code depicting coverage model classes controlled via user controlled configuration.

Requirements of configurable model

Let us first summarize very basic requirements necessary for re‐usability.

  • Turn ON/OFF each coverage model defined, on an individual basis. For example, user may not always want the error coverage to be ON, until he/she performs error testing. So, by default, we generally keep it disabled and enable only when required.
  • Turn ON/OFF coverage for each covergroup defined. Every covergroup should be created only if a user wishes to do so. So this configuration control is used in the class constructor itself to restrict the creation of the covergroup altogether. Also, the same control needs to be applied at the sampling of a covergroup.
  • User must be able to set the limits on the individual field being covered in the coverage model within a legal set of values. Say for example, transaction field like, Burst Length ‐user should be able to guide the model what are the limits on this field that one wishes to get coverage on within a legal set of values ranging from 1‐16 as per AXI spec. So providing lower and upper limits for transaction parameters like burst size, burst length, address etc. makes it re‐usable.

option.weight can be exploited for this purpose. Thus, weight of only those coverpoints can be set to 1 which are legal and within user defined limits

  • User should be able to control the number of bins to be created and the limits within which they should be created, for example in fields like address. auto_bin_max option can be exploited to achieve this, in case user doesn’t specify the bins explicitly. This can also be achieved by specifying the number of bins to be created as parameter to the bins construct, which works when there are user defined bins. So a legitimate choice needs to be made from above options.
  • User must be able to control the number of hits for which a bin can be considered as covered. option.atleast can be used for this purpose and the input to this can be a user defined parameter
  • User should also have the control to specify his coverage goal, i.e. when the coverage collector should show the covergroup “covered” even though the coverage is not 100 percent. This can be achieved by using option.goal, where goal is again a user defined parameter. This is useful in various applications as illustrated in later part of this paper. 

In depth analysis of the coverage model – transaction coverage

Transaction class in terms of methodology is a class that contains all the randomizable properties contributing towards complete testing of a given design. But unless all the possible values of every individual parameter as well as set of combinations of each one of them, is applied to the design, gaining confidence on our testing is difficult. However, even after one has created several random test cases, how can one be sure that the verification is complete and that he has covered all possible scenarios?

Thus it is of utmost important to build a coverage model that will let the verification engineer know quantitatively how much he/she has been able to achieve.

In order to get a better understanding of this coverage model, let us consider an example from AXI. There are several parameters in AXI which should be tested and checked for corner case hit. Some of them are mentioned in the Listing 2.

Listing 2: AXI Transaction parameters.

Although it is essential to check corner case hits from protocol specification perspective, but at the same time, it’s very important that exact hits relevant to one’s project specification get checked. For example, AXI spec does provide limits for parameter Burst Length from 1 to 16, but it is important to check for the values relevant to ones project specification and not as per AXI specification (assuming project specifies a subset of values supported by AXI). This is where configurability takes the lead. Not having a configurable coverage model might give us false numbers which are of no use to the specific project.

Also we need to ensure that duplication of code can be avoided while coding the same coverpoint across various covergroup(s) (i.e. individual covergroup for a given property and while defining it’s cross points). Here in the example below we have taken BurstLength from AXI to illustrate the same macro for burst length and burst size has been shown in Listings 3 & 4.

Listing 3: Macro definition for covergroup – Burst length. Here legal bins are defined within user configured limits, rest all are treated as illegal. Weight i.e. enable/disable & hit‐count are also set by the user.

Listing 4: Macro definition for covergroup – burst size.

The System Verilog feature that has been exploited in Burst Size covergroup is that illegal bins take precedence over bins. Thus, the approach used was:

  • Include all the legal values of Burst Size as per AXI spec in bins.
  • Include the values which are outside user defined limits in illegal_bins.
  • By default, rest all values are treated as illegal.

Since illegal_bins have greater precedence so the values of Burst Size which are common to both illegal_bins and bins are considered as part of illegal_bins thus giving us bins/coverage as per the user configuration.

We have also provided user configurable minimum hit count i.e. number of hits required to consider a bin/covergroup to be hit. While defining covergroup(s), it is essential to pass configuration parameters as an argument to that group. Note that the covergroup has to be created in class constructor where the configuration parameters are passed to the new() function of the covergroup and this covergroup is triggered using in‐built sample() function in the run() phase of OVM. Listing 5 illustrates the same.

Listing 5: Covergroup definition and creation of covergroup based on enable/disable with the configurable parameters passed and sample() function call in run() phase.

Coverage on parameters like address is also essential. However, for large address ranges, forming individual bin for each address might not be desirable or feasible. In such cases each bin can cover a range of addresses instead. Although the language has provided auto_bin_max construct for this, but it again has its own limitations, and this is where configurability comes in handy.

For example, what if a user wants to define address range within which he/she wishes to measure coverage? The option auto_bin_max creates specified number of bins only if no bins have been defined explicitly and thus is not useful in this case. Listing 6 shows how the scenario can be created and achieved.

The number of bins that need to be created can be passed as a parameter to the bin. Thus now the entire address range is divided such that, first the number of bins configured by the user gets created, with each bin carrying an address range as specified by the user per bin. Number of hits per bin as desired by user, can also be controlled by using option.atleast (Listing 6).

Listing 6: Covergroup definition with the [open_range_list] for the coverage of parameters like Address ranges.

Cross Coverage: Once individual coverage on each parameter has been checked, sometimes it’s also important for a verification engineer to check cross coverage. In fact, there are some parameters which should be checked for coverage only w.r.t. other parameters. Sighting an AXI example to explain this, if user wants to check coverage on Burst Length, one cannot deduce useful coverage numbers unless it is measured w.r.t. to the Burst Size. This would help in giving the correct idea of the narrow/aligned/unaligned transfers taking place in the simulation. Cross coverage becomes essential in such cases.

Again, although cross coverage is important, but 100 percent coverage goal might not be desirable always for same. Let us consider cross coverage between two AXI parameters namely, Burst Length and Burst Size. Here, usually the requirement is to check that for each value of Burst Size all values of Burst Lengths have been hit and vice versa. However, if user knows that not all combination scenarios are valid as per his project specification, then he should be able to check for only required combinations of this cross coverage, ignoring the rest. For example, say for Burst Length > 1, the project specification requires Burst Size to be fixed to 16, then the user knows that rest of the values of Burst Size will never hit. In such a case, user should have the power to redefine his goals, so that he/she knows when to consider the RTL as covered. This flexibility is achieved by providing user configurable goal for cross coverage. Listing 7 shows an example of cross coverage between Burst Size and Burst Length.

Listing 7: Example depicting the cross coverage between Burst Size & Burst length parameters (using macros in Listings 3 & 4). Here we have type_option.weight = 0 as we are just focusing on the instance coverage rather than type coverage.

The key features exploited in above coverage are as follows:

  • Definition of cross coverpoints has been given in separate covergroup. This is useful in case user does not wish to measure cross coverage, then on the basis of disable, the covergroup will not be created thus making things simpler since the group does not appear in the report.
  • Although the cross covergroups were defined separately, it was made sure that unnecessary code repetition is avoided by using System Verilog macros throughout.
  • User configurable goal was also provided. This is done by using “option.goal”
  • User configurable hit count was provided so that the user can decide how many hits of Burst Size are required for each Burst Length to consider a bin hit. This is done by providing configurable “option.atleast”

Error coverage

Negative scenario testing is one of the stressed domain these days (especially for the complex protocols) to get a confidence on the behavior of the design. But again with this comes one big question - Whether I have done enough error testing?

So building a generic coverage model that can be used on a given setup to help the verification engineer know how much error testing he/she has stressed upon as per given design specification, will help in closing negative testing quickly.

As is the case of AXI in our current study, we can introduce a wide‐range of error scenarios and test if the DUT responds correctly or not. A few possible error scenarios in AXI are listed in Listing 8 for your reference.

Note that each error scenario is attached to a unique message ID for coverage collection & report generation using OVM reporting mechanism. More about this is discussed below.

Listing 8: AXI error scenarios

However, all the scenarios may not be applicable to all the modules/ projects, so configurability is required to enable only the required set of coverpoints. Described below is an approach to deal with this requirement.

Here, we utilized the unique Message ID as a tool. Functional coverpoints were written on the unique message ID representing the error‐scenarios being covered. However, the following assumption was made while developing this coverage model:

Every error scenario emits one unique message ID, although there may be more message ID’s getting emitted from some other checks simultaneously, that might get triggered owing to a given scenario. These error message Id’s were issued in the report log using immediate assertions with the help of OVM reporting functions like ovm_report_error, ovm_report_fatal etc.

Listing 9 explains the reporting facility of OVMb used to achieve this.

Listing 9: OVM global/report server to get a handle of server in the component class.

As depicted, the global report server in OVM is used to get handle to the ovm_report_server, which in turn is used to access the methods of the report server class.

Using this handle, report server function get_id_count(<string>) is called, which takes a string i.e. the message ID as an argument and returns the incremented value of count variable that can be used in covergroup to indicate hits have happened, as depicted in Listing 10.

Listing 10: Collecting the count of Message ID’s in count variable. Task forked in the run() phase.

Now, using the get_config_*/ set_config_* utility of OVM, we get the object of configuration class, which basically contains the enable/disable control for each covergroup. Using the strategy defined earlier in Listing 5, each covergroup is created in the class constructor on the basis of configuration, as set by the user.

With the code infrastructure in Listing 10, the count variable is passed to the covergroup for coverage definition. The overall definition of covergroup is depicted in Listing 11.

Listing 11: Covergroup using 2‐D packed array variable for coverage on the individual message ID’s.

Note: We have used the 2‐D packed array to collect the count of any given message ID, due to the fact that covergroup doesn’t allow unpacked arrays to be passed as an argument.

Protocol coverage (AXI handshake coverage)/flow coverage

Protocol and flow coverage are mainly pertaining to the interface signals, on which various combination of their respective occurrence are possible, all of which are legal. Although all these combinations achieve same functionality, a user may wish to know whether all the combinations have been really covered or not.

The reason why protocol and flow coverage were separated in two categories is that we focused on the scenarios defined by the Standard AXI specs as a part of protocol coverage, whereas flow control describes coverage on user created scenarios. For coding both these aspects of coverage, a similar approach was used i.e. Assertion – based Functional Coverage, thus conceptually both will be discussed under a single head.

Again, in our AXI example, three combinations are possible with handshake signals (READY/VALID), on all the five respective channels, as per the AXI spec. Thus we need to ensure that we have covered all these combinations for all the 5 channels. There could be other similar combinations possible related to the interface pins that can be included under this type of coverage.

Assertion based coverage was used for this purpose since it fit the bill well for interface signals monitoring. System Verilog provides a construct called cover property for this specific requirement. A brief on cover property is discussed below.

System Verilog property helps us keep track of events occurring on interface signals. A property can be invoked in two ways:

  • Assert property - These are statements that assert the specified properties for its success/failure. Each assert property statement sets a flag in its action block if it fails.
  • Cover property - This is used to measure assertion based coverage. It has analogy to bins. In a covergroup, the way every hit in the bin increments its count by 1, so is the case with cover property. Every time the property is true, the count increments by 1 indicating a hit.

However, one of the major limitations of property is that it can be declared and called only inside an interface or a module container while configurability demands use of classes. Thus, it was very important to develop a relation between the two i.e. to pass configuration to the interface for it to be used by cover property. The schematic below depicts how we dealt with this limitation.

Figure 4: Interface explored to write cover‐property and class to exercise control over the properties.

Figure 4 shows a coverage class, which has a virtual interface. The connection of virtual interface to real interface is done in build() phase of this class. This class also takes all the configuration parameters from the main coverage class. On the other hand, we have interface, which has cover property. This interface also has a set_config function (user defined), which as the name suggests, gets called from the class to set the configuration, as shown in figure 4. Once set, these configuration parameters are used to control the behavior of the cover property defined in the interface as per user.

In order to avoid code repetition, a macro has been defined for the cover property so that it can be called for all the five channels in both master and slave interface, multiple times. Cover property has a disable_iff construct for conditional coverage, but even if the condition is true and the property is disabled, only the hits to the property are made 0, while it still contributes to overall coverage.

In a cover property we don’t have the concept of user‐defined bins; Listing 12 specifies the command while Listing 13 is an example text report from the simulator – Mentor Graphics Questasim.

Listing 13: Assertion based coverage report as depicted in the text format ‐ Questasim.

Limitations

System Verilog does not allow use of procedural statements and operators within a covergroup. The “iff” construct can be used for conditional dumping which can be used in coverpoint orbin. But this construct has limited functionality and only disables coverpoint/bin in cross coverage calculation thus providing limited functionality as explained below.

  • When used with coverpoint expression, the weight of each coverpoint has to be set explicitly based on whether the condition in iff construct is true or not. This is because the iff construct does not disable coverpoint in total coverage calculation even if the condition is false.
  • When used in bins, the iff construct does not disable actual dumping in bin. Talking about priority, illegal_bins have highest priority, bins have least, meaning if an element is common to both illegal_bins and bins, then it is dumped in illegal_bins. However, conditional dumping is not possible here i.e. even if the condition in iff construct related to illegal_bins is false, the element is still considered to be part of illegal_bins and not bins. Thus conditional dumping in illegal_bins is not possible.

auto_bin_max option can be used only if no bins have been defined explicitly for a coverpoint. When the bins are explicitly defined by a user, a configurable [open_range_list] specification is needed in cases where user wishes to restrict the number of bins.

Covergroups do not take unpacked arrays as an argument. A covergroup has to be created within the class constructor. Thus, the configuration to be passed to the group must be available in the class constructor only. So user has to get the configuration in class constructor only and OVM phases cannot be exploited much here. It should also be noted here that as per common coding practice, we always set and get configuration in build, but due to this limitation everything has to be done in class constructor.

As a matter of fact, System Verilog provides two types of coverage numbers, namely

  • Type Coverage – gives the overall coverage which is sum of all the instances
  • Instance Coverage – gives the coverage of individual instances

Thus, if a user creates a single instance, then the above two coverage numbers should ideally match. However, this is not the case always. The following example from AXI elaborates more on this. Our design supported a Burst Type of INCR type while the AXI spec. specifies this INCR, FIXED, WRAP as the legal set of values. So Type coverage would say 33.33 percent even if we covered INCR Burst Type as per our specification, while the instance coverage would report 100 percent.

This is because of System Verilog limitation. type_option cannot have weights as a parameter, it has to be a constant. Also, there are many options which are available for instance coverage but not for type coverage viz. at_least, auto_bin_max etc. This leads to an unavoidable mismatch between type and instance coverage even if user has a single instance.

Assertion based coverage was used for AXI handshake coverage. One of the limitations faced was incorporating the concept of configurability. This is because cover property cannot be defined inside a class. Thus, when we get the configuration inside the class, we had to find a method to export this configuration to interface where cover property could be defined.

Also, there is no way to exclude a property from overall coverage calculation. Although System Verilog provides with “disable_iff” construct for conditional coverage, it still takes it into account the disabled property while calculating total coverage. Hence final coverage number would be lower than actual.

The user‐defined configurable covergroup parameters have to be passed to the covergroup while creating its instance. Any class instantiating this covergroup, shall do so within its own constructor (refer to Listing 5). Thus, all the configuration parameters should be ready in the instantiating class’s constructor itself. This poses a big limitation to develop configurable model since the configuration has to be made available in class constructor itself while rest of the OVM test bench code is usually spread across various OVM phases following the new() constructor. So what if a user wants to decide on the configuration parameters at a later stage during the simulation?

  • Solution: System Verilog 2009 provides a solution to this limitation by providing a method to override the built‐in sample function. In this method, the pre‐defined sample() method is overridden with a triggering function that accepts arguments and facilitates sampling of coverage data from contexts other than the scope enclosing the covergroup definition. For example, an overridden sample method can be called with different arguments to pass directly to a covergroup, the data to be sampled. These arguments can come from either an automatic task or function, or from a particular instance of a process, or from a sequence or a property of a concurrent assertion. Listing 14 describes how this can be achieved.

Limitation to above solution: Although the latest version of System Verilog (2009) has provided this feature but it is still not supported by EDA tools and hence is not much of a use at this time. 

Listing 14: Example usage of new sample() function. Here a covergroup is defined and created. Also, it depicts the 2 methods of overriding the sample() function i.e. overriding sample() method from within a property and pass them as arguments and also overriding the parameters within a function and pass them as arguments.

Suggestions

Some basic coding practices that a user should follow while coding these coverage models, which will help in ease of use as well as less maintenance in long‐term:

  1. A covergroup name must be appended with the keyword CG_*
  2. Similarly a coverpoint name with CP_* and bins as CB_*.
  3. Same convention rule should also be followed in configuration, i.e. the disables/configuration inputs relevant to covergroup should be appended with cg_*, coverpoint with cp_*, and bins with cb_*. This provides a clear picture as to what is being configured and enhances readability.

On a closing note, once again to remind you, the motivation to write this paper came from the need for defining a reusable coverage model, something completely missing in todays highly methodology driven verification world.

You must have gathered by now from the discussion above, that the configurable coverage model has been very much devised using the existing System Verilog language constructs available in‐built for coverage purpose, without any other fancy stuff usage. Although there were certain limitations faced while using some of these constructs, but the language itself provided alternative solution to work around these limitations. A little extra thinking from an engineer’s perspective helped us overcome every hurdle we faced in making the configurable coverage model a success.

Wish you all “Happy coding functional coverage …..”

References 

  1. Parag Goel & Pushkar Naik, Applied Micro, “System Verilog + OVM: Mitigating verification Challenges and Maximizing Reusability”, Mentor U2U‐ Dec, 2009 
  2. IEEE Standard for System Verilog (IEEE Std 1800‐2009) – Language Reference Manual 
  3. Mark Litterick, Verilab, “Using SystemVerilog Assertions for Functional Coverage” 
  4. Clifford Cummings, “SystemVerilog Is Getting Even Better!”, DAC 2009
  5. Jason Sprott, Verilab, “Functional Coverage in SystemVerilog”, SystemVerilog User Group 2007

About the authors:

Parag Goel (pgoel@apm.com) is a senior design engineer and Sakshi Bajaj (sbajaj@apm.com) is a design engineer II at AppliedMicro. The content reviewers were Pushkar Naik (senior staff design engineer, AppliedMicro) and Ashish Kumar (lead application engineer, Mentor Graphics).

MyAMCC is now MyAPM! Visit MyAPM