diff --git a/cocotbext/ahb/ahb_bus.py b/cocotbext/ahb/ahb_bus.py index 6e891ab..d573b42 100644 --- a/cocotbext/ahb/ahb_bus.py +++ b/cocotbext/ahb/ahb_bus.py @@ -4,7 +4,7 @@ # License : MIT license # Author : Anderson I. da Silva (aignacio) # 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 @@ -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: @@ -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) diff --git a/cocotbext/ahb/ahb_master.py b/cocotbext/ahb/ahb_master.py index b234fd9..6b1bfa5 100644 --- a/cocotbext/ahb/ahb_master.py +++ b/cocotbext/ahb/ahb_master.py @@ -4,13 +4,13 @@ # License : MIT license # Author : Anderson I. da Silva (aignacio) # 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__ @@ -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, @@ -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) @@ -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) @@ -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) diff --git a/cocotbext/ahb/ahb_slave.py b/cocotbext/ahb/ahb_slave.py index 93d1098..a62c08c 100644 --- a/cocotbext/ahb/ahb_slave.py +++ b/cocotbext/ahb/ahb_slave.py @@ -4,11 +4,12 @@ # License : MIT license # Author : Anderson I. da Silva (aignacio) # 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 @@ -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.""" @@ -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, diff --git a/docs_utils/template.gtkw b/docs_utils/template.gtkw index 951edb4..f373315 100644 --- a/docs_utils/template.gtkw +++ b/docs_utils/template.gtkw @@ -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 @@ -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 @@ -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 diff --git a/noxfile.py b/noxfile.py index d8483a6..0f3c90d 100644 --- a/noxfile.py +++ b/noxfile.py @@ -4,7 +4,7 @@ # License : MIT license # Author : Anderson I. da Silva (aignacio) # Date : 08.10.2023 -# Last Modified Date: 08.10.2023 +# Last Modified Date: 22.10.2023 import nox @@ -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') diff --git a/tests/dut/dut.v b/tests/dut/dut.v index 84151b0..b8959e9 100644 --- a/tests/dut/dut.v +++ b/tests/dut/dut.v @@ -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, @@ -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, @@ -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, @@ -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; diff --git a/tests/test_ahb_lite.py b/tests/test_ahb_lite.py index 5423dad..c90e08f 100644 --- a/tests/test_ahb_lite.py +++ b/tests/test_ahb_lite.py @@ -4,7 +4,7 @@ # License : MIT license # Author : Anderson I. da Silva (aignacio) # Date : 08.10.2023 -# Last Modified Date: 17.10.2023 +# Last Modified Date: 22.10.2023 import cocotb import os @@ -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)] @@ -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)