示例#1
0
    def read(self, address, sync=True):
        """Issue a request to the bus and block until this comes back.

        Simulation time still progresses but syntactically it blocks.
        
        Args:
            address (int): The address to read from.
            sync (bool, optional): Wait for rising edge on clock initially.
                Defaults to True.
            
        Returns:
            BinaryValue: The read data value.
            
        Raises:
            OPBException: If read took longer than 16 cycles.
        """
        yield self._acquire_lock()

        # Apply values for next clock edge
        if sync:
            yield RisingEdge(self.clock)
        self.bus.ABus <= address
        self.bus.select <= 1
        self.bus.RNW <= 1
        self.bus.BE <= 0xF

        count = 0
        while not int(self.bus.xferAck.value):
            yield RisingEdge(self.clock)
            yield ReadOnly()
            if int(self.bus.toutSup.value):
                count = 0
            else:
                count += 1
            if count >= self._max_cycles:
                raise OPBException("Read took longer than 16 cycles")
        data = int(self.bus.DBus_out.value)

        # Deassert read
        self.bus.select <= 0
        self._release_lock()
        self.log.info("Read of address 0x%x returned 0x%08x" % (address, data))
        raise ReturnValue(data)
示例#2
0
文件: amba.py 项目: udog14/cocotb
    def _send_write_address(self, address, delay=0):
        """
        Send the write address, with optional delay
        """
        yield self.write_address_busy.acquire()
        for cycle in range(delay):
            yield RisingEdge(self.clock)

        self.bus.AWADDR <= address
        self.bus.AWVALID <= 1

        while True:
            yield ReadOnly()
            if self.bus.AWREADY.value:
                break
            yield RisingEdge(self.clock)
        yield RisingEdge(self.clock)
        self.bus.AWVALID <= 0
        self.write_address_busy.release()
示例#3
0
    def get_image(self):
        yield self.flush_pipeline()

        image = Image.new("RGBA", (self.width, self.height))

        for y in range(10):
            for x in range(self.total_width):
                yield RisingEdge(self.dut.pixel_clk)
                if x < self.width and y < self.height:
                    yield ReadOnly()
                    pixel = self.dut.pixel_data.value.integer
                    print x, y
                    print self.dut.pixel_data
                    r = (pixel >> 24) & bitmask(8)
                    g = (pixel >> 16) & bitmask(8)
                    b = (pixel >> 8) & bitmask(8)
                    a = pixel & bitmask(8)
                    image.putpixel((x, y), (r, g, b, a))

        image.save("tmp.png")
示例#4
0
文件: amba.py 项目: cnshijin/cocotb
    def _send_write_data(self, data, delay=0, byte_enable=0xF):
        """
        Send the write address, with optional delay
        """
        yield self.write_data_busy.acquire()
        for cycle in range(delay):
            yield RisingEdge(self.clock)

        self.bus.WDATA <= data
        self.bus.WVALID <= 1
        self.bus.WSTRB <= byte_enable

        while True:
            yield ReadOnly()
            if self.bus.WREADY.value:
                break
            yield RisingEdge(self.clock)
        yield RisingEdge(self.clock)
        self.bus.WVALID <= 0
        self.write_data_busy.release()
示例#5
0
    def _monitor_recv(self):
        """Watch the pins and reconstruct transactions."""

        # Avoid spurious object creation by recycling
        clkedge = RisingEdge(self.clock)
        rdonly = ReadOnly()

        def valid():
            if hasattr(self.bus, "ready"):
                return self.bus.valid.value and self.bus.ready.value
            return self.bus.valid.value

        # NB could yield on valid here more efficiently?
        while True:
            yield clkedge
            yield rdonly
            if valid():
                vec = self.bus.data.value
                vec.big_endian = self.config["firstSymbolInHighOrderBits"]
                self._recv(vec.buff)
示例#6
0
def test_writes_have_taken_effect_after_readwrite(dut):
    """ Test that ReadWrite fires first for the background write coro """
    dut.stream_in_data.setimmediatevalue(0)

    @cocotb.coroutine
    def write_manually():
        yield ReadWrite()
        # this should overwrite the write written below
        dut.stream_in_data.setimmediatevalue(2)

    # queue a backround task to do a manual write
    waiter = cocotb.fork(write_manually())

    # do a delayed write. This will be overwritten
    dut.stream_in_data <= 3
    yield waiter

    # check that the write we expected took precedence
    yield ReadOnly()
    assert dut.stream_in_data.value == 2
