Git Product home page Git Product logo

cocotbext-wishbone's Introduction

cocotb modules for Wishbone bus

This cocotb extension contains driver and monitor modules for the Wishbone bus.

Install

From Github

  • Clone the repository:

    $ git clone https://github.com/wallento/cocotbext-wishbone.git
    
  • Then install it with pip:

    $ python3 -m pip install -e cocotbext-wishbone
    

From pip global

To install it with pip published globally simply use pip install as usual:

$ python3 -m pip install cocotbext-wishbone

How to use it

Driver

As an example we will instantiate a Wishbone master cocotb driver to read and write on a DUT wishbone slave. First import this

from cocotbext.wishbone.driver import WishboneMaster
from cocotbext.wishbone.driver import WBOp

The DUT ports naming in Verilog is following:

input         clock,
input  [1:0]  io_wbs_adr,
input  [15:0] io_wbs_datwr,
output [15:0] io_wbs_datrd,
input         io_wbs_we,
input         io_wbs_stb,
output        io_wbs_ack,
input         io_wbs_cyc,

To initialize our master we have to do this:

self.wbs = WishboneMaster(dut, "io_wbs", dut.clock,
                          width=16,   # size of data bus
                          timeout=10) # in clock cycle number

But in actuals port name are rarely the same has seen above. In this case actuals ports names are for example:

input         clock
input  [1:0]  io_wbs_adr_i,
input  [15:0] io_wbs_dat_i,
output [15:0] io_wbs_dat_o,
input         io_wbs_we_i,
input         io_wbs_stb_i,
output        io_wbs_ack_o,
input         io_wbs_cyc_i,

Then we have to rename it with signals_dict arguments:

self.wbs = WishboneMaster(dut, "io_wbs", dut.clock,
                          width=16,   # size of data bus
                          timeout=10, # in clock cycle number
                          signals_dict={"cyc":  "cyc_i",
                                      "stb":  "stb_i",
                                      "we":   "we_i",
                                      "adr":  "adr_i",
                                      "datwr":"dat_i",
                                      "datrd":"dat_o",
                                      "ack":  "ack_o" })

In the testbench, to make read/write access we have to use the method send_cycle() with a list of special class operator named WBOp().

WBOp() is accepting the following arguments, all with default value:

adr: address of the operation
dat: data to write, None indicates a read cycle
idle: number of clock cycles between asserting cyc and stb
sel: the selection mask for the operation

WBOp(adr=0, dat=None, idle=0, sel=None)

If no dat is given, a wishbone read will be done. If dat is filled, it will be a write.

For example, to read respectively at address 2, 3, 0 then 1, we will do:

wbRes = async rdbg.wbs.send_cycle([WBOp(2), WBOp(3), WBOp(0), WBOp(1)])

The send_cycle() method returns a list of Wishbone Result Wrapper Class WBRes() with some data declared like it in :file:`driver.py`:

def __init__(self, ack=0, sel=None, adr=0, datrd=None, datwr=None, waitIdle=0, waitStall=0, waitAck=0):

If we want to print the value being read, we just have to read datrd value like so:

rvalues = [wb.datrd for wb in wbRes]
dut.log.info(f"Returned values : {rvalues}")

Which will print a log message like following:

1560.00ns INFO     Returned values : [0000000000000000, 0000000000000000, 0000000100000001, 0000000000000000]

We can add some write operations in our send_cycle(), by adding a second value in parameters:

wbRes = async rdbg.wbs.send_cycle([WBOp(3, 0xcafe), WBOp(0), WBOp(3)])

The above line will write 0xcafe at address 3, then read at address 0, then read at address 3.

Monitor

The Monitor instantiation works similarly to the Driver instantiation. First import the right module

from cocotbext.wishbone.monitor import WishboneSlave

Then instantiate the object with right signals names

wbm = WishboneSlave(dut, "io_wbm", dut.clock,
                 width=16,   # size of data bus
                 signals_dict={"cyc":  "cyc_o",
                             "stb":  "stb_o",
                             "we":   "we_o",
                             "adr":  "adr_o",
                             "datwr":"dat_o",
                             "datrd":"dat_i",
                             "ack":  "ack_i" })

WishboneSlave is a monitor, then it's mainly a passive class. It will supervise the Wishbone signal and records transaction in a list named _recvQ. Each time the monitor detect a transaction on the bus, the transaction is append to _recvQ.

