示例#1
0
    def unpack(self, data_bytes):
        """
        :param bytes data_bytes:
        :rtype: XilinxBitstream
        """
        sync_marker = self.context.format.sync_word
        sync_marker_index = data_bytes.find(sync_marker)
        assert sync_marker_index >= 0, \
            "The sync marker is not present in the provided bitstream data"

        assert sync_marker_index + len(sync_marker) < len(data_bytes) - WORD_SIZE, \
            "The configuration data is expected to contain at least one word size worth of data"

        return XilinxBitstream(
            DataObject.create_packed(self.context,
                                     data_bytes[:sync_marker_index],
                                     XilinxBitstreamHeaderInterface),
            DataObject.create_packed(
                self.context,
                data_bytes[sync_marker_index:sync_marker_index +
                           len(sync_marker)],
                XilinxBitstreamSyncMarker,
            ),
            DataObject.create_packed(
                self.context,
                data_bytes[sync_marker_index + len(sync_marker):],
                XilinxPackets,
            ))
示例#2
0
 def __init__(self, converters_by_type, analyzers_by_type,
              modifiers_by_type, bytes):
     super(XilinxContext,
           self).__init__(converters_by_type, analyzers_by_type,
                          modifiers_by_type)
     self._bitstream = DataObject.create_packed(self, bytes,
                                                XilinxBitstream)
示例#3
0
    def _create_type1_payload(self, data_stream, header, register_format):
        """
        Unpack the payload for a type 1 packet

        :param io.BytesIO data_stream:
        :param XilinxCtypePacketHeader header:
        :param XilinxRegisterFormat register_format:
        :rtype: Tuple[DataObject, bool]
        """
        if header.word_count == 0:
            return None, False
        payload_data = data_stream.read(header.word_count * WORD_SIZE)
        if header.opcode == 0:
            raise ValueError(
                "NOOP Xilinx packets are expected to have a 0 length payload")

        payload = DataObject.create_packed(
            self.context,
            payload_data,
            XilinxType1Payload,
            converter_args=(register_format, ),
        )
        if register_format.name == "Cmd":
            return payload, payload.unpack().get(
                "command").get_model().value_name == "DESYNC"

        return payload, False
示例#4
0
    def unpack(self, data_bytes):
        """
        :param bytes data_bytes:
        :rtype: ArrayModel
        """
        frames = []
        data_stream = io.BytesIO(data_bytes)
        expected_size = 0
        for frame_index in range(self._major_format.frame_count):
            frame_data = data_stream.read(self._major_format.frame_size)
            expected_size += self._major_format.frame_size
            frame_description = None
            if len(self._major_format.frame_descriptions) > frame_index:
                frame_description = self._major_format.frame_descriptions[
                    frame_index]
            FrameInterface = type("XilinxFdriLogicFrame",
                                  (XilinxFdriLogicFrame, ), {})
            FrameInterface.__doc__ = frame_description
            frames.append(
                DataObject.create_packed(self.context, frame_data,
                                         FrameInterface))

        assert expected_size == len(data_bytes), \
            "The number of bytes provided {} does not match the expected number of bytes {}".format(
                len(data_bytes),
                expected_size

        )
        major_name = "".join(
            [p.title() for p in self._major_format.name.split("_")])
        class_name = "{}".format(major_name)
        MajorModel = type(class_name, (XilinxFdriLogicMajor, ), {})
        MajorModel.__doc__ = "The config data for a {} major".format(
            self._major_format.name)
        return MajorModel(frames)
