Skip to content

Commit

Permalink
Update AHB lite slave to support signaling
Browse files Browse the repository at this point in the history
Signed-off-by: Anderson Ignacio <anderson@aignacio.com>
  • Loading branch information
aignacio committed Oct 22, 2023
1 parent 6919f41 commit f62a724
Show file tree
Hide file tree
Showing 7 changed files with 107 additions and 28 deletions.
12 changes: 10 additions & 2 deletions cocotbext/ahb/ahb_bus.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: 08.10.2023
# Last Modified Date: 22.10.2023

from cocotb_bus.drivers import Bus
from cocotb.handle import SimHandleBase
Expand All @@ -16,7 +16,7 @@ class AHBBus(Bus):
"hrdata", "hwrite", "hready", "hresp"]

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

def __init__(self, entity: SimHandleBase = None,
prefix: str = None, **kwargs: Any) -> None:
Expand All @@ -39,6 +39,14 @@ def addr_width(self):
def hsel_exist(self):
return True if 'hsel' in self._signals else False

@property
def hready_in_exist(self):
return True if 'hready_in' in self._signals else False

@property
def hburst_exist(self):
return True if 'hburst' in self._signals else False

@classmethod
def from_entity(cls, entity, **kwargs):
return cls(entity, **kwargs)
Expand Down
18 changes: 11 additions & 7 deletions cocotbext/ahb/ahb_master.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@
# License : MIT license <Check LICENSE>
# Author : Anderson I. da Silva (aignacio) <anderson@aignacio.com>
# Date : 08.10.2023
# Last Modified Date: 17.10.2023
# Last Modified Date: 22.10.2023

import cocotb
import logging
import copy

from .ahb_types import AHBTrans, AHBWrite, AHBSize, AHBResp
from .ahb_types import AHBTrans, AHBWrite, AHBSize, AHBResp, AHBBurst
from .ahb_bus import AHBBus
from .version import __version__

