Skip to main content

SPI modules for cocotb

Project description

Verilog SPI

Regression Tests

GitHub repository: https://github.com/schang412/cocotbext-spi

Introduction

SPI simulation framework for cocotb.

Installation

Installation from pip (release version, stable):

pip install cocotbext-spi

Installation from git (latest development version, potentially unstable):

pip install https://github.com/schang412/cocotbext-spi/archive/main.zip

Installation for active development:

git clone https://github.com/schang412/cocotbext-spi
pip install -e cocotbext-spi

Documentation and Usage

See the tests directory for complete testbenches using these modules

SPI Signals

The SPI bus signals are bundled together into a SpiSignals class.

To create the object simply call it like a class and pass in arguments:

from cocotbext.spi import SpiConfig

spi_signals = SpiSignals(
    sclk = dut.sclk,     # required
    mosi = dut.mosi,     # required
    miso = dut.miso,     # required
    cs   = dut.ncs,      # required
    cs_active_low = True # optional (assumed True)
)

cocotb does not provide a way to generate signals that follow another one, so cs_active_low bool is implemented to support both active high and active low chip selects.

SPI Config

SPI Configuration parameters are bundled together into a SpiConfig class.

To create the object simply call it like a class and pass in arguments:

from cocotbext.spi import SpiConfig

spi_config = SpiConfig(
    word_width = 16,     # number of bits in a SPI transaction
    sclk_freq  = 25e6,   # clock rate in Hz
    cpol       = False,  # clock idle polarity
    cpha       = True,   # clock phase (CPHA=True means sample on FallingEdge)
    msb_first  = True,   # the order that bits are clocked onto the wire
    data_output_idle = 1,# the idle value of the MOSI or MISO line 
    frame_spacing_ns = 1 # the spacing between frames that the master waits for or the slave obeys
                         #       the slave should raise SpiFrameError if this is not obeyed.
)

All parameters are optional, and the defaults are shown above.

SPI Master

The SpiMaster class acts as an SPI Master endpoint.

To use this class, import it, configure it, and connect to the dut.

from cocotbext.spi import SpiMaster, SpiSignals, SpiConfig

spi_signals = SpiSignals(
    sclk = dut.sclk,     # required
    mosi = dut.mosi,     # required
    miso = dut.miso,     # required
    cs   = dut.ncs,      # required
    cs_active_low = True # optional (assumed True)
)

spi_config = SpiConfig(
    word_width = 16,     # all parameters optional
    sclk_freq  = 25e6,   # these are the defaults
    cpol       = False,
    cpha       = True,
    msb_first  = True
)

spi_master = SpiMaster(spi_signals, spi_config)

To send data into a design with SpiMaster, call write() or write_nowait(). Accepted data types are iterables of ints including lists, bytes, bytearrays, etc. Optionally, call wait() to wait for the transmit operation to complete. We can take a look at the data received back with read() or read_nowait()

# TX/RX transaction example
spi_master.write_nowait(0xFFFF)
await spi_master.wait()
read_bytes = await spi_master.read()
print(read_bytes)

# we can alternatively call (which has equivalent functionality)
await spi_master.write(0xFFFF)
read_bytes = await spi_masetr.read()

Constructor Parameters

  • signals: SpiSignal
  • config: SpiConfig

Methods

  • write(data): send data (blocking)
  • write_nowait(data): send data (non-blocking)
  • read(count=-1): read count bytes from buffer, reading whole buffer by default (blocking)
  • read_nowait(count=-1): read count bytes from buffer, reading whole buffer by default (non-blocking)
  • count_tx(): returns the number of items in the transmit queue
  • count_rx(): returns the number of items in the receive queue
  • empty_tx(): returns True if the transmit queue is empty
  • empty_rx(): returns True if the receive queue is empty
  • idle(): returns True if the transmit and receive buffers are empty
  • clear(): drop all data in the queue

SPI Slave

The SpiSlaveBase acts as an abstract class for a SPI Slave Endpoint.