示例#7
0
def i2c_byte_read(dut, is_end):
    r_data = 0
    for i in range(0, 8):
        dut.sck_scl = 0
        yield Timer(I2C_PERIOD / 2)
        dut.sck_scl = 1
        yield ReadOnly()
        r_data = (r_data << 1) | (dut.sdo_sda.value.binstr != "0")
        yield Timer(I2C_PERIOD / 2)
        dut.sck_scl = 0
    yield Timer(200000)
    dut.sdo_sda = BinaryValue(
        "z") if is_end else 0  # no ack mean no further read
    yield Timer(I2C_PERIOD / 2)
    dut.sck_scl = 1
    yield Timer(I2C_PERIOD / 2)
    dut.sck_scl = 0
    dut.sdo_sda = BinaryValue("z")
    yield Timer(I2C_PERIOD / 2)
    raise ReturnValue(r_data)
示例#8
0
    def _monitor_recv(self):
        """Capture all DUT to Host IRQ requests"""

        irq = self.dut.reg_host_irq

        # Wait for the logic to be reset
        yield ReadOnly()
        yield RisingEdge(self.dut.reset_n)

        while True:

            # Wait on the regfile to assert the IRQ
            while irq.value.integer != 1:
                yield RisingEdge(irq)

            # Signal any subscribers that the IRQ has fired
            self._recv({'time': get_sim_time('ns')})

            # Wait for the interrupt(s) to be cleared
            while irq.value.integer == 1:
                yield FallingEdge(irq)
示例#9
0
文件: amba.py 项目: pgfarley/cocotb
    def write(self,
              address,
              value,
              byte_enable=0xf,
              address_latency=0,
              data_latency=0):
        """
        Write a value to an address.

        The *_latency KWargs allow control over the delta
        """

        c_addr = cocotb.fork(
            self._send_write_address(address, delay=address_latency))
        c_data = cocotb.fork(
            self._send_write_data(value,
                                  byte_enable=byte_enable,
                                  delay=data_latency))

        if c_addr:
            yield c_addr.join()
        if c_data:
            yield c_data.join()

        # Wait for the response
        while True:
            yield ReadOnly()
            if self.bus.BVALID.value and self.bus.BREADY.value:
                result = self.bus.BRESP.value
                break
            yield RisingEdge(self.clock)

        yield RisingEdge(self.clock)

        if int(result):
            raise AXIProtocolError(
                "Write to address 0x%08x failed with BRESP: %d" %
                (address, int(result)))

        raise ReturnValue(result)
示例#10
0
    def _get_read_data(self, address, id, dlen, dsize, delay):
        """
        Send a data word or a list of data words (supports multi-burst)
        @param address start address to read data from (just for logging)
        @param id expected receive data ID 
        @param dlen number of words to read 
        @param dsize - data width - (1 << dsize) bytes (MAXIGP has only 2 bits while AXI specifies 3) 2 means 32 bits
        @param delay latency in clock cycles
        """
        self.log.debug ("MAXIGPMaster._get_read_data("+str(address)+", "+str(id)+", "+str(dlen)+", "+str(dsize)+", "+str(delay))
        yield self.busy_channels[R_CHN].acquire()
        self.log.debug ("MAXIGPMaster._get_read_data(): acquired lock")
        for cycle in range(delay):
            yield RisingEdge(self.clock)
        self.log.debug ("MAXIGPMaster._get_read_data(): delay over")
        self.bus.rready <= 1
        data=[]
        for i in range(dlen):
            self.log.debug ("MAXIGPMaster._get_read_data(), i= %d"%(i))
            while True:
                yield ReadOnly()
                if self.bus.rvalid.value:
                    try:
                        data.append(self.bus.rdata.value.integer)
                    except:
                        bv = self.bus.rdata.value
                        bv.binstr = re.sub("[^1]","0",bv.binstr)
                        data.append(bv.integer)
                    rid = int(self.bus.rid.value)  
                    if rid != id:
                        self.log.error("Read data 0x%x ID mismatch - expected: 0x%x, got 0x%x"%(address+i,id, rid))
                    break
                yield RisingEdge(self.clock)
            yield RisingEdge(self.clock)
        self.bus.rready <= 0
        # FLoat all assigned bus signals but wvalid
