Source code for hwtLib.mem.hashTable_intf

from hwt.hwIO import HwIO
from hwt.hwIOs.agents.rdVldSync import HwIODataRdVldAgent
from hwt.hwIOs.std import HwIODataRdVld, HwIOVectSignal, HwIOSignal, HwIORdVldSync
from hwt.hwParam import HwParam
from hwt.math import log2ceil
from hwt.pyUtils.typingFuture import override
from hwtSimApi.agents.base import AgentBase
from hwtSimApi.hdlSimulator import HdlSimulator
from ipCorePackager.constants import DIRECTION


[docs] class HwIOInsertAgent(HwIODataRdVldAgent): """ Simulation agent for `.HwIOInsert` interface data format: * if interface has data signal, data format is tuple (hash, key, data, item_vld) * if interface does not have data signal, data format is tuple (hash, key, item_vld) """
[docs] def __init__(self, sim: HdlSimulator, hwIO: "HwIOInsert"): HwIODataRdVldAgent.__init__(self, sim, hwIO) self.hasData = bool(hwIO.DATA_WIDTH)
[docs] @override def get_data(self): i = self.hwIO _hash = i.hash.read() key = i.key.read() item_vld = i.item_vld.read() if self.hasData: data = i.data.read() return hash, key, data, item_vld else: return hash, key, item_vld
[docs] @override def set_data(self, data): i = self.hwIO if data is None: i.hash.write(None) i.key.write(None) if self.hasData: i.data.write(None) i.item_vld.write(None) else: if self.hasData: _hash, key, _data, item_vld = data i.data.write(_data) else: _hash, key, item_vld = data i.hash.write(_hash) i.key.write(key) i.item_vld.write(item_vld)
[docs] class HwIOInsert(HwIORdVldSync): """ .. hwt-autodoc:: """ @override def hwConfig(self): self.HASH_WIDTH = HwParam(8) self.KEY_WIDTH = HwParam(8) self.DATA_WIDTH = HwParam(0) @override def hwDeclr(self): super(HwIOInsert, self).hwDeclr() self.hash = HwIOVectSignal(self.HASH_WIDTH) self.key = HwIOVectSignal(self.KEY_WIDTH) if self.DATA_WIDTH: self.data = HwIOVectSignal(self.DATA_WIDTH) self.item_vld = HwIOSignal()
[docs] @override def _initSimAgent(self, sim: HdlSimulator): self._ag = HwIOInsertAgent(sim, self)
[docs] class HwIOLookupKeyAgent(HwIODataRdVldAgent): """ Simulation agent for HwIOLookupKey interface """
[docs] def __init__(self, sim: HdlSimulator, hwIO: "HwIOLookupKey"): HwIODataRdVldAgent.__init__(self, sim, hwIO) self.HAS_LOOKUP_ID = bool(hwIO.LOOKUP_ID_WIDTH)
[docs] @override def get_data(self): hwIO = self.hwIO if self.HAS_LOOKUP_ID: return hwIO.lookup_id.read(), hwIO.key.read() return hwIO.key.read()
[docs] @override def set_data(self, data): hwIO = self.hwIO if self.HAS_LOOKUP_ID: _id, _key = data return hwIO.lookup_id.write(_id), hwIO.key.write(_key) self.hwIO.key.write(data)
[docs] class HwIOLookupKey(HwIORdVldSync): """ .. hwt-autodoc:: """ @override def hwConfig(self): self.LOOKUP_ID_WIDTH = HwParam(0) self.KEY_WIDTH = HwParam(8) @override def hwDeclr(self): HwIORdVldSync.hwDeclr(self) if self.LOOKUP_ID_WIDTH: self.lookupId = HwIOVectSignal(self.LOOKUP_ID_WIDTH) self.key = HwIOVectSignal(self.KEY_WIDTH)
[docs] @override def _initSimAgent(self, sim: HdlSimulator): self._ag = HwIOLookupKeyAgent(sim, self)
[docs] class HwIOLookupResultAgent(HwIODataRdVldAgent): """ Simulation agent for `.HwIOLookupResult` data is stored in .data data format is tuple (hash, key, data, found) but some items can be missing depending on configuration of interface """
[docs] def __init__(self, sim, hwIO): HwIODataRdVldAgent.__init__(self, sim, hwIO) self.hasHash = bool(hwIO.LOOKUP_HASH) self.hasKey = bool(hwIO.LOOKUP_KEY) self.hasData = bool(hwIO.DATA_WIDTH)
[docs] @override def get_data(self): d = [] append = d.append hwIO = self.hwIO if self.hasHash: append(hwIO.hash.read()) if self.hasKey: append(hwIO.key.read()) if self.hasData: append(hwIO.data.read()) append(hwIO.found.read()) append(hwIO.occupied.read()) return tuple(d)
[docs] @override def set_data(self, data): hwIO = self.hwIO dIt = iter(data) if self.hasHash: hwIO.hash.write(next(dIt)) if self.hasKey: hwIO.key.write(next(dIt)) if self.hasData: hwIO.data.write(next(dIt)) hwIO.found.write(next(dIt)) hwIO.occupied.write(next(dIt)) try: next(dIt) raise AssertionError(f"To many items in data {data}") except IndexError: return
[docs] class HwIOLookupResult(HwIODataRdVld): """ HwIO for result of lookup in hash table :ivar ~.HASH_WIDTH: width of the hash used by hash table :ivar ~.KEY_WIDTH: width of the key used by hash table :ivar ~.LOOKUP_HASH: flag if this interface should have hash signal :ivar ~.LOOKUP_KEY: flag if this interface should have hash signal :ivar ~.hash: hash for this key (= index in this table) :ivar ~.key: original key which was searched for :ivar ~.data: data under this key :ivar ~.occupied: flag which tells if there is an valid item under this key .. hwt-autodoc:: """ @override def hwConfig(self): self.HASH_WIDTH = HwParam(8) self.KEY_WIDTH = HwParam(8) self.DATA_WIDTH = HwParam(0) self.LOOKUP_ID_WIDTH = HwParam(0) self.LOOKUP_HASH = HwParam(False) self.LOOKUP_KEY = HwParam(False) @override def hwDeclr(self): HwIORdVldSync.hwDeclr(self) if self.LOOKUP_ID_WIDTH: self.lookupId = HwIOVectSignal(self.LOOKUP_ID_WIDTH) if self.LOOKUP_HASH: self.hash = HwIOVectSignal(self.HASH_WIDTH) if self.LOOKUP_KEY: self.key = HwIOVectSignal(self.KEY_WIDTH) if self.DATA_WIDTH: self.data = HwIOVectSignal(self.DATA_WIDTH) self.found = HwIOSignal() self.occupied = HwIOSignal()
[docs] @override def _initSimAgent(self, sim: HdlSimulator): self._ag = HwIOLookupResultAgent(sim, self)
[docs] class HwIOHashTable(HwIO): """ .. hwt-autodoc:: """ @override def hwConfig(self): self.ITEMS_CNT = HwParam(32) self.KEY_WIDTH = HwParam(16) self.DATA_WIDTH = HwParam(8) self.LOOKUP_ID_WIDTH = HwParam(0) self.LOOKUP_HASH = HwParam(False) self.LOOKUP_KEY = HwParam(False) @override def hwDeclr(self): assert int(self.KEY_WIDTH) > 0 assert int(self.DATA_WIDTH) >= 0 assert int(self.ITEMS_CNT) > 1 self.HASH_WIDTH = log2ceil(self.ITEMS_CNT) assert self.HASH_WIDTH < int(self.KEY_WIDTH), ( "It makes no sense to use hash table when you can use key directly as index", self.HASH_WIDTH, self.KEY_WIDTH) with self._hwParamsShared(): self.insert = HwIOInsert() self.insert.HASH_WIDTH = self.HASH_WIDTH self.lookup = HwIOLookupKey() self.lookupRes = HwIOLookupResult(masterDir=DIRECTION.IN) self.lookupRes.HASH_WIDTH = self.HASH_WIDTH
[docs] @override def _initSimAgent(self, sim: HdlSimulator): self._ag = HwIOHashTableAgent(sim, self)
[docs] class HwIOHashTableAgent(AgentBase):
[docs] def __init__(self, sim:HdlSimulator, hwIO: HwIOHashTable): AgentBase.__init__(self, sim, hwIO) hwIO.insert._initSimAgent(sim) hwIO.lookup._initSimAgent(sim) hwIO.lookupRes._initSimAgent(sim)
[docs] @override def getDrivers(self): hwIO = self.hwIO yield from hwIO.insert._ag.getDrivers() yield from hwIO.lookup._ag.getDrivers() yield from hwIO.lookupRes._ag.getMonitors()
[docs] @override def getMonitors(self): hwIO = self.hwIO yield from hwIO.insert._ag.getMonitors() yield from hwIO.lookup._ag.getMonitors() yield from hwIO.lookupRes._ag.getDrivers()