A transaction is a list of WBRes objects which contain some signal values read on the bus

@public
class WBRes():
...
    def __init__(...):
        self.ack        = ack
        self.sel        = sel
        self.adr        = adr
        self.datrd      = datrd
        self.datwr      = datwr
        self.waitStall  = waitStall
        self.waitAck    = waitAck
        self.waitIdle   = waitIdle

At the end of the simulation, if we want to display the adr, datrd and datwr values on the bus we will do following for example

for transaction in wbm._recvQ:
    wbm.log.info(f"{[f'@{hex(v.adr)}r{hex(v.datrd)}w{hex(0 if v.datwr is None else v.datwr)}' for v in transaction]}")

We can also register a callback function that will be called each time a transaction occured:

def simple_callback(transaction):
    print(transaction)

wbm.add_callback(simple_callback)

But be aware that if a callback is registered, _recvQ will not be populated.

Projects using this module

Here are some projects that use this module, to use as examples:

  • ChisArmadeus: Useful chisel components for Armadeus boards. It uses cocotb for testing. An example is given for op6ul wrapper test here
  • wbGPIO: General purpose input output wishbone slave written in Chisel. The cocotb testbench is available here

cocotbext-wishbone's People

Contributors

akukulanski avatar chiggs avatar cmarqu avatar fatsie avatar fkwilken avatar jamieiles avatar koluckirafal avatar martoni avatar mkreider avatar tmichalak avatar wallento avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

cocotbext-wishbone's Issues

issue with installing cocotbext-wishbone

Hi,

:tools>python3 -m pip install cocotbext-wishbone
Defaulting to user installation because normal site-packages is not writeable
ERROR: Could not find a version that satisfies the requirement cocotbext-wishbone (from versions: none)
ERROR: No matching distribution found for cocotbext-wishbone

any idea how to resolve this error message?
I also tried this


> tools>python3 -m pip install -e cocotbext-wishbone
> Defaulting to user installation because normal site-packages is not writeable
> Obtaining file:///tools/cocotbext-wishbone
> ERROR: Command errored out with exit status 1:
> command: /opt/rh/rh-python36/root/usr/bin/python3 -c 'import sys, setuptools, tokenize; sys.argv[0] = '"'"'/tools/cocotbext-wishbone/setup.py'"'"'; file='"'"'/tools/cocotbext-wishbone/setup.py'"'"';f=getattr(tokenize, '"'"'open'"'"', open)(file);code=f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, file, '"'"'exec'"'"'))' egg_info --egg-base /tmp/pip-pip-egg-info-g90qfibg
> cwd: /tools/cocotbext-wishbone/
> Complete output (7 lines):
> Traceback (most recent call last):
> File "", line 1, in
> File "/tools/cocotbext-wishbone/setup.py", line 4, in
> long_description = fh.read()
> File "/opt/rh/rh-python36/root/usr/lib64/python3.6/encodings/ascii.py", line 26, in decode
> return codecs.ascii_decode(input, self.errors)[0]
> UnicodeDecodeError: 'ascii' codec can't decode byte 0xe2 in position 1370: ordinal not in range(128)
> ----------------------------------------
> ERROR: Command errored out with exit status 1: python setup.py egg_info Check the logs for full command output.

issue testing cocotbext-wishbone

Hello, I'm testing the extension and I'm having problems when I call WishboneMaster, the error occurs in the init method of the Wishbone class and it is:
self.bus.cyc.setimmediatevalue(0)
AttributeError: 'NoneType' object has no attribute 'setimmediatevalue'

I'm testing a simple gpo with wishbone, and using the same default names of the extension, so I don't have to use the signals_dict.
Any clue?

Thanks in advance

Switching from cocotb.fork to cocotb.start_soon breaks _read function

The read functional fails to get the last value returned in a sequence of reads. If you request a single address, no data will be returned, if you request n addresses, n-1 values will be returned. Simply replacing start_soon with fork fixes this issues, however, I know fork is deprecated.

This could potentially be fixed by changing cocotb.start_soon(self._read()) to await cocotb.start(self._read()). I wish I knew the difference I guess I should read up on that.

new signals break if they do not exist in the bus

