예제 #1
0
 def _create_attribute_object(
         self,
         attribute_format,
         class_name,
         value,
         value_name,
         value_description,
 ):
     AttributeModel = type(str(class_name), (XilinxType1PayloadAttribute, ), {})
     AttributeModel.__doc__ = attribute_format.description
     model = AttributeModel(int(value), value_name, value_description)
     return DataObject.create_unpacked(self.context, model, bit_size=attribute_format.bit_size)
예제 #2
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)
예제 #3
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)