Library Reference

Python Test Runner

Warning

Python runners and associated APIs are an experimental feature and subject to change.

Build HDL and run cocotb tests.

cocotb.runner.shlex_join(split_command)[source]

Return a shell-escaped string from split_command This is here more for compatibility purposes

class cocotb.runner.VHDL[source]

Tags source files and build arguments to build() as VHDL-specific.

class cocotb.runner.Verilog[source]

Tags source files and build arguments to build() as Verilog-specific.

class cocotb.runner.Simulator[source]
build(hdl_library='top', verilog_sources=[], vhdl_sources=[], sources=[], includes=[], defines={}, parameters={}, build_args=[], hdl_toplevel=None, always=False, build_dir='sim_build', clean=False, verbose=False, timescale=None, waves=None, log_file=None)[source]

Build the HDL sources.

With mixed language simulators, sources will be built, followed by vhdl_sources, then verilog_sources. With simulators that only support either VHDL or Verilog, sources will be built, followed by vhdl_sources and verilog_sources, respectively.

If your source files use an atypical file extension, use VHDL and Verilog to tag the path as a VHDL or Verilog source file, respectively. If the filepaths aren’t tagged, the extension is used to determine if they are VHDL or Verilog files.

Language

File Extensions

VHDL

.vhd, .vhdl

Verilog

.v, .sv, .vh, .svh

runner.build(
    sources=[
        VHDL("/my/file.is_actually_vhdl"),
        Verilog("/other/file.verilog"),
    ],
)

The same tagging works for build_args. Tagged build_args only supply that option to the compiler when building the source file for the tagged language. Non-tagged build_args are supplied when compiling any language.

Parameters:
  • hdl_library (str) – The library name to compile into.

  • verilog_sources (Sequence[PathLike[str] | str]) – Verilog source files to build.

  • vhdl_sources (Sequence[PathLike[str] | str]) – VHDL source files to build.

  • sources (Sequence[PathLike[str] | str | VHDL | Verilog]) – Language-agnostic list of source files to build.

  • includes (Sequence[PathLike[str] | str]) – Verilog include directories.

  • defines (Mapping[str, object]) – Defines to set.

  • parameters (Mapping[str, object]) – Verilog parameters or VHDL generics.

  • build_args (Sequence[str | VHDL | Verilog]) – Extra build arguments for the simulator.

  • hdl_toplevel (str | None) – The name of the HDL toplevel module.

  • always (bool) – Always run the build step.

  • build_dir (PathLike[str] | str) – Directory to run the build step in.

  • clean (bool) – Delete build_dir before building

  • verbose (bool) – Enable verbose messages.

  • timescale (Tuple[str, str] | None) – Tuple containing time unit and time precision for simulation.

  • waves (bool | None) – Record signal traces.

  • log_file (PathLike[str] | str | None) – File to write the build log to.

Return type:

None

test(test_module, hdl_toplevel, hdl_toplevel_library='top', hdl_toplevel_lang=None, gpi_interfaces=None, testcase=None, seed=None, test_args=[], plusargs=[], extra_env={}, waves=None, gui=None, parameters=None, build_dir=None, test_dir=None, results_xml=None, pre_cmd=[], verbose=False, timescale=None, log_file=None)[source]

Run the tests.

Parameters:
  • test_module (str | Sequence[str]) – Name(s) of the Python module(s) containing the tests to run. Can be a comma-separated list.

  • hdl_toplevel (str) – Name of the HDL toplevel module.

  • hdl_toplevel_library (str) – The library name for HDL toplevel module.

  • hdl_toplevel_lang (str | None) – Language of the HDL toplevel module.

  • gpi_interfaces (List[str] | None) – List of GPI interfaces to use, with the first one being the entry point.

  • testcase (str | Sequence[str] | None) – Name(s) of a specific testcase(s) to run. If not set, run all testcases found in test_module. Can be a comma-separated list.

  • seed (int | str | None) – A specific random seed to use.

  • test_args (Sequence[str]) – Extra arguments for the simulator.

  • plusargs (Sequence[str]) – ‘plusargs’ to set for the simulator.

  • extra_env (Mapping[str, str]) – Extra environment variables to set.

  • waves (bool | None) – Record signal traces.

  • gui (bool | None) – Run with simulator GUI.

  • parameters (Mapping[str, object]) – Verilog parameters or VHDL generics.

  • build_dir (PathLike[str] | str | None) – Directory the build step has been run in.

  • test_dir (PathLike[str] | str | None) – Directory to run the tests in.

  • results_xml (str | None) – Name of xUnit XML file to store test results in. If an absolute path is provided it will be used as-is, {build_dir}/results.xml otherwise. This argument should not be set when run with pytest.

  • verbose (bool) – Enable verbose messages.

  • pre_cmd (List[str]) – Commands to run before simulation begins.

  • timescale (Tuple[str, str] | None) – Tuple containing time unit and time precision for simulation.

  • log_file (PathLike[str] | str | None) – File to write the test log to.

Returns:

The absolute location of the results XML file which can be defined by the results_xml argument.

Return type:

Path

cocotb.runner.get_results(results_xml_file)[source]

Return number of tests and fails in results_xml_file.

Returns:

Tuple of number of tests and number of fails.

Raises:

SystemExitresults_xml_file is non-existent.

Parameters:

results_xml_file (Path)

Return type:

Tuple[int, int]

cocotb.runner.check_results_file(results_xml_file)[source]

Raise exception if results_xml_file does not exist or contains failed tests.

Raises:

SystemExitresults_xml_file is non-existent or contains fails.

Parameters:

results_xml_file (Path)

Return type:

None

cocotb.runner.outdated(output, dependencies)[source]

Return True if any source files in dependencies are newer than the output directory.

Returns:

True if any source files are newer, False otherwise.

Parameters:
Return type:

bool

cocotb.runner.get_abs_path(path)[source]

Return path in absolute form.

Parameters:

path (PathLike[str] | str)

Return type:

Path

cocotb.runner.get_abs_paths(paths)[source]

Return list of paths in absolute form.

Parameters:

paths (Sequence[PathLike[str] | str])

Return type:

List[Path]

exception cocotb.runner.UnknownFileExtension(source)[source]
Parameters:

source (os.PathLike[str] | str)

Return type:

None

class cocotb.runner.Icarus[source]
class cocotb.runner.Questa[source]
class cocotb.runner.Ghdl[source]
class cocotb.runner.Nvc[source]
class cocotb.runner.Riviera[source]
class cocotb.runner.Verilator[source]
class cocotb.runner.Xcelium[source]
cocotb.runner.get_runner(simulator_name)[source]

Return the simulator_name instance.

Parameters:

simulator_name (str)

Return type:

Simulator

Test Results

The exceptions in this module can be raised at any point by any code and will terminate the test.

cocotb.result.raise_error(obj, msg)[source]

Create a TestError exception and raise it after printing a traceback.

Deprecated since version 1.3: Raise a standard Python exception instead of calling this function. A stacktrace will be printed by cocotb automatically if the exception is unhandled.

Parameters:
  • obj – Object with a log method.

  • msg (str) – The log message.

cocotb.result.create_error(obj, msg)[source]

Like raise_error(), but return the exception rather than raise it, simply to avoid too many levels of nested try/except blocks.

Deprecated since version 1.3: Raise a standard Python exception instead of calling this function.

Parameters:
  • obj – Object with a log method.

  • msg (str) – The log message.

exception cocotb.result.ReturnValue(retval)[source]

Helper exception needed for Python versions prior to 3.3.

Deprecated since version 1.4: Use a return statement instead; this works in all supported versions of Python.

exception cocotb.result.TestComplete(*args, **kwargs)[source]

Exception showing that the test was completed. Sub-exceptions detail the exit status.

Deprecated since version 1.6.0: The stdout and stderr attributes.

exception cocotb.result.ExternalException(exception)[source]

Exception thrown by cocotb.external functions.

exception cocotb.result.TestError(*args, **kwargs)[source]

Exception showing that the test was completed with severity Error.

Deprecated since version 1.5: Raise a standard Python exception instead. A stacktrace will be printed by cocotb automatically if the exception is unhandled.