#        _float_signals((self.bus.wdata,self.bus.wstb,self.bus.wlast))
        self.busy_channels[R_CHN].release()
        self.log.debug ("MAXIGPMaster._get_read_data(): released lock %s"%(R_CHN))
        raise ReturnValue(data)
示例#11
0
    def write(self, data):
        yield self.busy.acquire()
        pos = 0
        count = 0
        total_length = len(data)
        rdy = 0

        while pos < total_length:
            while True:
                yield ReadOnly()
                rdy = int(self.bus.RDY)
                if rdy != 0:
                    yield RisingEdge(self.clock)
                    break
                yield RisingEdge(self.clock)

            if (rdy & 0x01) > 0:
                self.bus.ACT <= 0x01
            else:
                self.bus.ACT <= 0x02

            yield RisingEdge(self.clock)
            length = total_length
            if length > int(self.bus.SIZE):
                length = self.bus.SIZE

            print "Length: %d" % length

            for d in data[pos:length]:
                self.bus.STB <= 1
                self.bus.DATA <= d
                yield RisingEdge(self.clock)

            self.bus.STB <= 0
            pos += length
            yield RisingEdge(self.clock)
            self.bus.ACT <= 0
            yield RisingEdge(self.clock)

        self.busy.release()
示例#12
0
 def read_muon(self):
     i = 0
     self.sim_sorted_muon = []
     while i < self.n:
         yield RisingEdge(self.dut.clk)
         yield ReadOnly()
         if self.dut.source_valid.value.is_resolvable:
             if self.dut.source_valid.value.integer:
                 cand = []
                 for j in range(self.O):
                     cand.append({
                         'pt':
                         self.dut.muon_o[j].pt.value.integer,
                         'idx':
                         self.dut.muon_o[j].idx.value.integer,
                         'roi':
                         self.dut.muon_o[j].roi.value.integer,
                         'flags':
                         self.dut.muon_o[j].flags.value.integer,
                     })
                 self.sim_sorted_muon.append(cand)
                 i += 1
示例#13
0
    def _monitor_recv(self):
        """Watch the pins and reconstruct transactions.
        We monitor on falling edge to support post synthesis simulations
        """

        # Avoid spurious object creation by recycling
        clkedge = RisingEdge(self.clock)
        rdonly = ReadOnly()
        pkt = BinaryValue()

        def valid():
            if hasattr(self.bus, "tready"):
                return self.bus.tvalid.value and self.bus.tready.value
            return self.bus.tvalid.value

        # NB could yield on valid here more efficiently?
        while True:
            yield clkedge
            yield rdonly
            isValid = valid()
            self.log.debug("validity : {}".format(isValid))
            if isValid:
                vec = self.bus.tdata.value
                keep = BinaryValue(n_bits=int(len(self.bus.tdata)/8))
                keep = -1
                if hasattr(self.bus, "tkeep"):
                    keep = self.bus.tkeep.value
                    if 'U' in keep.binstr:
                        self.log.warning(
                            "received keep contains U value :{}, data : {}"
                            .format(keep.binstr, vec.binstr))
                for i, v in enumerate(keep.binstr[::-1]):
                    if v in '1U':
                        pkt.buff += bytes((vec.buff[::-1][i],))
                self.log.debug("received frame : {}".format(hex(vec)))
                if self.bus.tlast.value == 1:
                    self.log.debug("received packet : {}".format(hex(pkt)))
                    self._recv(pkt)
                    pkt = BinaryValue()
