Reference Documentation

Module coverage

Functional Coverage features.

Classes:

  • CoverageDB - singleton containing coverage database.

  • CoverItem - base class for coverage, corresponds to a covergroup, created automatically.

  • CoverPoint - a cover point with bins.

  • CoverCross - a cover cross of cover points.

  • CoverCheck - a cover point which checks only a pass/fail condition.

Functions:

  • coverage_section() - allows for convenient definition of multiple coverage items and combines them into a single decorator.

  • merge_coverage() - merges coverage files in XML or YAML format.

class cocotb_coverage.coverage.CoverageDB(*args, **kwargs)[source]

Bases: dict

Class (singleton) containing coverage database.

This is the coverage prefix tree (trie) containing all coverage objects with name string as a key (using dot as a stage separator). Coverage primitives may be accessed by string identificator. Example coverage trie is shown below:

_images/coverstruct.png

Examples:

>>> CoverageDB()["top"] #access whole coverage under ``top``
>>> CoverageDB()["top.b"] #access whole covergroup
>>> CoverageDB()["top.b.cp1"] #access specific coverpoint
report_coverage(logger, bins=False, node='')[source]

Print sorted coverage with optional bins details.

Parameters:
  • logger (func) – a logging function (e.g. logger.info or print).

  • bins (bool, optional) – print bins details.

  • node (str, optional) – starting node of the coverage trie.

export_to_yaml(filename='coverage.yml')[source]

Export coverage_db to YAML document.

Parameters:

filename (str) – output document name with .yml suffix

export_to_xml(filename='coverage.xml')[source]

Export coverage_db to xml document.

Parameters:

filename (str) – output document name with .xml suffix

cocotb_coverage.coverage.coverage_db = {}

Instance of the CoverageDB.

class cocotb_coverage.coverage.CoverItem(name)[source]

Bases: object

Class used to describe coverage groups.

CoverItem objects are created automatically. This is a base class for all coverage primitives (CoverPoint, CoverCross or CoverCheck). It may be used as a base class for other, user-defined coverage types.

add_threshold_callback(callback, threshold)[source]

Add a threshold callback to the CoverItem or any its derived class.

A callback is called (once) when the threshold is crossed, so that coverage level of this particular cover group (or other object) exceeds defined % value.

Parameters:
  • callback (func) – a callback function.

  • threshold (int) – a callback call threshold (% coverage).

Examples:

>>> def notify_threshold():
>>>     print("reached 50% coverage!")
>>>
>>> # add callback to the cover group
>>> coverage_db["top.covergroup1"].add_threshold_callback(
>>>   notify_threshold, 50
>>> )
>>> # add callback to the cover point
>>> coverage_db["top.covergroup1.coverpoint4"].add_threshold_callback(
>>>   notify_threshold, 50
>>> )
add_bins_callback(callback, bins)[source]

Add a bins callback to the derived class of the CoverItem.

A callback is called (once) when a specific bin is covered.

Parameters:
  • callback (func) – a callback function.

  • bins – a particular bin (type depends on bins type).

Examples:

>>> def notify_bins():
>>>     print("covered bin 'special case'")
>>>
>>> coverage_db["top.covergroup1.coverpoint5"].add_bins_callback(
>>>   notify_bins, 'special case'
>>> )
property size

Return size of the coverage primitive.

Size of the cover group (or other coverage primitive) is returned. This is a total number of bins associated with assigned weights.

Returns:

size of the coverage primitive.

Return type:

int

property coverage

Return size of the covered bins in the coverage primitive.

Number of the covered bins in cover group (or other coverage primitive) is returned. This is a number of covered bins associated with assigned weights.

Returns:

size of the covered bins.

Return type:

int

property cover_percentage

Return coverage level of the coverage primitive.

Percent of the covered bins in cover group (or other coverage primitive) is returned. This is basically a coverage() divided by size() in %.

Returns:

percent of the coverage.

Return type:

float

property detailed_coverage

Return detailed coverage - full list of bins associated with number of hits. If labels are assigned to bins, labels are returned instead of bins values.

A dictionary (bins) -> (number of hits) is returned.

Returns:

dictionary associating number of hits with a particular bins.

Return type:

dict

property new_hits

Return bins hit at last sampling event. Works only for objects deriving from CoverItem.

Returns:

list of the new bins (which have not been already covered) sampled at last sampling event.

Return type:

list

property weight

Return weight of the coverage primitive. Works only for objects deriving from CoverItem.

Returns:

weight of the coverage primitive.

Return type:

int

property at_least

Return at_least attribute of the coverage primitive. Works only for objects deriving from CoverItem.