exception cocotb.result.TestFailure(*args, **kwargs)[source]

Exception showing that the test was completed with severity Failure.

Deprecated since version 1.6.0: Use a standard assert statement instead of raising this exception. Use expect_fail rather than expect_error with this exception in the cocotb.test decorator.

exception cocotb.result.TestSuccess(*args, **kwargs)[source]

Exception showing that the test was completed successfully.

exception cocotb.result.SimFailure(*args, **kwargs)[source]

Exception showing that the simulator exited unsuccessfully.

exception cocotb.result.SimTimeoutError[source]

Exception for when a timeout, in terms of simulation time, occurs.

Writing and Generating tests

class cocotb.test(*args, **kwargs)[source]

Decorator to mark a Callable which returns a Coroutine as a test.

The test decorator provides a test timeout, and allows us to mark tests as skipped or expecting errors or failures. Tests are evaluated in the order they are defined in a test module.

Used as @cocotb.test(...).

Parameters:
  • timeout_time (numbers.Real or decimal.Decimal, optional) –

    Simulation time duration before timeout occurs.

    Added in version 1.3.

    Note

    Test timeout is intended for protection against deadlock. Users should use with_timeout if they require a more general-purpose timeout mechanism.

  • timeout_unit (str, optional) –

    Units of timeout_time, accepts any units that Timer does.

    Added in version 1.3.

    Deprecated since version 1.5: Using None as the timeout_unit argument is deprecated, use 'step' instead.

  • expect_fail (bool, optional) – If True and the test fails a functional check via an assert statement, pytest.raises, pytest.warns, or pytest.deprecated_call the test is considered to have passed. If True and the test passes successfully, the test is considered to have failed.

  • expect_error (exception type or tuple of exception types, optional) –

    Mark the result as a pass only if one of the exception types is raised in the test. This is primarily for cocotb internal regression use for when a simulator error is expected.

    Users are encouraged to use the following idiom instead:

    @cocotb.test()
    async def my_test(dut):
        try:
            await thing_that_should_fail()
        except ExceptionIExpect:
            pass
        else:
            assert False, "Exception did not occur"
    

    Changed in version 1.3: Specific exception types can be expected

    Deprecated since version 1.5: Passing a bool value is now deprecated. Pass a specific Exception or a tuple of Exceptions instead.

  • skip (bool, optional) – Don’t execute this test as part of the regression. Test can still be run manually by setting TESTCASE.

  • stage (int) – Order tests logically into stages, where multiple tests can share a stage. Defaults to 0.

class cocotb.coroutine(func)[source]

Decorator class that allows us to provide common coroutine mechanisms:

log methods will log to cocotb.coroutine.name.

join() method returns an event which will fire when the coroutine exits.

Used as @cocotb.coroutine.

class cocotb.external(func)[source]

Decorator to apply to an external function to enable calling from cocotb.

This turns a normal function that isn’t a coroutine into a blocking coroutine. Currently, this creates a new execution thread for each function that is called. Scope for this to be streamlined to a queue in future.

class cocotb.function(func)[source]

Decorator class that allows a function to block.

This allows a coroutine that consumes simulation time to be called by a thread started with cocotb.external; in other words, to internally block while externally appear to yield.

class cocotb.regression.TestFactory(test_function, *args, **kwargs)[source]

Factory to automatically generate tests.

Parameters:
  • test_function – A Callable that returns the test Coroutine. Must take dut as the first argument.

  • *args – Remaining arguments are passed directly to the test function. Note that these arguments are not varied. An argument that varies with each test must be a keyword argument to the test function.

  • **kwargs – Remaining keyword arguments are passed directly to the test function. Note that these arguments are not varied. An argument that varies with each test must be a keyword argument to the test function.

Assuming we have a common test function that will run a test. This test function will take keyword arguments (for example generators for each of the input interfaces) and generate tests that call the supplied function.

This Factory allows us to generate sets of tests based on the different permutations of the possible arguments to the test function.

For example, if we have a module that takes backpressure, has two configurable features where enabling feature_b requires feature_a to be active, and need to test against data generation routines gen_a and gen_b:

>>> tf = TestFactory(test_function=run_test)
>>> tf.add_option(name='data_in', optionlist=[gen_a, gen_b])
>>> tf.add_option('backpressure', [None, random_backpressure])
>>> tf.add_option(('feature_a', 'feature_b'), [(False, False), (True, False), (True, True)])
>>> tf.generate_tests()

We would get the following tests:

  • gen_a with no backpressure and both features disabled

  • gen_a with no backpressure and only feature_a enabled

  • gen_a with no backpressure and both features enabled

  • gen_a with random_backpressure and both features disabled

  • gen_a with random_backpressure and only feature_a enabled

  • gen_a with random_backpressure and both features enabled

  • gen_b with no backpressure and both features disabled

  • gen_b with no backpressure and only feature_a enabled

  • gen_b with no backpressure and both features enabled

  • gen_b with random_backpressure and both features disabled

  • gen_b with random_backpressure and only feature_a enabled

  • gen_b with random_backpressure and both features enabled

The tests are appended to the calling module for auto-discovery.

Tests are simply named test_function_N. The docstring for the test (hence the test description) includes the name and description of each generator.

Changed in version 1.5: Groups of options are now supported

add_option(name, optionlist)[source]

Add a named option to the test.

Parameters:
  • name (str or iterable of str) – An option name, or an iterable of several option names. Passed to test as keyword arguments.

  • optionlist (list) – A list of possible options for this test knob. If N names were specified, this must be a list of N-tuples or lists, where each element specifies a value for its respective option.

Changed in version 1.5: Groups of options are now supported

generate_tests(prefix='', postfix='')[source]

Generate an exhaustive set of tests using the cartesian product of the possible keyword arguments.

The generated tests are appended to the namespace of the calling module.

Parameters:
  • prefix (str) – Text string to append to start of test_function name when naming generated test cases. This allows reuse of a single test_function with multiple TestFactories without name clashes.

  • postfix (str) – Text string to append to end of test_function name when naming generated test cases. This allows reuse of a single test_function with multiple TestFactories without name clashes.

Interacting with the Simulator

Task Management

cocotb.fork(coro)[source]

Schedule a coroutine to be run concurrently. See Coroutines and Tasks for details on its use.

Deprecated since version 1.7.0: This function has been deprecated in favor of cocotb.start_soon() and cocotb.start(). In most cases you can simply substitute cocotb.fork with cocotb.start_soon. For more information on when to use start_soon vs start see Coroutines and Tasks.

Parameters:

coro (Task | Coroutine)

Return type:

Task

cocotb.start_soon(coro)[source]

Schedule a coroutine to be run concurrently.

Note that this is not an async function, and the new task will not execute until the calling task yields control.

Added in version 1.6.0.

Parameters:

coro (Task | Coroutine)

Return type:

Task

async cocotb.start(coro)[source]

Schedule a coroutine to be run concurrently, then yield control to allow pending tasks to execute.

The calling task will resume execution before control is returned to the simulator.

Added in version 1.6.0.

Parameters:

coro (Task | Coroutine)

Return type:

Task

cocotb.create_task(coro)[source]

Construct a coroutine into a Task without scheduling the Task.

The Task can later be scheduled with cocotb.fork(), cocotb.start(), or cocotb.start_soon().

Added in version 1.6.0.

Parameters:

coro (Task | Coroutine)

Return type:

Task

class cocotb.task.Task(inst)[source]

Concurrently executing task.

This class is not intended for users to directly instantiate. Use cocotb.create_task() to create a Task object, or use cocotb.start_soon() or cocotb.start() to create a Task and schedule it to run.

Changed in version 1.8.0: Moved to the cocotb.task module.

cancel(msg=None)[source]

Cancel a Task’s further execution.

When a Task is cancelled, a asyncio.CancelledError is thrown into the Task.

Parameters:

msg (str | None)

Return type:

None

cancelled()[source]

Return True if the Task was cancelled.

Return type:

bool

close()[source]

Raise GeneratorExit inside coroutine.

Return type:

None

done()[source]

Return True if the Task has finished executing.

Return type:

bool

exception()[source]

Return the exception of the Task.

