示例#1
0
def _dem_to_di_rx(dut, num_transfers=500, max_delay=100):

    reader = NocDiReader(dut, dut.clk)
    ex_packet = DiPacket()

    for i in range(num_transfers):
        delay = random.randint(0, max_delay)

        for _ in range(delay):
            yield RisingEdge(dut.clk)

        rx_packet = yield reader.receive_packet(set_ready=True)

        data = _dem_to_di_fifo.pop(0)

        ex_packet.set_contents(dest=SENDER_DI_ADDRESS,
                               src=MODULE_DI_ADDRESS,
                               type=DiPacket.TYPE.EVENT,
                               type_sub=0,
                               payload=[data])

        if not rx_packet:
            raise TestFailure("receive_packet() timed out")

        if not rx_packet.equal_to(dut, ex_packet, mask=None):
            raise TestFailure("Unexpected content of " + rx_packet.__str__() +
                              "\n Expected " + ex_packet.__str__())

        yield RisingEdge(dut.clk)
示例#2
0
def _trigger_reg_wr_req_err(dut, dest, src, word_width, regaddr, value):
    """
    Sends a register write request to the module and checks if an error response
    gets returned.
    """

    tx_packet = DiPacket()
    rx_packet = DiPacket()
    writer = NocDiWriter(dut, dut.clk)
    reader = NocDiReader(dut, dut.clk)

    if word_width == 16:
        type_sub = DiPacket.TYPE_SUB.REQ_WRITE_REG_16.value
        words = 1
    elif word_width == 32:
        type_sub = DiPacket.TYPE_SUB.REQ_WRITE_REG_32.value
        words = 2
    elif word_width == 64:
        type_sub = DiPacket.TYPE_SUB.REQ_WRITE_REG_64.value
        words = 4
    elif word_width == 128:
        type_sub = DiPacket.TYPE_SUB.REQ_WRITE_REG_128.value
        words = 8
    else:
        raise TestFailure("An invalid register width parameter was chosen! (%d)" %\
                           word_width)

    # Assemble payload of REG debug packet
    payload = [regaddr]
    for w in range(0, words):
        payload.append((value >> ((words - 1 - w) * 16)) & 0xFFFF)

    tx_packet.set_contents(dest=dest,
                           src=src,
                           type=DiPacket.TYPE.REG.value,
                           type_sub=type_sub,
                           payload=payload)

    yield writer.send_packet(tx_packet)

    rx_packet = yield reader.receive_packet(set_ready=True)

    if not rx_packet:
        raise TestFailure("No response packet received!")

    if rx_packet.type_sub != DiPacket.TYPE_SUB.RESP_WRITE_REG_ERROR.value:
        raise TestFailure(
            "Register write did not return RESP_WRITE_REG_ERROR "
            "when writing 0x%x to register 0x%x of module 0x%x." %
            (value, regaddr, dest))
示例#3
0
def test_only_regaccess_ready(dut):
    """
    Check if a register access packet passes through, even though the bypass
    ready signal is tied to 0.
    """

    yield _init_dut(dut)

    dut.out_reg_ready <= 1
    dut.out_bypass_ready <= 0

    reg_reader_signal_aliases = {
        'debug_out': 'out_reg',
        'debug_out_ready': 'out_reg_ready'
    }
    reg_reader = NocDiReader(dut, dut.clk, reg_reader_signal_aliases)

    writer_signal_aliases = {'debug_in': 'in', 'debug_in_ready': 'in_ready'}
    writer = NocDiWriter(dut, dut.clk, writer_signal_aliases)

    reg_pkg = DiPacket()
    reg_pkg.set_contents(dest=1,
                         src=0,
                         type=DiPacket.TYPE.REG.value,
                         type_sub=DiPacket.TYPE_SUB.REQ_WRITE_REG_16.value,
                         payload=[0xdead])

    # send a register write packet to the DUT
    write_thread = cocotb.fork(writer.send_packet(reg_pkg))

    # ensure that the bypass valid signal isn't asserted
    checker_thread = cocotb.fork(
        _assert_signal_stays_low(dut.clk, dut.out_bypass.valid))

    # get packet on reg output
    rcv_pkg = yield reg_reader.receive_packet()

    yield write_thread.join()
    checker_thread.kill()

    if not rcv_pkg:
        raise TestFailure("Register access packet not routed to output.")

    if not rcv_pkg.equal_to(dut, reg_pkg):
        raise TestFailure("Data corruption.")