Returns:

at_least attribute of the coverage primitive.

Return type:

int

class cocotb_coverage.coverage.CoverPoint(name, vname=None, xf=None, rel=None, bins=[], bins_labels=None, weight=1, at_least=1, inj=False)[source]

Bases: CoverItem

Class used to create coverage points as decorators.

This decorator samples members of the decorated function (its signature). Sampling matches predefined bins according to the rule: rel(xf(args), bin) == True

Parameters:
  • name (str) – a CoverPoint path and name, defining its position in a coverage trie.

  • vname (str, optional) – a name of the variable to be covered (use this only when covering a single variable in the decorated function signature).

  • xf (func, optional) – a transformation function which transforms arguments of the decorated function. If vname and xf are not defined, matched is a single input argument (if only one exists) or a tuple (if multiple exist). Note that the self argument is always removed from the argument list.

  • bins (list) – a list of bins objects to be matched. Note that for non-trivial types, a rel must always be defined (or the equality operator must be overloaded).

  • bins_labels (list, optional) – a list of labels (str) associated with defined bins. Both lists lengths must match.

  • rel (func, optional) – a relation function which defines the bins matching relation (by default, the equality operator ==).

  • weight (int, optional) – a CoverPoint weight (by default 1).

  • at_least (int, optional) – the number of hits per bins to be considered as covered (by default 1).

  • inj (bool, optional) – “injection” feature, defines that only one bin can be matched at single sampling (default True).

Example:

>>> @coverage.CoverPoint( # cover (arg/2) < 1 ... 4 (4 bins)
...     name = "top.parent.coverpoint1",
...     xf = lambda x : x/2,
...     rel = lambda x, y : x < y,
...     bins = list(range(5))
... )
>>> @coverage.CoverPoint( # cover (arg) == 1 ... 4 (4 bins)
...     name = "top.parent.coverpoint2",
...     vname = "arg",
...     bins = list(range(5))
... )
>>> def decorated_func1(self, arg):
...     ...
>>> @coverage.CoverPoint( # cover (arg1, arg2) == (1, 1) or (0, 0) (2 bins)
...     name = "top.parent.coverpoint3",
...     bins = [(1, 1), (0, 0)]
... )
>>> def decorated_func1(self, arg1, arg2):
...     ...
property coverage

Return size of the covered bins in the coverage primitive.

Number of the covered bins in cover group (or other coverage primitive) is returned. This is a number of covered bins associated with assigned weights.

Returns:

size of the covered bins.

Return type:

int

property detailed_coverage

Return detailed coverage - full list of bins associated with number of hits. If labels are assigned to bins, labels are returned instead of bins values.

A dictionary (bins) -> (number of hits) is returned.

Returns:

dictionary associating number of hits with a particular bins.

Return type:

dict

class cocotb_coverage.coverage.CoverCross(name, items=[], ign_bins=[], weight=1, at_least=1)[source]

Bases: CoverItem

Class used to create coverage crosses as decorators.

This decorator samples members of the decorated function (its signature). It matches tuples cross-bins which are Cartesian products of bins defined in CoverPoints (items).

Parameters:
  • name (str) – a CoverCross path and name, defining its position in a coverage trie.

  • items (list) – a list of CoverPoints by names, to create a Cartesian product of cross-bins.

  • ign_bins (list, optional) – a list of bins to be ignored.

  • weight (int, optional) – a CoverCross weight (by default 1).

  • at_least (int, optional) – the number of hits per bin to be considered as covered (by default 1).

Example:

>>> @coverage.CoverPoint(
...     name = "top.parent.coverpoint1",
...     xf = lambda x, y: x,
...     bins = list(range(5)) # 4 bins in total
... )
>>> @coverage.CoverPoint(
...     name = "top.parent.coverpoint2",
...     xf = lambda x, y: y,
...     bins = list(range(5)) # 4 bins in total
... )
>>> @coverage.CoverCross(
...     name = "top.parent.covercross",
...     items = ["top.parent.coverpoint1", "top.parent.coverpoint2"],
...     ign_bins = [(1, 1), (4, 4)], # 4x4 - 2 = 14 bins in total
... )
>>> def decorated_func(self, arg_a, arg_b):
>>> # bin from the bins list [(1, 2), (1, 3)...(4, 3)] will be matched
>>> # when a tuple (x=arg_a, y=arg_b) was sampled at this function call.
...     ...
property coverage

Return size of the covered bins in the coverage primitive.

Number of the covered bins in cover group (or other coverage primitive) is returned. This is a number of covered bins associated with assigned weights.

Returns:

size of the covered bins.

Return type:

int

property detailed_coverage