If the Task ran to completion, None is returned. If the Task failed with an exception, the exception is returned. If the Task was cancelled, the CancelledError is re-raised. If the coroutine is not yet complete, a asyncio.InvalidStateError is raised.

Return type:

BaseException | None

has_started()[source]

Return True if the Task has started executing.

Return type:

bool

join()[source]

Return a trigger that will fire when the wrapped coroutine exits.

Return type:

Join

kill()[source]

Kill a coroutine.

Return type:

None

result()[source]

Return the result of the Task.

If the Task ran to completion, the result is returned. If the Task failed with an exception, the exception is re-raised. If the Task was cancelled, the CancelledError is re-raised. If the coroutine is not yet complete, a asyncio.InvalidStateError is raised.

Return type:

T

property retval: T

Return the result of the Task.

If the Task ran to completion, the result is returned. If the Task failed with an exception, the exception is re-raised. If the Task is not yet complete, a RuntimeError is raised.

Deprecated since version 1.7.0.

send(value)[source]

Send a value into the coroutine. Return next yielded value or raise StopIteration.

Parameters:

value (Any)

Return type:

Any

throw(exc)[source]

Raise an exception in the coroutine. Return next yielded value or raise StopIteration.

Parameters:

exc (BaseException)

Return type:

Any

Handle Values

class cocotb.binary.BinaryRepresentation[source]
UNSIGNED = 0

Unsigned format

SIGNED_MAGNITUDE = 1

Sign and magnitude format

TWOS_COMPLEMENT = 2

Two’s complement format

class cocotb.binary.BinaryValue(value=None, n_bits=None, bigEndian=True, binaryRepresentation=0, bits=None)[source]

Representation of values in binary format.

The underlying value can be set or accessed using these aliasing attributes:

For example:

>>> vec = BinaryValue()
>>> vec.integer = 42
>>> print(vec.binstr)
101010
>>> print(vec.buff)
b'*'
Parameters:
  • value (str or int or long, optional) – Value to assign to the bus.

  • n_bits (int, optional) – Number of bits to use for the underlying binary representation.

  • bigEndian (bool, optional) – Interpret the binary as big-endian when converting to/from a string buffer.

  • binaryRepresentation (BinaryRepresentation) – The representation of the binary value (one of UNSIGNED, SIGNED_MAGNITUDE, TWOS_COMPLEMENT). Defaults to unsigned representation.

  • bits (int, optional) – Deprecated: Compatibility wrapper for n_bits.

assign(value)[source]

Decides how best to assign the value to the vector.

Picks from the type of its argument whether to set integer, binstr, or buff.

Parameters:

value (str or int or bytes) – The value to assign.

Changed in version 1.4: This no longer falls back to setting buff if a str containing any characters that aren’t 0, 1, X or Z is used, since buff now accepts only bytes. Instead, an error is raised.

property integer

The integer representation of the underlying vector.

property value

Integer access to the value. deprecated

property signed_integer

The signed integer representation of the underlying vector.

property is_resolvable: bool

Return whether the value contains only resolvable (i.e. no “unknown”) bits.

By default the values X, Z, U and W are considered unresolvable. This can be configured with COCOTB_RESOLVE_X.

This is similar to the SystemVerilog Assertion $isunknown system function or the VHDL function is_x (with an inverted meaning).

property buff: bytes

The value as a binary string buffer.

>>> BinaryValue("01000001" + "00101111").buff == b"\x41\x2F"
True

Changed in version 1.4: This changed from str to bytes. Note that for older versions used with Python 2 these types were indistinguishable.

property binstr

The binary representation stored as a string of 0, 1, and possibly x, z, and other states.

property n_bits

The number of bits of the binary value.

HDL Datatypes

These are a set of datatypes that model the behavior of common HDL datatypes. They can be used independently of cocotb for modeling and will replace BinaryValue as the types used by cocotb’s simulator handles.

Added in version 1.6.0.

class cocotb.types.Logic(value=None)[source]

Model of a 4-value (0, 1, X, Z) datatype commonly seen in HDLs.

This is modeled after (System)Verilog’s 4-value logic type. VHDL’s 9-value std_ulogic type maps to this type by treating weak values as full strength values and treating “uninitialized” (U) and “don’t care” (-) as “unknown” (X).

Logic can be converted to and from int, str, bool, and Bit by using the appropriate constructor syntax. The list of values convertable to Logic includes 0, 1, True, False, "0", "1", "X", "Z", Bit('0'), and Bit('1'). For a comprehensive list of values that can be converted into Logic see tests/pytest/test_logic.py.

>>> Logic("X")
Logic('X')
>>> Logic(True)
Logic('1')
>>> Logic(1)
Logic('1')
>>> Logic(Bit(0))
Logic('0')

>>> Logic()  # default value
Logic('X')

>>> str(Logic("Z"))
'Z'
>>> bool(Logic(0))
False
>>> int(Logic(1))
1
>>> Bit(Logic("1"))
Bit('1')

Note

The int and bool conversions will raise ValueError if the value is not 0 or 1.

Logic values are immutable and therefore hashable and can be placed in sets and used as keys in dicts.

Logic supports the common logic operations &, |, ^, and ~.

>>> def full_adder(a: Logic, b: Logic, carry: Logic) -> typing.Tuple[Logic, Logic]:
...     res = a ^ b ^ carry
...     carry_out = (a & b) | (b & carry) | (a & carry)
...     return res, carry_out

>>> full_adder(a=Logic('0'), b=Logic('1'), carry=Logic('1'))
(Logic('0'), Logic('1'))
Parameters:

value (str | int | bool | Logic | None) – value to construct into a Logic.

Raises:

ValueError – if the value cannot be constructed into a Logic.

Return type:

LogicT

class cocotb.types.Bit(value=None)[source]

Model of a 2-value (0, 1) datatype commonly seen in HDLs.

This is modeled after (System)Verilog’s 2-value bit type. VHDL’s bit type maps to this type perfectly.

Bit is a proper subtype of Logic, meaning a use of Logic can be substituted with a Bit. Some behavior may surprise you if you do not expect it.

>>> Bit(0) == Logic(0)
True
>>> Bit(0) in {Logic(0)}
True

Bit can be converted to and from int, str, bool, and Logic by using the appropriate constructor syntax. The list of values convertable to Bit includes 0, 1, True, False, "0", "1", Logic('0'), and Logic('1'). For a comprehensive list of values that can be converted into Bit see tests/pytest/test_logic.py.

>>> Bit("0")
Bit('0')
>>> Bit(True)
Bit('1')
>>> Bit(1)
Bit('1')
>>> Bit(Logic(0))
Bit('0')

>>> Bit()  # default value
Bit('0')

>>> str(Bit("0"))
'0'
>>> bool(Bit(False))
False
>>> int(Bit(1))
1
>>> Logic(Bit("1"))
Logic('1')

Bit values are hashable and can be placed in sets and used as keys in dicts.

Bit supports the common logic operations &, |, ^, and ~.

>>> def mux(a: Bit, b: Bit, s: Bit) -> Bit:
...     return (a & ~s) | (b & s)

>>> a = Bit(0)
>>> b = Bit(1)
>>> sel = Bit(1)  # choose second argument
>>> mux(a, b, sel)
Bit('1')
Parameters:

value (str | int | bool | Logic | None) – value to construct into a Bit.

Raises:

ValueError – if the value cannot be constructed into a Bit.

Return type:

LogicT

class cocotb.types.Range(left: int, direction: int)[source]
class cocotb.types.Range(left: int, direction: str, right: int)
class cocotb.types.Range(left: int, *, right: int)

Variant of range with inclusive right bound.

In Python, range and slice have a non-inclusive right bound. In both Verilog and VHDL, ranges and arrays have an inclusive right bound. This type mimics Python’s range type, but implements HDL-like inclusive right bounds, using the names left and right as replacements for start and stop to match VHDL. Range directionality can be specified using 'to' or 'downto' between the left and right bounds. Not specifying directionality will cause the directionality to be inferred.

>>> r = Range(-2, 3)
>>> r.left, r.right, len(r)
(-2, 3, 6)

>>> s = Range(8, 'downto', 1)
>>> s.left, s.right, len(s)
(8, 1, 8)

