cocotbext-ahb


Namecocotbext-ahb JSON
Version 0.2.6 PyPI version JSON
download
home_pagehttps://github.com/aignacio/cocotbext-ahb
SummaryCocotbExt AHB Bus VIP
upload_time2023-12-25 20:46:58
maintainer
docs_urlNone
authoraignacio (Anderson Ignacio)
requires_python>=3.6
licenseMIT
keywords soc vip hdl verilog systemverilog ahb
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage
            
[![Lint](https://github.com/aignacio/cocotbext-ahb/actions/workflows/lint.yaml/badge.svg)](https://github.com/aignacio/cocotbext-ahb/actions/workflows/lint.yaml) 
[![Regression Tests](https://github.com/aignacio/cocotbext-ahb/actions/workflows/test.yaml/badge.svg)](https://github.com/aignacio/cocotbext-ahb/actions/workflows/test.yaml) [![codecov](https://codecov.io/gh/aignacio/cocotbext-ahb/graph/badge.svg?token=RHYCK6SSCC)](https://codecov.io/gh/aignacio/cocotbext-ahb) 
[![Downloads](https://static.pepy.tech/badge/cocotbext-ahb)](https://pepy.tech/project/cocotbext-ahb)
[![PyPI version](https://badge.fury.io/py/cocotbext-ahb.svg)](https://badge.fury.io/py/cocotbext-ahb)

# Cocotb AHB bus driver

## Table of Contents
* [Introduction](#intro)
* [Installation](#install)
* [Classes and usage example](#classes)
* [License](#lic)

## <a name="intro"></a> Introduction

This repository contains AHB drivers (AHB and AHB Lite) and a monitor for [cocotb](https://github.com/cocotb/cocotb).

## <a name="install"></a> Installation

Installation from pip (release version, stable):
```bash
$ pip install cocotbext-ahb
```
Installation for active development:
```bash
$ git clone https://github.com/aignacio/cocotbext-ahb
```
The repository contains a small script that starts a container fetched from Docker Hub, equipped with all the required development tools.
```bash
$ cd cocotbext-ahb/
$ ./ship.sh
```
Once the container is up and running, to run the tests through [nox](https://nox.thea.codes/en/stable/) and [pytest](https://docs.pytest.org/), run the following:
```bash
$ nox -l # See the available build options
$ nox -s run-3.xx # Replace xx by a python version you want to test
```
The command above will take some time to complete (depends on your machine cfg) because it will run all the tests and its variants, generating waveforms in each `run_dir/*` folder. At the end of the test run, you can open the waveforms for each test in this format using gtkwave:
```bash
gtkwave run_dir/sim_build_icarus_(TEST_NAME)/ahb_template.fst  docs_utils/template.gtkw
```

Running specific tests:
```bash
$ nox -s run-3.10 -- -k "test_ahb_monitor_slave" # Runs on python 3.10, the test_ahb_monitor_slave
```
For the list of test, please check the [`tests/`](tests/) directory.

## <a name="classes"></a> Classes and usage example

This AHB extension is composed by master, slaves and a single monitor. Thus, the following available classes are:

* **AHB Master** - WIP for burst support, base class AHB Lite Master
* **AHB Lite Master** - Perform AHB transactions in non-/pipeline mode
* **AHB Slave** - WIP for burst support, base class AHB Lite Slave
* **AHB Lite Slave** - Support any type of AHB transaction but burst with back-pressure option and configurable default value 
* **AHB Monitor** - Basic monitor to check AHB transactions 

### AHB Bus

All the different master/slaves and also the monitor requires an **AHBBus** object to be passed to their constructors. This AHBBus object will map each of the AHB I/F pins the dut, some IOs are mandatory but others are optional. In order to create an AHBBus object, here are the two ways.

With a prefix:
```python
# In case your DUT has some prefix for the AHB I/F
# For instance if all AHB signals are following this convention:
# - test_haddr
# - test_hsel
# - ...
AHBBus.from_prefix(dut, "test")
```

Without a prefix:
```python
# In case your DUT has no prefix for the AHB I/F
# For instance if all AHB signals are following this convention:
# - haddr
# - hsel
# - ...
AHBBus.from_entity(dut)
```

For reference, down below is the class header of [AHB Bus](cocotbext/ahb/ahb_bus.py). More arguments can also be passed as this extends from [cocotb-bus](https://github.com/cocotb/cocotb-bus) base class.
```python
class AHBBus(Bus):
    _signals = ["haddr", "hsize", "htrans", "hwdata",
                "hrdata", "hwrite", "hready", "hresp"]

    _optional_signals = ["hburst", "hmastlock", "hprot", "hnonsec",
                         "hexcl", "hmaster", "hexokay", "hsel", "hready_in"]
```

#### Mandatory vs optional AHB signals

1. AHB Master signals

##### Mandatory

* haddr - Indicates AHB txn address 
* hsize - Indicates AHB txn size
* htrans - Indicates AHB txn type
* hwdata - Indicates AHB data to be written
* hwrite - Indicates type of AHB txn

##### Optional

* hburst
* hmastlock
* hprot
* hnonsec
* hexcl
* hmaster
* hsel 
* hready_in

2. AHB Slave signals 

##### Mandatory

* hresp - Indicates AHB txn response type
* hrdata - Indicates AHB txn read data
* hready - Indicates AHB slave availability

##### Optional

* hexokay

##### Signal customization for your design
To customize signals name to your design `signals` and `optional_signals` dictionnary can be provide. 
```python
AHBBus.from_prefix(
    dut, 
    prefix = "slave_driver",
    signals = {
        "haddr" : "haddr",
        "hsize" : "hsize",
        "htrans" : "htrans",
        "hwdata" : "hwdata",
        "hrdata" : "hrdata",
        "hwrite" : "hwrite",
        "hready" : "hreadyout",
        "hresp" : "hresp"
    }
,
    optional_signals = {
        "hsel" : "hsel",
        "hready_in" : "hready"
    }
)
```

#### Mandatory vs optional AHB signals

1. AHB Master signals

##### Mandatory

* haddr - Indicates AHB txn address 
* hsize - Indicates AHB txn size
* htrans - Indicates AHB txn type
* hwdata - Indicates AHB data to be written
* hwrite - Indicates type of AHB txn

##### Optional

* hburst

### AHB Master

Both AHB Master [WIP] and AHB Lite Master classes have the same constructor arguments. Within the arguments, it is required to pass the AHB Bus object, the clock and reset DUT pins. As optional args, a timeout value in clock cycles (per AHB txn), the default value of the master driven IOs and the name of the object.
```python
class AHBLiteMaster:
    def __init__(
        self,
        bus: AHBBus,
        clock: str,
        reset: str,
        timeout: int = 100,
        def_val: Union[int, str] = "Z",
        name: str = "ahb_lite",
        **kwargs,
    ):
```

In case of AHB Slave error response, the master will cancel the current transaction changing HTRANS from NSEQ to IDLE in the second clock cycle of the error response and then it will retry immediately after (following clock cycle). This is not mandatory but gives time for the master to decide whether it needs to be aborted or not the following transaction.

Its methods are composed by **read()**, **write()** and **custom()**. 

#### Write

For writes, the arguments are listed here:

```python
    async def write(
        self,
        address: Union[int, Sequence[int]],
        value: Union[int, Sequence[int]],
        size: Optional[Union[int, Sequence[int]]] = None,
        pip: Optional[bool] = False,
    ) -> Sequence[dict]:
```

**Arguments**
* address - Single or a list of integer addresses to be written
* value - Single or a list of integer values to be written
* Optional[size] - Integer number of bytes to be written (for instance, in 32-bit bus, 1, 2 or 4 bytes), default is the max bus size
* Optional[pip] - Define if the address/data phase will overlap in a pipeline manner or not, default non-pipelined 

**Return**
* Sequence[dict] - Once all transactions are dispatched and their responses are received, the function returns a list of dict with [AHBResp](cocotbext/ahb/ahb_types.py) responses along with the data.

*Note*: address, value and size have to match their length if provided.

#### Read

For reads, the arguments are listed here:

```python
    async def read(
        self,
        address: Union[int, Sequence[int]],
        size: Optional[Union[int, Sequence[int]]] = None,
        pip: Optional[bool] = False,
    ) -> Sequence[dict]:
```

**Arguments**
* address - Single or a list of integer addresses to be read from
* Optional[size] - Integer number of bytes to be read (for instance, in 32-bit bus, 1, 2 or 4 bytes), default is the max bus size
* Optional[pip] - Define if the address/data phase will overlap in a pipeline manner or not, default non-pipelined 

**Return**
* Sequence[dict] - Once all transactions are dispatched and their responses are received, the function returns a list of dict with [AHBResp](cocotbext/ahb/ahb_types.py) responses along with the data.

*Note*: address and size have to match their length if provided.

#### Custom

A third method provides flexibility in case the user wants to perform read or writes together like back-to-back operations such as WAR or RAW. For this, the arguments are listed here:

```python
    async def custom(
        self,
        address: Union[int, Sequence[int]],
        value: Union[int, Sequence[int]],
        mode: Union[int, Sequence[int]],
        size: Optional[Union[int, Sequence[int]]] = None,
        pip: Optional[bool]
    ) -> Sequence[dict]:
```

**Arguments**
* address - Single or a list of integer addresses to be written to or read from
* value - Single or a list of integer addresses to be written to or read from
* mode - Single or a list of operation types - 0 (Read) or 1 (Write)
* Optional[size] - Integer number of bytes to be written/read (for instance, in 32-bit bus, 1, 2 or 4 bytes), default is the max bus size
* Optional[pip] - Define if the address/data phase will overlap in a pipeline manner or not, default non-pipelined 

**Return**
* Sequence[dict] - Once all transactions are dispatched and their responses are received, the function returns a list of dict with [AHBResp](cocotbext/ahb/ahb_types.py) responses along with the data.

*Note*: address, value, mode and size have to match their length if provided.

### AHB Slave

Both AHB Slave [WIP] and AHB Lite Slave classes have the same constructor arguments. Within the arguments, it is required to pass the AHB Bus object, the clock and reset DUT pins. As optional arg, the default value of the slave driven IOs, a generator function to force back-pressure and the name of the object.

```python
class AHBLiteSlave:
    def __init__(
        self,
        bus: AHBBus,
        clock: str,
        reset: str,
        def_val: Union[int, str] = "Z",
        bp: Generator[int, None, None] = None,
        name: str = "ahb_lite",
        **kwargs,
    ):
```

The AHB slaves will not provide any specific data (always zero) or unexpected response, they serve as a basic slave just to check its connectivity while testing AHB Master and as a base class for the AHB Lite Slave RAM. The back-pressure feature is a way to force the slave to demonstrated unavailability while the master issue AHB transactions. The generator needs to return bool type values where bool True indicates slave available and bool False indicate slave unavailable. 

In case of an AHB error response, the Slave inserts a wait state (HREADY == LOW && HRESP == OKAY) however this not required and might change in the future sticking only to the mandatory obligation of 2-cycle error response:

* First: HREADY == LOW / HRESP == ERROR
* Second: HREADY == HIGH / HRESP == ERROR

#### AHB Lite Slave RAM 

The AHB Lite Slave RAM is a basic memory slave that can receive reads and write like a normal memory-mapped device. The only difference between the normal slave vs this one is the fact that as part of its constructor, a new argument **mem_size** is listed. This argument defines a memory size in bytes for the AHB slave. The only limitation for now, is the fact that all memory addresses have to be aligned to the data bus width, i.e for 32-bit slaves, address[1:0] == 2'b00.

```python
class AHBLiteSlaveRAM(AHBLiteSlave):
    def __init__(
        self,
        bus: AHBBus,
        clock: str,
        reset: str,
        def_val: Union[int, str] = "Z",
        bp: Generator[int, None, None] = None,
        name: str = "ahb_lite_ram",
        mem_size: int = 1024,
        **kwargs,
    ):
```

Thank you [@alexforencich](https://github.com/alexforencich/cocotbext-axi) for your work on the memory classes that were leveraged in this project.

### AHB Monitor

A basic AHB monitor was also developed, the idea is to ensure that basic protocol assumptions are respected throughout assertions, its constructor arguments are very similar to the previous discussed classes. For now, only two aspects are checked through this monitor, the first one ensure the master does not change its address phase transaction qualifier once a transaction is issued and the slave is not available. The second property checks that an AHB error response coming from the slave is following the 2-cycle response defined in the AMBA spec.

```python
class AHBMonitor:
    def __init__(
        self,
        bus: AHBBus,
        clock: str,
        reset: str,
        name: str = "ahb_monitor",
        **kwargs,
    ):
```

### Example

A basic example of this extension usage is demonstrated below and also within the [tests folder](test/) that are available.

```python
import cocotb
import os
import random
import math

from const import cfg
from cocotb_test.simulator import run
from cocotb.triggers import ClockCycles
from cocotb.clock import Clock
from cocotbext.ahb import AHBBus, AHBLiteMaster, AHBLiteSlaveRAM, AHBResp, AHBMonitor

def rnd_val(bit: int = 0, zero: bool = True):
    if zero is True:
        return random.randint(0, (2**bit) - 1)
    else:
        return random.randint(1, (2**bit) - 1)


def pick_random_value(input_list):
    if input_list:
        return random.choice(input_list)
    else:
        return None  # Return None if the list is empty

async def run_test(dut):
    data_width = 32
    mem_size_kib = 16
    N = 1000

    # Map the bus monitor to the I/F slave_h* I/F
    ahb_lite_mon = AHBMonitor(
        AHBBus.from_prefix(dut, "slave"), dut.hclk, dut.hresetn
    )

    # Create an AHB Lite Slave RAM connected to the master I/F
    ahb_lite_sram = AHBLiteSlaveRAM(
        AHBBus.from_prefix(dut, "master"),
        dut.hclk,
        dut.hresetn,
        def_val=0,
        bp=bp_fn,
        mem_size=mem_size_kib * 1024,
    )

    # Create an AHB Lite Master connected to the slave I/F
    ahb_lite_master = AHBLiteMaster(
        AHBBus.from_prefix(dut, "slave"), dut.hclk, dut.hresetn, def_val="Z"
    )
   
    # Create a lit of non-repeated addresses spaces by 8 from 0->2*current RAM size
    address = random.sample(range(0, 2 * mem_size_kib * 1024, 8), N)
    value = [rnd_val(data_width) for _ in range(N)]
    size = [pick_random_value([1, 2, 4]) for _ in range(N)]

    # Perform the writes and reads
    resp = await ahb_lite_master.write(address, value, size, pip=pip_mode)
    resp = await ahb_lite_master.read(address, size, pip=pip_mode)
```

### Example waveforms

![example_ext](docs_utils/txn_example.png)

## <a name="lic"></a> License
cocotbext-ahb is licensed under the permissive MIT license.Please refer to the [LICENSE](LICENSE) file for details.

            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/aignacio/cocotbext-ahb",
    "name": "cocotbext-ahb",
    "maintainer": "",
    "docs_url": null,
    "requires_python": ">=3.6",
    "maintainer_email": "",
    "keywords": "soc,vip,hdl,verilog,systemverilog,ahb",
    "author": "aignacio (Anderson Ignacio)",
    "author_email": "<anderson@aignacio.com>",
    "download_url": "https://files.pythonhosted.org/packages/f3/39/e327b009282de448a80a22ae91e6f1953a139f9868ce1ecbc5a4c546cabe/cocotbext-ahb-0.2.6.tar.gz",
    "platform": null,
    "description": "\n[![Lint](https://github.com/aignacio/cocotbext-ahb/actions/workflows/lint.yaml/badge.svg)](https://github.com/aignacio/cocotbext-ahb/actions/workflows/lint.yaml) \n[![Regression Tests](https://github.com/aignacio/cocotbext-ahb/actions/workflows/test.yaml/badge.svg)](https://github.com/aignacio/cocotbext-ahb/actions/workflows/test.yaml) [![codecov](https://codecov.io/gh/aignacio/cocotbext-ahb/graph/badge.svg?token=RHYCK6SSCC)](https://codecov.io/gh/aignacio/cocotbext-ahb) \n[![Downloads](https://static.pepy.tech/badge/cocotbext-ahb)](https://pepy.tech/project/cocotbext-ahb)\n[![PyPI version](https://badge.fury.io/py/cocotbext-ahb.svg)](https://badge.fury.io/py/cocotbext-ahb)\n\n# Cocotb AHB bus driver\n\n## Table of Contents\n* [Introduction](#intro)\n* [Installation](#install)\n* [Classes and usage example](#classes)\n* [License](#lic)\n\n## <a name=\"intro\"></a> Introduction\n\nThis repository contains AHB drivers (AHB and AHB Lite) and a monitor for [cocotb](https://github.com/cocotb/cocotb).\n\n## <a name=\"install\"></a> Installation\n\nInstallation from pip (release version, stable):\n```bash\n$ pip install cocotbext-ahb\n```\nInstallation for active development:\n```bash\n$ git clone https://github.com/aignacio/cocotbext-ahb\n```\nThe repository contains a small script that starts a container fetched from Docker Hub, equipped with all the required development tools.\n```bash\n$ cd cocotbext-ahb/\n$ ./ship.sh\n```\nOnce the container is up and running, to run the tests through [nox](https://nox.thea.codes/en/stable/) and [pytest](https://docs.pytest.org/), run the following:\n```bash\n$ nox -l # See the available build options\n$ nox -s run-3.xx # Replace xx by a python version you want to test\n```\nThe command above will take some time to complete (depends on your machine cfg) because it will run all the tests and its variants, generating waveforms in each `run_dir/*` folder. At the end of the test run, you can open the waveforms for each test in this format using gtkwave:\n```bash\ngtkwave run_dir/sim_build_icarus_(TEST_NAME)/ahb_template.fst  docs_utils/template.gtkw\n```\n\nRunning specific tests:\n```bash\n$ nox -s run-3.10 -- -k \"test_ahb_monitor_slave\" # Runs on python 3.10, the test_ahb_monitor_slave\n```\nFor the list of test, please check the [`tests/`](tests/) directory.\n\n## <a name=\"classes\"></a> Classes and usage example\n\nThis AHB extension is composed by master, slaves and a single monitor. Thus, the following available classes are:\n\n* **AHB Master** - WIP for burst support, base class AHB Lite Master\n* **AHB Lite Master** - Perform AHB transactions in non-/pipeline mode\n* **AHB Slave** - WIP for burst support, base class AHB Lite Slave\n* **AHB Lite Slave** - Support any type of AHB transaction but burst with back-pressure option and configurable default value \n* **AHB Monitor** - Basic monitor to check AHB transactions \n\n### AHB Bus\n\nAll the different master/slaves and also the monitor requires an **AHBBus** object to be passed to their constructors. This AHBBus object will map each of the AHB I/F pins the dut, some IOs are mandatory but others are optional. In order to create an AHBBus object, here are the two ways.\n\nWith a prefix:\n```python\n# In case your DUT has some prefix for the AHB I/F\n# For instance if all AHB signals are following this convention:\n# - test_haddr\n# - test_hsel\n# - ...\nAHBBus.from_prefix(dut, \"test\")\n```\n\nWithout a prefix:\n```python\n# In case your DUT has no prefix for the AHB I/F\n# For instance if all AHB signals are following this convention:\n# - haddr\n# - hsel\n# - ...\nAHBBus.from_entity(dut)\n```\n\nFor reference, down below is the class header of [AHB Bus](cocotbext/ahb/ahb_bus.py). More arguments can also be passed as this extends from [cocotb-bus](https://github.com/cocotb/cocotb-bus) base class.\n```python\nclass AHBBus(Bus):\n    _signals = [\"haddr\", \"hsize\", \"htrans\", \"hwdata\",\n                \"hrdata\", \"hwrite\", \"hready\", \"hresp\"]\n\n    _optional_signals = [\"hburst\", \"hmastlock\", \"hprot\", \"hnonsec\",\n                         \"hexcl\", \"hmaster\", \"hexokay\", \"hsel\", \"hready_in\"]\n```\n\n#### Mandatory vs optional AHB signals\n\n1. AHB Master signals\n\n##### Mandatory\n\n* haddr - Indicates AHB txn address \n* hsize - Indicates AHB txn size\n* htrans - Indicates AHB txn type\n* hwdata - Indicates AHB data to be written\n* hwrite - Indicates type of AHB txn\n\n##### Optional\n\n* hburst\n* hmastlock\n* hprot\n* hnonsec\n* hexcl\n* hmaster\n* hsel \n* hready_in\n\n2. AHB Slave signals \n\n##### Mandatory\n\n* hresp - Indicates AHB txn response type\n* hrdata - Indicates AHB txn read data\n* hready - Indicates AHB slave availability\n\n##### Optional\n\n* hexokay\n\n##### Signal customization for your design\nTo customize signals name to your design `signals` and `optional_signals` dictionnary can be provide. \n```python\nAHBBus.from_prefix(\n    dut, \n    prefix = \"slave_driver\",\n    signals = {\n        \"haddr\" : \"haddr\",\n        \"hsize\" : \"hsize\",\n        \"htrans\" : \"htrans\",\n        \"hwdata\" : \"hwdata\",\n        \"hrdata\" : \"hrdata\",\n        \"hwrite\" : \"hwrite\",\n        \"hready\" : \"hreadyout\",\n        \"hresp\" : \"hresp\"\n    }\n,\n    optional_signals = {\n        \"hsel\" : \"hsel\",\n        \"hready_in\" : \"hready\"\n    }\n)\n```\n\n#### Mandatory vs optional AHB signals\n\n1. AHB Master signals\n\n##### Mandatory\n\n* haddr - Indicates AHB txn address \n* hsize - Indicates AHB txn size\n* htrans - Indicates AHB txn type\n* hwdata - Indicates AHB data to be written\n* hwrite - Indicates type of AHB txn\n\n##### Optional\n\n* hburst\n\n### AHB Master\n\nBoth AHB Master [WIP] and AHB Lite Master classes have the same constructor arguments. Within the arguments, it is required to pass the AHB Bus object, the clock and reset DUT pins. As optional args, a timeout value in clock cycles (per AHB txn), the default value of the master driven IOs and the name of the object.\n```python\nclass AHBLiteMaster:\n    def __init__(\n        self,\n        bus: AHBBus,\n        clock: str,\n        reset: str,\n        timeout: int = 100,\n        def_val: Union[int, str] = \"Z\",\n        name: str = \"ahb_lite\",\n        **kwargs,\n    ):\n```\n\nIn case of AHB Slave error response, the master will cancel the current transaction changing HTRANS from NSEQ to IDLE in the second clock cycle of the error response and then it will retry immediately after (following clock cycle). This is not mandatory but gives time for the master to decide whether it needs to be aborted or not the following transaction.\n\nIts methods are composed by **read()**, **write()** and **custom()**. \n\n#### Write\n\nFor writes, the arguments are listed here:\n\n```python\n    async def write(\n        self,\n        address: Union[int, Sequence[int]],\n        value: Union[int, Sequence[int]],\n        size: Optional[Union[int, Sequence[int]]] = None,\n        pip: Optional[bool] = False,\n    ) -> Sequence[dict]:\n```\n\n**Arguments**\n* address - Single or a list of integer addresses to be written\n* value - Single or a list of integer values to be written\n* Optional[size] - Integer number of bytes to be written (for instance, in 32-bit bus, 1, 2 or 4 bytes), default is the max bus size\n* Optional[pip] - Define if the address/data phase will overlap in a pipeline manner or not, default non-pipelined \n\n**Return**\n* Sequence[dict] - Once all transactions are dispatched and their responses are received, the function returns a list of dict with [AHBResp](cocotbext/ahb/ahb_types.py) responses along with the data.\n\n*Note*: address, value and size have to match their length if provided.\n\n#### Read\n\nFor reads, the arguments are listed here:\n\n```python\n    async def read(\n        self,\n        address: Union[int, Sequence[int]],\n        size: Optional[Union[int, Sequence[int]]] = None,\n        pip: Optional[bool] = False,\n    ) -> Sequence[dict]:\n```\n\n**Arguments**\n* address - Single or a list of integer addresses to be read from\n* Optional[size] - Integer number of bytes to be read (for instance, in 32-bit bus, 1, 2 or 4 bytes), default is the max bus size\n* Optional[pip] - Define if the address/data phase will overlap in a pipeline manner or not, default non-pipelined \n\n**Return**\n* Sequence[dict] - Once all transactions are dispatched and their responses are received, the function returns a list of dict with [AHBResp](cocotbext/ahb/ahb_types.py) responses along with the data.\n\n*Note*: address and size have to match their length if provided.\n\n#### Custom\n\nA third method provides flexibility in case the user wants to perform read or writes together like back-to-back operations such as WAR or RAW. For this, the arguments are listed here:\n\n```python\n    async def custom(\n        self,\n        address: Union[int, Sequence[int]],\n        value: Union[int, Sequence[int]],\n        mode: Union[int, Sequence[int]],\n        size: Optional[Union[int, Sequence[int]]] = None,\n        pip: Optional[bool]\n    ) -> Sequence[dict]:\n```\n\n**Arguments**\n* address - Single or a list of integer addresses to be written to or read from\n* value - Single or a list of integer addresses to be written to or read from\n* mode - Single or a list of operation types - 0 (Read) or 1 (Write)\n* Optional[size] - Integer number of bytes to be written/read (for instance, in 32-bit bus, 1, 2 or 4 bytes), default is the max bus size\n* Optional[pip] - Define if the address/data phase will overlap in a pipeline manner or not, default non-pipelined \n\n**Return**\n* Sequence[dict] - Once all transactions are dispatched and their responses are received, the function returns a list of dict with [AHBResp](cocotbext/ahb/ahb_types.py) responses along with the data.\n\n*Note*: address, value, mode and size have to match their length if provided.\n\n### AHB Slave\n\nBoth AHB Slave [WIP] and AHB Lite Slave classes have the same constructor arguments. Within the arguments, it is required to pass the AHB Bus object, the clock and reset DUT pins. As optional arg, the default value of the slave driven IOs, a generator function to force back-pressure and the name of the object.\n\n```python\nclass AHBLiteSlave:\n    def __init__(\n        self,\n        bus: AHBBus,\n        clock: str,\n        reset: str,\n        def_val: Union[int, str] = \"Z\",\n        bp: Generator[int, None, None] = None,\n        name: str = \"ahb_lite\",\n        **kwargs,\n    ):\n```\n\nThe AHB slaves will not provide any specific data (always zero) or unexpected response, they serve as a basic slave just to check its connectivity while testing AHB Master and as a base class for the AHB Lite Slave RAM. The back-pressure feature is a way to force the slave to demonstrated unavailability while the master issue AHB transactions. The generator needs to return bool type values where bool True indicates slave available and bool False indicate slave unavailable. \n\nIn case of an AHB error response, the Slave inserts a wait state (HREADY == LOW && HRESP == OKAY) however this not required and might change in the future sticking only to the mandatory obligation of 2-cycle error response:\n\n* First: HREADY == LOW / HRESP == ERROR\n* Second: HREADY == HIGH / HRESP == ERROR\n\n#### AHB Lite Slave RAM \n\nThe AHB Lite Slave RAM is a basic memory slave that can receive reads and write like a normal memory-mapped device. The only difference between the normal slave vs this one is the fact that as part of its constructor, a new argument **mem_size** is listed. This argument defines a memory size in bytes for the AHB slave. The only limitation for now, is the fact that all memory addresses have to be aligned to the data bus width, i.e for 32-bit slaves, address[1:0] == 2'b00.\n\n```python\nclass AHBLiteSlaveRAM(AHBLiteSlave):\n    def __init__(\n        self,\n        bus: AHBBus,\n        clock: str,\n        reset: str,\n        def_val: Union[int, str] = \"Z\",\n        bp: Generator[int, None, None] = None,\n        name: str = \"ahb_lite_ram\",\n        mem_size: int = 1024,\n        **kwargs,\n    ):\n```\n\nThank you [@alexforencich](https://github.com/alexforencich/cocotbext-axi) for your work on the memory classes that were leveraged in this project.\n\n### AHB Monitor\n\nA basic AHB monitor was also developed, the idea is to ensure that basic protocol assumptions are respected throughout assertions, its constructor arguments are very similar to the previous discussed classes. For now, only two aspects are checked through this monitor, the first one ensure the master does not change its address phase transaction qualifier once a transaction is issued and the slave is not available. The second property checks that an AHB error response coming from the slave is following the 2-cycle response defined in the AMBA spec.\n\n```python\nclass AHBMonitor:\n    def __init__(\n        self,\n        bus: AHBBus,\n        clock: str,\n        reset: str,\n        name: str = \"ahb_monitor\",\n        **kwargs,\n    ):\n```\n\n### Example\n\nA basic example of this extension usage is demonstrated below and also within the [tests folder](test/) that are available.\n\n```python\nimport cocotb\nimport os\nimport random\nimport math\n\nfrom const import cfg\nfrom cocotb_test.simulator import run\nfrom cocotb.triggers import ClockCycles\nfrom cocotb.clock import Clock\nfrom cocotbext.ahb import AHBBus, AHBLiteMaster, AHBLiteSlaveRAM, AHBResp, AHBMonitor\n\ndef rnd_val(bit: int = 0, zero: bool = True):\n    if zero is True:\n        return random.randint(0, (2**bit) - 1)\n    else:\n        return random.randint(1, (2**bit) - 1)\n\n\ndef pick_random_value(input_list):\n    if input_list:\n        return random.choice(input_list)\n    else:\n        return None  # Return None if the list is empty\n\nasync def run_test(dut):\n    data_width = 32\n    mem_size_kib = 16\n    N = 1000\n\n    # Map the bus monitor to the I/F slave_h* I/F\n    ahb_lite_mon = AHBMonitor(\n        AHBBus.from_prefix(dut, \"slave\"), dut.hclk, dut.hresetn\n    )\n\n    # Create an AHB Lite Slave RAM connected to the master I/F\n    ahb_lite_sram = AHBLiteSlaveRAM(\n        AHBBus.from_prefix(dut, \"master\"),\n        dut.hclk,\n        dut.hresetn,\n        def_val=0,\n        bp=bp_fn,\n        mem_size=mem_size_kib * 1024,\n    )\n\n    # Create an AHB Lite Master connected to the slave I/F\n    ahb_lite_master = AHBLiteMaster(\n        AHBBus.from_prefix(dut, \"slave\"), dut.hclk, dut.hresetn, def_val=\"Z\"\n    )\n   \n    # Create a lit of non-repeated addresses spaces by 8 from 0->2*current RAM size\n    address = random.sample(range(0, 2 * mem_size_kib * 1024, 8), N)\n    value = [rnd_val(data_width) for _ in range(N)]\n    size = [pick_random_value([1, 2, 4]) for _ in range(N)]\n\n    # Perform the writes and reads\n    resp = await ahb_lite_master.write(address, value, size, pip=pip_mode)\n    resp = await ahb_lite_master.read(address, size, pip=pip_mode)\n```\n\n### Example waveforms\n\n![example_ext](docs_utils/txn_example.png)\n\n## <a name=\"lic\"></a> License\ncocotbext-ahb is licensed under the permissive MIT license.Please refer to the [LICENSE](LICENSE) file for details.\n",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "CocotbExt AHB Bus VIP",
    "version": "0.2.6",
    "project_urls": {
        "Bug Tracker": "https://github.com/aignacio/cocotbext-ahb/issues",
        "Homepage": "https://github.com/aignacio/cocotbext-ahb",
        "Source Code": "https://github.com/aignacio/cocotbext-ahb"
    },
    "split_keywords": [
        "soc",
        "vip",
        "hdl",
        "verilog",
        "systemverilog",
        "ahb"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "a3561c28bf752724867704818bf127ec65b3b96f36074b854e54bcbe19d902c3",
                "md5": "f860b2c4814e899674c893a4d8bbda60",
                "sha256": "b034043cf553102ea6b536cca5d117c4cad431cf8c9163159f07722b37be12ad"
            },
            "downloads": -1,
            "filename": "cocotbext_ahb-0.2.6-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "f860b2c4814e899674c893a4d8bbda60",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.6",
            "size": 21561,
            "upload_time": "2023-12-25T20:46:56",
            "upload_time_iso_8601": "2023-12-25T20:46:56.905162Z",
            "url": "https://files.pythonhosted.org/packages/a3/56/1c28bf752724867704818bf127ec65b3b96f36074b854e54bcbe19d902c3/cocotbext_ahb-0.2.6-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "f339e327b009282de448a80a22ae91e6f1953a139f9868ce1ecbc5a4c546cabe",
                "md5": "3f706f6f116c93bdf810c66bbfa1e192",
                "sha256": "6f9343591cb901ec14920ed33af0b693732c131bde6bbe90f6a44dcd16f9ce74"
            },
            "downloads": -1,
            "filename": "cocotbext-ahb-0.2.6.tar.gz",
            "has_sig": false,
            "md5_digest": "3f706f6f116c93bdf810c66bbfa1e192",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.6",
            "size": 23958,
            "upload_time": "2023-12-25T20:46:58",
            "upload_time_iso_8601": "2023-12-25T20:46:58.728971Z",
            "url": "https://files.pythonhosted.org/packages/f3/39/e327b009282de448a80a22ae91e6f1953a139f9868ce1ecbc5a4c546cabe/cocotbext-ahb-0.2.6.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2023-12-25 20:46:58",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "aignacio",
    "github_project": "cocotbext-ahb",
    "travis_ci": false,
    "coveralls": true,
    "github_actions": true,
    "lcname": "cocotbext-ahb"
}
        
Elapsed time: 0.16584s