示例#14
0
def test_fifo(dut):
   """Try writing values into the FIFO and reading back"""
   RAM = {}
   dut.rst = 0
   dut.wr = 0
   dut.rd = 0
   
   # Read the parameters back from the DUT to set up our testbench
   width = dut.WIDTH.value.integer
   depth = 2**dut.AWIDTH.value.integer
   dut.log.info("Found %d entry RAM by %d bits wide" % (depth, width))

   # Set up independent read/write clocks
   cocotb.fork(Clock(dut.clk, 10000).start())
   
   # Rest FIFO
   dut.log.info("Resetting FIFO...")
   yield reset_fifo(dut)
   yield ReadOnly()
   #dut.rst = 0
   
   dut.log.info("Writing in random values...")
   yield RisingEdge(dut.clk)
   for i in xrange(depth):
      RAM[i] = int(random.getrandbits(width))
      yield write_fifo(dut, RAM[i])

   dut.log.info("Reading back values and checking")
   dut.log.info("Write Data   Read Data")
   yield RisingEdge(dut.clk)
   for i in xrange(depth):
      value = yield read_fifo(dut)
      dut.log.info("0x%X\t\t0x%X" % (RAM[i], value))
      #if value != RAM[i]:
	 #dut.log.error("RAM[%d] expected %d but got %d" % (i, RAM[i], value))
	 #raise TestFailure("RAM contents incorrect")
   dut.log.info("RAM contents OK")
   dut.log.info("FIFO Read and Write Successful!!")
示例#15
0
    def _monitor_recv(self):
        transCollected = APBTransaction()
        transCollected.randomize()

        while True:
            yield RisingEdge(self.clock)

            if (self.bus.psel == 1 and self.bus.penable == 1):
                while True:
                    yield ReadOnly()
                    if (self.bus.pready):
                        transCollected.addr = self.bus.paddr.value
                        transCollected.slverr = self.bus.pslverr.value

                        if (self.bus.pwrite == 1):
                            transCollected.data = self.bus.pwdata.value
                        else:
                            transCollected.data = self.bus.prdata.value

                        transCollected.rw <= 0 if self.bus.pwrite else 1
                        break

                self._recv(transCollected)
示例#16
0
def simulator_timing_triggers(dut):
    """Playing with the Simulator Timing Triggers"""
    cocotb.fork(Clock(dut.clk_i, 2).start())
    yield reset(dut)
    #
    yield Timer(
        2)  # Fires after the specified simulation time period has elapsed
    print_fired(dut, "Timer")
    yield Timer(2, "ns")
    print_fired(dut, "Timer")
    yield Timer(2000, "ps")
    print_fired(dut, "Timer")
    yield Timer(0.002, "us")
    print_fired(dut, "Timer")
    #
    yield NextTimeStep()  # Fires when the next time step is started
    print_fired(dut, "NextTimeStep")
    yield ReadWrite(
    )  # Fires when the readwrite portion of the sim cycles is reached
    print_fired(dut, "ReadWrite")
    yield ReadOnly(
    )  # Fires when the current simulation timestep moves to the readonly phase
    print_fired(dut, "ReadOnly")
示例#17
0
    def write(self, data):
        yield self.busy.acquire()
        pos = 0
        count = 0
        total_length = len(data)
        rdy = 0

        while pos < total_length:
            while True:
                yield ReadOnly()
                rdy = int(self.bus.RDY)
                if rdy != 0:
                    yield RisingEdge(self.clock)
                    self.bus.ACT <= 1
                    break
                yield RisingEdge(self.clock)

            yield RisingEdge(self.clock)
            length = total_length - pos
            if length > int(self.bus.SIZE):
                length = int(self.bus.SIZE)

            print "Length: %d" % length
            print "pos: %d" % pos

            for d in data[pos:(pos + length)]:
                self.bus.STB <= 1
                self.bus.DATA <= d
                yield RisingEdge(self.clock)

            self.bus.STB <= 0
            pos += length
            yield RisingEdge(self.clock)
            self.bus.ACT <= 0
            yield RisingEdge(self.clock)

        self.busy.release()