Expand Down Expand Up @@ -85,6 +85,10 @@ def _addr_phase(self, addr: int,
self.bus.hwrite.value = mode
if self.bus.hsel_exist:
self.bus.hsel.value = 1
if self.bus.hready_in_exist:
self.bus.hready_in.value = 1
if self.bus.hburst_exist:
self.bus.hburst.value = AHBBurst.SINGLE

def _create_vector(self, vec: Sequence[int],
width: int,
Expand Down Expand Up @@ -215,10 +219,10 @@ async def write(self, address: Union[int, Sequence[int]],
width = len(self.bus.hsize)
t_size = self._create_vector(t_size, width, 'address_ph', pip)
# Default signaling
t_mode = [AHBWrite(0b1) for _ in range(len(t_address))]
t_mode = [AHBWrite.WRITE for _ in range(len(t_address))]
width = len(self.bus.hwrite)
t_mode = self._create_vector(t_mode, width, 'address_ph', pip)
t_trans = [AHBTrans(0b10) for _ in range(len(t_address))]
t_trans = [AHBTrans.NONSEQ for _ in range(len(t_address))]
width = len(self.bus.htrans)
t_trans = self._create_vector(t_trans, width, 'address_ph', pip)

Expand Down Expand Up @@ -260,10 +264,10 @@ async def read(self, address: Union[int, Sequence[int]],
width = len(self.bus.hsize)
t_size = self._create_vector(t_size, width, 'address_ph', pip)
# Default signaling
t_mode = [AHBWrite(0b0) for _ in range(len(t_address))]
t_mode = [AHBWrite.READ for _ in range(len(t_address))]
width = len(self.bus.hwrite)
t_mode = self._create_vector(t_mode, width, 'address_ph', pip)
t_trans = [AHBTrans(0b10) for _ in range(len(t_address))]
t_trans = [AHBTrans.NONSEQ for _ in range(len(t_address))]
width = len(self.bus.htrans)
t_trans = self._create_vector(t_trans, width, 'address_ph', pip)

Expand Down Expand Up @@ -316,7 +320,7 @@ async def custom(self, address: Union[int, Sequence[int]],
width = len(self.bus.hwrite)
t_mode = self._create_vector(t_mode, width, 'address_ph', pip)
width = len(self.bus.htrans)
t_trans = [AHBTrans(0b10) for _ in range(len(t_address))]
t_trans = [AHBTrans.NONSEQ for _ in range(len(t_address))]
width = len(self.bus.htrans)
t_trans = self._create_vector(t_trans, width, 'address_ph', pip)

Expand Down
64 changes: 62 additions & 2 deletions cocotbext/ahb/ahb_slave.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 : 16.10.2023
# Last Modified Date: 16.10.2023
# Last Modified Date: 22.10.2023

import cocotb
import logging
import copy
import random

from .ahb_types import AHBTrans, AHBWrite, AHBSize, AHBResp
from .ahb_bus import AHBBus
Expand All @@ -31,10 +32,11 @@ def __init__(self, bus: AHBBus, clock: str, reset: str,
self.log = logging.getLogger(f"cocotb.{name}.{bus._name}."
f"{bus._entity._name}")
self._init_bus()
self.log.info(f"AHB ({name}) master")
self.log.info(f"AHB ({name}) slave")
self.log.info("cocotbext-ahb version %s", __version__)
self.log.info("Copyright (c) 2023 Anderson Ignacio da Silva")
self.log.info("https://github.com/aignacio/cocotbext-ahb")
cocotb.start_soon(self._proc_txn())

def _init_bus(self) -> None:
"""Initialize the bus with default value."""
Expand All @@ -51,6 +53,64 @@ def _get_def(self, width: int = 1) -> BinaryValue:
"""Return a handle obj with the default value"""
return LogicArray([self.def_val for _ in range(width)])

def _rnd_val(self, bit: int = 0, zero: Optional[bool] = True) -> int:
if zero is True:
return random.randint(0, (2**bit) - 1)
else:
return random.randint(1, (2**bit) - 1)

async def _proc_txn(self):
"""Process any incoming txns"""
while True:
# Wait for a txn
await RisingEdge(self.clk)
# Default values in case there is no txn
self.bus.hready.value = self._get_def(1)
self.bus.hrdata.value = self._get_def(len(self.bus.hrdata))
self.bus.hresp.value = AHBResp.OKAY

if self._check_inputs():
if self._check_valid_txn():
self.bus.hready.value = 1
self.bus.hrdata.value = self._rnd_val(self.bus.data_width)
self.bus.hresp.value = AHBResp.OKAY
else:
self.bus.hready.value = 1
self.bus.hrdata.value = self._rnd_val(self.bus.data_width)
self.bus.hresp.value = AHBResp.OKAY

def _check_inputs(self) -> bool:
"""Check any of the master signals are resolvable (i.e not 'z')"""
signals = {'htrans': self.bus.htrans}

for var, val in signals.items():
if val.value.is_resolvable is False:
self.log.warn(f"{var} is not resolvable")
return False
return True

def _check_valid_txn(self) -> bool:
htrans_st = ((AHBTrans(self.bus.htrans.value) != AHBTrans.IDLE) and
(AHBTrans(self.bus.htrans.value) != AHBTrans.BUSY))

if self.bus.hsel_exist:
if self.bus.hready_in_exist:
if ((self.bus.hsel.value == 1) and
(self.bus.hready_in.value == 1) and htrans_st):
return True
else:
return False
else:
if (self.bus.hsel.value == 1) and htrans_st:
return True
else:
return False
else:
if htrans_st:
return True
else:
return False


class AHBSlave(AHBLiteSlave):
def __init__(self, bus: AHBBus, clock: str, reset: str,
Expand Down
20 changes: 11 additions & 9 deletions docs_utils/template.gtkw
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
[*]
[*] GTKWave Analyzer v3.4.0 (w)1999-2022 BSI
[*] Tue Oct 10 19:50:18 2023
[*] Sun Oct 22 10:23:45 2023
[*]
[dumpfile] "run_dir/sim_build_icarus_test_ahb_lite/ahb_template.fst"
[dumpfile_mtime] "Tue Oct 10 19:49:34 2023"
[dumpfile_size] 1093
[dumpfile_mtime] "Sun Oct 22 10:19:54 2023"
[dumpfile_size] 2878
[savefile] "/Users/aignacio/projects/cocotbext-ahb/docs_utils/template.gtkw"
[timestart] 0
[size] 2864 759
[pos] 1977 -885
*-14.506138 24280 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
[timestart] 1926470
[size] 2248 1028
[pos] 1977 0
*-13.691751 1976810 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
[sst_width] 253
[signals_width] 263
[sst_expanded] 1
[sst_vpaned_height] 175
[sst_vpaned_height] 252
@28
ahb_template.hresetn
ahb_template.hclk
Expand All @@ -29,6 +29,7 @@ ahb_template.slave_hwrite
@22
ahb_template.slave_hwdata[31:0]
@28
ahb_template.slave_hready_in
ahb_template.slave_hready
ahb_template.slave_hresp
@22
Expand All @@ -41,10 +42,11 @@ ahb_template.master_haddr[31:0]
@28
ahb_template.master_hsize[2:0]
ahb_template.master_htrans[1:0]
@29
ahb_template.master_hwrite
@22
ahb_template.master_hwdata[31:0]
@29
ahb_template.master_hready_in
@28
ahb_template.master_hready
ahb_template.master_hresp
Expand Down
5 changes: 3 additions & 2 deletions noxfile.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: 08.10.2023
# Last Modified Date: 22.10.2023

import nox

Expand All @@ -29,5 +29,6 @@ def run(session):
@nox.session(python=["3.9", "3.10"])
def lint(session):
session.install('flake8')
session.run('flake8', '--ignore=F401')
# session.run('flake8','--exclude=cocotbext/ahb/__init__.py')
session.run('flake8', '--ignore=F401,W504')
# session.run('flake8','--exclude=__init__.py')
5 changes: 5 additions & 0 deletions tests/dut/dut.v
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ module ahb_template #(
input [1:0] slave_htrans,
input [(DATA_WIDTH-1):0] slave_hwdata,
input slave_hwrite,
input slave_hready_in,
// From slave to interconnect/master
output [(DATA_WIDTH-1):0] slave_hrdata,
output slave_hready,
Expand All @@ -37,6 +38,7 @@ module ahb_template #(
// MASTER - OUT
//---------------------------------------
// From master/interconnect to slave/decoder
output [(ADDR_WIDTH-1):0] master_hsel,
output [(ADDR_WIDTH-1):0] master_haddr,
output [2:0] master_hburst,
output master_hmastlock,
Expand All @@ -48,6 +50,7 @@ module ahb_template #(
output [1:0] master_htrans,
output [(DATA_WIDTH-1):0] master_hwdata,
output master_hwrite,
output master_hready_in,
// From slave to interconnect/master
input [(DATA_WIDTH-1):0] master_hrdata,
input master_hready,
Expand All @@ -65,6 +68,8 @@ module ahb_template #(
assign master_htrans = slave_htrans;
assign master_hwdata = slave_hwdata;
assign master_hwrite = slave_hwrite;
assign master_hready_in = slave_hready_in;
assign master_hsel = slave_hsel;

assign slave_hrdata = master_hrdata;
assign slave_hready = master_hready;
Expand Down
11 changes: 5 additions & 6 deletions tests/test_ahb_lite.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: 17.10.2023
# Last Modified Date: 22.10.2023

import cocotb
import os
Expand Down Expand Up @@ -50,12 +50,10 @@ async def run_test(dut):
ahb_lite_slave = AHBLiteSlave(AHBBus.from_prefix(dut, "master"),
dut.hclk,
dut.hresetn,
def_val=1)
def_val=0)

type(ahb_lite_slave)

# dut.master_hready.value = 1
# dut.master_hresp.value = 0
# dut.master_hrdata.value = 0
print(type(ahb_lite_slave))
address = [rnd_val(32) for _ in range(200)]
value = [rnd_val(32) for _ in range(200)]
size = [pick_random_value([1, 2, 4]) for _ in range(200)]
Expand All @@ -76,6 +74,7 @@ async def run_test(dut):
mode = [0, 1]
resp = await ahb_lite_master.custom(address, value, mode, size)
print(resp)

mode = [1, 0]
resp = await ahb_lite_master.custom(address, value, mode, size)
print(resp)
Expand Down

0 comments on commit f62a724

Please sign in to comment.