mirror of https://github.com/openXC7/prjxray.git
Merge branch 'master' into tileconnloops
This commit is contained in:
commit
89854a55e6
|
|
@ -4,7 +4,7 @@ add_library(libprjxray
|
|||
segbits_file_reader.cc
|
||||
xilinx/xc7series/bitstream_reader.cc
|
||||
xilinx/xc7series/block_type.cc
|
||||
xilinx/xc7series/configuration_frame_address.cc
|
||||
xilinx/xc7series/frame_address.cc
|
||||
xilinx/xc7series/configuration_frame_range.cc
|
||||
xilinx/xc7series/configuration_packet.cc
|
||||
xilinx/xc7series/configuration_register.cc
|
||||
|
|
@ -50,19 +50,20 @@ if (PRJXRAY_BUILD_TESTING)
|
|||
add_test(NAME xilinx_xc7series_block_type_test
|
||||
COMMAND xilinx_xc7series_block_type_test)
|
||||
|
||||
add_executable(xilinx_xc7series_configuration_frame_address_test
|
||||
xilinx/xc7series/configuration_frame_address_test.cc)
|
||||
target_link_libraries(xilinx_xc7series_configuration_frame_address_test
|
||||
add_executable(xilinx_xc7series_frame_address_test
|
||||
xilinx/xc7series/frame_address_test.cc)
|
||||
target_link_libraries(xilinx_xc7series_frame_address_test
|
||||
libprjxray gtest_main absl::span)
|
||||
add_test(NAME xilinx_xc7series_configuration_frame_address_test
|
||||
COMMAND xilinx_xc7series_configuration_frame_address_test)
|
||||
add_test(NAME xilinx_xc7series_frame_address_test
|
||||
COMMAND xilinx_xc7series_frame_address_test)
|
||||
|
||||
add_executable(xilinx_xc7series_configuration_test
|
||||
xilinx/xc7series/configuration_test.cc)
|
||||
target_link_libraries(xilinx_xc7series_configuration_test
|
||||
libprjxray gtest_main absl::span)
|
||||
add_test(NAME xilinx_xc7series_configuration_test
|
||||
COMMAND xilinx_xc7series_configuration_test)
|
||||
COMMAND xilinx_xc7series_configuration_test
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/test_data)
|
||||
|
||||
add_executable(xilinx_xc7series_configuration_packet_test
|
||||
xilinx/xc7series/configuration_packet_test.cc)
|
||||
|
|
|
|||
|
|
@ -4,6 +4,8 @@
|
|||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include <absl/types/span.h>
|
||||
|
||||
namespace prjxray {
|
||||
|
||||
class MemoryMappedFile {
|
||||
|
|
@ -16,6 +18,10 @@ class MemoryMappedFile {
|
|||
void* const data() const { return data_; }
|
||||
const size_t size() const { return size_; }
|
||||
|
||||
absl::Span<uint8_t> as_bytes() const {
|
||||
return {static_cast<uint8_t*>(data_), size_};
|
||||
}
|
||||
|
||||
private:
|
||||
MemoryMappedFile(void *data, size_t size)
|
||||
: data_(data), size_(size) {};
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ class BitstreamReader {
|
|||
// Construct a `BitstreamReader` from a Container of bytes.
|
||||
// Any bytes preceding an initial sync word are ignored.
|
||||
template<typename T>
|
||||
static absl::optional<BitstreamReader> InitWithBytes(T &bitstream);
|
||||
static absl::optional<BitstreamReader> InitWithBytes(T bitstream);
|
||||
|
||||
const std::vector<uint32_t> &words() { return words_; };
|
||||
|
||||
|
|
@ -62,7 +62,7 @@ class BitstreamReader {
|
|||
};
|
||||
|
||||
template<typename T>
|
||||
absl::optional<BitstreamReader> BitstreamReader::InitWithBytes(T &bitstream) {
|
||||
absl::optional<BitstreamReader> BitstreamReader::InitWithBytes(T bitstream) {
|
||||
// If this is really a Xilinx 7-Series bitstream, there will be a sync
|
||||
// word somewhere toward the beginning.
|
||||
auto sync_pos = std::search(bitstream.begin(), bitstream.end(),
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
#include <absl/types/span.h>
|
||||
#include <prjxray/bit_ops.h>
|
||||
#include <prjxray/xilinx/xc7series/bitstream_reader.h>
|
||||
#include <prjxray/xilinx/xc7series/configuration_frame_address.h>
|
||||
#include <prjxray/xilinx/xc7series/frame_address.h>
|
||||
#include <prjxray/xilinx/xc7series/part.h>
|
||||
|
||||
namespace prjxray {
|
||||
|
|
@ -15,7 +15,7 @@ namespace xc7series {
|
|||
|
||||
class Configuration {
|
||||
public:
|
||||
using FrameMap = std::map<ConfigurationFrameAddress,
|
||||
using FrameMap = std::map<FrameAddress,
|
||||
absl::Span<uint32_t>>;
|
||||
|
||||
template<typename Collection>
|
||||
|
|
@ -46,7 +46,7 @@ absl::optional<Configuration> Configuration::InitWithPackets(
|
|||
|
||||
// Internal state machine for writes.
|
||||
bool start_new_write = false;
|
||||
ConfigurationFrameAddress current_frame_address = 0;
|
||||
FrameAddress current_frame_address = 0;
|
||||
|
||||
Configuration::FrameMap frames;
|
||||
for (auto packet : packets) {
|
||||
|
|
@ -112,20 +112,24 @@ absl::optional<Configuration> Configuration::InitWithPackets(
|
|||
// 7-series frames are 101-words long. Writes to this
|
||||
// register can be multiples of that to do
|
||||
// auto-incrementing block writes.
|
||||
int frames_written = packet.data().size() /
|
||||
kWordsPerFrame;
|
||||
|
||||
for (int ii = 0; ii < frames_written; ++ii) {
|
||||
for (size_t ii = 0;
|
||||
ii < packet.data().size();
|
||||
ii += kWordsPerFrame) {
|
||||
frames[current_frame_address] =
|
||||
packet.data().subspan(
|
||||
ii * kWordsPerFrame,
|
||||
kWordsPerFrame);
|
||||
auto next_address =
|
||||
part.GetNextConfigurationFrameAddress(
|
||||
ii, kWordsPerFrame);
|
||||
|
||||
auto next_address = part.GetNextFrameAddress(
|
||||
current_frame_address);
|
||||
if (next_address) {
|
||||
current_frame_address = *next_address;
|
||||
if (!next_address) break;
|
||||
|
||||
// Bitstreams appear to have 2 frames of
|
||||
// padding between rows.
|
||||
if (next_address->row_address() !=
|
||||
current_frame_address.row_address()) {
|
||||
ii += 2 * kWordsPerFrame;
|
||||
}
|
||||
current_frame_address = *next_address;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,49 +0,0 @@
|
|||
#ifndef PRJXRAY_LIB_XILINX_XC7SERIES_CONFIGURATION_FRAME_ADDRESS_H_
|
||||
#define PRJXRAY_LIB_XILINX_XC7SERIES_CONFIGURATION_FRAME_ADDRESS_H_
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
#include <prjxray/xilinx/xc7series/block_type.h>
|
||||
#include <yaml-cpp/yaml.h>
|
||||
|
||||
namespace prjxray {
|
||||
namespace xilinx {
|
||||
namespace xc7series {
|
||||
|
||||
class ConfigurationFrameAddress {
|
||||
public:
|
||||
ConfigurationFrameAddress()
|
||||
: address_(0) {}
|
||||
|
||||
ConfigurationFrameAddress(uint32_t address)
|
||||
: address_(address) {};
|
||||
|
||||
ConfigurationFrameAddress(
|
||||
BlockType block_type, bool is_bottom_half_rows,
|
||||
uint8_t row, uint16_t column, uint8_t minor);
|
||||
|
||||
operator uint32_t() const { return address_; }
|
||||
|
||||
BlockType block_type() const;
|
||||
bool is_bottom_half_rows() const;
|
||||
uint8_t row_address() const;
|
||||
uint16_t column_address() const;
|
||||
uint8_t minor_address() const;
|
||||
|
||||
private:
|
||||
uint32_t address_;
|
||||
};
|
||||
|
||||
} // namespace xc7series
|
||||
} // namespace xilinx
|
||||
} // namespace prjxray
|
||||
|
||||
namespace YAML {
|
||||
template<>
|
||||
struct convert<prjxray::xilinx::xc7series::ConfigurationFrameAddress> {
|
||||
static Node encode(const prjxray::xilinx::xc7series::ConfigurationFrameAddress &rhs);
|
||||
static bool decode(const Node& node,
|
||||
prjxray::xilinx::xc7series::ConfigurationFrameAddress &lhs);
|
||||
};
|
||||
} // namespace YAML
|
||||
#endif // PRJXRAY_LIB_XILINX_XC7SERIES_CONFIGURATION_FRAME_ADDRESS_H_
|
||||
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
#include <cstdint>
|
||||
|
||||
#include <prjxray/xilinx/xc7series/configuration_frame_address.h>
|
||||
#include <prjxray/xilinx/xc7series/frame_address.h>
|
||||
#include <yaml-cpp/yaml.h>
|
||||
|
||||
namespace prjxray {
|
||||
|
|
@ -14,21 +14,20 @@ class ConfigurationFrameRange {
|
|||
public:
|
||||
ConfigurationFrameRange() : begin_(0), end_(0) {}
|
||||
|
||||
ConfigurationFrameRange(ConfigurationFrameAddress begin,
|
||||
ConfigurationFrameAddress end)
|
||||
ConfigurationFrameRange(FrameAddress begin, FrameAddress end)
|
||||
: begin_(begin), end_(end) {};
|
||||
|
||||
ConfigurationFrameAddress begin() const { return begin_; }
|
||||
ConfigurationFrameAddress end() const { return end_; }
|
||||
FrameAddress begin() const { return begin_; }
|
||||
FrameAddress end() const { return end_; }
|
||||
|
||||
size_t size() const { return end_ - begin_; }
|
||||
bool empty() const { return size() == 0; }
|
||||
|
||||
bool Contains(ConfigurationFrameAddress address) const;
|
||||
bool Contains(FrameAddress address) const;
|
||||
|
||||
private:
|
||||
ConfigurationFrameAddress begin_;
|
||||
ConfigurationFrameAddress end_;
|
||||
FrameAddress begin_;
|
||||
FrameAddress end_;
|
||||
};
|
||||
|
||||
} // namespace xc7series
|
||||
|
|
|
|||
|
|
@ -0,0 +1,50 @@
|
|||
#ifndef PRJXRAY_LIB_XILINX_XC7SERIES_FRAME_ADDRESS_H_
|
||||
#define PRJXRAY_LIB_XILINX_XC7SERIES_FRAME_ADDRESS_H_
|
||||
|
||||
#include <cstdint>
|
||||
#include <ostream>
|
||||
|
||||
#include <prjxray/xilinx/xc7series/block_type.h>
|
||||
#include <yaml-cpp/yaml.h>
|
||||
|
||||
namespace prjxray {
|
||||
namespace xilinx {
|
||||
namespace xc7series {
|
||||
|
||||
class FrameAddress {
|
||||
public:
|
||||
FrameAddress() : address_(0) {}
|
||||
|
||||
FrameAddress(uint32_t address)
|
||||
: address_(address) {};
|
||||
|
||||
FrameAddress(BlockType block_type, bool is_bottom_half_rows,
|
||||
uint8_t row, uint16_t column, uint8_t minor);
|
||||
|
||||
operator uint32_t() const { return address_; }
|
||||
|
||||
BlockType block_type() const;
|
||||
bool is_bottom_half_rows() const;
|
||||
uint8_t row_address() const;
|
||||
uint16_t column_address() const;
|
||||
uint8_t minor_address() const;
|
||||
|
||||
private:
|
||||
uint32_t address_;
|
||||
};
|
||||
|
||||
std::ostream &operator<<(std::ostream &o, const FrameAddress& addr);
|
||||
|
||||
} // namespace xc7series
|
||||
} // namespace xilinx
|
||||
} // namespace prjxray
|
||||
|
||||
namespace YAML {
|
||||
template<>
|
||||
struct convert<prjxray::xilinx::xc7series::FrameAddress> {
|
||||
static Node encode(const prjxray::xilinx::xc7series::FrameAddress &rhs);
|
||||
static bool decode(const Node& node,
|
||||
prjxray::xilinx::xc7series::FrameAddress &lhs);
|
||||
};
|
||||
} // namespace YAML
|
||||
#endif // PRJXRAY_LIB_XILINX_XC7SERIES_FRAME_ADDRESS_H_
|
||||
|
|
@ -4,7 +4,7 @@
|
|||
#include <vector>
|
||||
|
||||
#include <absl/types/optional.h>
|
||||
#include <prjxray/xilinx/xc7series/configuration_frame_address.h>
|
||||
#include <prjxray/xilinx/xc7series/frame_address.h>
|
||||
#include <prjxray/xilinx/xc7series/configuration_frame_range.h>
|
||||
|
||||
namespace prjxray {
|
||||
|
|
@ -28,9 +28,8 @@ class Part {
|
|||
const std::vector<ConfigurationFrameRange>&
|
||||
configuration_frame_ranges() const { return frame_ranges_; }
|
||||
|
||||
absl::optional<ConfigurationFrameAddress>
|
||||
GetNextConfigurationFrameAddress(
|
||||
ConfigurationFrameAddress address) const;
|
||||
absl::optional<FrameAddress>
|
||||
GetNextFrameAddress(FrameAddress address) const;
|
||||
|
||||
private:
|
||||
uint32_t idcode_;
|
||||
|
|
|
|||
Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because it is too large
Load Diff
|
|
@ -4,8 +4,7 @@ namespace prjxray {
|
|||
namespace xilinx {
|
||||
namespace xc7series {
|
||||
|
||||
bool ConfigurationFrameRange::Contains(
|
||||
ConfigurationFrameAddress address) const {
|
||||
bool ConfigurationFrameRange::Contains(FrameAddress address) const {
|
||||
return address >= begin_ && address < end_;
|
||||
}
|
||||
|
||||
|
|
@ -34,8 +33,8 @@ bool convert<xc7series::ConfigurationFrameRange>::decode(
|
|||
!node["end"]) return false;
|
||||
|
||||
lhs = xc7series::ConfigurationFrameRange(
|
||||
node["begin"].as<xc7series::ConfigurationFrameAddress>(),
|
||||
node["end"].as<xc7series::ConfigurationFrameAddress>());
|
||||
node["begin"].as<xc7series::FrameAddress>(),
|
||||
node["end"].as<xc7series::FrameAddress>());
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
#include <absl/types/span.h>
|
||||
#include <gtest/gtest.h>
|
||||
#include <prjxray/memory_mapped_file.h>
|
||||
#include <prjxray/xilinx/xc7series/configuration_packet.h>
|
||||
#include <prjxray/xilinx/xc7series/configuration_register.h>
|
||||
#include <prjxray/xilinx/xc7series/part.h>
|
||||
|
|
@ -106,6 +107,106 @@ TEST(ConfigurationTest, ConstructFromPacketsWithAutoincrement) {
|
|||
absl::Span<uint32_t> frame_span(frame);
|
||||
EXPECT_EQ(test_config->part().idcode(), static_cast<uint32_t>(0x1234));
|
||||
EXPECT_EQ(test_config->frames().size(), static_cast<size_t>(2));
|
||||
EXPECT_EQ(test_config->frames().at(0x456F), frame_span.subspan(0, 101));
|
||||
EXPECT_EQ(test_config->frames().at(0x4580), frame_span.subspan(101));
|
||||
EXPECT_EQ(test_config->frames().at(0x456F), std::vector<uint32_t>(101, 0xAA));
|
||||
EXPECT_EQ(test_config->frames().at(0x4580), std::vector<uint32_t>(101, 0xBB));
|
||||
}
|
||||
|
||||
TEST(ConfigurationTest, DebugAndPerFrameCrcBitstreamsProduceEqualConfigurations) {
|
||||
auto part = xc7series::Part::FromFile("configuration_test.yaml");
|
||||
ASSERT_TRUE(part);
|
||||
|
||||
auto debug_bitstream = prjxray::MemoryMappedFile::InitWithFile(
|
||||
"configuration_test.debug.bit");
|
||||
ASSERT_TRUE(debug_bitstream);
|
||||
|
||||
auto debug_reader = xc7series::BitstreamReader::InitWithBytes(
|
||||
debug_bitstream->as_bytes());
|
||||
ASSERT_TRUE(debug_reader);
|
||||
|
||||
auto debug_configuration = xc7series::Configuration::InitWithPackets(
|
||||
*part, *debug_reader);
|
||||
ASSERT_TRUE(debug_configuration);
|
||||
|
||||
auto perframecrc_bitstream = prjxray::MemoryMappedFile::InitWithFile(
|
||||
"configuration_test.perframecrc.bit");
|
||||
ASSERT_TRUE(perframecrc_bitstream);
|
||||
|
||||
auto perframecrc_reader = xc7series::BitstreamReader::InitWithBytes(
|
||||
perframecrc_bitstream->as_bytes());
|
||||
ASSERT_TRUE(perframecrc_reader);
|
||||
|
||||
auto perframecrc_configuration = xc7series::Configuration::InitWithPackets(
|
||||
*part, *perframecrc_reader);
|
||||
ASSERT_TRUE(perframecrc_configuration);
|
||||
|
||||
for (auto debug_frame : debug_configuration->frames()) {
|
||||
auto perframecrc_frame = perframecrc_configuration->frames().find(debug_frame.first);
|
||||
if (perframecrc_frame == perframecrc_configuration->frames().end()) {
|
||||
ADD_FAILURE() << debug_frame.first << ": missing in perframecrc bitstream";
|
||||
continue;
|
||||
}
|
||||
|
||||
for (int ii = 0; ii < 101; ++ii) {
|
||||
EXPECT_EQ(perframecrc_frame->second[ii], debug_frame.second[ii])
|
||||
<< debug_frame.first << ": word " << ii;
|
||||
}
|
||||
}
|
||||
|
||||
for (auto perframecrc_frame : perframecrc_configuration->frames()) {
|
||||
auto debug_frame = debug_configuration->frames().find(perframecrc_frame.first);
|
||||
if (debug_frame == debug_configuration->frames().end()) {
|
||||
ADD_FAILURE() << perframecrc_frame.first
|
||||
<< ": unexpectedly present in perframecrc bitstream";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST(ConfigurationTest, DebugAndNormalBitstreamsProduceEqualConfigurations) {
|
||||
auto part = xc7series::Part::FromFile("configuration_test.yaml");
|
||||
ASSERT_TRUE(part);
|
||||
|
||||
auto debug_bitstream = prjxray::MemoryMappedFile::InitWithFile(
|
||||
"configuration_test.debug.bit");
|
||||
ASSERT_TRUE(debug_bitstream);
|
||||
|
||||
auto debug_reader = xc7series::BitstreamReader::InitWithBytes(
|
||||
debug_bitstream->as_bytes());
|
||||
ASSERT_TRUE(debug_reader);
|
||||
|
||||
auto debug_configuration = xc7series::Configuration::InitWithPackets(
|
||||
*part, *debug_reader);
|
||||
ASSERT_TRUE(debug_configuration);
|
||||
|
||||
auto normal_bitstream = prjxray::MemoryMappedFile::InitWithFile(
|
||||
"configuration_test.bit");
|
||||
ASSERT_TRUE(normal_bitstream);
|
||||
|
||||
auto normal_reader = xc7series::BitstreamReader::InitWithBytes(
|
||||
normal_bitstream->as_bytes());
|
||||
ASSERT_TRUE(normal_reader);
|
||||
|
||||
auto normal_configuration = xc7series::Configuration::InitWithPackets(
|
||||
*part, *normal_reader);
|
||||
ASSERT_TRUE(normal_configuration);
|
||||
|
||||
for (auto debug_frame : debug_configuration->frames()) {
|
||||
auto normal_frame = normal_configuration->frames().find(debug_frame.first);
|
||||
if (normal_frame == normal_configuration->frames().end()) {
|
||||
ADD_FAILURE() << debug_frame.first << ": missing in normal bitstream";
|
||||
continue;
|
||||
}
|
||||
|
||||
for (int ii = 0; ii < 101; ++ii) {
|
||||
EXPECT_EQ(normal_frame->second[ii], debug_frame.second[ii])
|
||||
<< debug_frame.first << ": word " << ii;
|
||||
}
|
||||
}
|
||||
|
||||
for (auto normal_frame : normal_configuration->frames()) {
|
||||
auto debug_frame = debug_configuration->frames().find(normal_frame.first);
|
||||
if (debug_frame == debug_configuration->frames().end()) {
|
||||
ADD_FAILURE() << normal_frame.first
|
||||
<< ": unexpectedly present in normal bitstream";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
#include <prjxray/xilinx/xc7series/configuration_frame_address.h>
|
||||
#include <prjxray/xilinx/xc7series/frame_address.h>
|
||||
|
||||
#include <iomanip>
|
||||
|
||||
#include <prjxray/bit_ops.h>
|
||||
|
||||
|
|
@ -6,10 +8,8 @@ namespace prjxray {
|
|||
namespace xilinx {
|
||||
namespace xc7series {
|
||||
|
||||
|
||||
ConfigurationFrameAddress::ConfigurationFrameAddress(
|
||||
BlockType block_type, bool is_bottom_half_rows,
|
||||
uint8_t row, uint16_t column, uint8_t minor) {
|
||||
FrameAddress::FrameAddress(BlockType block_type, bool is_bottom_half_rows,
|
||||
uint8_t row, uint16_t column, uint8_t minor) {
|
||||
address_ = bit_field_set(0, 25, 23, block_type);
|
||||
address_ = bit_field_set(address_, 22, 22, is_bottom_half_rows);
|
||||
address_ = bit_field_set(address_, 21, 17, row);
|
||||
|
|
@ -17,26 +17,46 @@ ConfigurationFrameAddress::ConfigurationFrameAddress(
|
|||
address_ = bit_field_set(address_, 6, 0, minor);
|
||||
}
|
||||
|
||||
BlockType ConfigurationFrameAddress::block_type() const {
|
||||
BlockType FrameAddress::block_type() const {
|
||||
return static_cast<BlockType>(bit_field_get(address_, 25, 23));
|
||||
}
|
||||
|
||||
bool ConfigurationFrameAddress::is_bottom_half_rows() const {
|
||||
bool FrameAddress::is_bottom_half_rows() const {
|
||||
return bit_field_get(address_, 22, 22);
|
||||
}
|
||||
|
||||
uint8_t ConfigurationFrameAddress::row_address() const {
|
||||
uint8_t FrameAddress::row_address() const {
|
||||
return bit_field_get(address_, 21, 17);
|
||||
}
|
||||
|
||||
uint16_t ConfigurationFrameAddress::column_address() const {
|
||||
uint16_t FrameAddress::column_address() const {
|
||||
return bit_field_get(address_, 16, 7);
|
||||
}
|
||||
|
||||
uint8_t ConfigurationFrameAddress::minor_address() const {
|
||||
uint8_t FrameAddress::minor_address() const {
|
||||
return bit_field_get(address_, 6, 0);
|
||||
}
|
||||
|
||||
std::ostream &operator<<(std::ostream &o, const FrameAddress& addr) {
|
||||
o << "["
|
||||
<< std::hex << std::showbase << std::setw(10)
|
||||
<< static_cast<uint32_t>(addr)
|
||||
<< "] "
|
||||
<< (addr.is_bottom_half_rows() ? "BOTTOM" : "TOP")
|
||||
<< " Row="
|
||||
<< std::setw(2) << std::dec
|
||||
<< static_cast<unsigned int>(addr.row_address())
|
||||
<< " Column="
|
||||
<< std::setw(2) << std::dec
|
||||
<< addr.column_address()
|
||||
<< " Minor="
|
||||
<< std::setw(2) << std::dec
|
||||
<< static_cast<unsigned int>(addr.minor_address())
|
||||
<< " Type="
|
||||
<< addr.block_type();
|
||||
return o;
|
||||
}
|
||||
|
||||
} // namespace xc7series
|
||||
} // namespace xilinx
|
||||
} // namespace prjxray
|
||||
|
|
@ -45,10 +65,10 @@ namespace YAML {
|
|||
|
||||
namespace xc7series = prjxray::xilinx::xc7series;
|
||||
|
||||
Node convert<xc7series::ConfigurationFrameAddress>::encode(
|
||||
const xc7series::ConfigurationFrameAddress &rhs) {
|
||||
Node convert<xc7series::FrameAddress>::encode(
|
||||
const xc7series::FrameAddress &rhs) {
|
||||
Node node;
|
||||
node.SetTag("xilinx/xc7series/configuration_frame_address");
|
||||
node.SetTag("xilinx/xc7series/frame_address");
|
||||
node["block_type"] = rhs.block_type();
|
||||
node["row_half"] = (rhs.is_bottom_half_rows() ? "bottom" : "top");
|
||||
node["row"] = static_cast<unsigned int>(rhs.row_address());
|
||||
|
|
@ -57,9 +77,10 @@ Node convert<xc7series::ConfigurationFrameAddress>::encode(
|
|||
return node;
|
||||
}
|
||||
|
||||
bool convert<xc7series::ConfigurationFrameAddress>::decode(
|
||||
const Node &node, xc7series::ConfigurationFrameAddress &lhs) {
|
||||
if (node.Tag() != "xilinx/xc7series/configuration_frame_address" ||
|
||||
bool convert<xc7series::FrameAddress>::decode(
|
||||
const Node &node, xc7series::FrameAddress &lhs) {
|
||||
if (!(node.Tag() == "xilinx/xc7series/frame_address" ||
|
||||
node.Tag() == "xilinx/xc7series/configuration_frame_address") ||
|
||||
!node["block_type"] ||
|
||||
!node["row_half"] ||
|
||||
!node["row"] ||
|
||||
|
|
@ -75,7 +96,7 @@ bool convert<xc7series::ConfigurationFrameAddress>::decode(
|
|||
return false;
|
||||
}
|
||||
|
||||
lhs = prjxray::xilinx::xc7series::ConfigurationFrameAddress(
|
||||
lhs = prjxray::xilinx::xc7series::FrameAddress(
|
||||
node["block_type"].as<xc7series::BlockType>(),
|
||||
row_half,
|
||||
node["row"].as<unsigned int>(),
|
||||
|
|
@ -1,17 +1,16 @@
|
|||
#include <prjxray/xilinx/xc7series/configuration_frame_address.h>
|
||||
#include <prjxray/xilinx/xc7series/frame_address.h>
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
namespace xc7series = prjxray::xilinx::xc7series;
|
||||
|
||||
TEST(ConfigurationFrameAddressTest, YamlEncode) {
|
||||
xc7series::ConfigurationFrameAddress address(
|
||||
xc7series::BlockType::BLOCK_RAM,
|
||||
false, 10, 0, 5);
|
||||
TEST(FrameAddressTest, YamlEncode) {
|
||||
xc7series::FrameAddress address(xc7series::BlockType::BLOCK_RAM,
|
||||
false, 10, 0, 5);
|
||||
|
||||
YAML::Node node(address);
|
||||
|
||||
EXPECT_EQ(node.Tag(), "xilinx/xc7series/configuration_frame_address");
|
||||
EXPECT_EQ(node.Tag(), "xilinx/xc7series/frame_address");
|
||||
EXPECT_EQ(node["block_type"].as<std::string>(), "BLOCK_RAM");
|
||||
EXPECT_EQ(node["row_half"].as<std::string>(), "top");
|
||||
EXPECT_EQ(node["row"].as<std::string>(), "10");
|
||||
|
|
@ -19,17 +18,17 @@ TEST(ConfigurationFrameAddressTest, YamlEncode) {
|
|||
EXPECT_EQ(node["minor"].as<std::string>(), "5");
|
||||
}
|
||||
|
||||
TEST(ConfigurationFrameAddressTest, YamlDecode) {
|
||||
TEST(FrameAddressTest, YamlDecode) {
|
||||
YAML::Node node;
|
||||
node.SetTag("xilinx/xc7series/configuration_frame_address");
|
||||
node.SetTag("xilinx/xc7series/frame_address");
|
||||
node["block_type"] = "BLOCK_RAM";
|
||||
node["row_half"] = "bottom";
|
||||
node["row"] = "0";
|
||||
node["column"] = "5";
|
||||
node["minor"] = "11";
|
||||
|
||||
xc7series::ConfigurationFrameAddress address =
|
||||
node.as<xc7series::ConfigurationFrameAddress>();
|
||||
xc7series::FrameAddress address =
|
||||
node.as<xc7series::FrameAddress>();
|
||||
EXPECT_EQ(address.block_type(), xc7series::BlockType::BLOCK_RAM);
|
||||
EXPECT_TRUE(address.is_bottom_half_rows());
|
||||
EXPECT_EQ(address.row_address(), 0);
|
||||
|
|
@ -16,16 +16,16 @@ absl::optional<Part> Part::FromFile(const std::string &path) {
|
|||
}
|
||||
}
|
||||
|
||||
absl::optional<ConfigurationFrameAddress>
|
||||
Part::GetNextConfigurationFrameAddress(ConfigurationFrameAddress address) const {
|
||||
absl::optional<FrameAddress>
|
||||
Part::GetNextFrameAddress(FrameAddress address) const {
|
||||
// Start with the next linear address.
|
||||
ConfigurationFrameAddress target_address(address + 1);
|
||||
FrameAddress target_address(address + 1);
|
||||
|
||||
// The address space is non-continguous. If the next linear address
|
||||
// happens to fall in a valid range, that's the next address.
|
||||
// Otherwise, find the closest valid range and use it's beginning
|
||||
// address.
|
||||
absl::optional<ConfigurationFrameAddress> closest_address;
|
||||
absl::optional<FrameAddress> closest_address;
|
||||
int32_t closest_distance;
|
||||
for (auto iter = frame_ranges_.begin();
|
||||
iter != frame_ranges_.end();
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ TEST(PartTest, GetNextAddressWhereNextIsInValidRange) {
|
|||
|
||||
xc7series::Part part(0x1234, ranges);
|
||||
|
||||
auto next_address = part.GetNextConfigurationFrameAddress(0x4);
|
||||
auto next_address = part.GetNextFrameAddress(0x4);
|
||||
EXPECT_TRUE(next_address);
|
||||
EXPECT_EQ(static_cast<uint32_t>(0x5), *next_address);
|
||||
}
|
||||
|
|
@ -23,7 +23,7 @@ TEST(PartTest, GetNextAddressWhereNextIsBetweenRanges) {
|
|||
|
||||
xc7series::Part part(0x1234, ranges);
|
||||
|
||||
auto next_address = part.GetNextConfigurationFrameAddress(0xF);
|
||||
auto next_address = part.GetNextFrameAddress(0xF);
|
||||
EXPECT_TRUE(next_address);
|
||||
EXPECT_EQ(static_cast<uint32_t>(0x20), *next_address);
|
||||
}
|
||||
|
|
@ -35,6 +35,6 @@ TEST(PartTest, GetNextAddressWhereNextWouldBePastLastRange) {
|
|||
|
||||
xc7series::Part part(0x1234, ranges);
|
||||
|
||||
auto next_address = part.GetNextConfigurationFrameAddress(0x2F);
|
||||
auto next_address = part.GetNextFrameAddress(0x2F);
|
||||
EXPECT_FALSE(next_address);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,8 @@
|
|||
/.Xil
|
||||
/design/
|
||||
/design.bit
|
||||
/design.bits
|
||||
/design.dcp
|
||||
/usage_statistics_webtalk.*
|
||||
/vivado*
|
||||
/design.txt
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
all:
|
||||
bash runme.sh
|
||||
|
||||
clean:
|
||||
rm -rf specimen_[0-9][0-9][0-9]/ seg_clblx.segbits vivado*.log vivado_*.str vivado*.jou design *.bits *.dcp *.bit design.txt .Xil
|
||||
|
||||
.PHONY: all clean
|
||||
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
Creates an ROI with clk, inputs, and outputs to use as a partial reconfiguration test harness
|
||||
|
||||
Basic idea:
|
||||
-LOC LUTs in the ROI to terminate input and output routing
|
||||
-Let Vivado LOC the rest of the logic
|
||||
-Manually route signals in and out of the ROI enough to avoid routing loops into the ROI
|
||||
-Let Vivado finish the rest of the routes
|
||||
|
||||
There is no logic outside of the ROI in order to keep IOB to ROI delays short
|
||||
Its expected the end user will rip out everything inside the ROI
|
||||
|
||||
To target Arty A7 you should source the artix DB environment script then source arty.sh
|
||||
|
|
@ -0,0 +1 @@
|
|||
export XRAY_PART=xc7a35tcsg324-1
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
#!/bin/bash
|
||||
|
||||
set -ex
|
||||
vivado -mode batch -source runme.tcl
|
||||
test -z "$(fgrep CRITICAL vivado.log)"
|
||||
|
||||
|
|
@ -0,0 +1,273 @@
|
|||
# WARNING: this is somewhat paramaterized, but is only tested on A50T/A35T with the traditional ROI
|
||||
# Your ROI should at least have a SLICEL on the left
|
||||
|
||||
set DIN_N 8
|
||||
set DOUT_N 8
|
||||
# X12 in the ROI, X10 just to the left
|
||||
# Start at bottom left of ROI and work up
|
||||
# (IOs are to left)
|
||||
# SLICE_X12Y100:SLICE_X27Y149
|
||||
# set X_BASE 12
|
||||
set X_BASE [lindex [split [lindex [split "$::env(XRAY_ROI)" Y] 0] X] 1]
|
||||
set Y_BASE [lindex [split [lindex [split "$::env(XRAY_ROI)" Y] 1] :] 0]
|
||||
# set Y_DIN_BASE 100
|
||||
set Y_CLK_BASE $Y_BASE
|
||||
# Clock lut in middle
|
||||
set Y_DIN_BASE [expr "$Y_CLK_BASE + 1"]
|
||||
set Y_DOUT_BASE [expr "$Y_DIN_BASE + $DIN_N"]
|
||||
|
||||
puts "Environment"
|
||||
puts " XRAY_ROI: $::env(XRAY_ROI)"
|
||||
puts " X_BASE: $X_BASE"
|
||||
puts " Y_DIN_BASE: $Y_DIN_BASE"
|
||||
puts " Y_CLK_BASE: $Y_CLK_BASE"
|
||||
puts " Y_DOUT_BASE: $Y_DOUT_BASE"
|
||||
|
||||
source ../../utils/utils.tcl
|
||||
|
||||
create_project -force -part $::env(XRAY_PART) design design
|
||||
read_verilog top.v
|
||||
# added flatten_hierarchy
|
||||
# dout_shr was getting folded into the pblock
|
||||
# synth_design -top top -flatten_hierarchy none -no_lc -keep_equivalent_registers -resource_sharing off
|
||||
synth_design -top top -flatten_hierarchy none -verilog_define DIN_N=$DIN_N -verilog_define DOUT_N=$DOUT_N
|
||||
|
||||
# TODO: find a way to more automatically assign these?
|
||||
# Sequential I/O Bank 16 layout
|
||||
set part "$::env(XRAY_PART)"
|
||||
if {$part eq "xc7a50tfgg484-1"} {
|
||||
# Partial list, expand as needed
|
||||
set bank_16 "F21 G22 G21 D21 E21 D22 E22 A21 B21 B22 C22 C20 D20 F20 F19 A19 A18"
|
||||
set banki 0
|
||||
|
||||
# CLK
|
||||
set pin [lindex $bank_16 $banki]
|
||||
incr banki
|
||||
set_property -dict "PACKAGE_PIN $pin IOSTANDARD LVCMOS33" [get_ports "clk"]
|
||||
|
||||
# DIN
|
||||
for {set j 0} {$j < $DIN_N} {incr j} {
|
||||
set pin [lindex $bank_16 $banki]
|
||||
incr banki
|
||||
set_property -dict "PACKAGE_PIN $pin IOSTANDARD LVCMOS33" [get_ports "din[$j]"]
|
||||
}
|
||||
|
||||
# DOUT
|
||||
for {set j 0} {$j < $DOUT_N} {incr j} {
|
||||
set pin [lindex $bank_16 $banki]
|
||||
incr banki
|
||||
set_property -dict "PACKAGE_PIN $pin IOSTANDARD LVCMOS33" [get_ports "dout[$j]"]
|
||||
}
|
||||
# Arty A7 optimized I/O layout
|
||||
} elseif {$part eq "xc7a35tcsg324-1"} {
|
||||
# https://reference.digilentinc.com/reference/programmable-logic/arty/reference-manual?redirect=1
|
||||
set pmod_ja "G13 B11 A11 D12 D13 B18 A18 K16"
|
||||
set pmod_jb "E15 E16 D15 C15 J17 J18 K15 J15"
|
||||
set pmod_jc "U12 V12 V10 V11 U14 V14 T13 U13"
|
||||
|
||||
# CLK on Pmod JA
|
||||
set pin [lindex $pmod_ja 0]
|
||||
set_property -dict "PACKAGE_PIN G13 IOSTANDARD LVCMOS33" [get_ports "clk"]
|
||||
|
||||
# DIN on Pmod JB
|
||||
for {set i 0} {$i < $DIN_N} {incr i} {
|
||||
set pin [lindex $pmod_jb $i]
|
||||
set_property -dict "PACKAGE_PIN $pin IOSTANDARD LVCMOS33" [get_ports "din[$i]"]
|
||||
}
|
||||
|
||||
# DOUT on Pmod JC
|
||||
for {set i 0} {$i < $DOUT_N} {incr i} {
|
||||
set pin [lindex $pmod_jc $i]
|
||||
set_property -dict "PACKAGE_PIN $pin IOSTANDARD LVCMOS33" [get_ports "dout[$i]"]
|
||||
}
|
||||
} else {
|
||||
error "Unsupported part $part"
|
||||
}
|
||||
|
||||
create_pblock roi
|
||||
set_property EXCLUDE_PLACEMENT 1 [get_pblocks roi]
|
||||
add_cells_to_pblock [get_pblocks roi] [get_cells roi]
|
||||
resize_pblock [get_pblocks roi] -add "$::env(XRAY_ROI)"
|
||||
|
||||
set_property CFGBVS VCCO [current_design]
|
||||
set_property CONFIG_VOLTAGE 3.3 [current_design]
|
||||
set_property BITSTREAM.GENERAL.PERFRAMECRC YES [current_design]
|
||||
|
||||
set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets clk_IBUF]
|
||||
|
||||
#write_checkpoint -force synth.dcp
|
||||
|
||||
|
||||
|
||||
proc loc_roi_clk_left {ff_x ff_y} {
|
||||
# Place an ROI clk on the left edge of the ROI
|
||||
# It doesn't actually matter where we place this, just do it to keep things neat looking
|
||||
# ff_x: ROI SLICE X position
|
||||
# ff_yy: row primitives will be placed at
|
||||
|
||||
set slice_ff "SLICE_X${ff_x}Y${ff_y}"
|
||||
|
||||
# Fix FFs to guide route in
|
||||
set cell [get_cells "roi/clk_reg_reg"]
|
||||
set_property LOC $slice_ff $cell
|
||||
set_property BEL AFF $cell
|
||||
}
|
||||
|
||||
proc loc_roi_in_left {index lut_x y} {
|
||||
# Place an ROI input on the left edge of the ROI
|
||||
# index: input bus index
|
||||
# lut_x: ROI SLICE X position. FF position is implicit to left
|
||||
# y: row primitives will be placed at
|
||||
|
||||
set slice_lut "SLICE_X${lut_x}Y${y}"
|
||||
|
||||
# Fix LUTs near the edge
|
||||
set cell [get_cells "roi/ins[$index].lut"]
|
||||
set_property LOC $slice_lut $cell
|
||||
set_property BEL A6LUT $cell
|
||||
}
|
||||
|
||||
proc loc_roi_out_left {index lut_x y} {
|
||||
# Place an ROI output on the left edge of the ROI
|
||||
# index: input bus index
|
||||
# lut_x: ROI SLICE X position. FF position is implicit to left
|
||||
# y: row primitives will be placed at
|
||||
|
||||
set slice_lut "SLICE_X${lut_x}Y${y}"
|
||||
|
||||
# Fix LUTs near the edge
|
||||
set cell [get_cells "roi/outs[$index].lut"]
|
||||
set_property LOC $slice_lut $cell
|
||||
set_property BEL A6LUT $cell
|
||||
}
|
||||
|
||||
|
||||
if {1} {
|
||||
set x $X_BASE
|
||||
|
||||
# Place ROI clock right after inputs
|
||||
puts "Placing ROI clock"
|
||||
loc_roi_clk_left $x $Y_CLK_BASE
|
||||
|
||||
# Place ROI inputs
|
||||
puts "Placing ROI inputs"
|
||||
set y $Y_DIN_BASE
|
||||
for {set i 0} {$i < $DIN_N} {incr i} {
|
||||
loc_roi_in_left $i $x $y
|
||||
set y [expr {$y + 1}]
|
||||
}
|
||||
|
||||
# Place ROI outputs
|
||||
set y $Y_DOUT_BASE
|
||||
puts "Placing ROI outputs"
|
||||
for {set i 0} {$i < $DOUT_N} {incr i} {
|
||||
loc_roi_out_left $i $x $y
|
||||
set y [expr {$y + 1}]
|
||||
}
|
||||
}
|
||||
|
||||
place_design
|
||||
#write_checkpoint -force placed.dcp
|
||||
|
||||
# Version with more error checking for missing end node
|
||||
# Will do best effort in this case
|
||||
proc route_via2 {net nodes} {
|
||||
# net: net as string
|
||||
# nodes: string list of one or more intermediate routing nodes to visit
|
||||
|
||||
set net [get_nets $net]
|
||||
# Start at the net source
|
||||
set fixed_route [get_nodes -of_objects [get_site_pins -filter {DIRECTION == OUT} -of_objects $net]]
|
||||
# End at the net destination
|
||||
# For sone reason this doesn't always show up
|
||||
set site_pins [get_site_pins -filter {DIRECTION == IN} -of_objects $net]
|
||||
if {$site_pins eq ""} {
|
||||
puts "WARNING: could not find end node"
|
||||
#error "Could not find end node"
|
||||
} else {
|
||||
set end_node [get_nodes -of_objects]
|
||||
lappend nodes [$end_node]
|
||||
}
|
||||
|
||||
puts ""
|
||||
puts "Routing net $net:"
|
||||
|
||||
foreach to_node $nodes {
|
||||
if {$to_node eq ""} {
|
||||
error "Empty node"
|
||||
}
|
||||
|
||||
# Node string to object
|
||||
set to_node [get_nodes -of_objects [get_wires $to_node]]
|
||||
# Start at last routed position
|
||||
set from_node [lindex $fixed_route end]
|
||||
# Let vivado do heavy liftin in between
|
||||
set route [find_routing_path -quiet -from $from_node -to $to_node]
|
||||
if {$route == ""} {
|
||||
# Some errors print a huge route
|
||||
puts [concat [string range " $from_node -> $to_node" 0 1000] ": no route found - assuming direct PIP"]
|
||||
lappend fixed_route $to_node
|
||||
} {
|
||||
puts [concat [string range " $from_node -> $to_node: $route" 0 1000] "routed"]
|
||||
set fixed_route [concat $fixed_route [lrange $route 1 end]]
|
||||
}
|
||||
set_property -quiet FIXED_ROUTE $fixed_route $net
|
||||
}
|
||||
|
||||
set_property -quiet FIXED_ROUTE $fixed_route $net
|
||||
puts ""
|
||||
}
|
||||
|
||||
# XXX: maybe add IOB?
|
||||
set fp [open "design.txt" w]
|
||||
puts $fp "name node"
|
||||
if {1} {
|
||||
set x $X_BASE
|
||||
|
||||
# Nothing needed for clk
|
||||
# It will go to high level interconnect that goes everywhere
|
||||
|
||||
puts "Routing ROI inputs"
|
||||
# Arbitrary offset as observed
|
||||
set y [expr {$Y_DIN_BASE - 1}]
|
||||
for {set i 0} {$i < $DIN_N} {incr i} {
|
||||
#route_via2 "din_IBUF[$i]" "INT_R_X9Y${y}/NE2BEG3"
|
||||
# needed to force routes away to avoid looping into ROI
|
||||
#set x_EE2BEG3 [expr {$x - 2}]
|
||||
set x_EE2BEG3 7
|
||||
set x_NE2BEG3 9
|
||||
set node "INT_R_X${x_NE2BEG3}Y${y}/NE2BEG3"
|
||||
route_via2 "din_IBUF[$i]" "INT_R_X${x_EE2BEG3}Y${y}/EE2BEG3 $node"
|
||||
puts $fp "din[$i] $node"
|
||||
|
||||
set y [expr {$y + 1}]
|
||||
}
|
||||
|
||||
puts "Routing ROI outputs"
|
||||
# Arbitrary offset as observed
|
||||
set y [expr {$Y_DOUT_BASE + 0}]
|
||||
for {set i 0} {$i < $DOUT_N} {incr i} {
|
||||
# XXX: find a better solution if we need harness long term
|
||||
# works on 50t but not 35t
|
||||
if {$part eq "xc7a50tfgg484-1"} {
|
||||
set node "INT_L_X10Y${y}/WW2BEG0"
|
||||
route_via2 "roi/dout[$i]" "$node"
|
||||
# works on 35t but not 50t
|
||||
} elseif {$part eq "xc7a35tcsg324-1"} {
|
||||
set node "INT_L_X10Y${y}/SW6BEG0"
|
||||
route_via2 "roi/dout[$i]" "$node"
|
||||
} else {
|
||||
error "Unsupported part $part"
|
||||
}
|
||||
puts $fp "dout[$i] $node"
|
||||
set y [expr {$y + 1}]
|
||||
}
|
||||
}
|
||||
close $fp
|
||||
|
||||
puts "routing design"
|
||||
route_design
|
||||
|
||||
write_checkpoint -force design.dcp
|
||||
write_bitstream -force design.bit
|
||||
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
//See README and tcl for more info
|
||||
|
||||
`ifndef DIN_N
|
||||
`define DIN_N 4
|
||||
`endif
|
||||
|
||||
`ifndef DOUT_N
|
||||
`define DOUT_N 4
|
||||
`endif
|
||||
|
||||
module top(input wire clk,
|
||||
input [DIN_N-1:0] din, output [DOUT_N-1:0] dout);
|
||||
parameter DIN_N = `DIN_N;
|
||||
parameter DOUT_N = `DOUT_N;
|
||||
|
||||
roi #(.DIN_N(DIN_N), .DOUT_N(DOUT_N)) roi (
|
||||
.clk(clk),
|
||||
.din(din), .dout(dout));
|
||||
endmodule
|
||||
|
||||
module roi(input clk,
|
||||
input [DIN_N-1:0] din, output [DOUT_N-1:0] dout);
|
||||
parameter DIN_N = 4;
|
||||
parameter DOUT_N = 4;
|
||||
|
||||
genvar i;
|
||||
generate
|
||||
//CLK
|
||||
(* KEEP, DONT_TOUCH *)
|
||||
reg clk_reg;
|
||||
always @(posedge clk) begin
|
||||
clk_reg <= clk_reg;
|
||||
end
|
||||
|
||||
//DIN
|
||||
for (i = 0; i < DIN_N; i = i+1) begin:ins
|
||||
(* KEEP, DONT_TOUCH *)
|
||||
LUT6 #(
|
||||
.INIT(64'b01)
|
||||
) lut (
|
||||
.I0(din[i]),
|
||||
.I1(1'b0),
|
||||
.I2(1'b0),
|
||||
.I3(1'b0),
|
||||
.I4(1'b0),
|
||||
.I5(1'b0),
|
||||
.O());
|
||||
end
|
||||
|
||||
//DOUT
|
||||
for (i = 0; i < DOUT_N; i = i+1) begin:outs
|
||||
(* KEEP, DONT_TOUCH *)
|
||||
LUT6 #(
|
||||
.INIT(64'b01)
|
||||
) lut (
|
||||
.I0(1'b0),
|
||||
.I1(1'b0),
|
||||
.I2(1'b0),
|
||||
.I3(1'b0),
|
||||
.I4(1'b0),
|
||||
.I5(1'b0),
|
||||
.O(dout[i]));
|
||||
end
|
||||
endgenerate
|
||||
endmodule
|
||||
|
|
@ -78,10 +78,8 @@ int main(int argc, char **argv) {
|
|||
std::cout << "Bitstream size: " << in_file->size() << " bytes"
|
||||
<< std::endl;
|
||||
|
||||
auto in_bytes = absl::Span<uint8_t>(
|
||||
static_cast<uint8_t*>(in_file->data()),
|
||||
in_file->size());
|
||||
reader = xc7series::BitstreamReader::InitWithBytes(in_bytes);
|
||||
reader = xc7series::BitstreamReader::InitWithBytes(
|
||||
in_file->as_bytes());
|
||||
} else {
|
||||
std::vector<uint8_t> bitdata;
|
||||
while (1) {
|
||||
|
|
|
|||
|
|
@ -31,10 +31,8 @@ int ListConfigPackets(int argc, char *argv[]) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
auto in_bytes = absl::Span<uint8_t>(
|
||||
static_cast<uint8_t*>(in_file->data()),
|
||||
in_file->size());
|
||||
auto reader = xc7series::BitstreamReader::InitWithBytes(in_bytes);
|
||||
auto reader = xc7series::BitstreamReader::InitWithBytes(
|
||||
in_file->as_bytes());
|
||||
if (!reader) {
|
||||
std::cerr << "Input doesn't look like a bitstream"
|
||||
<< std::endl;
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
#include <iomanip>
|
||||
#include <iostream>
|
||||
|
||||
#include <prjxray/xilinx/xc7series/configuration_frame_address.h>
|
||||
#include <prjxray/xilinx/xc7series/frame_address.h>
|
||||
|
||||
namespace xc7series = prjxray::xilinx::xc7series;
|
||||
|
||||
|
|
@ -18,7 +18,7 @@ int main(int argc, char *argv[]) {
|
|||
for (uint32_t frame_address_raw;
|
||||
(*input_stream) >> std::setbase(0) >> frame_address_raw;
|
||||
) {
|
||||
xc7series::ConfigurationFrameAddress frame_address(frame_address_raw);
|
||||
xc7series::FrameAddress frame_address(frame_address_raw);
|
||||
std::cout << "["
|
||||
<< std::hex << std::showbase << std::setw(10)
|
||||
<< frame_address_raw
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@
|
|||
#include <absl/types/span.h>
|
||||
#include <prjxray/memory_mapped_file.h>
|
||||
#include <prjxray/xilinx/xc7series/bitstream_reader.h>
|
||||
#include <prjxray/xilinx/xc7series/configuration_frame_address.h>
|
||||
#include <prjxray/xilinx/xc7series/configuration_frame_range.h>
|
||||
#include <prjxray/xilinx/xc7series/part.h>
|
||||
#include <yaml-cpp/yaml.h>
|
||||
|
|
@ -31,10 +30,8 @@ int main(int argc, char *argv[]) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
auto in_bytes = absl::Span<uint8_t>(
|
||||
static_cast<uint8_t*>(in_file->data()),
|
||||
in_file->size());
|
||||
auto reader = xc7series::BitstreamReader::InitWithBytes(in_bytes);
|
||||
auto reader = xc7series::BitstreamReader::InitWithBytes(
|
||||
in_file->as_bytes());
|
||||
if (!reader) {
|
||||
std::cerr << "Input doesn't look like a bitstream"
|
||||
<< std::endl;
|
||||
|
|
|
|||
Loading…
Reference in New Issue