示例#18
0
 def _send_write_data(self, data, wrstb,  delay, id, dsize):
     """
     Send a data word or a list of data words (supports multi-burst)
     @param data a list/tuple of words to send
     @param wrstb - write mask list (same size as data)
     @param delay latency in clock cycles
     @param id transaction ID 
     @param dsize - data width - (1 << dsize) bytes (MAXIGP has only 2 bits while AXI specifies 3) 2 means 32 bits
     """
     self.log.debug ("MAXIGPMaster._send_write_data("+str(data)+", "+str(wrstb)+", "+str(delay)+", "+str(id)+", "+str(dsize))
     yield self.busy_channels[W_CHN].acquire()
     self.log.debug ("MAXIGPMaster._send_write_data(): acquired lock")
     for cycle in range(delay):
         yield RisingEdge(self.clock)
     self.log.debug ("MAXIGPMaster._send_write_data(): delay over")
     self.bus.wvalid <= 1
     self.bus.wid <= id
     for i,val_wstb in enumerate(zip(data,wrstb)):
         self.log.debug ("MAXIGPMaster._send_write_data(), i= %d, val_stb=%s "%(i,str(val_wstb)))
         if (i == (len(data) - 1)) or ((i % 16) == 15):
             self.bus.wlast <= 1
         else:
             self.bus.wlast <= 0
         self.bus.wdata <= val_wstb[0]
         self.bus.wstb <= val_wstb[1]
         while True:
             yield ReadOnly()
             if self.bus.wready.value:
                 break
             yield RisingEdge(self.clock)
         yield RisingEdge(self.clock)
     self.bus.wvalid <= 0
     # FLoat all assigned bus signals but wvalid
     _float_signals((self.bus.wdata,self.bus.wstb,self.bus.wlast))
     self.busy_channels[W_CHN].release()
     self.log.debug ("MAXIGPMaster._send_write_data(): released lock %s"%(W_CHN))
     raise ReturnValue(dsize)
示例#19
0
    def read(self, address, sync=True):
        """
        Issue a request to the bus and block until this
        comes back. Simulation time still progresses
        but syntactically it blocks.
        See http://www.altera.com/literature/manual/mnl_avalon_spec_1_3.pdf
        """
        if not self._can_read:
            self.log.error("Cannot read - have no read signal")
            raise TestError("Attempt to read on a write-only AvalonMaster")

        yield self._acquire_lock()

        # Apply values for next clock edge
        if sync:
            yield RisingEdge(self.clock)
        self.bus.address <= address
        self.bus.read <= 1

        # Wait for waitrequest to be low
        if hasattr(self.bus, "waitrequest"):
            yield self._wait_for_nsignal(self.bus.waitrequest)

        # Assume readLatency = 1
        # FIXME need to configure this,
        # should take a dictionary of Avalon properties.
        yield RisingEdge(self.clock)

        # Deassert read
        self.bus.read <= 0

        # Get the data
        yield ReadOnly()
        data = self.bus.readdata.value
        yield NextTimeStep()
        self._release_lock()
        raise ReturnValue(data)
示例#20
0
 def send(self, transaction):
     rval = 0
     yield RisingEdge(self.clock)
     self.bus.PADDR <= transaction.addr
     self.bus.PWDATA <= transaction.data
     self.bus.PSELx <= 1
     self.bus.PWRITE <= 1 if transaction.write else 0
     yield RisingEdge(self.clock)
     self.bus.PENABLE <= 1
     while True:
         yield ReadOnly()
         if (self.bus.PREADY == 1):
             rval = self.bus.PRDATA
             break
         yield RisingEdge(self.clock)
     yield RisingEdge(self.clock)
     self.bus.PADDR <= 0
     self.bus.PWDATA <= 0
     self.bus.PSELx <= 0
     self.bus.PWRITE <= 0
     self.bus.PENABLE <= 0
     for i in range(transaction.delay):
         yield RisingEdge(self.clock)
     raise ReturnValue(rval)
示例#21
0
    def write_four_bytes(self, data, last):

        yield RisingEdge(self.clock)
        self.bus.RXFn <= 0
        self.bus.DIN <= int(data & 0xFF)

        while True:
            yield ReadOnly()
            if self.bus.RDn.value == 0:
                break
            yield FallingEdge(self.clock)

        yield RisingEdge(self.clock)
        self.bus.DIN <= int((data >> 8) & 0xFF)

        yield RisingEdge(self.clock)
        self.bus.DIN <= int((data >> 16) & 0xFF)

        yield RisingEdge(self.clock)
        self.bus.DIN <= int((data >> 24) & 0xFF)

        if last is True:
            yield RisingEdge(self.clock)
            self.bus.RXFn <= 1
