User:pigsonthewing/sandbox3

From Wikipedia, the free encyclopedia
cocotb
Developer(s)Stuart Hodgson, Chris Higgs, and cocotb contributors
Initial release9 July 2013; 10 years ago (2013-07-09)[1]
Stable release
4 May 2021; 2 years ago (2021-05-04)[2]
Written inPython, C++, VHDL, C and others
Operating systemmacOS, Windows 7 and later, and Linux[3]
Available inEnglish
TypeCo-simulation environment
LicenseBSD License

cocotb is an open-source COroutine-based COsimuation TestBench (hence the name) environment, developed for the verification of hardware description languages like VHDL, Verilog and SystemVerilog, by means of Python programming language in the field of electronic design automation (EDA).[4] The project is hosted on GitHub, and is available for use, relying on an HDL simulator for simulating the HDL code, on Windows, Linux and macOS.

History[edit]

cocotb was first released on Jul 9, 2013 by Stuart Hodgson, one of its first developers together with Chris Higgs, both from Potential Ventures, and supported also by Solarflare Communications Ltd (then acquired, in July 2019, by Xilinx Inc),[5][1][6][7] and is currently developed and maintained by an active community.

cocotb, as an independent project, is since 2018 under the auspices of the Free and Open Source Silicon Foundation, which provides for cocotb's financial, legal and administrative support, holding also its assets.[8][9]

cocotb vs UVM[edit]

While relying on the same concept of design re-use and random testing, UVM (Universal Verification Methodology) is based on a SystemVerilog library,[10] resulting in a powerful, yet more complicated environment than the one granted by cocotb. Indeed, cocotb limits the usage of the target HDL for the design itself, using instead Python for the design of the tests.[11] Being Python an object-oriented, interpreted, and interactive programming language, the advantages given by cocotb while building the tests are numerous:

  • cocotb is fast, allowing to build test in a fraction of the time needed for a UVM test;
  • cocotb is easy to interface with;
  • Python features huge standard libraries;
  • Python is popular and widespread;
  • Python is interpreted, allowing edits on the tests without the need of the design to be recompiled.

Working principle[edit]

Once the developer has completed the part of the design that is to be tested, i.e. the Device under test (DUT), he can instantiate it as top-level in the simulator. cocotb provides an interface between the simulator and Python, and allows to drive the DUT inputs, waiting for the simulation time to pass and monitoring its outputs, all through Python functions. The design and testbenches can be simulated independently, using the concept of cosimulation.[12] The simulation is run when the Python code, which in this context is called "coroutine" is paused and, viceversa, simulation does not advance while a coroutine is in execution. The triggering conditions that determine which is to advance and which to pause can be one of the many triggers that cocotb offers, such as timers, edges of predetermined signals, certain number of clock cycles.[13]

Cocotb working principle

Coroutines[edit]

A cocotb testbench is based on what are called coroutines. As mentioned, coroutines execute when the simulation is paused, using the await keyword for passing the control back to the simulator when simulation time is needed to advance. The "awaited" object is, typically, a trigger, that awakes the coroutine on its occurrence, or it can also be another coroutine. A coroutine is, in the end, a Python function, identified by the decorator @cocotb.coroutine, and can, thus, return values to be used in other coroutines. They can be forked, which means that they can be used in concurrent operations, and even killed before their natural end.[14]

Triggers[edit]

Triggers are a cocotb class that is used to indicate the moment when the cocotb scheduler should regain a coroutine execution, upon having waited an await event, pausing then the simulation for the coroutine to advance.[15] There is a complete class of triggers provided for cocotb, both for the simulator and for Python, that comprises, for example:

  • Signals, which include
    • Edge, for triggering on whatever edge of a signal
    • Rising Edge, for triggering on the rising edge of a signal
    • Falling Edge, for triggering on the falling edge of a signal
    • Clock Cycles, that triggers after num_cycles, given as a parameter
  • Timing, featuring a "Timer" that allows to specify
    • time, as a real or decimal value
    • units, to specify the magnitude of the inserted value