Return detailed coverage - full list of bins associated with number of hits. If labels are assigned to bins, labels are returned instead of bins values.

A dictionary (bins) -> (number of hits) is returned.

Returns:

dictionary associating number of hits with a particular bins.

Return type:

dict

class cocotb_coverage.coverage.CoverCheck(name, f_fail, f_pass=None, weight=1, at_least=1)[source]

Bases: CoverItem

Class used to create coverage checks as decorators.

It is a simplified CoverPoint with defined 2 bins: PASS and FAIL and f_pass() and f_fail() functions.

Parameters:
  • name (str) – a CoverCheck path and name, defining its position in a coverage trie.

  • f_fail – a failure condition function - if it returns True, the coverage level is set to 0 permanently.

  • f_pass – a pass condition function - if it returns True, the coverage level is set to weight after at_least hits.

  • weight (int, optional) – a CoverCheck weight (by default 1).

  • at_least (int, optional) – the number of hits of the f_pass function to consider a particular CoverCheck as covered.

Example:

>>> @coverage.CoverCheck(
...     name = "top.parent.check",
...     f_fail = lambda x : x == 0,
...     f_pass = lambda x : x < 5)
>>> def decorated_fun(self, arg):
>>> # CoverCheck is 100% covered when (arg < 5) and never (arg == 0) was
>>> # sampled. CoverCheck is set to 0 unconditionally when at least once
>>> # (arg == 0) was sampled.
...     ...
property coverage

Return size of the covered bins in the coverage primitive.

Number of the covered bins in cover group (or other coverage primitive) is returned. This is a number of covered bins associated with assigned weights.

Returns:

size of the covered bins.

Return type:

int

property detailed_coverage

Return detailed coverage - full list of bins associated with number of hits. If labels are assigned to bins, labels are returned instead of bins values.

A dictionary (bins) -> (number of hits) is returned.

Returns:

dictionary associating number of hits with a particular bins.

Return type:

dict

cocotb_coverage.coverage.coverage_section(*coverItems)[source]

Combine multiple coverage items into a single decorator.

Parameters:

*coverItems ((multiple) CoverItem) – coverage primitives to be combined.

Example:

>>> my_coverage = coverage.coverage_section(
...     coverage.CoverPoint("x", ...),
...     coverage.CoverPoint("y", ...),
...     coverage.CoverCross("z", ...),
...     ...
... )
>>>
>>> @my_coverage
>>> def decorated_fun(self, arg):
...     ...
cocotb_coverage.coverage.merge_coverage(logger, merged_file_name, *files)[source]

Function used for merging coverage metrics in XML and YAML format.

Parameters:
  • logger (func) – a logger function

  • merged_file_name (str) – output filename

  • *files ((multiple) str) – comma separated filenames to merge coverage from

Example:

>>> merge_coverage('merged.xml', 'one.xml', 'other.xml') # merge one and other
cocotb_coverage.coverage.reportCoverage(logger, bins=False)[source]

Deprecated since version 1.0.

cocotb_coverage.coverage.coverageSection(*coverItems)[source]

Deprecated since version 1.0.

Module crv (Constrained Random Verification)

Constrained-random verification features.

Classes:

class cocotb_coverage.crv.Randomized[source]

Bases: object

Base class for randomized types.

The final class should contain defined random variables using the add_rand() method.

Constraints may be added and deleted using the add_constraint() and del_constraint() methods respectively.

A constraint is an arbitrary function and may either return a True/False value (hard constraints) or a numeric value, which may be interpreted as soft constraints or distribution functions.

Constraint function arguments (names) must match final class attributes (random or not). Constraints may have multiple random arguments which corresponds to multi-dimensional distributions.

The function randomize() performs a randomization for all random variables meeting all defined constraints.

The function randomize_with() performs a randomization using additional constraint functions given in an argument.

The functions pre_randomize() and post_randomize() are called before and after randomize() and should be overloaded in a final class if necessary.

If hard constraint cannot be resolved, an exception is thrown. If a soft constraint cannot be resolved (all acceptable solutions have zero probability), then the variable value is not being randomized.

Example:

>>> class FinalRandomized(Randomized):
>>>   def __init__(self, x):
>>>       Randomized.__init__(self)
>>>       self.x = x
>>>       self.y = 0
>>>       self.z = 0
>>>
>>>       # define y as a random variable taking values from 0 to 9
>>>       add_rand("y", list(range(10)))
>>>
>>>       # define z as a random variable taking values from 0 to 4
>>>       add_rand("z", list(range(5)))
>>>
>>>       # hard constraint
>>>       add_constraint(lambda x, y: x !=y)
>>>       # multi-dimensional distribution
>>>       add_constraint(lambda y, z: y + z)
>>>
>>> # create randomized object instance (default values at this point)
>>> obj_ = FinalRandomized(5)
>>> # randomize object with additional contraint
>>> obj_.randomize_with(lambda z : z > 3)