from_range() and to_range() can be used to convert from and to range.

>>> r = Range(-2, 3)
>>> r.to_range()
range(-2, 4)

Range supports “null” ranges as seen in VHDL. “null” ranges occur when a left bound cannot reach a right bound with the given direction. They have a length of 0, but the left, right, and direction values remain as given.

>>> r = Range(1, 'to', 0)  # no way to count from 1 'to' 0
>>> r.left, r.direction, r.right
(1, 'to', 0)
>>> len(r)
0

Note

This is only possible when specifying the direction.

Ranges also support all the features of range including, but not limited to:

  • value in range to see if a value is in the range,

  • range.index(value) to see what position in the range the value is,

The typical use case of this type is in conjunction with Array.

Parameters:
  • left (int) – leftmost bound of range

  • direction (int | str | None) – 'to' if values are ascending, 'downto' if descending

  • right (int | None) – rightmost bound of range (inclusive)

property direction: str

'to' if values are meant to be ascending, 'downto' otherwise.

classmethod from_range(range)[source]

Convert range to Range.

Parameters:

range (range)

Return type:

Range

property left: int

Leftmost value in a range.

property right: int

Rightmost value in a range.

to_range()[source]

Convert Range to range.

Return type:

range

cocotb.types.concat(a, b)[source]

Create a new array that is the concatenation of one array with another.

Uses the __concat__() or __rconcat__() special methods to dispatch to a particular implementation, exactly like other binary operations in Python.

Raises:

TypeError – when the arguments do not support concatenation in the given order.

Parameters:
Return type:

Any

class cocotb.types.Array(value, range=None)[source]

Fixed-size, arbitrarily-indexed, homogeneous collection type.

Arrays are similar to, but different from Python lists. An array can store values of any type or values of multiple types at a time, just like a list. Unlike lists, an array’s size cannot change.

The indexes of an array can start or end at any integer value, they are not limited to 0-based indexing. Indexing schemes can be either ascending or descending in value. An array’s indexes are described using a Range object. Initial values are treated as iterables, which are copied into an internal buffer.

>>> Array("1234")  # the 0-based range `(0, len(value)-1)` is inferred
Array(['1', '2', '3', '4'], Range(0, 'to', 3))

>>> Array([1, True, None, "example"], Range(-2, 1))  # initial value and range lengths must be equal
Array([1, True, None, 'example'], Range(-2, 'to', 1))

Arrays also support “null” ranges; “null” arrays have zero length and cannot be indexed.

>>> Array([], range=Range(1, "to", 0))
Array([], Range(1, 'to', 0))

Indexing and slicing is very similar to lists, but it uses the indexing scheme specified. Slicing, just like the Range object uses an inclusive right bound, which is commonly seen in HDLs. Like lists, if a start or stop index is not specified, it is inferred as the start or end of the array. Slicing an array returns a new Array object, whose bounds are the slice indexes.

>>> a = Array("1234abcd")
>>> a[7]
'd'
>>> a[2:5]
Array(['3', '4', 'a', 'b'], Range(2, 'to', 5))
>>> a[2:5] = reversed(a[2:5])
>>> "".join(a)
'12ba43cd'

>>> b = Array("1234", Range(0, -3))
>>> b[-2]
'3'
>>> b[-1:]
Array(['2', '3', '4'], Range(-1, 'downto', -3))
>>> b[:] = reversed(b)
>>> b
Array(['4', '3', '2', '1'], Range(0, 'downto', -3))

Warning

Arrays behave differently in certain situations than Python’s builtin sequence types (list, tuple, etc.).

  • Arrays are not necessarily 0-based and slices use inclusive right bounds, so many functions that work on Python sequences by index (like bisect) may not work on arrays.

  • Slice indexes must be specified in the same direction as the array and do not support specifying a “step”.

  • When setting a slice, the new value must be an iterable of the same size as the slice.

  • Negative indexes are not treated as an offset from the end of the array, but are treated literally.

Arrays are equal to other arrays of the same length with the same values (structural equality). Bounds do not matter for equality.

>>> a = Array([1, 1, 2, 3, 5], Range(4, "downto", 0))
>>> b = Array([1, 1, 2, 3, 5], Range(-2, "to", 2))
>>> a == b
True

You can change the bounds of an array by setting the range to a new value. The new bounds must be the same length of the array.

>>> a = Array("1234")
>>> a.range
Range(0, 'to', 3)
>>> a.range = Range(3, 'downto', 0)
>>> a.range
Range(3, 'downto', 0)

Arrays support the methods and semantics defined by collections.abc.Sequence.

>>> a = Array("stuff", Range(2, "downto", -2))
>>> len(a)
5
>>> "t" in a
True
>>> a.index("u")
0
>>> for c in a:
...     print(c)
s
t
u
f
f
Parameters:
  • value (Iterable[T]) – Initial value for the array.

  • range (Range | None) – Indexing scheme of the array.

Raises:
  • ValueError – When argument values cannot be used to construct an array.

  • TypeError – When invalid argument types are used.

property direction: str

"to" if indexes are ascending, "downto" otherwise.

property left: int

Leftmost index of the array.

property range: Range

Range of the indexes of the array.

property right: int

Rightmost index of the array.

class cocotb.types.LogicArray(value: int | Iterable[str | int | bool | Logic] | BinaryValue, range: Range | None)[source]
class cocotb.types.LogicArray(value: int | Iterable[str | int | bool | Logic] | BinaryValue | None, range: Range)

Fixed-sized, arbitrarily-indexed, array of cocotb.types.Logic.

LogicArrays can be constructed from either iterables of values constructible into Logic: like bool, str, int; or from integers. If constructed from a positive integer, an unsigned bit representation is used to construct the LogicArray. If constructed from a negative integer, a two’s complement bit representation is used. Like Array, if no range argument is given, it is deduced from the length of the iterable or bit string used to initialize the variable. If a range argument is given, but no value, the array is filled with the default value of Logic().

>>> LogicArray("01XZ")
LogicArray('01XZ', Range(3, 'downto', 0))

>>> LogicArray([0, True, "X"])
LogicArray('01X', Range(2, 'downto', 0))

>>> LogicArray(0xA)  # picks smallest range that can fit the value
LogicArray('1010', Range(3, 'downto', 0))

>>> LogicArray(-4, Range(0, "to", 3))  # will sign-extend
LogicArray('1100', Range(0, 'to', 3))

>>> LogicArray(range=Range(0, "to", 3))  # default values
LogicArray('XXXX', Range(0, 'to', 3))

LogicArrays support the same operations as Array; however, it enforces the condition that all elements must be a Logic.

>>> la = LogicArray("1010")
>>> la[0]                               # is indexable
Logic('0')

>>> la[1:]                              # is slice-able
LogicArray('10', Range(1, 'downto', 0))

>>> Logic("0") in la                    # is a collection
True

>>> list(la)                            # is an iterable
[Logic('1'), Logic('0'), Logic('1'), Logic('0')]

When setting an element or slice, the value is first constructed into a Logic.

>>> la = LogicArray("1010")
>>> la[3] = "Z"
>>> la[3]
Logic('Z')

>>> la[2:] = ['X', True, 0]
>>> la
LogicArray('ZX10', Range(3, 'downto', 0))

LogicArrays can be converted into strs or ints.

>>> la = LogicArray("1010")
>>> la.binstr
'1010'

>>> la.integer          # uses unsigned representation
10

>>> la.signed_integer   # uses two's complement representation
-6

LogicArrays also support element-wise logical operations: &, |, ^, and ~.

>>> def big_mux(a: LogicArray, b: LogicArray, sel: Logic) -> LogicArray:
...     s = LogicArray([sel] * len(a))
...     return (a & ~s) | (b & s)

>>> la = LogicArray("0110")
>>> p = LogicArray("1110")
>>> sel = Logic('1')        # choose second option
>>> big_mux(la, p, sel)
LogicArray('1110', Range(3, 'downto', 0))
Parameters:
Raises:
  • ValueError – When argument values cannot be used to construct an array.

  • TypeError – When invalid argument types are used.

Triggers

See Simulator Triggers for a list of sub-classes. Below are the internal classes used within cocotb.

