Source code for hwtLib.cesnet.mi32.intf

from hwt.hdl.constants import READ, WRITE, READ_WRITE
from hwt.interfaces.agents.handshaked import HandshakedAgent
from hwt.interfaces.agents.vldSynced import VldSyncedAgent
from hwt.interfaces.std import VectSignal, Signal
from hwt.simulator.agentBase import SyncAgentBase
from hwt.synthesizer.interface import Interface
from hwt.synthesizer.param import Param
from hwtLib.avalon.mm import AvalonMmAddrAgent
from ipCorePackager.constants import DIRECTION
from pyMathBitPrecise.bit_utils import mask
from hwtSimApi.hdlSimulator import HdlSimulator


[docs]class Mi32(Interface): """ 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:: """ def _config(self): self.DATA_WIDTH = Param(32) self.ADDR_WIDTH = Param(32) def _declr(self): self.addr = VectSignal(self.ADDR_WIDTH) self.rd = Signal() self.wr = Signal() self.ardy = Signal(masterDir=DIRECTION.IN) self.be = VectSignal(self.DATA_WIDTH // 8) self.dwr = VectSignal(self.DATA_WIDTH) self.drd = VectSignal(self.DATA_WIDTH, masterDir=DIRECTION.IN) self.drdy = Signal(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] 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, intf: Mi32, allowNoReset=False): SyncAgentBase.__init__(self, sim, intf, allowNoReset=allowNoReset) self.addrAg = Mi32AddrAgent(sim, intf, allowNoReset=allowNoReset) self.dataAg = Mi32DataAgent(sim, intf, 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] def getDrivers(self): self.setEnable = self.setEnable_asDriver yield from self.dataAg.getMonitors() yield from self.addrAg.getDrivers()
[docs] def getMonitors(self): self.setEnable = self.setEnable_asMonitor yield from self.dataAg.getDrivers() yield from self.addrAg.getMonitors()
[docs]class Mi32AddrAgent(HandshakedAgent): """ :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 def get_ready_signal(cls, intf): return intf.ardy
[docs] @classmethod def get_valid_signal(cls, intf): return (intf.rd, intf.wr)
[docs] 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] def set_valid(self, val): AvalonMmAddrAgent.set_valid(self, val)
[docs] def get_data(self): intf = self.intf address = intf.addr.read() byteEnable = intf.be.read() read = bool(intf.rd.read()) write = bool(intf.wr.read()) wdata = intf.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] def set_data(self, data): intf = self.intf if data is None: intf.addr.write(None) intf.be.write(None) intf.rd.write(0) intf.wr.write(0) else: rw = data[0] if rw is READ: _, address = data rd, wr = 1, 0 be = mask(intf.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}") intf.addr.write(address) intf.rd.write(rd) intf.wr.write(wr) intf.be.write(be) intf.dwr.write(wdata)
[docs]class Mi32DataAgent(VldSyncedAgent):
[docs] @classmethod def get_valid_signal(cls, intf: Mi32): return intf.drdy
[docs] def get_data(self): return self.intf.drd.read()
[docs] def set_data(self, data): self.intf.drd.write(data)