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, stage=None)[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
stage: (int)
Order tests logically into stages, where multiple tests can share a stage
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.

Parameters:
  • 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 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 – 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.
class cocotb.hook[source]

Decorator to mark a function as a hook for cocotb

All hooks are run at the beginning of a cocotb test suite, prior to any test code being run.

Interacting with the Simulator

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 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 representation of the underlying vector

get_value_signed()[source]

value is an signed integer representation of the underlying vector

integer

Integer access to the value

n_bits

Access to the number of bits of the binary 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=[], bus_separator='_', array_idx=None)[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

capture()[source]

Capture the values from the bus, returning an object representing the capture

Returns:A dict that supports access by attribute, each attribute corresponds to each signal’s value
drive(obj, strict=False)[source]

Drives values onto the bus.

Parameters:obj (any type) – object with attribute names that match the bus signals
Kwargs:
strict (bool) : Check that all signals are being assigned
Raises:AttributeError
sample(obj, strict=False)[source]

Sample the values from the bus, assigning them to obj.

Parameters:obj (any type) – object with attribute names that match the bus signals
Kwargs:
strict (bool) : Check that all signals being sampled are present in obj
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(coroutine)[source]

Join a coroutine, firing when it exits

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.

_driver_send(transaction, sync=True)[source]

actual impementation of the send.

subclasses should override this method to implement the actual send routine

_send[source]

assumes the caller has already acquired the busy lock

releases busy lock once sending is complete

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

send[source]

Blocking send call (hence must be “yielded” rather than called)

Sends the transaction over the bus

Parameters:transaction (any) – the transaction to send
Kwargs:
sync (boolean): synchronise the transfer by waiting for risingedge

Monitor

class cocotb.monitors.Monitor(callback=None, event=None)[source]

Base class for Monitor objects. Monitors are passive ‘listening’ objects that monitor pins in or out of a DUT. This class should not be used directly, but should be subclassed and the internal _monitor_recv method should be overridden and decorated as a @coroutine. This _monitor_recv method should capture some behavior of the pins, form a transaction, and pass this transaction to the internal _recv method. The _monitor_recv method is added to the cocotb scheduler during the __init__ phase, so it should not be yielded anywhere.

The primary use of a Monitor is as an interface for a cocotb.scoreboard.Scoreboard.

Parameters:
  • callback (callable) – Callback to be called with each recovered transaction as the argument. If the callback isn’t used, received transactions will be placed on a queue and the event used to notify any consumers.
  • event (event) – Object that supports a set method that will be called when a transaction is received through the internal _recv method.
_monitor_recv[source]

actual impementation of the receiver

subclasses should override this method to implement the actual receive routine and call self._recv() with the recovered transaction

_recv(transaction)[source]

Common handling of a received transaction.

class cocotb.monitors.BusMonitor(entity, name, clock, reset=None, reset_n=None, callback=None, event=None, bus_separator='_')[source]

Wrapper providing common functionality for monitoring busses

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?

Utilities

cocotb.utils.exec_(_code_, _globs_=None, _locs_=None)[source]

Execute code in a namespace.

cocotb.utils.get_sim_steps(time, units=None)[source]

Calculates the number of Simulation time steps for a given amount of time

Parameters:time (int/float) – The value to convert to simulation time steps.
Kwargs:
units (str): String specifying the units of the result. (None,’fs’,’ps’,’ns’,’us’,’ms’,’sec’)
None means time is already in simulation time steps.
Returns:The number of simulation time steps
cocotb.utils.get_sim_time(units=None)[source]

Retrieves the simulation time from the simulator

Kwargs:
units (str): String specifying the units of the result. (None,’fs’,’ps’,’ns’,’us’,’ms’,’sec’)
None will return the raw simulation time.
Returns:The simulation time in the specified units
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. (‘fs’,’ps’,’ns’,’us’,’ms’,’sec’)
Returns:

The simulation time in the specified units

cocotb.utils.hexdiffs(x, y)[source]

Return a diff string showing differences between 2 binary strings

cocotb.utils.hexdump(x)[source]

Hexdump a buffer

cocotb.utils.pack(ctypes_obj)[source]

Convert a ctypes structure into a python string

Parameters:ctypes_obj (ctypes.Structure) – ctypes structure to convert to a string
Returns:New python string containing the bytes from memory holding ctypes_obj
cocotb.utils.unpack(ctypes_obj, string, bytes=None)[source]

Unpack a python string into a ctypes structure

Parameters:
  • ctypes_obj (ctypes.Structure) – ctypes structure to pack into
  • string (str) – String to copy over the ctypes_obj memory space
Kwargs:
bytes: Number of bytes to copy
Raises:ValueError, MemoryError

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

Simulation Object Handles

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

Factory function to create the correct type of SimHandle object

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

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

Bases: cocotb.handle.SimHandleBase

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

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

Bases: cocotb.handle.RegionObject

Hierarchy objects are namespace/scope objects

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

Bases: cocotb.handle.RegionObject

Hierarchy Array are containers of Hierarchy Objects

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

Bases: cocotb.handle.SimHandleBase

Common base class for all non-hierarchy objects

value

A reference to the value

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

Bases: cocotb.handle.NonHierarchyObject

Constant objects have a value that can be read, but not set.

We can also cache the value since it is elaboration time fixed and won’t change within a simulation

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

Bases: cocotb.handle.NonHierarchyObject

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

Bases: cocotb.handle.NonHierarchyIndexableObject

drivers()[source]

An iterator for gathering all drivers for a signal

loads()[source]

An iterator for gathering all loads on a signal

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

Bases: cocotb.handle.NonConstantObject

Base class for simulator objects whose values can be modified

setimmediatevalue(value)[source]

Set the value of the underlying simulation object to value.

Parameters:value (ctypes.Structure, cocotb.binary.BinaryValue, int, double) – The value to drive onto the simulator object
Raises:TypeError

This operation will fail unless the handle refers to a modifiable object eg net, signal or variable.

We determine the library call to make based on the type of the value

Assigning integers less than 32-bits is faster

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

Bases: cocotb.handle.ModifiableObject

Specific object handle for Real signals and variables

setimmediatevalue(value)[source]

Set the value of the underlying simulation object to value.

Parameters:value (float) – The value to drive onto the simulator object
Raises:TypeError

This operation will fail unless the handle refers to a modifiable object eg net, signal or variable.

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

Bases: cocotb.handle.ModifiableObject

Specific object handle for ENUM signals and variables

setimmediatevalue(value)[source]

Set the value of the underlying simulation object to value.

Parameters:value (int) – The value to drive onto the simulator object
Raises:TypeError

This operation will fail unless the handle refers to a modifiable object eg net, signal or variable.

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

Bases: cocotb.handle.ModifiableObject

Specific object handle for Integer and Enum signals and variables

setimmediatevalue(value)[source]

Set the value of the underlying simulation object to value.

Parameters:value (int) – The value to drive onto the simulator object
Raises:TypeError

This operation will fail unless the handle refers to a modifiable object eg net, signal or variable.

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

Bases: cocotb.handle.ModifiableObject

Specific object handle for String variables

setimmediatevalue(value)[source]

Set the value of the underlying simulation object to value.

Parameters:value (string) – The value to drive onto the simulator object
Raises:TypeError

This operation will fail unless the handle refers to a modifiable object eg net, signal or variable.

Implemented Testbench Structures

Drivers

AD9361

class cocotb.drivers.ad9361.AD9361(dut, rx_channels=1, tx_channels=1, tx_clock_half_period=16276, rx_clock_half_period=16276, loopback_queue_maxlen=16)[source]

classdocs

AMBA

Advanced Microcontroller Bus Archicture

class cocotb.drivers.amba.AXI4LiteMaster(entity, name, clock)[source]

AXI4-Lite Master

TODO: Kill all pending transactions if reset is asserted…

read[source]

Read from an address.

write[source]

Write a value to an address.

The *_latency KWargs allow control over the delta

Avalon

class cocotb.drivers.avalon.AvalonMM(entity, name, clock)[source]

Avalon-MM Driver

Currently we only support the mode required to communicate with SF avalon_mapper which is a limited subset of all the signals

Blocking operation is all that is supported at the moment, and for the near future as well Posted responses from a slave are not supported.

class cocotb.drivers.avalon.AvalonMaster(entity, name, clock)[source]

Avalon-MM master

read[source]

Issue a request to the bus and block until this comes back. Simulation time still progresses but syntactically it blocks. See http://www.altera.com/literature/manual/mnl_avalon_spec_1_3.pdf

write[source]

Issue a write to the given address with the specified value. See http://www.altera.com/literature/manual/mnl_avalon_spec_1_3.pdf

class cocotb.drivers.avalon.AvalonMemory(entity, name, clock, readlatency_min=1, readlatency_max=1, memory=None, avl_properties={})[source]

Emulate a memory, with back-door access

class cocotb.drivers.avalon.AvalonST(entity, name, clock, valid_generator=None)[source]
class cocotb.drivers.avalon.AvalonSTPkts(*args, **kwargs)[source]

OPB

class cocotb.drivers.opb.OPBMaster(entity, name, clock)[source]

On-chip peripheral bus master

read[source]

Issue a request to the bus and block until this comes back. Simulation time still progresses but syntactically it blocks.

write[source]

XGMII

class cocotb.drivers.xgmii.XGMII(signal, clock, interleaved=True)[source]

XGMII driver

idle()[source]

Helper to set bus to IDLE state

static layer1(packet)[source]

Take an Ethernet packet (as a string) and format as a layer 1 packet

Pads to 64-bytes, prepends preamble and appends 4-byte CRC on the end

terminate(index)[source]

Helper function to terminate from a provided lane index

Monitors

Avalon

class cocotb.monitors.avalon.AvalonST(entity, name, clock, reset=None, reset_n=None, callback=None, event=None, bus_separator='_')[source]

AvalonST bus.

Non-packetised so each valid word is a separate transaction

class cocotb.monitors.avalon.AvalonSTPkts(*args, **kwargs)[source]

Packetised AvalonST bus

XGMII

class cocotb.monitors.xgmii.XGMII(signal, clock, interleaved=True, callback=None, event=None)[source]

XGMII Monitor

Assumes a single vector, either 4 or 8 bytes plus control bit for each byte

If interleaved is true then the control bits are adjacent to the bytes