class cocotb.triggers.Trigger[source]

Base class to derive from.

abstract prime(callback)[source]

Set a callback to be invoked when the trigger fires.

The callback will be invoked with a single argument, self.

Sub-classes must override this, but should end by calling the base class method.

Warning

Do not call this directly within a task. It is intended to be used only by the scheduler.

unprime()[source]

Remove the callback, and perform cleanup if necessary.

After being un-primed, a Trigger may be re-primed again in the future. Calling unprime multiple times is allowed, subsequent calls should be a no-op.

Sub-classes may override this, but should end by calling the base class method.

Warning

Do not call this directly within a task. It is intended to be used only by the scheduler.

class cocotb.triggers.GPITrigger[source]

Base Trigger class for GPI triggers.

Consumes simulation time.

unprime()[source]

Disable a primed trigger, can be re-primed.

class cocotb.triggers.Waitable[source]

Base class for trigger-like objects implemented using coroutines.

This converts a _wait abstract method into a suitable __await__.

async _wait()[source]

Should be implemented by the sub-class. Called by await self to convert the waitable object into a coroutine.

Testbench Structure

Clock

class cocotb.clock.Clock(signal, period, units='step')[source]

Simple 50:50 duty cycle clock driver.

Instances of this class should call its start() method and pass the coroutine object to one of the functions in Task Management.

This will create a clocking task that drives the signal at the desired period/frequency.

Example:

c = Clock(dut.clk, 10, 'ns')
await cocotb.start(c.start())
Parameters:
  • signal – The clock pin/signal to be driven.

  • period (int) – The clock period. Must convert to an even number of timesteps.

  • units (str, optional) – One of 'step', 'fs', 'ps', 'ns', 'us', 'ms', 'sec'. When units is 'step', the timestep is determined by the simulator (see COCOTB_HDL_TIMEPRECISION).

If you need more features like a phase shift and an asymmetric duty cycle, it is simple to create your own clock generator (that you then start()):

async def custom_clock():
    # pre-construct triggers for performance
    high_time = Timer(high_delay, units="ns")
    low_time = Timer(low_delay, units="ns")
    await Timer(initial_delay, units="ns")
    while True:
        dut.clk.value = 1
        await high_time
        dut.clk.value = 0
        await low_time

If you also want to change the timing during simulation, use this slightly more inefficient example instead where the Timers inside the while loop are created with current delay values:

async def custom_clock():
    while True:
        dut.clk.value = 1
        await Timer(high_delay, units="ns")
        dut.clk.value = 0
        await Timer(low_delay, units="ns")

high_delay = low_delay = 100
await cocotb.start(custom_clock())
await Timer(1000, units="ns")
high_delay = low_delay = 10  # change the clock speed
await Timer(1000, units="ns")

Changed in version 1.5: Support 'step' as the units argument to mean “simulator time step”.

Deprecated since version 1.5: Using None as the units argument is deprecated, use 'step' instead.

async start(cycles=None, start_high=True)[source]

Clocking coroutine. Start driving your clock by cocotb.start()ing a call to this.

Parameters:
  • cycles (int, optional) – Cycle the clock cycles number of times, or if None then cycle the clock forever. Note: 0 is not the same as None, as 0 will cycle no times.

  • start_high (bool, optional) –

    Whether to start the clock with a 1 for the first half of the period. Default is True.

    Added in version 1.3.

Utilities

Collection of handy functions.

cocotb.utils.get_sim_time(units='step')[source]

Retrieves the simulation time from the simulator.

Parameters:

units (str) –

String specifying the units of the result (one of 'step', 'fs', 'ps', 'ns', 'us', 'ms', 'sec'). 'step' will return the raw simulation time.

Deprecated since version 1.6.0: Using None as the units argument is deprecated, use 'step' instead.

Returns:

The simulation time in the specified units.

Return type:

int

Changed in version 1.6.0: Support 'step' as the the units argument to mean “simulator time step”.

cocotb.utils.get_time_from_sim_steps(steps, units)[source]

Calculates simulation time in the specified units from the steps based on the simulator precision.

Parameters:
  • steps (int) – Number of simulation steps.

  • units (str) – String specifying the units of the result (one of 'fs', 'ps', 'ns', 'us', 'ms', 'sec').

Returns:

The simulation time in the specified units.

Return type:

int

cocotb.utils.get_sim_steps(time, units='step', *, round_mode='error')[source]

Calculates the number of simulation time steps for a given amount of time.

When round_mode is "error", a ValueError is thrown if the value cannot be accurately represented in terms of simulator time steps. When round_mode is "round", "ceil", or "floor", the corresponding rounding function from the standard library will be used to round to a simulator time step.

Parameters:
  • time (Real | Decimal) – The value to convert to simulation time steps.

  • units (str) – String specifying the units of the result (one of 'step', 'fs', 'ps', 'ns', 'us', 'ms', 'sec'). 'step' means time is already in simulation time steps.

  • round_mode (str) – String specifying how to handle time values that sit between time steps (one of 'error', 'round', 'ceil', 'floor').

Returns:

The number of simulation time steps.

Raises:

ValueError – if the value cannot be represented accurately in terms of simulator time steps when round_mode is "error".

Return type:

int

Changed in version 1.5: Support 'step' as the units argument to mean “simulator time step”.

Changed in version 1.6: Support rounding modes.

cocotb.utils.pack(ctypes_obj)[source]

Convert a ctypes structure into a Python string.

Parameters:

ctypes_obj (ctypes.Structure) – The ctypes structure to convert to a string.

Returns:

New Python string containing the bytes from memory holding ctypes_obj.

Deprecated since version 1.5: This function is deprecated, use bytes(ctypes_obj) instead.

cocotb.utils.unpack(ctypes_obj, string, bytes=None)[source]

Unpack a Python string into a ctypes structure.

If the length of string is not the correct size for the memory footprint of the ctypes structure then the bytes keyword argument must be used.

Parameters:
  • ctypes_obj (ctypes.Structure) – The ctypes structure to pack into.

  • string (str) – String to copy over the ctypes_obj memory space.

  • bytes (int, optional) – Number of bytes to copy. Defaults to None, meaning the length of string is used.

Raises:
  • ValueError – If length of string and size of ctypes_obj are not equal.

  • MemoryError – If bytes is longer than size of ctypes_obj.

Deprecated since version 1.5: Converting bytes to a ctypes object should be done with from_buffer_copy(). If you need to assign bytes into an existing ctypes object, use memoryview(ctypes_obj).cast('B')[:bytes] = string, see memoryview for details.

cocotb.utils.hexdump(x)[source]

Hexdump a buffer.

Parameters:

x (bytes) – Object that supports conversion to bytes.

Returns:

A string containing the hexdump.

Return type:

str

Deprecated since version 1.4: Passing a str to this function is deprecated, as it is not an appropriate type for binary data. Doing so anyway will encode the string to latin1.

Deprecated since version 1.6.0: The function will be removed in the next major version. Use scapy.utils.hexdump() instead.

Example

>>> print(hexdump(b'this somewhat long string'))
0000   74 68 69 73 20 73 6F 6D 65 77 68 61 74 20 6C 6F   this somewhat lo
0010   6E 67 20 73 74 72 69 6E 67                        ng string
cocotb.utils.hexdiffs(x, y)[source]

Return a diff string showing differences between two binary strings.

Parameters:
  • x (bytes) – Object that supports conversion to bytes.

  • y (bytes) – Object that supports conversion to bytes.

Return type:

str

Deprecated since version 1.4: Passing strs to this function is deprecated, as it is not an appropriate type for binary data. Doing so anyway will encode the string to latin1.

Deprecated since version 1.6.0: The function will be removed in the next major version. Use scapy.utils.hexdiff() instead.

Example

>>> print(hexdiffs(b'a', b'b'))
0000      61                                               a
     0000 62                                               b

>>> print(hexdiffs(b'this short thing', b'this also short'))
0000      746869732073686F 7274207468696E67 this short thing
     0000 7468697320616C73 6F  2073686F7274 this also  short
class cocotb.utils.ParametrizedSingleton(*args, **kwargs)[source]