Supported simulators[edit]

cocotb has grown its support to many of the available HDL simulators, and, more in general, can be used with any simulator supporting the industry-standard Verilog Procedural Interface (VPI), VHDL Procedural Interface (VHPI), or ModelSim Foreign Language Interface (FLI) interfaces, showing a behavior with minor differences from one simulator to the other, all taken care by cocotb.[16] Here is a list of the supported simulators:

The simulator in use must be specified in the Makefile, referred to the SIM variable, so that cocotb can properly make use of it.

Buses and extensions[edit]

Buses[edit]

Supported buses, previously part of the same GitHub repository, are now pre-packaged as testbenching tools and re-usable interfaces under the cocotb_bus repository. The tools comprehend both drivers and monitors, supporting standard such as AMBA Advanced eXtensible Interface protocols, which represent a de facto standard in terms of embedded processors bus architectures, Intel's Avalon (limited functionalities),[17] IBM's On-chip Peripheral Bus (OPB, with limited functionalities), which is part of the CoreConnect microprocessor bus-architecture for SoCs and XGMII (10 Gigabit Media-Independent Interface), an IEEE 802.3 standard for full duplex 10 Gigabit Ethernet connection for electronic devices, which is a variant of the original Media-independent interface, and is typically used for on-chip connections.

The cocotb_bus repository also includes scoreboards,[18] which are a class used to compare actual outputs from the simulations to the expected outputs generated using Python. Scoreboards make use of the previously mentioned monitors in order to perform the comparison. These buses drivers and monitor play, via Python, the role that a Bus Functional Model (BFM) plays when verifying integrated circuits in the classical way, which is via a non-synthesizable model of an Integrated circuit written in HDL, featuring one or more external buses.

Extensions[edit]

cocotb, taking advantage of being open-source, is prone to be extended by its users. In fact, when the available functionalities do not cover some needs, which is the case, in particular, for drivers and monitors, users can package new functionalities and distribute them as extensions, sharing them allowing their re-use. Such extensions, which in the verification world are usually referred to as "verification IPs" (VIPs), are, for cocotb, normal Python packages, and can, thus, make use of all standard Python packaging and distribution techniques. The cocotb community has come up with naming conventions, in order to ease the making and discovering of extensions.[19] A bus extension, for example, could be providing an interface to a bus such as SPI, and should be built on top of a set of common classes to offer a uniform interface to the users. There are, usually, three kinds of functionalities that a bus extension should deliver:

  • the bus itself, as an abstraction
  • an active part, the driver, which drives the signals on the bus
  • a passive part, the monitor, which serves to observe the signal changes

Code examples[edit]

VHDL vs Python[edit]

Here is reported a code example of a D Flip-Flop in both the VHDL implementation and in the correspondent Python couterpart, using cocotb.

D Flip-Flop example
VHDL Python (cocotb)
library ieee;
use ieee.std_logic_1164.all;

entity dff is
port(
  clk: in std_logic;
  d: in std_logic;
  q: out std_logic);
end dff;

architecture behavioral of dff is
begin
  process (clk) begin
    if rising_edge(clk) then
      q <= d;
    end if;
  end process;
end behavioral;
import random
import cocotb
from cocotb.clock import Clock
from cocotb.triggers import FallingEdge

@cocotb.test()
async def test_dff_simple(dut):
    """Test that d propagates to q."""

    clock = Clock(dut.clk, 10, units="us")  # Create a 10us period clock on port clk
    cocotb.fork(clock.start())  # Start the clock

    await FallingEdge(dut.clk)  # Synchronize with the clock
    for i in range(10):
        val = random.randint(0, 1)
        dut.d <= val  # Assign the random value val to the input port d
        await FallingEdge(dut.clk)
        assert dut.q.value == val, f"output q was incorrect on the {i}th cycle"

AXI4 Lite Master example[edit]

This is, instead, an example of a cocotb test on an AXI4Lite Master