示例#22
0
 def _monitor_recv(self):
     started = False
     pre_started = False
     prev_scl = 1
     while True:
         yield RisingEdge(self.clock)
         yield ReadOnly()
         try:
             sda = 0 if self.bus.SDA == 'x' else int(self.bus.SDA)
         except ValueError:
             sda = 0
         if (self.bus.SCL == 1):
             #start bit
             if (not started) & (not pre_started) & (sda == 1):
                 pre_started = True
             elif (not started) & pre_started & (sda == 0):
                 started = True
                 pre_started = False
                 rdata = 0
                 data_cnt = 0
                 ack = 1
             #sample data at SCL
             elif started & (prev_scl == 0):
                 prev_scl = 1
                 if data_cnt == 32:
                     started = False
                     xaction = I2CTransaction(rdata, write=False)
                     self._recv(xaction)
                 elif (data_cnt % 8 != 0) | ack:
                     ack = 0
                     rdata = rdata + (sda << data_cnt)
                     data_cnt += 1
                 else:  #ack state
                     ack = 1
         elif started:
             prev_scl = 0
示例#23
0
    def multiply(self, data, accumulator=0):
        # Check that we've set a weight
        if self.weight == None:
            raise TestFailure("No weight set in tb yet!")

        # Perform the MAC operation
        self.dut.data_in = data
        self.dut.accumulator_in = accumulator
        self.dut.mac_stall_in = 0
        yield RisingEdge(self.dut.clock)

        # Get the result and compare
        yield ReadOnly()
        acc_out = self.dut.accumulator_out
        data_out = self.dut.data_out

        acc_cor = data * self.weight + accumulator
        if acc_out != acc_cor:
            raise TestFailure("Result was %d instead of %d" %
                              (acc_out, acc_cor))

        if data_out != data:
            raise TestFailure("Data out was %d instead of %d" %
                              (data_out, data))
示例#24
0
文件: amba.py 项目: cnshijin/cocotb
    def read(self, wait_for_valid = False):
        """Read a packe of data from the Axi Ingress stream"""
        yield self.read_data_busy.acquire()
        yield RisingEdge(self.clock)

        if wait_for_valid:
            while not self.bus.TVALID.value:
                #cocotb.log.info("Valid Not Detected")
                yield RisingEdge(self.clock)

            #cocotb.log.info("Found valid!")
            yield RisingEdge(self.clock)
            self.bus.TREADY <=  1

            while self.bus.TVALID.value:
                yield RisingEdge(self.clock)
                self.data.extend(self.bus.TDATA.value)
                if self.bus.TLAST.value:
                    break
        else:
            self.bus.TREADY <= 1

            while True:
                yield ReadOnly()
                yield RisingEdge(self.clock)
                if self.bus.TVALID.value:
                    cocotb.log.debug("Found Valid")
                    break
                yield RisingEdge(self.clock)


            while self.bus.TVALID.value:
                yield RisingEdge(self.clock)
                self.data.extend(self.bus.TDATA.value)
                if self.bus.TLAST.value:
                    break
示例#25
0
文件: amba.py 项目: nanduraj1/cocotb
    def read(self, address, sync=True):
        """Read from an address.
        
        Args:
            address (int): The address to read from.
            sync (bool, optional): Wait for rising edge on clock initially.
                Defaults to True.
            
        Returns:
            BinaryValue: The read data value.
            
        Raises:
            AXIProtocolError: If read response from AXI is not ``OKAY``.
        """
        if sync:
            yield RisingEdge(self.clock)

        yield self._send_read_address(address)

        # Wait for the response
        while True:
            if self.bus.RVALID.value and self.bus.RREADY.value:
                data = self.bus.RDATA.value
                result = self.bus.RRESP.value
                break
            yield RisingEdge(self.clock)
            yield ReadOnly()

        yield RisingEdge(self.clock)

        if int(result):
            raise AXIProtocolError(
                "Read address 0x%08x failed with RRESP: %d" %
                (address, int(result)))

        raise ReturnValue(data)