A metaclass that allows class construction to reuse an existing instance.

We use this so that RisingEdge(sig) and Join(coroutine) always return the same instance, rather than creating new copies.

cocotb.utils.reject_remaining_kwargs(name, kwargs)[source]

Helper function to emulate Python 3 keyword-only arguments.

Use as:

def func(x1, **kwargs):
    a = kwargs.pop('a', 1)
    b = kwargs.pop('b', 2)
    reject_remaining_kwargs('func', kwargs)
    ...

To emulate the Python 3 syntax:

def func(x1, *, a=1, b=2):
    ...

Deprecated since version 1.4: Since the minimum supported Python version is now 3.5, this function is not needed.

class cocotb.utils.lazy_property(fget)[source]

A property that is executed the first time, then cached forever.

It does this by replacing itself on the instance, which works because unlike @property it does not define __set__.

This should be used for expensive members of objects that are not always used.

cocotb.utils.want_color_output()[source]

Return True if colored output is possible/requested and not running in GUI.

Colored output can be explicitly requested by setting COCOTB_ANSI_OUTPUT to 1.

cocotb.utils.remove_traceback_frames(tb_or_exc, frame_names)[source]

Strip leading frames from a traceback

Parameters:
  • tb_or_exc (Union[traceback, BaseException, exc_info]) – Object to strip frames from. If an exception is passed, creates a copy of the exception with a new shorter traceback. If a tuple from sys.exc_info is passed, returns the same tuple with the traceback shortened

  • frame_names (List[str]) – Names of the frames to strip, which must be present.

cocotb.utils.walk_coro_stack(coro)[source]

Walk down the coroutine stack, starting at coro.

Supports coroutines and generators.

cocotb.utils.extract_coro_stack(coro, limit=None)[source]

Create a list of pre-processed entries from the coroutine stack.

This is based on traceback.extract_tb().

If limit is omitted or None, all entries are extracted. The list is a traceback.StackSummary object, and each entry in the list is a traceback.FrameSummary object containing attributes filename, lineno, name, and line representing the information that is usually printed for a stack trace. The line is a string with leading and trailing whitespace stripped; if the source is not available it is None.

Logging

cocotb.log.default_config()[source]

Apply the default cocotb log formatting to the root logger.

This hooks up the logger to write to stdout, using either SimColourLogFormatter or SimLogFormatter depending on whether colored output is requested. It also adds a SimTimeContextFilter filter so that created_sim_time is available to the formatter.

The logging level for cocotb logs is set based on the COCOTB_LOG_LEVEL environment variable, which defaults to INFO.

If desired, this logging configuration can be overwritten by calling logging.basicConfig(..., force=True) (in Python 3.8 onwards), or by manually resetting the root logger instance. An example of this can be found in the section on Rotating Log Files.

Added in version 1.4.

class cocotb.log.SimLogFormatter[source]

Bases: Formatter

Log formatter to provide consistent log message handling.

This will only add simulator timestamps if the handler object this formatter is attached to has a SimTimeContextFilter filter attached, which cocotb ensures by default.

Takes no arguments.

class cocotb.log.SimColourLogFormatter[source]

Bases: SimLogFormatter

Log formatter to provide consistent log message handling.

Takes no arguments.

class cocotb.log.SimTimeContextFilter[source]

Bases: Filter

A filter to inject simulator times into the log records.

This uses the approach described in the Python logging cookbook.

This adds the created_sim_time attribute.

Added in version 1.4.

logging.LogRecord.created_sim_time

The result of get_sim_time() at the point the log was created (in simulator units). The formatter is responsible for converting this to something like nanoseconds via get_time_from_sim_steps().

This is added by cocotb.log.SimTimeContextFilter.

Simulation Object Handles

The class inheritance diagram for cocotb.handle
class cocotb.handle.SimHandleBase(handle, path)[source]

Bases: object

Base class for all simulation objects.

We maintain a handle which we can use for GPI calls.

Parameters:
  • handle (int) – The GPI handle to the simulator object.

  • path (str) – Path to this handle, None if root.

_name: str

The name of an object.

_type: str

The type of an object as a string.

_path: str

The path to this handle, or its name if this is the root handle.

_def_name: str

The name of a GPI object’s definition.

This is the value of vpiDefName for VPI, vhpiNameP for VHPI, and mti_GetPrimaryName for FLI. Support for this depends on the specific object type and simulator used.

_def_file: str

The name of the file that sources the object’s definition.

This is the value of vpiDefFile for VPI, vhpiFileNameP for VHPI, and mti_GetRegionSourceName for FLI. Support for this depends on the specific object type and simulator used.

__len__()[source]

Return the “length” (the number of elements) of the underlying object.

For vectors this is the number of bits.

class cocotb.handle.RegionObject(handle, path)[source]

Bases: SimHandleBase

A region object, such as a scope or namespace.

Region objects don’t have values, they are effectively scopes or namespaces.

Parameters:
  • handle (int) – The GPI handle to the simulator object.

  • path (str) – Path to this handle, None if root.

class cocotb.handle.HierarchyObject(handle, path)[source]

Bases: RegionObject

Hierarchy objects are namespace/scope objects.

Parameters:
  • handle (int) – The GPI handle to the simulator object.

  • path (str) – Path to this handle, None if root.

_id(name, extended=True)[source]

Query the simulator for an object with the specified name, and cache the result to build a tree of objects.

If extended is True, run the query only for VHDL extended identifiers. For Verilog, only extended=False is supported.

Parameters:

extended (bool)

class cocotb.handle.HierarchyArrayObject(handle, path)[source]

Bases: RegionObject

Hierarchy Arrays are containers of Hierarchy Objects.

Parameters:
  • handle (int) – The GPI handle to the simulator object.

  • path (str) – Path to this handle, None if root.

__len__()[source]

Return the “length” of the generate block.

class cocotb.handle.NonHierarchyObject(handle, path)[source]

Bases: SimHandleBase

Common base class for all non-hierarchy objects.

Parameters:
  • handle (int) – The GPI handle to the simulator object.

  • path (str) – Path to this handle, None if root.

property value

The value of this simulation object.

Note

When setting this property, the value is stored by the Scheduler and all stored values are written at the same time at the end of the current simulator time step.

Use setimmediatevalue() to set the value immediately.

setimmediatevalue(value)[source]

Assign a value to this simulation object immediately.

class cocotb.handle.ConstantObject(handle, path, handle_type)[source]

Bases: NonHierarchyObject

An object which has a value that can be read, but not set.

The value is cached in the class since it is fixed at elaboration time and won’t change within a simulation.

Parameters:
  • handle (int) – The GPI handle to the simulator object.

  • path (str) – Path to this handle, None if root.

  • handle_type – The type of the handle (simulator.INTEGER, simulator.ENUM, simulator.REAL, simulator.STRING).

property value

The value of this simulation object.

class cocotb.handle.NonHierarchyIndexableObject(handle, path)[source]

Bases: NonHierarchyObject

A non-hierarchy indexable object.

Getting and setting the current value of an array is done by iterating through sub-handles in left-to-right order.

Given an HDL array arr:

Verilog

VHDL

arr.value is equivalent to

arr[4:7]

arr(4 to 7)

[arr[4].value, arr[5].value, arr[6].value, arr[7].value]

arr[7:4]

arr(7 downto 4)

[arr[7].value, arr[6].value, arr[5].value, arr[4].value]

When setting the signal as in arr.value = ..., the same index equivalence as noted in the table holds.

Warning

Assigning a value to a sub-handle:

  • Wrong: dut.some_array.value[0] = 1 (gets value as a list then updates index 0)

  • Correct: dut.some_array[0].value = 1

Parameters:
  • handle (int) – The GPI handle to the simulator object.

  • path (str) – Path to this handle, None if root.

property value: list

The value of this simulation object.

Note

When setting this property, the value is stored by the Scheduler and all stored values are written at the same time at the end of the current simulator time step.

Use setimmediatevalue() to set the value immediately.

class cocotb.handle.NonConstantObject(handle, path)[source]

Bases: NonHierarchyIndexableObject

A non-constant object

Parameters:
  • handle (int) – The GPI handle to the simulator object.

  • path (str) – Path to this handle, None if root.

