def driver(self): sig = self.intf yield WaitWriteOnly() sig.write(1) yield Timer(self.initDelay) yield WaitWriteOnly() sig.write(0)
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 get_pull_up_driver(sim: HdlSimulator, sig, delay): yield WaitWriteOnly() sig.write(0) yield Timer(delay) assert sim.now == delay yield WaitWriteOnly() sig.write(1)
def pop_control(): pop = u.pop._ag yield WaitWriteOnly() pop.setEnable(False) yield Timer(4 * CLK_PERIOD) yield WaitWriteOnly() pop.dinData.extend([0]) pop.setEnable(True)
def get_clk_driver(sim: HdlSimulator, clk, clk_period): while True: yield WaitWriteOnly() clk.write(0) yield Timer(clk_period // 2) yield WaitWriteOnly() clk.write(1) yield Timer(clk_period // 2)
def get_rst_driver(sim: HdlSimulator, rst, delay): yield WaitWriteOnly() assert sim.now == 0 rst.write(1) yield Timer(delay) assert sim.now == delay yield WaitWriteOnly() assert sim.now == delay rst.write(0)
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 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 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 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 driverWithTimer(self): if self.initPending: if self.initDelay: yield Timer(self.initDelay) self.initPending = False # if clock is specified this function is periodically called every # clk tick while True: yield WaitWriteOnly() if self._enabled and self.data and self.notReset(): yield WaitWriteOnly() if self._enabled: d = self.data.popleft() self.set_data(d) yield Timer(self.delay)
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 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 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): 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 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 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 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 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): 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 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): # 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 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()