Skip to content

Commit

Permalink
Merge pull request #5 from aignacio/bus_monitor_impr
Browse files Browse the repository at this point in the history
Bus monitor improvements
  • Loading branch information
aignacio committed Jun 15, 2024
2 parents 5c45c1a + f7860d1 commit 24b26a3
Show file tree
Hide file tree
Showing 16 changed files with 10,985 additions and 113 deletions.
1 change: 1 addition & 0 deletions .github/workflows/test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ on:
branches:
- master
- 'stable/**'
- bus_monitor_impr
pull_request:
branches:
- master
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -134,3 +134,4 @@ output
run_dir/
.nox/*
.DS_Store
*.txt
33 changes: 23 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,14 @@ The repository contains a small script that starts a container fetched from Dock
```bash
$ cd cocotbext-ahb/
$ ./ship.sh
# To run all tests
$ nox
# To run a specific test
$ nox -s run -- -k "test_ahb_lite.py"
# To run lint
$ nox -s lint
```

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
Expand All @@ -54,7 +61,7 @@ This AHB extension is composed by master, slaves and a single monitor. Thus, the
* **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 Monitor** - Basic monitor to check AHB transactions, extends from [Monitor](https://github.com/cocotb/cocotb-bus/blob/master/src/cocotb_bus/monitors/__init__.py#L30) cocotb-bus class

### AHB Bus

Expand Down Expand Up @@ -309,20 +316,26 @@ Thank you [@alexforencich](https://github.com/alexforencich/cocotbext-axi) for y

### 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.
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, the monitor checks for basic protocol violations such as :

- Ensure the master/bus decoder does not change its address phase transaction qualifiers (hsel[if app], haddr, htrans, hwrite) while the slave is not available (hready == 0);
- Ensure the master/bus decoder does not change its data phase transaction qualifier (hwdata) while the slave is not available (hready == 0);
- Checks that an AHB error response coming from the slave is following the 2-cycle response defined in the AMBA spec.

```python
class AHBMonitor:
class AHBMonitor(Monitor):
def __init__(
self,
bus: AHBBus,
clock: str,
reset: str,
name: str = "ahb_monitor",
**kwargs,
):
self,
bus: AHBBus,
clock: str,
reset: str,
prefix: str = None,
**kwargs: Any
) -> None:
```

As the monitor is extended from [Monitor](https://github.com/cocotb/cocotb-bus/blob/master/src/cocotb_bus/monitors/__init__.py#L30) cocotb-bus class, it is possible to pass its object as a callable reference to a [Scoreboard](https://github.com/cocotb/cocotb-bus/blob/master/src/cocotb_bus/scoreboard.py#L18) object and use it to compare transactions. For reference, please check the [`tests/test_ahb_lite_monitor_scoreboard.py`](tests/test_ahb_lite_monitor_scoreboard.py) and see how its implemented.

### Example

A basic example of this extension usage is demonstrated below and also within the [tests folder](test/) that are available.
Expand Down
4 changes: 2 additions & 2 deletions cocotbext/ahb/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
# License : MIT license <Check LICENSE>
# Author : Anderson I. da Silva (aignacio) <anderson@aignacio.com>
# Date : 08.10.2023
# Last Modified Date: 27.10.2023
# Last Modified Date: 15.06.2024

# Imported all classes in the default constructor to avoid
# specific imports by knowing the folder/files
Expand All @@ -17,4 +17,4 @@
from .ahb_slave import AHBLiteSlave, AHBSlave, AHBLiteSlaveRAM
from .ahb_bus import AHBBus
from .ahb_types import AHBResp, AHBSize, AHBBurst, AHBTrans, AHBWrite
from .ahb_monitor import AHBMonitor
from .ahb_monitor import AHBMonitor, AHBTxn
21 changes: 13 additions & 8 deletions cocotbext/ahb/ahb_master.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@
# License : MIT license <Check LICENSE>
# Author : Anderson I. da Silva (aignacio) <anderson@aignacio.com>
# Date : 08.10.2023
# Last Modified Date: 25.12.2023
# Last Modified Date: 15.06.2024

import cocotb
import logging
import copy
import datetime

from .ahb_types import AHBTrans, AHBWrite, AHBSize, AHBResp, AHBBurst
from .ahb_bus import AHBBus
Expand Down Expand Up @@ -42,7 +43,9 @@ def __init__(
self._init_bus()
self.log.info(f"AHB ({name}) master")
self.log.info("cocotbext-ahb version %s", __version__)
self.log.info("Copyright (c) 2023 Anderson Ignacio da Silva")
self.log.info(
f"Copyright (c) {datetime.datetime.now().year} Anderson Ignacio da Silva"
)
self.log.info("https://github.com/aignacio/cocotbext-ahb")

def _init_bus(self) -> None:
Expand Down Expand Up @@ -268,15 +271,17 @@ async def write(
if size is None:
size = [self.bus._data_width // 8 for _ in range(len(address))]
else:
if not isinstance(size, list):
size = [size]
for sz in size:
AHBLiteMaster._check_size(sz, len(self.bus.hwdata) // 8)

# Convert all inputs into lists, if not already

if not isinstance(value, list):
value = [value]
if not isinstance(size, list):
size = [size]
# if not isinstance(size, list):
# size = [size]

# First check if the input sizes are correct
if len(address) != len(value):
Expand Down Expand Up @@ -329,13 +334,13 @@ async def read(
if size is None:
size = [self.bus._data_width // 8 for _ in range(len(address))]
else:
# Convert all inputs into lists, if not already
if not isinstance(size, list):
size = [size]

for sz in size:
AHBLiteMaster._check_size(sz, len(self.bus.hwdata) // 8)

# Convert all inputs into lists, if not already
if not isinstance(size, list):
size = [size]

# First check if the input sizes are correct
if len(address) != len(size):
raise Exception(
Expand Down
Loading

0 comments on commit 24b26a3

Please sign in to comment.