Hi, I updated to the latest version (my bus does not have cti and bte signals), and the library now break at line 257 of the driver.py file, where they are used and there is no check if they exists.
Also there is no tag of the previous version, so its not an easy way to use the old version.

How to rename Wishbone signals interface ?

I'm trying to use cocomod-wishbone in my test project. My DUT has a wishbone slave interface with following signals name :

  input  [1:0]  io_wbs_adr_i,
  input  [11:0] io_wbs_dat_i,
  output [11:0] io_wbs_dat_o,
  input         io_wbs_we_i,
  input         io_wbs_stb_i,
  output        io_wbs_ack_o,
  input         io_wbs_cyc_i

Then I just want to simulate simple read/write from a master-intercon. But unfortunately names are not recognized by default name convention. And if I try to instanciate it like following :

self.wbs = WishboneMaster(self._dut, "io_wbs", self.clock, width=16)

I get error from python module :

AttributeError: MyModule contains no object named io_wbs_cyc

Version via pip (0.2) too old for cocotb >= 1.6

The version of this package on pip (0.2) seems to be too old to work with cocotb >= 1.6. The needed fix is already done in the git repo (#18), but not pushed to the package index, I assume.

...
/usr/local/lib/python3.9/dist-packages/attrdict/mapping.py:4: DeprecationWarning: Using or importing the ABCs from 'coll
ections' instead of from 'collections.abc' is deprecated since Python 3.3, and in 3.10 it will stop working
  from collections import Mapping
/usr/local/lib/python3.9/dist-packages/attrdict/mixins.py:5: DeprecationWarning: Using or importing the ABCs from 'colle
ctions' instead of from 'collections.abc' is deprecated since Python 3.3, and in 3.10 it will stop working
  from collections import Mapping, MutableMapping, Sequence
     0.00ns CRITICAL Failed to import module tb_wishbone: No module named 'cocotb.drivers'
     0.00ns INFO     MODULE variable was "tb_wishbone"
     0.00ns INFO     Traceback: 
     0.00ns INFO     Traceback (most recent call last):
                       File "/usr/local/lib/python3.9/dist-packages/cocotb/regression.py", line 175, in _discover_tests
                         module = _my_import(module_name)
                       File "/usr/local/lib/python3.9/dist-packages/cocotb/regression.py", line 69, in _my_import
                         mod = __import__(name)
                       File "/build/tests/tb_wishbone.py", line 11, in <module>
                         from cocotbext.wishbone.monitor import WishboneSlave
                       File "/usr/local/lib/python3.9/dist-packages/cocotbext/wishbone/__init__.py", line 1, in <module>
                         from .driver import *
                       File "/usr/local/lib/python3.9/dist-packages/cocotbext/wishbone/driver.py", line 6, in <module>
                         from cocotb.drivers import BusDriver
                     ModuleNotFoundError: No module named 'cocotb.drivers'
                     
Traceback (most recent call last):
  File "/usr/local/lib/python3.9/dist-packages/cocotb/__init__.py", line 242, in _initialise_testbench
    _initialise_testbench_(argv_)
  File "/usr/local/lib/python3.9/dist-packages/cocotb/__init__.py", line 345, in _initialise_testbench_
    regression_manager = RegressionManager.from_discovery(top)
  File "/usr/local/lib/python3.9/dist-packages/cocotb/regression.py", line 150, in from_discovery
    return cls(dut, tests)
  File "/usr/local/lib/python3.9/dist-packages/cocotb/regression.py", line 129, in __init__
    for test in tests:
  File "/usr/local/lib/python3.9/dist-packages/cocotb/regression.py", line 175, in _discover_tests
    module = _my_import(module_name)
  File "/usr/local/lib/python3.9/dist-packages/cocotb/regression.py", line 69, in _my_import
    mod = __import__(name)
  File "/build/tests/tb_wishbone.py", line 11, in <module>
    from cocotbext.wishbone.monitor import WishboneSlave
  File "/usr/local/lib/python3.9/dist-packages/cocotbext/wishbone/__init__.py", line 1, in <module>
    from .driver import *
  File "/usr/local/lib/python3.9/dist-packages/cocotbext/wishbone/driver.py", line 6, in <module>
    from cocotb.drivers import BusDriver
ModuleNotFoundError: No module named 'cocotb.drivers'
     0.00ns ERROR    Failing test at simulator request before test run completion: Simulator shutdown prematurely

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.