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 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 checkRequests(self): """ Check if any request has appeared on interfaces """ yield WaitWriteOnly() if self.bus._ag.addrAg.data: rw, addr, burstCount = self.parseReq( self.bus._ag.addrAg.data.popleft()) if rw == READ_WRITE: self.doRead(addr, burstCount) self.wPending.append((addr, burstCount)) elif rw == READ: self.doRead(addr, burstCount) else: assert rw == WRITE, rw self.wPending.append((addr, burstCount)) wData = self.bus._ag.wData if wData and self.wPending[0][1] <= len(wData): addr, burstCount = self.wPending.popleft() for i in range(burstCount - 1): # consume the additional write requests which were generated during write data send _a, _ = self.wPending.popleft() assert int(addr) == int(_a), ( "inconsystent addres in write burst transaction", addr, burstCount, i, _a) self.doWrite(addr, burstCount) self._registerOnClock()
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: if self.HAS_WE: we = intf.we.read() we = int(we) elif intf.HAS_W: we = 1 else: we = 0 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 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 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 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 driver(self): assert isinstance(self.period, int) assert isinstance(self.initWait, int) sig = self.intf yield WaitWriteOnly() sig.write(0) yield Timer(self.initWait) while True: halfPeriod = self.period // 2 yield Timer(halfPeriod) yield WaitWriteOnly() sig.write(1) yield Timer(halfPeriod) yield WaitWriteOnly() sig.write(0)
def driver(self): o = self.o high = self.pullMode low = not self.pullMode halfPeriod = self.period // 2 yield WaitWriteOnly() o.write(low) self.t.write(1) while True: yield Timer(halfPeriod) yield WaitWriteOnly() o.write(high) yield Timer(halfPeriod) yield WaitWriteOnly() o.write(low)
def driverInit(self): yield WaitWriteOnly() if not self._enabled: return try: d = self.data[0] except IndexError: d = None self.set_data(d)
def checkRequests(self): """ Check if any request has appeared on interfaces """ yield WaitWriteOnly() req = self.intf._ag.requests if req: self.on_req(req) self._registerOnClock()
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 dataWriter(self): # delay data litle bit to have nicer wave # otherwise wirte happens before next clk period # and it means in 0 time and we will not be able to see it in wave yield Timer(1) yield WaitWriteOnly() self.set_data(self.lastData) if self.lastData_invalidate: self.lastData = None if not self._enabled: self.dataWriter.setEnable(False)
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 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 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 driver(self): # now intf.sdc is rising # prepare data for next clk yield WaitWriteOnly() if self.bits: b = self.bits.popleft() if b == self.START: self.start = True return elif b == self.STOP: self.bit_index = None self.stop = True return else: b = NOP self.sda._write(b)
def get_sync_pull_up_driver_with_reset(sim: HdlSimulator, sig, clk, rst): # init yield WaitWriteOnly() sig.write(0) assert sim.now == 0 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 yield OnRisingCallbackLoop(sim, clk, pull_up_after, lambda: True)()
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 checkRequests(self): """ Check if any request has appeared on interfaces """ yield WaitWriteOnly() if self.arAg is not None: if self.arAg.data: self.onReadReq() if self.rPending: self.doRead() if self.awAg is not None: if self.awAg.data: self.onWriteReq() if self.wPending and self.wPending[0][2] <= len(self.wAg.data): self.doWrite() self._registerOnClock()
def tx_bits(self): """ Transmit bit to io tristate signal on falling edge of c clock """ if self.sim._current_time_slot.write_only is DONE: yield Timer(1) yield WaitWriteOnly() tx_bits = self.tx_bits_tmp if tx_bits: b = tx_bits.popleft() self.intf.io.i.write(b) if not tx_bits: yield Edge(self.intf.c) self.reset_state() # release the io bus if self.sim._current_time_slot.write_only is DONE: yield Timer(1) yield self.intf.io._ag.monitor()
def driver(self): """ Drive 'o' and 't' from data buffer. One step if not selfSynchronization else infinite loop. """ while True: yield WaitWriteOnly() if self.data: o = self.data.popleft() if o == NOP: t = 0 o = 0 else: t = 1 self.o.write(o) self.t.write(t) if self.selfSynchronization: yield Timer(CLK_PERIOD) else: break
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): # 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 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 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
def init(): yield WaitWriteOnly() u.dataOut._ag.setEnable(False)
def driver_init(self): yield WaitWriteOnly() self.intf.wait.write(not self._enabled)
def monitor_init(self): yield WaitWriteOnly() self.intf.en.write(self._enabled)
def dissableErrHandling(): yield WaitWriteOnly() u.raise_ExampleHwException1_0._ag.setEnable(False)