blob: fe06664fd67f3e9b7890c263d54362f7a7bd2c7a [file] [log] [blame]
/*
* Copyright (C) 2017-2020 The Project X-Ray Authors.
*
* Use of this source code is governed by a ISC-style
* license that can be found in the LICENSE file or at
* https://opensource.org/licenses/ISC
*
* SPDX-License-Identifier: ISC
*/
#include <iostream>
#include <prjxray/bit_ops.h>
#include <prjxray/xilinx/architectures.h>
#include <prjxray/xilinx/bitstream_writer.h>
namespace prjxray {
namespace xilinx {
template <>
// Per UG380 pg 78: Bus Width Auto Detection
typename BitstreamWriter<Spartan6>::header_t BitstreamWriter<Spartan6>::header_{
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xAA99, 0x5566};
// Per UG470 pg 80: Bus Width Auto Detection
template <>
typename BitstreamWriter<Series7>::header_t BitstreamWriter<Series7>::header_{
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x000000BB, 0x11220044,
0xFFFFFFFF, 0xFFFFFFFF, 0xAA995566};
template <>
typename BitstreamWriter<UltraScale>::header_t
BitstreamWriter<UltraScale>::header_{0xFFFFFFFF, 0x000000BB, 0x11220044,
0xFFFFFFFF, 0xFFFFFFFF, 0xAA995566};
template <>
typename BitstreamWriter<UltraScalePlus>::header_t
BitstreamWriter<UltraScalePlus>::header_{
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x000000BB, 0x11220044,
0xFFFFFFFF, 0xFFFFFFFF, 0xAA995566};
uint32_t packet2header(
const ConfigurationPacket<Spartan6ConfigurationRegister>& packet) {
uint32_t ret = 0;
ret = bit_field_set(ret, 15, 13, packet.header_type());
switch (packet.header_type()) {
case NONE:
// Bitstreams are 0 padded sometimes, essentially making
// a type 0 frame Ignore the other fields for now
break;
case TYPE1: {
// Table 5-20: Type 1 Packet Header Format
ret = bit_field_set(ret, 12, 11, packet.opcode());
ret = bit_field_set(ret, 10, 5, packet.address());
ret = bit_field_set(ret, 4, 0, packet.data().length());
break;
}
case TYPE2: {
// Table 5-22: Type 2 Packet Header
ret = bit_field_set(ret, 12, 11, packet.opcode());
ret = bit_field_set(ret, 10, 5, packet.address());
break;
}
default:
break;
}
return ret;
}
uint32_t packet2header(
const ConfigurationPacket<Series7ConfigurationRegister>& packet) {
uint32_t ret = 0;
ret = bit_field_set(ret, 31, 29, packet.header_type());
switch (packet.header_type()) {
case NONE:
// Bitstreams are 0 padded sometimes, essentially making
// a type 0 frame Ignore the other fields for now
break;
case TYPE1: {
// Table 5-20: Type 1 Packet Header Format
ret = bit_field_set(ret, 28, 27, packet.opcode());
ret = bit_field_set(ret, 26, 13, packet.address());
ret = bit_field_set(ret, 10, 0, packet.data().length());
break;
}
case TYPE2: {
// Table 5-22: Type 2 Packet Header
// Note address is from previous type 1 header
ret = bit_field_set(ret, 28, 27, packet.opcode());
ret = bit_field_set(ret, 26, 0, packet.data().length());
break;
}
default:
break;
}
return ret;
}
} // namespace xilinx
} // namespace prjxray