mirror of https://github.com/openXC7/prjxray.git
110 lines
3.2 KiB
C++
110 lines
3.2 KiB
C++
/*
|
|
* 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
|