import os
import cocotb
from cocotb.clock import Clock
from cocotb.triggers import Timer
from cocotb_bus.drivers.amba import AXI4LiteMaster, AXIProtocolError

CLK_PERIOD_NS = 10

MODULE_PATH = os.path.join(os.path.dirname(__file__), os.pardir, "hdl")
MODULE_PATH = os.path.abspath(MODULE_PATH)

def setup_dut(dut):
    cocotb.fork(Clock(dut.clk, CLK_PERIOD_NS, units='ns').start())

# Write to address 0 and verify that value got through
@cocotb.test()
async def write_address_0(dut):
    """Write to the register at address 0, verify the value has changed.
    Test ID: 0
    Expected Results:
        The value read directly from the register is the same as the
        value written.
    """

    # Reset
    dut.rst <= 1
    dut.test_id <= 0
    axim = AXI4LiteMaster(dut, "AXIML", dut.clk)
    setup_dut(dut)
    await Timer(CLK_PERIOD_NS * 10, units='ns')
    dut.rst <= 0

    ADDRESS = 0x00
    DATA = 0xAB

    await axim.write(ADDRESS, DATA)
    await Timer(CLK_PERIOD_NS * 10, units='ns')

    value = dut.dut.r_temp_0
    assert value == DATA, ("Register at address 0x%08X should have been "
                           "0x%08X but was 0x%08X" % (ADDRESS, DATA, int(value)))
    dut._log.info("Write 0x%08X to address 0x%08X" % (int(value), ADDRESS))

Export waveforms[edit]

cocotb has also the ability, based on the simulation option and simulator behavior, to export waveform files such as VCD, a Verilog standard used by almost any wave viewer, GHW (GHdl Waveform), a file format supporting dumping of any VHDL typ, as VCD only supports a few of them, and fst, which handles the same signals of VCD, but in a much smaller file.[20]

Waveforms of cocotb visualized on GTKWave

See also[edit]

Additional material[edit]

HDL languages[edit]

References[edit]

  1. ^ a b "Initial release". cocotb docs. Retrieved 15 June 2021.
  2. ^ "Latest release". cocotb docs. Retrieved 15 June 2021.
  3. ^ "Prerequisites". cocotb docs. Retrieved 15 June 2021.
  4. ^ "Cocotb docs". cocotb docs. Retrieved 15 June 2021.
  5. ^ "Cocotb: a Python-based digital logic verification framework" (PDF). Indico, CERN. p. 8. Retrieved 16 June 2021.
  6. ^ "Potential Ventures: cocotb". Potential Ventures. Retrieved 17 June 2021.
  7. ^ "Xilinx to acquire Solarflare". Xilinx Inc. Retrieved 17 June 2021.
  8. ^ "Contributors". GitHub. Retrieved 16 June 2021.
  9. ^ "Foundation Projects". FOSSi. Retrieved 17 June 2021.
  10. ^ "UVM Verification Primer". Doulos. Retrieved 16 June 2021.
  11. ^ "UVM vs cocotb". cocotb docs. Retrieved 15 June 2021.
  12. ^ "GHDL co-simulation". ghdl.github.io. Retrieved 17 June 2021.
  13. ^ "Triggers". cocotb docs. Retrieved 16 June 2021.
  14. ^ "Coroutines". cocotb docs. Retrieved 17 June 2021.
  15. ^ "Triggers". cocotb docs. Retrieved 17 June 2021.
  16. ^ "Simulator Support". cocotb docs. Retrieved 17 June 2021.
  17. ^ "Avalon® Interface specification" (PDF). Intel. Retrieved 17 June 2021.
  18. ^ "Scoreboard". cocotb docs. Retrieved 17 June 2021.
  19. ^ "Writing cocotb extensions". cocotb docs. Retrieved 17 June 2021.
  20. ^ "Export waveforms". cocotb docs. Retrieved 17 June 2021.

Category:Free software Category:Digital electronics Category:Electronic design automation