示例#4
0
def test_event_pkg(dut):
    """
    Check if a register access packet passes through
    """

    yield _init_dut(dut)

    dut.out_reg_ready <= 1
    dut.out_bypass_ready <= 1

    bypass_reader_signal_aliases = {
        'debug_out': 'out_bypass',
        'debug_out_ready': 'out_bypass_ready'
    }
    bypass_reader = NocDiReader(dut, dut.clk, bypass_reader_signal_aliases)

    writer_signal_aliases = {'debug_in': 'in', 'debug_in_ready': 'in_ready'}
    writer = NocDiWriter(dut, dut.clk, writer_signal_aliases)

    event_pkg = DiPacket()
    event_pkg.set_contents(dest=1,
                           src=0,
                           type=DiPacket.TYPE.EVENT.value,
                           type_sub=0,
                           payload=[0xdead])

    # send an event packet to the DUT
    write_thread = cocotb.fork(writer.send_packet(event_pkg))

    # ensure that the register output valid signal isn't asserted
    checker_thread = cocotb.fork(
        _assert_signal_stays_low(dut.clk, dut.out_reg.valid))

    # get packet on bypass output
    rcv_pkg = yield bypass_reader.receive_packet()

    yield write_thread.join()
    checker_thread.kill()

    if not rcv_pkg:
        raise TestFailure("Event access packet not routed to output.")

    if not rcv_pkg.equal_to(dut, event_pkg):
        raise TestFailure("Data corruption.")
示例#5
0
def test_fixedwidth(dut):
    """Test the generation of two packets with a byte padding"""
    yield _init_dut(dut)

    dut.id <= MODULE_DI_ADDRESS
    dut.dest <= SENDER_DI_ADDRESS
    data_str = '\xef\x12\x34\xde\xad\xbe\xef\xef\xab\xab\xcd'
    dut.data.value = BinaryValue(data_str)
    dut.overflow <= 0
    dut.event_available <= 1


    # packet 1
    exp_pkg = DiPacket()
    exp_pkg.set_contents(dest=SENDER_DI_ADDRESS,
                         src=MODULE_DI_ADDRESS,
                         type=DiPacket.TYPE.EVENT,
                         type_sub=1,
                         payload=[0xabcd, 0xefab, 0xbeef, 0x0dead, 0x1234])

    reader = NocDiReader(dut, dut.clk)
    rcv_pkg = yield reader.receive_packet(set_ready=True)

    if not rcv_pkg:
        raise TestFailure("No packet 1 generated!")

    if not rcv_pkg.equal_to(dut, exp_pkg):
        raise TestFailure("Received packet 1 doesn't match expected packet. "
                          "Got %s, expected %s" % (str(rcv_pkg), str(exp_pkg)))

    # packet 2
    yield RisingEdge(dut.clk)
    exp_pkg = DiPacket()
    exp_pkg.set_contents(dest=SENDER_DI_ADDRESS,
                         src=MODULE_DI_ADDRESS,
                         type=DiPacket.TYPE.EVENT,
                         type_sub=0,
                         payload=[0x00ef])

    reader = NocDiReader(dut, dut.clk)
    rcv_pkg = yield reader.receive_packet(set_ready=True)

    if not rcv_pkg:
        raise TestFailure("No packet 2 generated!")

    if not rcv_pkg.equal_to(dut, exp_pkg):
        raise TestFailure("Received packet 2 doesn't match expected packet. "
                          "Got %s, expected %s" % (str(rcv_pkg), str(exp_pkg)))

    # check if the DUT is ready for the next event transfer
    if not dut.event_consumed.value:
        raise TestFailure("DUT does not indicate that the event has been "
                          "consumed.")
示例#6
0
    def _create_di_pkgs(self, mam_transfer):
        """
        Get DI packages representing the memory transfer
        """
        pkgs = []

        max_payload_bytes = (self.MAX_PKT_LEN - 3) * 2
        number_of_pkgs = ceil(len(mam_transfer) / max_payload_bytes)

        b = 0
        for _ in range(number_of_pkgs):
            pkg = DiPacket()
            pkg.dest = self.MODULE_DI_ADDRESS
            pkg.src = self.SENDER_DI_ADDRESS
            pkg.type = DiPacket.TYPE.EVENT.value
            pkg.type_sub = 0

            for i in range(int(max_payload_bytes / 2)):
                payload_word = mam_transfer[b] << 8 | mam_transfer[b + 1]
                pkg.payload.append(payload_word)

                b += 2
                if b >= len(mam_transfer):
                    break

            pkgs.append(pkg)

        return pkgs
