Source code for hwtLib.cesnet.mi32.intf

from hwt.constants import READ, WRITE, READ_WRITE
from hwt.hwIO import HwIO
from hwt.hwIOs.agents.rdVldSync import HwIODataRdVldAgent
from hwt.hwIOs.agents.vldSync import HwIODataVldAgent
from hwt.hwIOs.std import HwIOVectSignal, HwIOSignal
from hwt.hwParam import HwParam
from hwt.pyUtils.typingFuture import override
from hwt.simulator.agentBase import SyncAgentBase
from hwtLib.avalon.mm import AvalonMmAddrAgent
from hwtSimApi.hdlSimulator import HdlSimulator
from ipCorePackager.constants import DIRECTION
from pyMathBitPrecise.bit_utils import mask


[docs] class Mi32(HwIO): """ Simple memory interface similar to AvalonMM :ivar ~.addr: r/w address :ivar ~.rd: read enable :ivar ~.wr: write enable :ivar ~.ardy: slave address channel ready :ivar ~.be: data byte mask for write :ivar ~.dwr: write data :ivar ~.drd: read data :ivar ~.drdy: read data valid .. hwt-autodoc:: """ @override def hwConfig(self): self.DATA_WIDTH = HwParam(32) self.ADDR_WIDTH = HwParam(32) @override def hwDeclr(self): self.addr = HwIOVectSignal(self.ADDR_WIDTH) self.rd = HwIOSignal() self.wr = HwIOSignal() self.ardy = HwIOSignal(masterDir=DIRECTION.IN) self.be = HwIOVectSignal(self.DATA_WIDTH // 8) self.dwr = HwIOVectSignal(self.DATA_WIDTH) self.drd = HwIOVectSignal(self.DATA_WIDTH, masterDir=DIRECTION.IN) self.drdy = HwIOSignal(masterDir=DIRECTION.IN)
[docs] def _getWordAddrStep(self): """ :return: size of one word in unit of address """ return int(self.DATA_WIDTH) // self._getAddrStep()
[docs] def _getAddrStep(self): """ :return: how many bits is one unit of address (e.g. 8 bits for char * pointer, 36 for 36 bit bram) """ return 8
[docs] @override def _initSimAgent(self, sim: HdlSimulator): self._ag = Mi32Agent(sim, self)
[docs] class Mi32Agent(SyncAgentBase): """ Simulation agent for Mi32 bus interface :ivar ~.requests: request data, items are tuples (READ, address) or (WRITE, address, data, be_mask) :ivar ~.rData: data read from interface """
[docs] def __init__(self, sim: HdlSimulator, hwIO: Mi32, allowNoReset=False): SyncAgentBase.__init__(self, sim, hwIO, allowNoReset=allowNoReset) self.addrAg = Mi32AddrAgent(sim, hwIO, allowNoReset=allowNoReset) self.dataAg = Mi32DataAgent(sim, hwIO, allowNoReset=allowNoReset)
[docs] def requests_get(self): return self.addrAg.data
[docs] def requests_set(self, v): self.addrAg.data = v
requests = property(requests_get, requests_set)
[docs] def r_data_get(self): return self.dataAg.data
[docs] def r_data_set(self, v): self.dataAg.data = v
r_data = property(r_data_get, r_data_set)
[docs] @override def getDrivers(self): self.setEnable = self.setEnable_asDriver yield from self.dataAg.getMonitors() yield from self.addrAg.getDrivers()
[docs] @override def getMonitors(self): self.setEnable = self.setEnable_asMonitor yield from self.dataAg.getDrivers() yield from self.addrAg.getMonitors()
[docs] class Mi32AddrAgent(HwIODataRdVldAgent): """ :ivar ~.requests: request data, items are tuples (READ, address) or (WRITE, address, data, be_mask) :note: two valid signals "read", "write" :note: one ready_n signal "waitrequest" :note: on write set data and byteenamble as well """
[docs] @classmethod @override def get_ready_signal(cls, hwIO): return hwIO.ardy
[docs] @classmethod @override def get_valid_signal(cls, hwIO): return (hwIO.rd, hwIO.wr)
[docs] @override def get_valid(self): r = self._vld[0].read() w = self._vld[1].read() r.val = r.val | w.val r.vld_mask = r.vld_mask & w.vld_mask return r
[docs] @override def set_valid(self, val): AvalonMmAddrAgent.set_valid(self, val)
[docs] @override def get_data(self): hwIO = self.hwIO address = hwIO.addr.read() byteEnable = hwIO.be.read() read = bool(hwIO.rd.read()) write = bool(hwIO.wr.read()) wdata = hwIO.dwr.read() if read and write: rw = READ_WRITE elif read: rw = READ elif write: rw = WRITE else: raise AssertionError("This funtion should not be called when data" "is not ready on interface") return (rw, address, wdata, byteEnable)
[docs] @override def set_data(self, data): hwIO = self.hwIO if data is None: hwIO.addr.write(None) hwIO.be.write(None) hwIO.rd.write(0) hwIO.wr.write(0) else: rw = data[0] if rw is READ: _, address = data rd, wr = 1, 0 be = mask(hwIO.DATA_WIDTH // 8) wdata = None elif rw is WRITE: rd, wr = 0, 1 _, address, wdata, be = data elif rw is READ_WRITE: rd, wr = 1, 1 _, address, wdata, be = data else: raise TypeError(f"rw is in invalid format {rw}") hwIO.addr.write(address) hwIO.rd.write(rd) hwIO.wr.write(wr) hwIO.be.write(be) hwIO.dwr.write(wdata)
[docs] class Mi32DataAgent(HwIODataVldAgent):
[docs] @classmethod @override def get_valid_signal(cls, hwIO: Mi32): return hwIO.drdy
[docs] @override def get_data(self): return self.hwIO.drd.read()
[docs] @override def set_data(self, data): self.hwIO.drd.write(data)