drivers()[source]

An iterator for gathering all drivers for a signal.

This is currently only available for VPI. Also, only a few simulators implement this.

loads()[source]

An iterator for gathering all loads on a signal.

This is currently only available for VPI. Also, only a few simulators implement this.

class cocotb.handle.ModifiableObject(handle, path)[source]

Bases: NonConstantObject

Base class for simulator objects whose values can be modified.

Parameters:
  • handle (int) – The GPI handle to the simulator object.

  • path (str) – Path to this handle, None if root.

property value: BinaryValue

The value of this simulation object.

Note

When setting this property, the value is stored by the Scheduler and all stored values are written at the same time at the end of the current simulator time step.

Use setimmediatevalue() to set the value immediately.

class cocotb.handle.RealObject(handle, path)[source]

Bases: ModifiableObject

Specific object handle for Real signals and variables.

Parameters:
  • handle (int) – The GPI handle to the simulator object.

  • path (str) – Path to this handle, None if root.

property value: float

The value of this simulation object.

Note

When setting this property, the value is stored by the Scheduler and all stored values are written at the same time at the end of the current simulator time step.

Use setimmediatevalue() to set the value immediately.

class cocotb.handle.EnumObject(handle, path)[source]

Bases: ModifiableObject

Specific object handle for enumeration signals and variables.

Parameters:
  • handle (int) – The GPI handle to the simulator object.

  • path (str) – Path to this handle, None if root.

property value: int

The value of this simulation object.

Note

When setting this property, the value is stored by the Scheduler and all stored values are written at the same time at the end of the current simulator time step.

Use setimmediatevalue() to set the value immediately.

class cocotb.handle.IntegerObject(handle, path)[source]

Bases: ModifiableObject

Specific object handle for integer and enumeration signals and variables.

Parameters:
  • handle (int) – The GPI handle to the simulator object.

  • path (str) – Path to this handle, None if root.

property value: int

The value of this simulation object.

Note

When setting this property, the value is stored by the Scheduler and all stored values are written at the same time at the end of the current simulator time step.

Use setimmediatevalue() to set the value immediately.

class cocotb.handle.StringObject(handle, path)[source]

Bases: ModifiableObject

Specific object handle for String variables.

Parameters:
  • handle (int) – The GPI handle to the simulator object.

  • path (str) – Path to this handle, None if root.

property value: bytes

The value of this simulation object.

Note

When setting this property, the value is stored by the Scheduler and all stored values are written at the same time at the end of the current simulator time step.

Use setimmediatevalue() to set the value immediately.

cocotb.handle.SimHandle(handle, path=None)[source]

Factory function to create the correct type of SimHandle object.

Parameters:
  • handle (int) – The GPI handle to the simulator object.

  • path (str) – Path to this handle, None if root.

Returns:

The SimHandle object.

Raises:

NotImplementedError – If no matching object for GPI type could be found.

Assignment Methods

class cocotb.handle.Deposit(value)[source]

Action used for placing a value into a given handle.

class cocotb.handle.Force(value)[source]

Action used to force a handle to a given value until a release is applied.

class cocotb.handle.Freeze[source]

Action used to make a handle keep its current value until a release is used.

class cocotb.handle.Release[source]

Action used to stop the effects of a previously applied force/freeze action.

Other Handle Methods

len(handle)

Return the “length” (the number of elements) of the underlying object.

For vectors this is the number of bits.

dir(handle)

Return a list of the sub-handles of handle, that is, the instances, signals, constants etc. of a certain hierarchy level in the DUT.

Miscellaneous

Asynchronous Queues

exception cocotb.queue.QueueFull[source]

Raised when the Queue.put_nowait() method is called on a full Queue.

exception cocotb.queue.QueueEmpty[source]

Raised when the Queue.get_nowait() method is called on a empty Queue.

class cocotb.queue.Queue(maxsize=0)[source]

A queue, useful for coordinating producer and consumer coroutines.

If maxsize is less than or equal to 0, the queue size is infinite. If it is an integer greater than 0, then put() will block when the queue reaches maxsize, until an item is removed by get().

Parameters:

maxsize (int)

qsize()[source]

Number of items in the queue.

Return type:

int

property maxsize: int

Number of items allowed in the queue.

empty()[source]

Return True if the queue is empty, False otherwise.

Return type:

bool

full()[source]

Return True if there are maxsize() items in the queue.

Note

If the Queue was initialized with maxsize=0 (the default), then full() is never True.

Return type:

bool

async put(item)[source]

Put an item into the queue.

If the queue is full, wait until a free slot is available before adding the item.

Parameters:

item (T)

Return type:

None

put_nowait(item)[source]

Put an item into the queue without blocking.

If no free slot is immediately available, raise asyncio.QueueFull.

Parameters:

item (T)

Return type:

None

async get()[source]

Remove and return an item from the queue.

If the queue is empty, wait until an item is available.

Return type:

T

get_nowait()[source]

Remove and return an item from the queue.

Return an item if one is immediately available, else raise asyncio.QueueEmpty.

Return type:

T

class cocotb.queue.PriorityQueue(maxsize=0)[source]

A subclass of Queue; retrieves entries in priority order (smallest item first).

Entries are typically tuples of the form (priority number, data).

Parameters:

maxsize (int)

class cocotb.queue.LifoQueue(maxsize=0)[source]

A subclass of Queue; retrieves most recently added entries first.

Parameters:

maxsize (int)

Other Runtime Information

cocotb.argv: List[str] | None = None

The argument list as seen by the simulator.

This is guaranteed to hold a value at test time.

cocotb.SIM_NAME: str | None = None

The running simulator product information.

None if cocotb was not loaded from a simulator.

cocotb.SIM_VERSION: str | None = None

The version of the running simulator.

None if cocotb was not loaded from a simulator.

cocotb.RANDOM_SEED: int | None = None

The value passed to the Python default random number generator.

See RANDOM_SEED for details on how the value is computed. This is guaranteed to hold a value at test time.

cocotb.plusargs: Dict[str, bool | str] | None = None

A dictionary of “plusargs” handed to the simulation.

See PLUSARGS for details. This is guaranteed to hold a value at test time.

cocotb.LANGUAGE: str | None = None

The value of TOPLEVEL_LANG.

This is guaranteed to hold a value at test time.

cocotb.top: SimHandleBase | None = None

A handle to the TOPLEVEL entity/module.

This is equivalent to the DUT parameter given to cocotb tests, so it can be used wherever that variable can be used. It is particularly useful for extracting information about the DUT in module-level class and function definitions; and in parameters to TestFactorys. None if cocotb was not loaded from a simulator.

Signal Tracer for WaveDrom

class cocotb.wavedrom.Wavedrom(obj, name='')[source]

Base class for a WaveDrom compatible tracer.

sample()[source]

Record a sample of the signal value at this point in time.

clear()[source]

Delete all sampled data.

get(add_clock=True)[source]

Return the samples as a list suitable for use with WaveDrom.

class cocotb.wavedrom.trace(*args, clk=None)[source]

Context manager to enable tracing of signals.

Arguments are an arbitrary number of signals or buses to trace. We also require a clock to sample on, passed in as a keyword argument.

Usage:

with trace(sig1, sig2, a_bus, clk=clk) as waves:
    # Stuff happens, we trace it

    # Dump to JSON format compatible with WaveDrom
    j = waves.dumpj()

Implementation Details

Note

In general, nothing in this section should be interacted with directly - these components work mostly behind the scenes.

The Scheduler

cocotb.scheduler: Scheduler | None = None

The global scheduler instance.

This is guaranteed to hold a value at test time.

class cocotb.scheduler.Scheduler(handle_result)[source]

The main scheduler.

Here we accept callbacks from the simulator and schedule the appropriate coroutines.

A callback fires, causing the react method to be called, with the trigger that caused the callback as the first argument.

We look up a list of coroutines to schedule (indexed by the trigger) and schedule them in turn.

Attention

Implementors should not depend on the scheduling order!

Some additional management is required since coroutines can return a list of triggers, to be scheduled when any one of the triggers fires. To ensure we don’t receive spurious callbacks, we have to un-prime all the other triggers when any one fires.

