Exemple #1
0
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)()
Exemple #2
0
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)()
Exemple #3
0
 def getMonitors(self):
     self.dataReader = OnRisingCallbackLoop(self.sim, self.clk,
                                            self.dataReader, self.getEnable)
     return ([self.monitor_init()] +
             super(FifoReaderAgent, self).getMonitors() +
             [self.dataReader()])
Exemple #4
0
 def getDrivers(self):
     self.dataWriter = OnRisingCallbackLoop(self.sim, self.clk,
                                            self.dataWriter, self.getEnable)
     return ([self.driver_init()] +
             super(FifoReaderAgent, self).getDrivers() +
             [self.dataWriter()])
Exemple #5
0
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()