示例#7
0
def _trigger_reg_rd_req_err(dut, dest, src, word_width, regaddr):
    """
    Sends a register read request to the module and checks if an error response
    gets returned.
    """

    tx_packet = DiPacket()
    rx_packet = DiPacket()
    writer = NocDiWriter(dut, dut.clk)
    reader = NocDiReader(dut, dut.clk)

    if word_width == 16:
        type_sub = DiPacket.TYPE_SUB.REQ_READ_REG_16.value
    elif word_width == 32:
        type_sub = DiPacket.TYPE_SUB.REQ_READ_REG_32.value
    elif word_width == 64:
        type_sub = DiPacket.TYPE_SUB.REQ_READ_REG_64.value
    elif word_width == 128:
        type_sub = DiPacket.TYPE_SUB.REQ_READ_REG_128.value
    else:
        raise TestFailure("An invalid register width parameter was chosen! (%d)" %\
                           word_width)

    tx_packet.set_contents(dest=dest,
                           src=src,
                           type=DiPacket.TYPE.REG.value,
                           type_sub=type_sub,
                           payload=[regaddr])

    yield writer.send_packet(tx_packet)

    rx_packet = yield reader.receive_packet(set_ready=True)

    if not rx_packet:
        raise TestFailure("No response packet received!")

    if rx_packet.type_sub != DiPacket.TYPE_SUB.RESP_READ_REG_ERROR.value:
        raise TestFailure("Register read did not return RESP_READ_REG_ERROR "
                          "when reading from register 0x%x of module 0x%x." %
                          (regaddr, dest))
示例#8
0
def _create_pkgs(dut):
    writer_signal_aliases = {'debug_in': 'in', 'debug_in_ready': 'in_ready'}
    writer = NocDiWriter(dut, dut.clk, writer_signal_aliases)

    for i in range(STRESS_TEST_PKG_COUNT):
        is_reg_pkg = random.randint(0, 1)
        pkg = DiPacket()
        if is_reg_pkg:
            pkg.set_contents(dest=1,
                             src=0,
                             type=DiPacket.TYPE.REG.value,
                             type_sub=DiPacket.TYPE_SUB.REQ_WRITE_REG_16.value,
                             payload=[0xdead])
        else:
            payload_len = random.randint(0, 5)
            payload = []
            for _ in range(payload_len):
                payload.append(random.randint(0, 2**16 - 1))

            pkg.set_contents(dest=1,
                             src=0,
                             type=DiPacket.TYPE.EVENT.value,
                             type_sub=0x3,
                             payload=payload)

        # wait a random number of cycles before sending the packet
        for s in range(random.randint(0, 100)):
            yield RisingEdge(dut.clk)

        _sent_pkgs.append(pkg)
        yield writer.send_packet(pkg)
示例#9
0
    def drive(self, mem_transfer):
        """
        Drive the Debug Interconnect with a memory transfer and check the
        results
        """

        # request
        mam_transfer_request = self._create_mam_transfer(mem_transfer)
        req_pkgs = self._create_di_pkgs(mam_transfer_request)
        for pkg in req_pkgs:
            yield self.di_writer.send_packet(pkg)

        # response
        if mem_transfer.operation == 'read':
            rcv_data = bytearray()

            while len(rcv_data) < len(mem_transfer.data):
                yield RisingEdge(self.clock)
                pkg = yield self.di_reader.receive_packet(set_ready=True)

                self.log.debug("Received memory read response " + str(pkg))
                for payload_word in pkg.payload:
                    rcv_data.extend(payload_word.to_bytes(2, byteorder='big'))

            # check received data
            if rcv_data != mem_transfer.data:
                raise TestFailure("Got invalid data.\nExpected: %s\nReceived: %s" %
                                  (mem_transfer.data.hex(), rcv_data.hex()))

        # for synchronous writes: check if we received a acknowledgement packet
        if mem_transfer.operation == 'write' and mem_transfer.sync:
            pkg = yield self.di_reader.receive_packet(set_ready=True)
            exp_sync_pkg = DiPacket()
            exp_sync_pkg.set_contents(self.SENDER_DI_ADDRESS,
                                      self.MODULE_DI_ADDRESS,
                                      DiPacket.TYPE.EVENT.value, 0, [])
            if not pkg.equal_to(self.entity, exp_sync_pkg):
                raise TestFailure(
                    "Acknowledgement packet for sync write invalid.")
