예제 #1
0
    def __init__(self, sim: HdlSimulator, intf: "Spi", allowNoReset=False):
        AgentBase.__init__(self, sim, intf)

        self.txData = deque()
        self.rxData = deque()
        self.chipSelects = deque()

        self._txBitBuff = deque()
        self._rxBitBuff = deque()
        self.csMask = mask(intf.cs._dtype.bit_length())
        self.slaveEn = False

        # resolve clk and rstn
        self.clk = self.intf._getAssociatedClk()._sigInside
        self.rst, self.rstOffIn = self._discoverReset(
            intf, allowNoReset=allowNoReset)

        # read on rising edge write on falling
        self.monitorRx = OnRisingCallbackLoop(self.sim, self.clk,
                                              self.monitorRx, self.getEnable)
        self.monitorTx = OnFallingCallbackLoop(self.sim, self.clk,
                                               self.monitorTx, self.getEnable)

        self.driverRx = OnFallingCallbackLoop(self.sim, self.clk,
                                              self.driverRx, self.getEnable)
        self.driverTx = OnRisingCallbackLoop(self.sim, self.clk, self.driverTx,
                                             self.getEnable)
예제 #2
0
파일: fifo.py 프로젝트: pradeepchawda/hwt
 def getDrivers(self):
     self.dataWriter = OnRisingCallbackLoop(self.sim, self.clk,
                                            self.dataWriter,
                                            self.getEnable)
     return ([self.driver_init()] +
             super(FifoReaderAgent, self).getDrivers() +
             [self.dataWriter()])
예제 #3
0
파일: fifo.py 프로젝트: pradeepchawda/hwt
 def getMonitors(self):
     self.dataReader = OnRisingCallbackLoop(self.sim, self.clk,
                                            self.dataReader,
                                            self.getEnable)
     return ([self.monitor_init()] +
             super(FifoReaderAgent, self).getMonitors() +
             [self.dataReader()])
예제 #4
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)()
예제 #5
0
파일: i2c.py 프로젝트: Nic30/hwtSimApi
    def getMonitors(self):
        sim = self.sim
        scl = self.intf[0]
        self.scl = TristateClkAgent(
            sim, scl, (self.rst, self.rstOffIn),
        )
        self.monitor = OnRisingCallbackLoop(
            sim, scl.i, self.monitor, self.getEnable)
        self.startListener = OnFallingCallbackLoop(
            sim, scl.i, self.startListener, self.getEnable)

        return (
            self.monitor(),
            self.startListener(),
            *self.sda.getMonitors(),
            *self.scl.getMonitors()
        )
예제 #6
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)()
예제 #7
0
파일: i2c.py 프로젝트: Nic30/hwtSimApi
 def getDrivers(self):
     sim = self.sim
     scl = self.intf[0]
     driver = self.driver
     self.scl = TristateClkAgent(
         sim, scl, (self.rst, self.rstOffIn),
     )
     self.driver = OnRisingCallbackLoop(
         sim, scl.i, self.driver, self.getEnable)
     self.startSender = OnFallingCallbackLoop(
         sim, scl.i, self.startSender, self.getEnable)
     self.scl.setEnable(False, None)
     return (
         driver(),  # initialization of the interface
         self.driver(),
         self.startSender(),
         *self.sda.getDrivers(),
         *self.scl.getDrivers()
     )
예제 #8
0
 def __init__(self,
              sim: HdlSimulator,
              intf,
              allowNoReset=False,
              wrap_monitor_and_driver_in_edge_callback=True):
     super(MdioAgent,
           self).__init__(sim,
                          intf,
                          allowNoReset=allowNoReset,
                          wrap_monitor_and_driver_in_edge_callback=False)
     self.intf.io._initSimAgent(sim)
     if wrap_monitor_and_driver_in_edge_callback:
         self.rx_bits = OnRisingCallbackLoop(sim, intf.c, self.rx_bits,
                                             lambda: True)
         self.tx_bits = OnFallingCallbackLoop(sim, intf.c, self.tx_bits,
                                              lambda: True)
     self.rx_bits_tmp = deque()
     self.tx_bits_tmp = deque()
     self.reset_state()
     self.data = {}
예제 #9
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 get_data(self):
        return self.intf.data.read()

    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 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 set_data(self, d):
        self.intf.data.write(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):
        # 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()
예제 #10
0
class SpiAgent(SyncAgentBase):
    """
    Simulation agent for SPI interface

    :ivar ~.txData: data to transceiver container
    :ivar ~.rxData: received data
    :ivar ~.chipSelects: values of chip select

    chipSelects, rxData and txData are lists of integers
    """
    BITS_IN_WORD = 8

    def __init__(self, sim: HdlSimulator, intf: "Spi", allowNoReset=False):
        AgentBase.__init__(self, sim, intf)

        self.txData = deque()
        self.rxData = deque()
        self.chipSelects = deque()

        self._txBitBuff = deque()
        self._rxBitBuff = deque()
        self.csMask = mask(intf.cs._dtype.bit_length())
        self.slaveEn = False

        # resolve clk and rstn
        self.clk = self.intf._getAssociatedClk()._sigInside
        self.rst, self.rstOffIn = self._discoverReset(
            intf, allowNoReset=allowNoReset)

        # read on rising edge write on falling
        self.monitorRx = OnRisingCallbackLoop(self.sim, self.clk,
                                              self.monitorRx, self.getEnable)
        self.monitorTx = OnFallingCallbackLoop(self.sim, self.clk,
                                               self.monitorTx, self.getEnable)

        self.driverRx = OnFallingCallbackLoop(self.sim, self.clk,
                                              self.driverRx, self.getEnable)
        self.driverTx = OnRisingCallbackLoop(self.sim, self.clk, self.driverTx,
                                             self.getEnable)

    def setEnable(self, en):
        self._enabled = en
        self.monitorRx.setEnable(en)
        self.monitorTx.setEnable(en)
        self.driverRx.setEnable(en)
        self.driverTx.setEnable(en)

    def splitBits(self, v):
        return deque(
            [get_bit(v, i) for i in range(self.BITS_IN_WORD - 1, -1, -1)])

    def mergeBits(self, bits):
        t = Bits(self.BITS_IN_WORD, False)
        val = 0
        vld_mask = 0
        for v in bits:
            val <<= 1
            val |= v.val
            vld_mask <<= 1
            vld_mask |= v.vld_mask

        return t.getValueCls()(t, val, vld_mask)

    def readRxSig(self, sig):
        d = sig.read()
        bits = self._rxBitBuff
        bits.append(d)
        if len(bits) == self.BITS_IN_WORD:
            self.rxData.append(self.mergeBits(bits))
            self._rxBitBuff = []

    def writeTxSig(self, sig):
        bits = self._txBitBuff
        if not bits:
            if not self.txData:
                return
            d = self.txData.popleft()
            bits = self._txBitBuff = self.splitBits(d)

        sig.write(bits.popleft())

    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 monitorTx_pre_set(self):
    #     yield WaitWriteOnly()
    #     self.writeTxSig(self.intf.miso)

    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 driverRx(self):
        yield WaitCombRead()
        if self.notReset() and self.slaveEn:
            self.readRxSig(self.intf.miso)

    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 getDrivers(self):
        return [self.driverRx(), self.driverTx()]

    def getMonitors(self):
        return [
            self.monitorRx(),
            # self.monitorTx_pre_set(),
            self.monitorTx()
        ]