Library Reference

Test Results

The following exceptions can be raised at any point by any code and will terminate the test:

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

Exceptions are used to pass test results around.

class cocotb.result.TestError(*args, **kwargs)[source]
class cocotb.result.TestFailure(*args, **kwargs)[source]
class cocotb.result.TestSuccess(*args, **kwargs)[source]

Writing and Generating tests

class cocotb.test(timeout=None, expect_fail=False, expect_error=False, skip=False)[source]

Decorator to mark a function as a test

All tests are coroutines. The test decorator provides some common reporting etc, a test timeout and allows us to mark tests as expected failures.

KWargs:
timeout: (int)
value representing simulation timeout (not implemented)
expect_fail: (bool):
Don’t mark the result as a failure if the test fails
expect_error: (bool):
Don’t make the result as an error if an error is raised This is for cocotb internal regression use
skip: (bool):
Don’t execute this test as part of the regression
class cocotb.coroutine(func)[source]

Decorator class that allows us to provide common coroutine mechanisms:

log methods will will log to cocotb.coroutines.name

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

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

Used to automatically generate tests.

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 and idles and have some packet generations routines gen_a and gen_b.

>>> tf = TestFactory(run_test)
>>> tf.add_option('data_in', [gen_a, gen_b])
>>> tf.add_option('backpressure', [None, random_backpressure])
>>> tf.add_option('idles', [None, random_idles])
>>> tf.generate_tests()
We would get the following tests:
  • gen_a with no backpressure and no idles
  • gen_a with no backpressure and random_idles
  • gen_a with random_backpressure and no idles
  • gen_a with random_backpressure and random_idles
  • gen_b with no backpressure and no idles
  • gen_b with no backpressure and random_idles
  • gen_b with random_backpressure and no idles
  • gen_b with random_backpressure and random_idles

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.

add_option(name, optionlist)[source]

Add a named option to the test.

Args:
name (string): name of the option. passed to test as a keyword
argument

optionlist (list): A list of possible options for this test knob

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

Generates exhasutive set of tests using the cartesian product of the possible keyword arguments.

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

Args:
prefix: 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: 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

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

Represenatation of values in binary format.

The underlying value can be set or accessed using three aliasing attributes

  • BinaryValue.integer is an integer
  • BinaryValue.signed_integer is a signed integer
  • BinaryValue.binstr is a string of “01xXzZ”
  • BinaryValue.buff is a binary buffer of bytes
  • BinaryValue.value is an integer * deprecated *

For example:

>>> vec = BinaryValue()
>>> vec.integer = 42
>>> print vec.binstr
101010
>>> print repr(vec.buff)
'*'
assign(value)[source]

Decides how best to assign the value to the vector

We possibly try to be a bit too clever here by first of all trying to assign the raw string as a binstring, however if the string contains any characters that aren’t 0, 1, X or Z then we interpret the string as a binary buffer...

binstr

Access to the binary string

buff

Access to the value as a buffer

get_binstr()[source]

Attribute binstr is the binary representation stored as a string of 1s and 0s

get_buff()[source]

Attribute self.buff represents the value as a binary string buffer

>>> "0100000100101111".buff == "A/"
True
get_value()[source]

value is an integer representaion of the underlying vector

get_value_signed()[source]

value is an signed integer representaion of the underlying vector

integer

Integer access to the value

signed_integer

Signed integer access to the value

value

Integer access to the value * deprecated *

class cocotb.bus.Bus(entity, name, signals, optional_signals=[])[source]

Wraps up a collection of signals

Assumes we have a set of signals/nets named:

entity.bus_name_signal
for example a bus named “stream_in” with signals [“valid”, “data”]
dut.stream_in_valid dut.stream_in_data
TODO:
Support for struct/record ports where signals are member names
drive(obj, strict=False)[source]

Drives values onto the bus.

Args:
obj (any type) : object with attribute names that match the bus
signals
Kwargs:
strict (bool) : Check that all signals are being assigned
Raises:
AttributeError

Triggers

Triggers are used to indicate when the scheduler should resume coroutine execution. Typically a coroutine will yield a trigger or a list of triggers.

Simulation Timing

class cocotb.triggers.Timer(time_ps, units=None)[source]

Execution will resume when the specified time period expires

Consumes simulation time

class cocotb.triggers.ReadOnly[source]

Python Triggers

class cocotb.triggers.Event(name='')[source]

Event to permit synchronisation between two coroutines

clear()[source]

Clear this event that’s fired.

Subsequent calls to wait will block until set() is called again

set(data=None)[source]

Wake up any coroutines blocked on this event

wait()[source]

This can be yielded to block this coroutine until another wakes it

class cocotb.triggers.Lock(name='')[source]

Lock primitive (not re-entrant)

acquire()[source]

This can be yielded to block until the lock is acquired

class cocotb.triggers.Join[source]

Testbench Structure

class cocotb.drivers.Driver[source]

Class defining the standard interface for a driver within a testbench

The driver is responsible for serialising transactions onto the physical pins of the interface. This may consume simulation time.

append(transaction, callback=None, event=None)[source]

Queue up a transaction to be sent over the bus.

Mechanisms are provided to permit the caller to know when the transaction is processed

callback: optional function to be called when the transaction has been sent

event: event to be set when the tansaction has been sent

clear()[source]

Clear any queued transactions without sending them onto the bus

class cocotb.monitors.Monitor(callback=None, event=None)[source]
class cocotb.scoreboard.Scoreboard(dut, reorder_depth=0, fail_immediately=True)[source]

Generic scoreboarding class

We can add interfaces by providing a monitor and an expected output queue

The expected output can either be a function which provides a transaction or a simple list containing the expected output.

TODO:
Statistics for end-of-test summary etc.
add_interface(monitor, expected_output, compare_fn=None, reorder_depth=0, strict_type=True)[source]

Add an interface to be scoreboarded.

Provides a function which the monitor will callback with received transactions

Simply check against the expected output.

compare(got, exp, log, strict_type=True)[source]

Common function for comparing two transactions.

Can be re-implemented by a subclass.

result

Determine the test result, do we have any pending data remaining?