Triggers¶
Triggers are used to indicate when the cocotb scheduler should resume coroutine execution.
To use a trigger, a coroutine should await
or yield
it.
This will cause execution of the current coroutine to pause.
When the trigger fires, execution of the paused coroutine will resume:
@cocotb.coroutine
def coro():
print("Some time before the edge")
yield RisingEdge(clk)
print("Immediately after the edge")
Or using the syntax in Python 3.5 onwards:
@cocotb.coroutine
async def coro():
print("Some time before the edge")
await RisingEdge(clk)
print("Immediately after the edge")
Simulator Triggers¶
Signals¶
-
class
cocotb.triggers.
RisingEdge
(signal)[source]¶ Fires on the rising edge of signal, on a transition from
0
to1
.
-
class
cocotb.triggers.
FallingEdge
(signal)[source]¶ Fires on the falling edge of signal, on a transition from
1
to0
.
Timing¶
-
class
cocotb.triggers.
Timer
(time_ps, units=None)[source]¶ Fires after the specified simulation time period has elapsed.
- Parameters
time_ps (numbers.Real or decimal.Decimal) – The time value. Note that despite the name this is not actually in picoseconds but depends on the units argument.
units (str or None, optional) – One of
None
,'fs'
,'ps'
,'ns'
,'us'
,'ms'
,'sec'
. When no units is given (None
) the timestep is determined by the simulator.
Examples
>>> yield Timer(100, units='ps')
The time can also be a
float
:>>> yield Timer(100e-9, units='sec')
which is particularly convenient when working with frequencies:
>>> freq = 10e6 # 10 MHz >>> yield Timer(1 / freq, units='sec')
Other builtin exact numeric types can be used too:
>>> from fractions import Fraction >>> yield Timer(Fraction(1, 10), units='ns')
>>> from decimal import Decimal >>> yield Timer(Decimal('100e-9'), units='sec')
These are most useful when using computed durations while avoiding floating point inaccuracies.
See also
-
class
cocotb.triggers.
ReadOnly
[source]¶ Fires when the current simulation timestep moves to the read-only phase.
The read-only phase is entered when the current timestep no longer has any further delta steps. This will be a point where all the signal values are stable as there are no more RTL events scheduled for the timestep. The simulator will not allow scheduling of more events in this timestep. Useful for monitors which need to wait for all processes to execute (both RTL and cocotb) to ensure sampled signal values are final.
Python Triggers¶
-
class
cocotb.triggers.
Combine
(*triggers)[source]¶ Fires when all of triggers have fired.
Like most triggers, this simply returns itself.
-
class
cocotb.triggers.
First
(*triggers)[source]¶ Fires when the first trigger in triggers fires.
Returns the result of the trigger that fired.
As a shorthand,
t = yield [a, b]
can be used instead oft = yield First(a, b)
. Note that this shorthand is not available when usingawait
.Note
The event loop is single threaded, so while events may be simultaneous in simulation time, they can never be simultaneous in real time. For this reason, the value of
t_ret is t1
in the following example is implementation-defined, and will vary by simulator:t1 = Timer(10, units='ps') t2 = Timer(10, units='ps') t_ret = yield First(t1, t2)
-
class
cocotb.triggers.
Join
(coroutine)[source]¶ Fires when a
fork()
ed coroutine completes.The result of blocking on the trigger can be used to get the coroutine result:
@cocotb.coroutine() def coro_inner(): yield Timer(1, units='ns') raise ReturnValue("Hello world") task = cocotb.fork(coro_inner()) result = yield Join(task) assert result == "Hello world"
Or using the syntax in Python 3.5 onwards:
@cocotb.coroutine() async def coro_inner(): await Timer(1, units='ns') return "Hello world" task = cocotb.fork(coro_inner()) result = await Join(task) assert result == "Hello world"
If the coroutine threw an exception, the
await
oryield
will re-raise it.-
property
retval
¶ The return value of the joined coroutine.
Note
Typically there is no need to use this attribute - the following code samples are equivalent:
forked = cocotb.fork(mycoro()) j = Join(forked) yield j result = j.retval
forked = cocotb.fork(mycoro()) result = yield Join(forked)
-
property
Synchronization¶
These are not Trigger
s themselves, but contain methods that can be used as triggers.
These are used to synchronize coroutines with each other.
-
class
cocotb.triggers.
Event
(name='')[source]¶ Event to permit synchronization between two coroutines.
Yielding
wait()
from one coroutine will block the coroutine untilset()
is called somewhere else.
-
class
cocotb.triggers.
Lock
(name='')[source]¶ Lock primitive (not re-entrant).
This should be used as:
yield lock.acquire() try: # do some stuff finally: lock.release()
-
locked
= None¶ True
if the lock is held.
-
-
cocotb.triggers.
with_timeout
()[source]¶ Waits on triggers, throws an exception if it waits longer than the given time.
Usage:
yield with_timeout(coro, 100, 'ns') yield with_timeout(First(coro, event.wait()), 100, 'ns')
- Parameters
trigger (cocotb_waitable) – A single object that could be right of a
yield
(orawait
in Python 3) expression in cocotb.timeout_time (numbers.Real or decimal.Decimal) – Time duration.
timeout_unit (str or None, optional) – Units of duration, accepts any values that
Timer
does.
- Returns
First trigger that completed if timeout did not occur.
- Raises
SimTimeoutError – If timeout occurs.
New in version 1.3.