示例#10
0
def _di_to_bus_tx(dut, num_transfers=500, max_delay=100, random_data=False):

    writer = NocDiWriter(dut, dut.clk);
    tx_packet = DiPacket();

    for i in range(num_transfers):
        delay = random.randint(0, max_delay)

        for _ in range(delay):
            yield RisingEdge(dut.clk)

        data = random.randint(0, 255) if random_data else 0x42

        tx_packet.set_contents(dest=MODULE_DI_ADDRESS, src=SENDER_DI_ADDRESS,
                               type=DiPacket.TYPE.EVENT.value, type_sub=0,
                               payload=[data])

        yield writer.send_packet(tx_packet)

        yield RisingEdge(dut.clk)

        _di_to_bus_fifo.append(data)
示例#11
0
def _assert_trace_event(dut, trace_id, trace_value):
    """
    Stimuli on the trace port will be generated once to trigger the emission
    of a new debug event packet which will be read and evaluated.
    """

    generator = StmTraceGenerator()
    reader = NocDiReader(dut, dut.clk)

    # Build expected packet
    expected_packet = DiPacket()
    exp_payload = [0, 0, trace_id]
    payload_words = int(dut.VALWIDTH.value.integer / 16)
    for w in range(0, payload_words):
        exp_payload.append(trace_value >> (w * 16) & 0xFFFF)

    expected_packet.set_contents(dest=SENDER_DI_ADDRESS,
                                 src=MODULE_DI_ADDRESS,
                                 type=DiPacket.TYPE.EVENT.value,
                                 type_sub=0,
                                 payload=exp_payload)

    # Build comparison mask for expected packet
    # Ignore flits 0 and 1 with timestamp
    exp_payload_mask = [1] * len(exp_payload)
    exp_payload_mask[0] = 0
    exp_payload_mask[1] = 0

    yield generator.trigger_event(dut, trace_id, trace_value)
    rcv_pkg = yield reader.receive_packet(set_ready=True)

    if not rcv_pkg:
        raise TestFailure("No response received!")

    if not rcv_pkg.equal_to(dut, expected_packet, exp_payload_mask):
        raise TestFailure(
            "The STM generated an unexpected debug event packet!")
def test_fixedwidth(dut):
    """Test the generation of two packets with a byte padding"""
    yield _init_dut(dut)

    
    dut.id <= MODULE_DI_ADDRESS
    dut.dest <= SENDER_DI_ADDRESS
    
    # create data for two packets: one full packet, and one packet with 
    # only a single payload word
    payload_words_per_pkg = dut.MAX_PKT_LEN.value.integer - 3 # 3 header words
    payload_bytes = (payload_words_per_pkg + 1) * 2
    data_bytes = bytearray(random.getrandbits(8) for _ in range(payload_bytes))
    data_int = int.from_bytes(data_bytes, byteorder='little', signed=False)
    dut.data.value = BinaryValue(data_int)

    dut.overflow <= 0
    dut.event_available <= 1


    # packet 1
    exp_pkg1_payload = [data_bytes[i+1] << 8 | data_bytes[i] for i in range(0, payload_words_per_pkg * 2, 2)]
    exp_pkg = DiPacket()
    exp_pkg.set_contents(dest=SENDER_DI_ADDRESS,
                         src=MODULE_DI_ADDRESS,
                         type=DiPacket.TYPE.EVENT,
                         type_sub=1,
                         payload=exp_pkg1_payload)

    reader = NocDiReader(dut, dut.clk)
    rcv_pkg = yield reader.receive_packet(set_ready=True)

    if not rcv_pkg:
        raise TestFailure("No packet 1 generated!")

    if not rcv_pkg.equal_to(dut, exp_pkg):
        raise TestFailure("Received packet 1 doesn't match expected packet. "
                          "Got %s, expected %s" % (str(rcv_pkg), str(exp_pkg)))

    # packet 2
    yield RisingEdge(dut.clk)
    exp_pkg2_payload = [data_bytes[i+1] << 8 | data_bytes[i] for i in range(payload_words_per_pkg * 2, payload_bytes, 2)]
    exp_pkg = DiPacket()
    exp_pkg.set_contents(dest=SENDER_DI_ADDRESS,
                         src=MODULE_DI_ADDRESS,
                         type=DiPacket.TYPE.EVENT,
                         type_sub=0,
                         payload=exp_pkg2_payload)

    reader = NocDiReader(dut, dut.clk)
    rcv_pkg = yield reader.receive_packet(set_ready=True)

    if not rcv_pkg:
        raise TestFailure("No packet 2 generated!")

    if not rcv_pkg.equal_to(dut, exp_pkg):
        raise TestFailure("Received packet 2 doesn't match expected packet. "
                          "Got %s, expected %s" % (str(rcv_pkg), str(exp_pkg)))

    # check if the DUT is ready for the next event transfer
    if not dut.event_consumed.value:
        raise TestFailure("DUT does not indicate that the event has been "
                          "consumed.")