示例#5
0
    def unpack(self, data_bytes):
        """
        :param bytes data_bytes:
        :rtype: ArrayModel
        """
        if self.context.id_code is None:
            raise ValueError(
                "The ID code for the targeted device has not been set on the bitstream context."
            )

        rows = []
        expected_size = 0
        data_stream = io.BytesIO(data_bytes)
        fdri_format = self.context.format.get_fdri_format(self.context.id_code)
        for row_format in fdri_format.logic_block_format:
            row_size = sum([
                major_format.frame_size * major_format.frame_count
                for major_format in row_format
            ])
            expected_size += row_size
            rows.append(
                DataObject.create_packed(
                    self.context,
                    data_stream.read(row_size),
                    XilinxFdriLogicRow,
                    converter_args=(row_format, ),
                ))

        assert expected_size == len(data_bytes), \
            "The number of bytes provided {} does not match the expected number of bytes {}".format(
                len(data_bytes),
                expected_size
            )
        return XilinxFdriLogicBlock(rows)
示例#6
0
    def unpack(self, data_bytes):
        """
        :param bytes data_bytes:
        :rtype: CustomXilinxHeaderModel
        """
        assert len(data_bytes) == 16, \
            "The header data is expected to contain 16 bytes"

        return CustomXilinxHeaderModel(
            DataObject.create_packed(self.context, data_bytes[:4],
                                     CustomXilinxHeaderPart1Interface),
            DataObject.create_packed(
                self.context,
                data_bytes[4:16],
                CustomXilinxHeaderPart2Interface,
            ),
        )
示例#7
0
 def unpack(self, data_bytes):
     """
     :param bytes data_bytes:
     :rtype: XilinxFdriPayload
     """
     if self.context.id_code is None:
         raise ValueError(
             "The ID code for the targeted device has not been set on the bitstream context."
         )
     fdri_format = self.context.format.get_fdri_format(self.context.id_code)
     expected_size = fdri_format.logic_block_size + fdri_format.bram_block_size + \
             fdri_format.io_block_size + fdri_format.crc_size
     assert len(data_bytes) == expected_size, \
         "The size of the config data ({}) does not match the expected size ({})".format(
             len(data_bytes),
             expected_size
         )
     data_stream = io.BytesIO(data_bytes)
     return XilinxFdriPayload(
         DataObject.create_packed(
             self.context,
             data_stream.read(fdri_format.logic_block_size),
             XilinxFdriLogicBlock,
         ),
         DataObject.create_packed(
             self.context,
             data_stream.read(fdri_format.bram_block_size),
             XilinxFdriRAMBlockInterface,
         ),
         DataObject.create_packed(
             self.context, data_stream.read(fdri_format.io_block_size),
             XilinxFdriIOBlockInterface),
         DataObject.create_packed(
             self.context,
             data_stream.read(fdri_format.crc_size),
             XilinxFdriCRCInterface,
         ),
     )
示例#8
0
    def _create_type2_payload(self, data_stream, header):
        """
        Unpack the payload for a type 2 packet
        :param io.BytesIO data_stream:
        :param XilinxCtypePacketHeader header:
        :rtype: Tuple[DataObject,DataObject]
        """
        register_format = self._get_register_format(header)
        word_count_data = data_stream.read(4)
        word_count, = struct.unpack(">I", word_count_data)
        payload_size_object = DataObject.create_unpacked(
            self.context, WordCountValue(word_count), bytes=word_count_data)
        payload_data = data_stream.read((word_count + 2) * WORD_SIZE)
        # TODO: Remove this hack for the LX45T, it's got 2 FDRI packets, one is waaaaay too small.
        if register_format.name != "Fdri" or len(payload_data) < 500:
            return payload_size_object, DataObject.create_packed(
                self.context,
                payload_data,
                XilinxType2PayloadInterface,
                converter_args=(register_format, ))

        return payload_size_object, DataObject.create_packed(
            self.context, payload_data, XilinxFdriPayload)
