def check_if_can_read(): yield WaitCombStable() assert (len(io.fifo_inst.memory) == 3) item0 = io.fifo_inst.memory[0] item0.read() for i in io.fifo_inst.memory: i.read()
def monitorWithClk(self): # if clock is specified this function is periodically called every # clk tick, when agent is enabled yield WaitCombStable() if self._enabled and self.notReset(): d = self.get_data() self.data.append(d)
def checkIfRdWillBeValid(self): yield WaitCombStable() rd = self.get_ready() try: rd = int(rd) except ValueError: raise AssertionError(self.sim.now, self.intf, "rd signal in invalid state")
def data_collector(): yield Timer(CLK_PERIOD // 2) assert sim.now == CLK_PERIOD // 2 val = io.val while True: yield Timer(CLK_PERIOD) yield WaitCombStable() data.append((sim.now, int(val.read())))
def monitor(self): yield WaitCombStable() if self.notReset(): intf = self.intf vld = self.get_valid() vld = int(vld) if vld: d = self.get_data() if self._debugOutput is not None: self._debugOutput.write( "%s, read, %d: %r\n" % (intf._getFullName(), self.sim.now, d)) self.data.append(d)
def monitor(self): """ Handle read/write request on this interfaces This method is executed on clock edge. This means that the read data should be put on dout after clock edge. """ intf = self.intf yield WaitCombStable() if self.notReset(): en = intf.en.read() en = int(en) if en: we = intf.we.read() we = int(we) addr = intf.addr.read() if we: data = intf.din.read() self.onWriteReq(addr, data) else: self.onReadReq(addr) if self.requests: req = self.requests.popleft() t = req[0] addr = req[1] if t == READ: v = self.mem.get(addr.val, None) yield Timer(1) yield WaitWriteOnly() intf.dout.write(v) else: assert t == WRITE # yield WaitWriteOnly() # intf.dout.write(None) yield Timer(1) # after clock edge yield WaitWriteOnly() self.mem[addr.val] = req[2]
def monitor(self): # set wait signal # if en == 1 take data intf = self.intf yield WaitWriteOnly() intf.wait.write(0) yield WaitCombStable() # wait for potential update of en en = intf.en.read() try: en = int(en) except ValueError: raise AssertionError(self.sim.now, intf, "en signal in invalid state") if en: yield Timer(CLK_PERIOD / 10) yield WaitCombRead() self.data.append(self.get_data())
def driver(self): intf = self.intf if self.requireInit: yield WaitWriteOnly() intf.en.write(0) intf.we.write(0) self.requireInit = False readPending = self.readPending yield WaitCombRead() if self.requests and self.notReset(): yield WaitWriteOnly() req = self.requests.popleft() if req is NOP: intf.en.write(0) intf.we.write(0) self.readPending = False else: self.doReq(req) intf.en.write(1) else: yield WaitWriteOnly() intf.en.write(0) intf.we.write(0) self.readPending = False if readPending: # in previous clock the read request was dispatched, now we are collecting the data yield WaitCombStable() # now we are after clk edge d = intf.dout.read() self.r_data.append(d) if self._debugOutput is not None: self._debugOutput.write("%s, on %r read_data: %d\n" % ( self.intf._getFullName(), self.sim.now, d.val))
def monitor(self): """ Collect data from interface """ start = self.sim.now yield WaitCombRead() if not self._enabled: return if self.notReset(): yield WaitWriteOnly() if not self._enabled: return # update rd signal only if required if self._lastRd is not 1: self.set_ready(1) self._lastRd = 1 # try to run onMonitorReady if there is any try: onMonitorReady = self.onMonitorReady except AttributeError: onMonitorReady = None if onMonitorReady is not None: onMonitorReady() else: yield WaitCombRead() assert int(self.get_ready()) == self._lastRd, ( "Something changed the value of ready withou notifying of this agent" " which is responsible for this", self.sim.now, self.get_ready(), self._lastRd) if not self._enabled: return if not self._enabled: return # wait for response of master yield WaitCombStable() if not self._enabled: return vld = self.get_valid() try: vld = int(vld) except ValueError: raise AssertionError( self.sim.now, self.intf, "vld signal is in invalid state") if vld: # master responded with positive ack, do read data d = self.get_data() if self._debugOutput is not None: self._debugOutput.write( "%s, read, %d: %r\n" % ( self.intf._getFullName(), self.sim.now, d)) self.data.append(d) if self._afterRead is not None: self._afterRead() else: if self._lastRd is not 0: yield WaitWriteOnly() # can not receive, say it to masters self.set_ready(0) self._lastRd = 0 else: assert int(self.get_ready()) == self._lastRd assert start == self.sim.now
def driver(self): """ Push data to interface set vld high and wait on rd in high then pass new data """ start = self.sim.now yield WaitWriteOnly() if not self._enabled: return # pop new data if there are not any pending if self.actualData is NOP and self.data: self.actualData = self.data.popleft() doSend = self.actualData is not NOP # update data on signals if is required if self.actualData is not self._lastWritten: if doSend: data = self.actualData else: data = None self.set_data(data) self._lastWritten = self.actualData yield WaitCombRead() if not self._enabled: return en = self.notReset() vld = int(en and doSend) if self._lastVld is not vld: yield WaitWriteOnly() self.set_valid(vld) self._lastVld = vld if not self._enabled: # we can not check rd it in this function because we can not wait # because we can be reactivated in this same time yield self.checkIfRdWillBeValid() return # wait for response of slave yield WaitCombStable() if not self._enabled: return rd = self.get_ready() try: rd = int(rd) except ValueError: raise AssertionError( self.sim.now, self.intf, "rd signal in invalid state") from None if not vld: assert start == self.sim.now return if rd: # slave did read data, take new one if self._debugOutput is not None: self._debugOutput.write("%s, wrote, %d: %r\n" % ( self.intf._getFullName(), self.sim.now, self.actualData)) a = self.actualData # pop new data, because actual was read by slave if self.data: self.actualData = self.data.popleft() else: self.actualData = NOP # try to run onDriverWriteAck if there is any onDriverWriteAck = getattr(self, "onDriverWriteAck", None) if onDriverWriteAck is not None: onDriverWriteAck() onDone = getattr(a, "onDone", None) if onDone is not None: onDone() assert start == self.sim.now
def monitor(self): """ Collect data from interface If onMonitorReady is present run it before setting ready and before data is read from the channel """ start = self.sim.now yield WaitCombRead() if not self._enabled: return if self.notReset(): yield WaitWriteOnly() if not self._enabled: return if self._readyComnsummed: # try to run onMonitorReady if there is any to preset value on signals potentially # going against main data flow of this channel onMonitorReady = getattr(self, "onMonitorReady", None) if onMonitorReady is not None: onMonitorReady() self._readyComnsummed = False # update rd signal only if required if self._lastRd != 1: self.set_ready(1) self._lastRd = 1 else: yield WaitCombRead() assert int(self.get_ready()) == self._lastRd, ( "Something changed the value of ready without notifying this agent" " which is responsible for this", self.sim.now, self.get_ready(), self._lastRd) if not self._enabled: return # wait for response of master yield WaitCombStable() if not self._enabled: return vld = self.get_valid() try: vld = int(vld) except ValueError: raise AssertionError(self.sim.now, self.intf, "vld signal is in invalid state") if vld: # master responded with positive ack, do read data d = self.get_data() if self._debugOutput is not None: name = self.intf._getFullName() self._debugOutput.write( f"{name:s}, read, {self.sim.now:d}: {d}\n") self.data.append(d) if self._afterRead is not None: self._afterRead() # data was read from th channel next ready bellongs to a different data chunk self._readyComnsummed = True else: self._readyComnsummed = True if self._lastRd != 0: yield WaitWriteOnly() # can not receive, say it to masters self.set_ready(0) self._lastRd = 0 else: assert int(self.get_ready()) == self._lastRd assert start == self.sim.now