As generating constrained random objects may involve a lot of computations, it is recommended to limit random variables domains and use pre_randomize()/post_randomize() methods where possible.

add_rand(var, domain=None)[source]

Add a random variable to the solver.

All random variables must be defined before adding any constraint with add_constraint(). Therefore it is highly recommended to call add_rand in the __init__ method of your final class.

Parameters:
  • var (str) – a variable name corresponding to the class member variable.

  • domain (list, optional) – a list of all allowed values of the variable var. By default, a list with values 0 to 65534 (16 bit unsigned int domain) is used.

Examples:

>>> add_rand("data", list(range(1024)))
>>> add_rand("delay", ["small", "medium", "high"])
add_constraint(cstr)[source]

Add a constraint function to the solver.

A constraint may return True/False or a numeric value. Constraint function arguments must be valid class member names (random or not). Arguments must be listed in alphabetical order.

Due to calculation complexity, it is recommended to create as few constraints as possible and implement pre_randomize()/post_randomize() methods, or use the solve_order() function.

Each constraint is associated with its arguments being random variables,which means for each random variable combination only one constraint of the True/False type and one numeric may be defined. The latter will overwrite the existing one.

For example, when class has two random variables (x, y), six constraint functions may be defined: boolean and numeric constraints of x, y and a pair (x, y).

Parameters:

cstr (func) – a constraint function.

Returns:

an overwritten constraint or None if no overwrite happened.

Return type:

func or None

Examples:

>>> def highdelay_cstr(delay):
>>>     return delay == "high"
>>>
>>> add_constraint(highdelay_cstr)  # hard constraint
>>> add_constraint(lambda data : data < 128)  # hard constraint
>>>
>>> # distribution (highest probability density at the boundaries):
>>> add_constraint(lambda data : abs(64 - data))
>>>
>>> # hard constraint of multiple variables (some of them may be
>>> # non-random):
>>> add_constraint(lambda x,y,z : x + y + z == 0)
>>>
>>> # soft constraint created by applying low probability density for
>>> # some solutions:
>>> add_constraint(
>>>  lambda delay, size : 0.01 if (size < 5 & delay == "medium") else 1
>>> )
>>> # constraint that overwrites the previously defined one
>>> # (data < 128)
>>> add_constraint(lambda data : data < 256)
solve_order(*orderedVars)[source]

Define an order of the constraints resolving.

Constraints are being resolved in a given order, which means that randomization is called in separated steps, where at each next step some constraints are already resolved. Number of arguments defines number of the randomization steps. If this funcion is specified multiple times for a given object, only the last one remains valid.

Parameters:

*orderedVars (multiple str or list) – Variables that are requested to be resolved in an specific order.

Example:

>>> add_rand("x", list(range(0,10)))
>>> add_rand("y", list(range(0,10)))
>>> add_rand("z", list(range(0,10)))
>>> add_rand("w", list(range(0,10)))
>>> add_constraint(lambda x, y : x + y = 9)
>>> add_constraint(lambda z : z < 5)
>>> add_constraint(lambda w : w > 5)
>>>
>>> solve_order(["x", "z"], "y")
>>> # In a first step, "z", "x" and "w" will be resolved, which means
>>> # only the second and third constraint will be applied. In a second
>>> # step, the first constraint will be resolved as it was requested
>>> # to solve "y" after "x" and "z". "x" will be interpreted as a
>>> # constant in this case.
del_constraint(cstr)[source]

Delete a constraint function.

Parameters:

cstr (func) – a constraint function.

Example:

>>> del_constraint(highdelay_cstr)
pre_randomize()[source]

A function that is called before randomize()/randomize_with().

To be overridden in a final class if used.

post_randomize()[source]

A function that is called after randomize()/randomize_with().

To be overridden in a final class if used.

randomize()[source]

Randomize a final class using only predefined constraints.

randomize_with(*constraints)[source]

Randomize a final class using the additional constraints given.

Additional constraints may override existing ones.

Parameters:

*constraints ((multiple) func) – additional constraints to be applied.

addRand(var, domain=None)[source]

Deprecated since version 1.0.

solveOrder(*orderedVars)[source]

Deprecated since version 1.0.

addConstraint(cstr)[source]

Deprecated since version 1.0.

delConstraint(cstr)[source]

Deprecated since version 1.0.