示例#9
0
    def unpack(self, data_bytes):
        sync_marker = hex_to_bytes("AA995566")
        sync_marker_index = data_bytes.find(sync_marker)
        assert sync_marker_index >= 0, \
            "The sync marker is not present in the provided bitstream data"

        assert sync_marker_index + len(sync_marker) < len(data_bytes) - 2, \
            "The configuration data is expected to contain at least one word size worth of data"

        return XilinxBitstream(
            DataObject.create_packed(self.context,
                                     data_bytes[:sync_marker_index],
                                     XilinxBitstreamHeaderInterface),
            DataObject.create_packed(
                self.context,
                data_bytes[sync_marker_index:sync_marker_index +
                           len(sync_marker)],
                XilinxBitstreamSyncMarkerInterface,
            ),
            DataObject.create_packed(
                self.context,
                data_bytes[sync_marker_index + len(sync_marker):],
                XilinxPacketsInterface,
            ))
示例#10
0
    def unpack(self, data_bytes):
        """
        :param bytes data_bytes:
        :rtype: ArrayModel
        """
        majors = []
        data_stream = io.BytesIO(data_bytes)
        expected_size = 0
        for major_format in self._row_format:
            major_size = major_format.frame_count * major_format.frame_size
            expected_size += major_size
            majors.append(
                DataObject.create_packed(self.context,
                                         data_stream.read(major_size),
                                         XilinxFdriLogicMajor,
                                         converter_args=(major_format, )))

        assert expected_size == len(data_bytes), \
            "The number of bytes provided {} does not match the expected number of bytes {}".format(
                len(data_bytes),
                expected_size
            )
        return XilinxFdriLogicRow(majors)
示例#11
0
    def unpack(self, data_bytes):
        """
        :param bytes data_bytes:
        :rtype: XilinxPackets
        """
        packets = []
        data_stream = io.BytesIO(data_bytes)
        previous_packet_type = 0
        while data_stream.tell() < len(data_bytes):
            header_raw_data = data_stream.read(2)
            header = XilinxCtypePacketHeader.from_buffer_copy(
                bytearray([header_raw_data[0], header_raw_data[1], 0, 0]))
            is_done = False
            register_format = self._get_register_format(header)
            if header.type == 0:
                payload_object = None
                payload_size_object = None
            elif header.type == 1:
                payload_object, is_done = self._create_type1_payload(
                    data_stream, header, register_format)
                payload_size_object = None
            elif header.type == 2:
                if previous_packet_type != 1:
                    raise ValueError(
                        "Unexpected packet type 2 after a packet type {}".
                        format(previous_packet_type))
                payload_size_object, payload_object = self._create_type2_payload(
                    data_stream, header)
            else:
                raise ValueError(
                    "Unexpected packet type {} while parsing the Xilinx bitstream"
                    .format(header.type))
            previous_packet_type = header.type
            raw_packet_data = header_raw_data
            if payload_size_object is not None:
                raw_packet_data += payload_size_object.get_bytes()
            if payload_object is not None:
                raw_packet_data += payload_object.get_bytes()

            header_object = DataObject.create_unpacked(
                self.context,
                model=XilinxPacketHeader(
                    DataObject.create_unpacked(
                        self.context,
                        TypeValue(int(header.type),
                                  self._get_type_name(header.type)),
                        3,
                    ),
                    DataObject.create_unpacked(
                        self.context,
                        OpCodeValue(int(header.opcode),
                                    self._get_opcode_name(header.opcode)),
                        2,
                    ),
                    DataObject.create_unpacked(
                        self.context,
                        RegisterAddressValue(int(header.register_address),
                                             register_format.name),
                        6,
                    ),
                    DataObject.create_unpacked(
                        self.context,
                        WordCountValue(int(header.word_count)),
                        5,
                    ),
                ),
                bytes=header_raw_data,
            )
            packets.append(
                DataObject.create_unpacked(
                    self.context,
                    model=XilinxPacket(
                        header_object,
                        payload_size_object,
                        payload_object,
                    ),
                    bytes=raw_packet_data,
                ))
            if is_done is True:
                packets.append(
                    DataObject.create_packed(
                        self.context,
                        data_stream.read(),
                        XilinxPacketsTail,
                    ))
                break
        return XilinxPackets(packets)