Due to the simulator nuances and fun with delta delays we have the following modes:

Normal mode
  • Callbacks cause coroutines to be scheduled

  • Any pending writes are cached and do not happen immediately

ReadOnly mode
  • Corresponds to cbReadOnlySynch (VPI) or vhpiCbRepEndOfTimeStep (VHPI). In this state we are not allowed to perform writes.

Write mode
  • Corresponds to cbReadWriteSynch (VPI) or vhpiCbRepLastKnownDeltaCycle (VHPI) In this mode we play back all the cached write updates.

We can legally transition from Normal to Write by registering a ReadWrite callback, however usually once a simulator has entered the ReadOnly phase of a given timestep then we must move to a new timestep before performing any writes. The mechanism for moving to a new timestep may not be consistent across simulators and therefore we provide an abstraction to assist with compatibility.

Unless a coroutine has explicitly requested to be scheduled in ReadOnly mode (for example wanting to sample the finally settled value after all delta delays) then it can reasonably be expected to be scheduled during “normal mode” i.e. where writes are permitted.

Parameters:

handle_result (Callable[[Task], None])

react(trigger)[source]

Deprecated since version 1.5: This function is now private.

unschedule(coro)[source]

Deprecated since version 1.5: This function is now private.

queue(coroutine)[source]

Deprecated since version 1.5: This function is now private.

queue_function(coro)[source]

Deprecated since version 1.5: This function is now private.

run_in_executor(func, *args, **kwargs)[source]

Deprecated since version 1.5: This function is now private.

static create_task(coroutine)[source]

Check to see if the given object is a schedulable coroutine object and if so, return it.

Parameters:

coroutine (Any)

Return type:

Task

start_soon(coro)[source]

Schedule a coroutine to be run concurrently, starting after the current coroutine yields control.

In contrast to fork() which starts the given coroutine immediately, this function starts the given coroutine only after the current coroutine yields control. This is useful when the coroutine to be forked has logic before the first await that may not be safe to execute immediately.

Added in version 1.5.

Parameters:

coro (Coroutine | Task)

Return type:

Task

add_test(test_coro)[source]

Deprecated since version 1.5: This function is now private.

schedule(coroutine, trigger=None)[source]

Deprecated since version 1.5: This function is now private.

finish_test(exc)[source]

Deprecated since version 1.5: This function is now private.

finish_scheduler(exc)[source]

Deprecated since version 1.5: This function is now private.

cleanup()[source]

Deprecated since version 1.5: This function is now private.

The Regression Manager

cocotb.regression_manager: RegressionManager | None = None

The global regression manager instance.

This is guaranteed to hold a value at test time.

class cocotb.regression.RegressionManager(dut, tests)[source]

Encapsulates all regression capability into a single place

Parameters:
  • dut (SimHandle) – The root handle to pass into test functions.

  • tests (Iterable[Test]) – tests to run

classmethod from_discovery(dut)[source]

Obtains the test list by discovery.

See MODULE and TESTCASE for details on how tests are discovered.

Parameters:

dut (SimHandle) – The root handle to pass into test functions.

The cocotb.simulator module

This module is a Python wrapper to libgpi. It should not be considered public API, but is documented here for developers of cocotb.

cocotb.simulator.get_precision() int

Get the precision of the simulator in powers of 10.

For example, if -12 is returned, the simulator’s time precision is 10**-12 or 1 ps.

cocotb.simulator.get_root_handle(name: str) cocotb.simulator.gpi_sim_hdl

Get the root handle.

cocotb.simulator.get_sim_time() Tuple[int, int]

Get the current simulation time.

Time is represented as a tuple of 32 bit integers ([low32, high32]) comprising a single 64 bit integer.

cocotb.simulator.get_simulator_product() str

Get the simulator’s product string.

cocotb.simulator.get_simulator_version() str

Get the simulator’s product version string.

class cocotb.simulator.gpi_cb_hdl

GPI callback handle

deregister() None

De-register this callback.

class cocotb.simulator.gpi_iterator_hdl

GPI iterator handle.

class cocotb.simulator.gpi_sim_hdl

GPI object handle

Contains methods for getting and setting the value of a GPI object, and introspection.

get_const() bool

Return True if the object is a constant.

get_definition_file() str

Get the file that sources the object’s definition.

get_definition_name() str

Get the name of a GPI object’s definition.

get_handle_by_index(index: int) cocotb.simulator.gpi_sim_hdl

Get a handle to a child object by index.

get_handle_by_name(name: str) cocotb.simulator.gpi_sim_hdl

Get a handle to a child object by name.

get_name_string() str

Get the name of an object as a string.

get_num_elems() int

Get the number of elements contained in the handle.

get_range() Tuple[int, int]

Get the range of elements (tuple) contained in the handle, return None if not indexable.

get_signal_val_binstr() str

Get the value of a logic vector signal as a string of (0, 1, X, etc.), one element per character.

get_signal_val_long() int

Get the value of a signal as an integer.

get_signal_val_real() float

Get the value of a signal as a float.

get_signal_val_str() bytes

Get the value of a signal as a byte string.

get_type() int

Get the GPI type of an object as an enum.

get_type_string() str

Get the GPI type of an object as a string.

iterate(mode: int) cocotb.simulator.gpi_iterator_hdl

Get an iterator handle to loop over all members in an object.

set_signal_val_binstr(action: int, value: str) None

Set the value of a logic vector signal using a string of (0, 1, X, etc.), one element per character.

set_signal_val_int(action, value, /)

Set the value of a signal using an int

set_signal_val_real(action: int, value: float) None

Set the value of a signal using a float.

set_signal_val_str(action: int, value: bytes) None

Set the value of a signal using a user-encoded string.

cocotb.simulator.is_running() bool

Returns True if the caller is running within a simulator.

Added in version 1.4.

cocotb.simulator.log_level(level: int) None

Set the log level for GPI.

cocotb.simulator.log_msg(name: str, path: str, funcname: str, lineno: int, msg: str) None

Log a message.

cocotb.simulator.register_nextstep_callback(func: Callable[..., None], *args: Any) cocotb.simulator.gpi_cb_hdl

Register a callback for the cbNextSimTime callback.

cocotb.simulator.register_readonly_callback(func: Callable[..., None], *args: Any) cocotb.simulator.gpi_cb_hdl

Register a callback for the read-only section.

cocotb.simulator.register_rwsynch_callback(func: Callable[..., None], *args: Any) cocotb.simulator.gpi_cb_hdl

Register a callback for the read-write section.

cocotb.simulator.register_timed_callback(time: int, func: Callable[..., None], *args: Any) cocotb.simulator.gpi_cb_hdl

Register a timed callback.

cocotb.simulator.register_value_change_callback(signal: cocotb.simulator.gpi_sim_hdl, func: Callable[..., None], edge: int, *args: Any) cocotb.simulator.gpi_cb_hdl

Register a signal change callback.

cocotb.simulator.stop_simulator() None

Instruct the attached simulator to stop. Users should not call this function.

The cocotb-config script

cocotb-config - CLI interface

cocotb-config [-h] [--prefix] [--share] [--makefiles] [--python-bin] [--help-vars]
              [--libpython] [--lib-dir] [--lib-name INTERFACE SIMULATOR]
              [--lib-name-path INTERFACE SIMULATOR] [-v]
cocotb-config options
  • -h, --help - show this help message and exit

  • --prefix - echo the package-prefix of cocotb (default: None)

  • --share - echo the package-share of cocotb (default: None)

  • --makefiles - echo the package-makefiles of cocotb (default: None)

  • --python-bin - echo the path to the Python binary cocotb is installed for (default: None)

  • --help-vars - show help about supported variables (default: None)

  • --libpython - Print the absolute path to the libpython associated with the current Python installation (default: None)

  • --lib-dir - Print the absolute path to the interface libraries location (default: None)

  • --lib-name INTERFACE - Print the name of interface library for given interface (VPI/VHPI/FLI) and simulator (default: None)

  • --lib-name-path INTERFACE - Print the absolute path of interface library for given interface (VPI/VHPI/FLI) and simulator (default: None)

  • -v, --version - echo the version of cocotb (default: None)