示例#26
0
    def write(self, address, value, sync=True):
        """Issue a write to the given address with the specified
        value.
        
        Args:
            address (int): The address to read from.
            value (int): The data value to write.
            sync (bool, optional): Wait for rising edge on clock initially.
                Defaults to True.
            
        Raises:
            OPBException: If write took longer than 16 cycles
        """
        yield self._acquire_lock()

        if sync:
            yield RisingEdge(self.clock)
        self.bus.ABus <= address
        self.bus.select <= 1
        self.bus.RNW <= 0
        self.bus.BE <= 0xF
        self.bus.DBus_out <= value

        count = 0
        while not int(self.bus.xferAck.value):
            yield RisingEdge(self.clock)
            yield ReadOnly()
            if int(self.bus.toutSup.value):
                count = 0
            else:
                count += 1
            if count >= self._max_cycles:
                raise OPBException("Write took longer than 16 cycles")

        self.bus.select <= 0
        self._release_lock()
示例#27
0
    def _respond(self):
        """
        Coroutine to response to the actual requests
        """
        edge = RisingEdge(self.clock)
        while True:
            yield edge
            self._do_response()

            yield ReadOnly()

            if self._readable and self.bus.read.value:
                if not self._burstread:
                    self._pad()
                    addr = self.bus.address.value.integer
                    if addr not in self._mem:
                        self.log.warning("Attempt to read from uninitialised "
                                         "address 0x%x" % addr)
                        self._responses.append(True)
                    else:
                        self.log.debug(
                            "Read from address 0x%x returning 0x%x" %
                            (addr, self._mem[addr]))
                        self._responses.append(self._mem[addr])
                else:
                    addr = self.bus.address.value.integer
                    if addr % self.dataByteSize != 0:
                        self.log.error(
                            "Address must be aligned to data width" +
                            "(addr = " + hex(addr) + ", width = " +
                            str(self._width))
                    addr = int(addr / self.dataByteSize)
                    burstcount = self.bus.burstcount.value.integer
                    byteenable = self.bus.byteenable.value
                    if byteenable != int("1" * len(self.bus.byteenable), 2):
                        self.log.error("Only full word access is supported " +
                                       "for burst read (byteenable must be " +
                                       "0b" + "1" * len(self.bus.byteenable) +
                                       ")")
                    if burstcount == 0:
                        self.log.error("Burstcount must be 1 at least")

                    # toggle waitrequest
                    # TODO: configure waitrequest time with avalon properties
                    yield NextTimeStep()  # can't write during read-only phase
                    self.bus.waitrequest <= 1
                    yield edge
                    yield edge
                    self.bus.waitrequest <= 0

                    # wait for read data
                    for i in range(self._avalon_properties["readLatency"]):
                        yield edge
                    for count in range(burstcount):
                        if (addr + count) * self.dataByteSize not in self._mem:
                            self.log.warning(
                                "Attempt to burst read from uninitialised " +
                                "address 0x%x (addr 0x%x count 0x%x)" %
                                ((addr + count) * self.dataByteSize, addr,
                                 count))
                            self._responses.append(True)
                        else:
                            value = 0
                            for i in range(self.dataByteSize):
                                rvalue = self._mem[(addr + count) *
                                                   self.dataByteSize + i]
                                value += rvalue << i * 8
                            self.log.debug(
                                "Read from address 0x%x returning 0x%x" %
                                ((addr + count) * self.dataByteSize, value))
                            self._responses.append(value)
                        yield edge
                        self._do_response()

            if self._writeable and self.bus.write.value:
                if not self._burstwrite:
                    addr = self.bus.address.value.integer
                    data = self.bus.writedata.value.integer
                    if hasattr(self.bus, "byteenable"):
                        byteenable = int(self.bus.byteenable.value)
                        mask = 0
                        oldmask = 0
                        olddata = 0
                        if (addr in self._mem):
                            olddata = self._mem[addr]
                        self.log.debug("Old Data  : %x" % olddata)
                        self.log.debug("Data in   : %x" % data)
                        self.log.debug("Width     : %d" % self._width)
                        self.log.debug("Byteenable: %x" % byteenable)
                        for i in range(self._width / 8):
                            if (byteenable & 2**i):
                                mask |= 0xFF << (8 * i)
                            else:
                                oldmask |= 0xFF << (8 * i)

                        self.log.debug("Data mask : %x" % mask)
                        self.log.debug("Old mask  : %x" % oldmask)

                        data = (data & mask) | (olddata & oldmask)

                        self.log.debug("Data out  : %x" % data)

                    self.log.debug("Write to address 0x%x -> 0x%x" %
                                   (addr, data))
                    self._mem[addr] = data
                else:
                    self.log.debug("writing burst")
                    # maintain waitrequest high randomly
                    yield self._waitrequest()

                    addr, byteenable, burstcount = self._write_burst_addr()

                    count = 0
                    for count in range(burstcount):
                        while self.bus.write.value == 0:
                            yield NextTimeStep()
                        # self._mem is aligned on 8 bits words
                        yield self._writing_byte_value(addr + count *
                                                       self.dataByteSize)
                        self.log.debug("writing %016X @ %08X" %
                                       (self.bus.writedata.value.integer,
                                        addr + count * self.dataByteSize))
                        yield edge
                        # generate waitrequest randomly
                        yield self._waitrequest()

                    if self._avalon_properties.get("WriteBurstWaitReq", True):
                        self.bus.waitrequest <= 1