To use this class, import it and inherit it. Then use the subclass as the slave and connect it to the dut.

from cocotbext.spi import SpiMaster, SpiSignals, SpiConfig

class SimpleSpiSlave(SpiSlaveBase):
    def __init__(self, signals):
        self._config = SpiConfig()
        self.content = 0
        super().__init__(signals)

    async def get_content(self):
        await self.idle.wait()
        return self.content

    async def _transaction(self, frame_start, frame_end):
        await frame_start
        self.idle.clear()

        self.content = int(await self._shift(16, tx_word=(0xAAAA)))

        await frame_end

spi_signals = SpiSignals(
    sclk = dut.sclk,
    mosi = dut.mosi,
    miso = dut.miso,
    cs   = dut.ncs
)
spi_slave = SimpleSpiSlave(spi_signals)

Implementation

All SPI Slave Classes should:

  • inherit the SpiSlaveBase class
  • define self._config adjust the values for:
    • word_width
    • cpha
    • cpol
    • msb_first
    • frame_spacing_ns
  • implement a _transaction coroutine
    • the coroutine should take 3 arguments, self, frame_start and frame_end
    • the coroutine should await frame_start at the transaction start, and frame_end when done.
      • frame_start and frame_end are Rising and Falling edges of the chip select based on the chip select polarity
    • when the coroutine receives a frame_start signal, it should clear the self.idle Event.
      • self.idle is automatically set when _transaction returns
  • when implementing a method to read the class contents, make sure to await the self.idle, otherwise the data may not be up to date because the device is in the middle of a transaction.

Simulated Devices

This framework includes some SPI Slave devices built in. A list of supported devices can be found in cocotbext/spi/devices and are sorted by vendor.

To use these devices, you can simply import them.

from cocotbext.spi.devices.TI import DRV8306

spi_signals = SpiSignals(
    sclk = dut.sclk,
    mosi = dut.mosi,
    miso = dut.miso,
    cs   = dut.ncs
)
spi_slave = DRV8306(spi_signals)

To submit a new device, make a pull request.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

cocotbext-spi-0.1.2.tar.gz (13.7 kB view details)

Uploaded Source

Built Distribution

cocotbext_spi-0.1.2-py3-none-any.whl (12.5 kB view details)

Uploaded Python 3

File details

Details for the file cocotbext-spi-0.1.2.tar.gz.

File metadata

  • Download URL: cocotbext-spi-0.1.2.tar.gz
  • Upload date:
  • Size: 13.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.4.2 importlib_metadata/4.0.1 pkginfo/1.7.1 requests/2.21.0 requests-toolbelt/0.9.1 tqdm/4.62.0 CPython/3.7.3

File hashes

Hashes for cocotbext-spi-0.1.2.tar.gz
Algorithm Hash digest
SHA256 940daa1c4cd7016d6e44934845e507f3bc0f63c9742fc4cd4ce8dbc5b6d6a340
MD5 c1b38b09d5403e98c603d6bc13769a5e
BLAKE2b-256 b33f663a535b3edb3e22e038457671cec9c4741eb28fd4c4d02269ed6870dcf3

See more details on using hashes here.

File details

Details for the file cocotbext_spi-0.1.2-py3-none-any.whl.

File metadata

  • Download URL: cocotbext_spi-0.1.2-py3-none-any.whl
  • Upload date:
  • Size: 12.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.4.2 importlib_metadata/4.0.1 pkginfo/1.7.1 requests/2.21.0 requests-toolbelt/0.9.1 tqdm/4.62.0 CPython/3.7.3

File hashes

Hashes for cocotbext_spi-0.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 0cc4ed76fa10918d51be8f0bdd58a92342fb4a5148dc11c02810df5fcc7a7332
MD5 39e8c16b5dcb2f03bdd4dea274b0d799
BLAKE2b-256 e19340101d71508204f3933b17bf9a01fa8f616d95b24b380a88fb0444a1cce2

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page