def monitor(self): """ Initialize data reading if wait is 0 """ intf = self.intf yield WaitCombRead() if self.notReset(): # wait until wait signal is stable wait_last = None while True: yield WaitCombRead() wait = intf.wait.read() try: wait = int(wait) except ValueError: raise AssertionError(self.sim.now, intf, "wait signal in invalid state") if wait is wait_last: break else: wait_last = wait yield WaitWriteOnly() rd = not wait else: rd = False yield WaitWriteOnly() intf.en.write(rd) self.readPending = rd
def __call__(self): try: sig = self.sig fn = self.fn sig_read = sig.read if self.isGenerator: if self.pre_init: yield from fn() while True: yield Edge(sig) if self._enable and self.shouldBeEnabledFn(): yield WaitCombRead() if sig_read(): yield from fn() else: if self.pre_init: fn() while True: yield Edge(sig) if self._enable and self.shouldBeEnabledFn(): yield WaitCombRead() if sig_read(): fn() except ExitCallbackLoop: pass
def monitor(self): """Collect data from interface""" yield WaitCombRead() if self.notReset() and self._enabled: yield WaitWriteOnly() self.set_ready(1) yield WaitCombRead() d = self.get_data() self.data.append(d) else: yield WaitWriteOnly() self.set_ready(0)
def monitor(self): """ The evaluate a tristate 'i' value from 'o' and 't' and optionaly store it. One step. """ yield WaitCombRead() # read in pre-clock-edge t = self.t.read() o = self.o.read() sim = self.sim if self.pullMode is not None and sim.now > 0: try: t = int(t) except ValueError: raise AssertionError( sim.now, self.t, "Invalid value on tristate interface => ioblock would burn" ) try: o = int(o) except ValueError: raise AssertionError( sim.now, self.o, "Invalid value on tristate interface => ioblock would burn" ) if self.pullMode == o: raise AssertionError( sim.now, self.o, "Can not set value to a same as pull up," " because others may try to set it to oposite => ioblock would burn" ) if t: v = o else: v = self.pullMode last = self.i.read() try: last = int(last) except ValueError: last = None yield WaitWriteOnly() self.i.write(v) if self.collectData and sim.now > 0: yield WaitCombRead() if self.notReset(): self.data.append(v)
def driver(self): intf = self.intf actual = self.actual actual_next = actual if self._requireInit: yield WaitWriteOnly() intf.bus2ip_cs.write(0) self._requireInit = False yield WaitCombRead() # now we are after clk edge if actual is not NOP: if actual[0] is READ: yield WaitCombRead() rack = intf.ip2bus_rdack.read() rack = int(rack) if rack: d = intf.ip2bus_data.read() if self._debugOutput is not None: name = self.intf._getFullName() self._debugOutput.write( f"{name:s}, on {self.sim.now} read_data: {d.val:d}\n" ) self.r_data.append(d) actual_next = NOP else: # write in progress wack = int(intf.ip2bus_wrack.read()) if wack: if self._debugOutput is not None: name = self.intf._getFullName() self._debugOutput.write( f"{name:s}, on {self.sim.now} write_ack\n") actual_next = NOP en = self.notReset() if en: if self.actual is NOP: if self.requests: req = self.requests.popleft() if req is not NOP: yield WaitWriteOnly() self.doReq(req) self.actual = req return else: self.actual = actual_next return yield WaitWriteOnly() intf.bus2ip_cs.write(0)
def driver(self): # now we are before clock event # * set wait signal # * set last data (done in separate process) # * if en == 1, pop next data for next clk intf = self.intf yield WaitCombRead() rst_n = self.notReset() # speculative write if rst_n and self.data: wait = 0 else: wait = 1 yield WaitWriteOnly() intf.wait.write(wait) if rst_n: # wait for potential update of en # check if write can be performed and if it possible do real write yield WaitTimeslotEnd() en = intf.en.read() try: en = int(en) except ValueError: raise AssertionError(self.sim.now, intf, "en signal in invalid state") if en: assert self.data, (self.sim.now, intf, "underflow") self.lastData = self.data.popleft()
def monitor(self): assert isinstance(self.period, int) assert isinstance(self.initWait, int) yield WaitCombRead() v = self.intf.read() try: v = int(v) except ValueError: v = None now = self.sim.now last = self.last _next = (now, v) if last[0] == now: if last[1] is not v: # update last value last = (now, v) self.last = last if self.data: self.data[-1] = last else: self.data.append(last) else: return else: self.data.append(_next) self.last = _next
def data_collect(): for d_ref in test_data: yield WaitCombRead() d = io.outp.read() d = int(d) r_data.append(d) self.assertEqual(d, d_ref) yield Timer(CLK_PERIOD)
def dataCollector(): # random small value to collect data after it is set yield Timer(CLK_PERIOD + 1) while True: yield WaitCombRead() d = u.dataOut.read() collected.append(d) yield Timer(CLK_PERIOD)
def monitorRx(self): yield WaitCombRead() if self.notReset(): cs = self.intf.cs.read() cs = int(cs) if cs != self.csMask: # if any slave is enabled if not self._rxBitBuff: self.chipSelects.append(cs) self.readRxSig(self.intf.mosi)
def pull_up_after(): exp_t = sim.now yield WaitCombRead() assert sim.now == exp_t if not rst.read(): yield WaitWriteOnly() sig.write(1) assert sim.now == exp_t
def monitorTx(self): yield WaitCombRead() if self.notReset(): cs = self.intf.cs.read() cs = int(cs) if cs != self.csMask: yield Timer(1) yield WaitWriteOnly() self.writeTxSig(self.intf.miso)
def dataReader(self): yield Timer(1) if self.readPending: yield WaitCombRead() d = self.get_data() self.data.append(d) if self.readPending_invalidate: self.readPending = False if not self.readPending and not self._enabled: self.dataWriter.setEnable(False)
def monitorWithTimer(self): if self.initPending and self.initDelay: yield Timer(self.initDelay) self.initPending = False # if there is no clk, we have to manage periodic call by our self while True: yield WaitCombRead() if self._enabled and self.notReset(): d = self.get_data() self.data.append(d) yield Timer(self.delay)
def driverWithClk(self): # if clock is specified this function is periodically called every # clk tick, if agent is enabled yield WaitCombRead() if not self._enabled: return if self.data and self.notReset(): yield WaitWriteOnly() if not self._enabled: return d = self.data.popleft() self.set_data(d)
def driver(self): # if wait == 0 set en=1 and set data intf = self.intf d = None v = 0 yield WaitCombRead() if self.notReset() and self.data: yield WaitCombRead() wait = intf.wait.read() try: wait = int(wait) except ValueError: raise AssertionError(self.sim.now, intf, "wait signal in invalid state") if not wait: d = self.data.popleft() v = 1 yield WaitWriteOnly() self.set_data(d) intf.en.write(v)
def monitor(self): # now intf.sdc is rising yield WaitCombRead() # wait on all agents to update values and on # simulator to apply them if self.sim.now > 0 and self.notReset(): if self.bit_index != 8: self.bit_index += 1 yield WaitCombStable() v = self.sda.i.read() self.bit_cntrl_rx.append(v) else: yield WaitWriteOnly() self.sda._write(self.ACK)
def get_pull_up_driver_with_reset(sim: HdlSimulator, sig, reset, clk_period): exp_t = 0 yield WaitWriteOnly() sig.write(0) assert sim.now == exp_t while True: yield WaitCombRead() if not reset.read(): assert sim.now == exp_t yield WaitWriteOnly() sig.write(1) return else: yield Timer(clk_period) exp_t += clk_period
def driverTx(self): yield WaitCombRead() if self.notReset(): if not self._txBitBuff: try: cs = self.chipSelects.popleft() except IndexError: self.slaveEn = False yield WaitWriteOnly() self.intf.cs.write(self.csMask) return self.slaveEn = True yield WaitWriteOnly() self.intf.cs.write(cs) yield WaitWriteOnly() self.writeTxSig(self.intf.mosi)
def driver(self): yield WaitCombRead() if self.data and self.notReset(): d = self.data.popleft() else: d = NOP yield WaitWriteOnly() if d is NOP: self.set_data(None) self.set_valid(0) else: self.set_data(d) self.set_valid(1) if self._debugOutput is not None: self._debugOutput.write( "%s, wrote, %d: %r\n" % (self.intf._getFullName(), self.sim.now, self.actualData))
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) if self.HAS_WE: 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) if self.HAS_WE: intf.we.write(0) self.readPending = False else: self.doReq(req) intf.en.write(1) else: yield WaitWriteOnly() intf.en.write(0) if self.HAS_WE: 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 driver(self): """Push data to interface""" yield WaitWriteOnly() if self.actualData is NOP and self.data: self.actualData = self.data.popleft() do = self.actualData is not NOP if do: self.set_data(self.actualData) else: self.set_data(None) yield WaitCombRead() en = self.notReset() and self._enabled if not (en and do): return if en: rd = self.get_ready() try: rd = int(rd) except ValueError: raise AssertionError( ("%r: ready signal for interface %r is in invalid state," " this would cause desynchronization") % (self.sim.now, self.intf)) if rd: if self._debugOutput is not None: self._debugOutput.write("%s, wrote, %d: %r\n" % (self.intf._getFullName(), self.sim.now, self.actualData)) if self.data: self.actualData = self.data.popleft() else: self.actualData = NOP
def driverRx(self): yield WaitCombRead() if self.notReset() and self.slaveEn: self.readRxSig(self.intf.miso)
def _wait_until_command_completion(self): # wait untill command get processed while self.bit_cntrl: yield WaitCombRead() if self.bit_cntrl: yield WaitTimeslotEnd()
def monitorWithClk(): # if clock is specified this function is periodically called every # clk tick yield WaitCombRead() if not rst.read(): result.append((sim.now, int(sig.read())))
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 it is required if self.actualData is not self._lastWritten: if doSend: data = self.actualData else: data = None if self._lastVld: # forward set valid=0 to prevent spike right before clock edge self.set_valid(0) self._lastVld = 0 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: name = self.intf._getFullName() self._debugOutput.write( f"{name:s}, wrote, {self.sim.now:d}: {self.actualData}\n") 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
def monitor(self): intf = self.intf yield WaitCombRead() en = self.notReset() yield WaitWriteOnly() if self._requireInit or not en: intf.ip2bus_rdack.write(0) intf.ip2bus_wrack.write(0) intf.ip2bus_error.write(None) self._requireInit = False if not en: return yield WaitCombRead() st = self._monitor_st if st == IpifAgentState.IDLE: yield WaitCombRead() cs = intf.bus2ip_cs.read() cs = int(cs) # [TODO] there can be multiple chips # and we react on all chip selects if cs: # print("") # print(sim.now, "cs") self._rnw = bool(intf.bus2ip_rnw.read()) self._addr = int(intf.bus2ip_addr.read()) if self._rnw: st = IpifAgentState.READ else: self._be = int(intf.bus2ip_be.read()) self._wdata = intf.bus2ip_data.read() st = IpifAgentState.WRITE else: yield WaitWriteOnly() # print("") # print(sim.now, "not cs") intf.ip2bus_rdack.write(0) intf.ip2bus_wrack.write(0) intf.ip2bus_error.write(None) intf.ip2bus_data.write(None) doStabilityCheck = False else: doStabilityCheck = True yield WaitWriteOnly() if st == IpifAgentState.READ: intf.ip2bus_wrack.write(0) if self._latencyCntr == self.READ_LATENCY: # print(sim.now, "read-done") self._latencyCntr = 0 d = self.onRead(self._addr) intf.ip2bus_data.write(d) intf.ip2bus_rdack.write(1) intf.ip2bus_error.write(0) st = IpifAgentState.IDLE else: # print(sim.now, "read-wait") intf.ip2bus_data.write(None) self._latencyCntr += 1 elif st == IpifAgentState.WRITE: intf.ip2bus_rdack.write(0) intf.ip2bus_data.write(None) if self._latencyCntr == self.WRITE_LATENCY: # print(sim.now, "write-done") self.onWrite(self._addr, self._wdata, self._be) intf.ip2bus_wrack.write(1) intf.ip2bus_error.write(0) self._latencyCntr = 0 st = IpifAgentState.IDLE else: # print(sim.now, "write-wait") self._latencyCntr += 1 if doStabilityCheck: sim = self.sim yield WaitCombStable() cs = bool(intf.bus2ip_cs.read()) assert cs, (sim.now, "chip select signal has to be stable") rnw = bool(intf.bus2ip_rnw.read()) assert rnw == self._rnw, (sim.now, "read not write signal has to be stable", rnw, self._rnw) addr = int(intf.bus2ip_addr.read()) assert addr == self._addr, (sim.now, "address signal has to be stable", addr, self._addr) if st == IpifAgentState.WRITE: be = int(intf.bus2ip_be.read()) assert be == self._be, (sim.now, "byte enable signal has to be stable", be, self._be) d = intf.bus2ip_data.read() assert (self._wdata.val == d.val and self._wdata.vld_mask == d.vld_mask), (sim.now, "ip2bus_data signal has to be stable", be, self._be) self._monitor_st = st