示例#28
0
    def run(self):
        self.bus.HIT <= self.hit
        self.bus.TRIG_EXT <= 0

        res = 0
        while res == 0:
            # Wait for RESET signal
            yield FallingEdge(self.clock)
            yield ReadOnly()
            res = self.bus.RESET_TB.value.integer

        while res == 1:
            # Wait for falling edge of RESET signal
            yield FallingEdge(self.clock)
            yield ReadOnly()
            res = self.bus.RESET_TB.value.integer

        for _ in range(5):
            # Delay hit w.r.t. RESET. Minimum 3 clk cycles
            yield FallingEdge(self.clock)

        bv = BitLogic(len(self.hit))
        bv[10] = 1
        bv[15] = 1
        self.hit.assign(str(bv))
        self.bus.HIT <= self.hit
        self.bus.TRIG_EXT <= 0

        for _ in range(14):
            # Stop HIT after 10 CLK_BX
            yield FallingEdge(self.clock)

        bv = BitLogic(len(self.hit))
        bv.setall(False)
        self.hit.assign(str(bv))
        self.bus.HIT <= self.hit
        self.bus.TRIG_EXT <= 1

        yield FallingEdge(self.clock)
        self.bus.TRIG_EXT <= 0

        #         for _ in range(5):
        #             # Delay hit
        #             yield FallingEdge(self.clock)
        #
        #         bv = BitLogic(len(self.hit))
        #         bv[20] = 1
        #         self.hit.assign(str(bv))
        #         self.bus.HIT <= self.hit
        #         self.bus.TRIG_EXT <= 0
        #
        #         for _ in range(10):
        #             # Stop HIT after 10 CLK_BX
        #             yield FallingEdge(self.clock)
        #
        #         bv = BitLogic(len(self.hit))
        #         bv.setall(False)
        #         self.hit.assign(str(bv))
        #         self.bus.HIT <= self.hit
        #         self.bus.TRIG_EXT <= 1
        #         yield FallingEdge(self.clock)
        #         self.bus.TRIG_EXT <= 0

        #         for _ in range(5):
        #             # Delay hit
        #             yield FallingEdge(self.clock)
        # #
        #         bv = BitLogic(len(self.hit))
        #         bv[20] = 1
        #         self.hit.assign(str(bv))
        #         self.bus.HIT <= self.hit
        #         self.bus.TRIG_EXT <= 0
        #
        #         for _ in range(10):
        #             # Stop HIT after 10 CLK_BX
        #             yield FallingEdge(self.clock)
        #
        #         bv = BitLogic(len(self.hit))
        #         bv.setall(False)
        #         self.hit.assign(str(bv))
        #         self.bus.HIT <= self.hit
        #         self.bus.TRIG_EXT <= 1
        #         yield FallingEdge(self.clock)
        self.bus.TRIG_EXT <= 0
示例#29
0
def do_test_afterdelay_in_readonly(dut, delay):
    global exited
    yield RisingEdge(dut.clk)
    yield ReadOnly()
    yield Timer(delay)
    exited = True
示例#30
0
def do_test_cached_write_in_readonly(dut):
    global exited
    yield RisingEdge(dut.clk)
    yield ReadOnly()
    dut.clk <= 0
    exited = True