def get_sync_sig_monitor(sim: HdlSimulator, sig, clk, rst, result): 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()))) return OnRisingCallbackLoop(sim, clk, monitorWithClk, lambda: True)()
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 getMonitors(self): self.dataReader = OnRisingCallbackLoop(self.sim, self.clk, self.dataReader, self.getEnable) return ([self.monitor_init()] + super(FifoReaderAgent, self).getMonitors() + [self.dataReader()])
def getDrivers(self): self.dataWriter = OnRisingCallbackLoop(self.sim, self.clk, self.dataWriter, self.getEnable) return ([self.driver_init()] + super(FifoReaderAgent, self).getDrivers() + [self.dataWriter()])
class FifoReaderAgent(SyncAgentBase): """ Simulation agent for FifoReader interface """ def __init__(self, sim, intf, allowNoReset=False): super(FifoReaderAgent, self).__init__(sim, intf, allowNoReset) self.data = deque() self.readPending = False self.lastData = None # flags to keep data coherent when enable state changes self.lastData_invalidate = False self.readPending_invalidate = False def setEnable_asDriver(self, en): lastEn = self._enabled super(FifoReaderAgent, self).setEnable_asDriver(en) self.intf.wait.write(not en) self.lastData_invalidate = not en if not lastEn: self.dataWriter.setEnable(en) def setEnable_asMonitor(self, en): lastEn = self._enabled super(FifoReaderAgent, self).setEnable_asMonitor(en) self.intf.en.write(en) self.readPending_invalidate = not en if not lastEn: self.dataReader.setEnable(en) # else dataReader will disable itself 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 dataReader(self): yield Timer(1) if self.readPending: yield WaitCombRead() d = self.intf.data.read() self.data.append(d) if self.readPending_invalidate: self.readPending = False if not self.readPending and not self._enabled: self.dataWriter.setEnable(False) def getMonitors(self): self.dataReader = OnRisingCallbackLoop(self.sim, self.clk, self.dataReader, self.getEnable) return ([self.monitor_init()] + super(FifoReaderAgent, self).getMonitors() + [self.dataReader()]) 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 getDrivers(self): self.dataWriter = OnRisingCallbackLoop(self.sim, self.clk, self.dataWriter, self.getEnable) return ([self.driver_init()] + super(FifoReaderAgent, self).getDrivers() + [self.dataWriter()]) 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.intf.data.write(self.lastData) if self.lastData_invalidate: self.lastData = None if not self._enabled: self.dataWriter.setEnable(False) 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()