diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index 8000b610..4a01fbec 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -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) diff --git a/lib/include/prjxray/memory_mapped_file.h b/lib/include/prjxray/memory_mapped_file.h index 6ed4e4ec..c2fd955d 100644 --- a/lib/include/prjxray/memory_mapped_file.h +++ b/lib/include/prjxray/memory_mapped_file.h @@ -4,6 +4,8 @@ #include #include +#include + 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 as_bytes() const { + return {static_cast(data_), size_}; + } + private: MemoryMappedFile(void *data, size_t size) : data_(data), size_(size) {}; diff --git a/lib/include/prjxray/xilinx/xc7series/bitstream_reader.h b/lib/include/prjxray/xilinx/xc7series/bitstream_reader.h index 7b6ad034..fad41bde 100644 --- a/lib/include/prjxray/xilinx/xc7series/bitstream_reader.h +++ b/lib/include/prjxray/xilinx/xc7series/bitstream_reader.h @@ -47,7 +47,7 @@ class BitstreamReader { // Construct a `BitstreamReader` from a Container of bytes. // Any bytes preceding an initial sync word are ignored. template - static absl::optional InitWithBytes(T &bitstream); + static absl::optional InitWithBytes(T bitstream); const std::vector &words() { return words_; }; @@ -62,7 +62,7 @@ class BitstreamReader { }; template -absl::optional BitstreamReader::InitWithBytes(T &bitstream) { +absl::optional 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(), diff --git a/lib/include/prjxray/xilinx/xc7series/configuration.h b/lib/include/prjxray/xilinx/xc7series/configuration.h index 8d9984a5..7fa643ab 100644 --- a/lib/include/prjxray/xilinx/xc7series/configuration.h +++ b/lib/include/prjxray/xilinx/xc7series/configuration.h @@ -6,7 +6,7 @@ #include #include #include -#include +#include #include namespace prjxray { @@ -15,7 +15,7 @@ namespace xc7series { class Configuration { public: - using FrameMap = std::map>; template @@ -46,7 +46,7 @@ absl::optional 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::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; } diff --git a/lib/include/prjxray/xilinx/xc7series/configuration_frame_address.h b/lib/include/prjxray/xilinx/xc7series/configuration_frame_address.h deleted file mode 100644 index fe5cb89c..00000000 --- a/lib/include/prjxray/xilinx/xc7series/configuration_frame_address.h +++ /dev/null @@ -1,49 +0,0 @@ -#ifndef PRJXRAY_LIB_XILINX_XC7SERIES_CONFIGURATION_FRAME_ADDRESS_H_ -#define PRJXRAY_LIB_XILINX_XC7SERIES_CONFIGURATION_FRAME_ADDRESS_H_ - -#include - -#include -#include - -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 { - 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_ diff --git a/lib/include/prjxray/xilinx/xc7series/configuration_frame_range.h b/lib/include/prjxray/xilinx/xc7series/configuration_frame_range.h index 97690d69..4445871b 100644 --- a/lib/include/prjxray/xilinx/xc7series/configuration_frame_range.h +++ b/lib/include/prjxray/xilinx/xc7series/configuration_frame_range.h @@ -3,7 +3,7 @@ #include -#include +#include #include 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 diff --git a/lib/include/prjxray/xilinx/xc7series/frame_address.h b/lib/include/prjxray/xilinx/xc7series/frame_address.h new file mode 100644 index 00000000..88ef7e82 --- /dev/null +++ b/lib/include/prjxray/xilinx/xc7series/frame_address.h @@ -0,0 +1,50 @@ +#ifndef PRJXRAY_LIB_XILINX_XC7SERIES_FRAME_ADDRESS_H_ +#define PRJXRAY_LIB_XILINX_XC7SERIES_FRAME_ADDRESS_H_ + +#include +#include + +#include +#include + +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 { + 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_ diff --git a/lib/include/prjxray/xilinx/xc7series/part.h b/lib/include/prjxray/xilinx/xc7series/part.h index 7d674f33..5ffe891d 100644 --- a/lib/include/prjxray/xilinx/xc7series/part.h +++ b/lib/include/prjxray/xilinx/xc7series/part.h @@ -4,7 +4,7 @@ #include #include -#include +#include #include namespace prjxray { @@ -28,9 +28,8 @@ class Part { const std::vector& configuration_frame_ranges() const { return frame_ranges_; } - absl::optional - GetNextConfigurationFrameAddress( - ConfigurationFrameAddress address) const; + absl::optional + GetNextFrameAddress(FrameAddress address) const; private: uint32_t idcode_; diff --git a/lib/test_data/configuration_test.bit b/lib/test_data/configuration_test.bit new file mode 100644 index 00000000..6ef4f5ef Binary files /dev/null and b/lib/test_data/configuration_test.bit differ diff --git a/lib/test_data/configuration_test.debug.bit b/lib/test_data/configuration_test.debug.bit new file mode 100644 index 00000000..3dfd7482 Binary files /dev/null and b/lib/test_data/configuration_test.debug.bit differ diff --git a/lib/test_data/configuration_test.perframecrc.bit b/lib/test_data/configuration_test.perframecrc.bit new file mode 100644 index 00000000..7179e2d3 Binary files /dev/null and b/lib/test_data/configuration_test.perframecrc.bit differ diff --git a/lib/test_data/configuration_test.yaml b/lib/test_data/configuration_test.yaml new file mode 100644 index 00000000..2666355e --- /dev/null +++ b/lib/test_data/configuration_test.yaml @@ -0,0 +1,1680 @@ +! +idcode: 0x362c093 +configuration_ranges: + - ! + begin: ! + block_type: CLB_IO_CLK + row_half: top + row: 0 + column: 0 + minor: 0 + end: ! + block_type: CLB_IO_CLK + row_half: top + row: 0 + column: 0 + minor: 42 + - ! + begin: ! + block_type: CLB_IO_CLK + row_half: top + row: 0 + column: 1 + minor: 0 + end: ! + block_type: CLB_IO_CLK + row_half: top + row: 0 + column: 1 + minor: 30 + - ! + begin: ! + block_type: CLB_IO_CLK + row_half: top + row: 0 + column: 2 + minor: 0 + end: ! + block_type: CLB_IO_CLK + row_half: top + row: 0 + column: 2 + minor: 36 + - ! + begin: ! + block_type: CLB_IO_CLK + row_half: top + row: 0 + column: 3 + minor: 0 + end: ! + block_type: CLB_IO_CLK + row_half: top + row: 0 + column: 3 + minor: 36 + - ! + begin: ! + block_type: CLB_IO_CLK + row_half: top + row: 0 + column: 4 + minor: 0 + end: ! + block_type: CLB_IO_CLK + row_half: top + row: 0 + column: 4 + minor: 36 + - ! + begin: ! + block_type: CLB_IO_CLK + row_half: top + row: 0 + column: 5 + minor: 0 + end: ! + block_type: CLB_IO_CLK + row_half: top + row: 0 + column: 5 + minor: 36 + - ! + begin: ! + block_type: CLB_IO_CLK + row_half: top + row: 0 + column: 6 + minor: 0 + end: ! + block_type: CLB_IO_CLK + row_half: top + row: 0 + column: 6 + minor: 28 + - ! + begin: ! + block_type: CLB_IO_CLK + row_half: top + row: 0 + column: 7 + minor: 0 + end: ! + block_type: CLB_IO_CLK + row_half: top + row: 0 + column: 7 + minor: 36 + - ! + begin: ! + block_type: CLB_IO_CLK + row_half: top + row: 0 + column: 8 + minor: 0 + end: ! + block_type: CLB_IO_CLK + row_half: top + row: 0 + column: 8 + minor: 36 + - ! + begin: ! + block_type: CLB_IO_CLK + row_half: top + row: 0 + column: 9 + minor: 0 + end: ! + block_type: CLB_IO_CLK + row_half: top + row: 0 + column: 9 + minor: 28 + - ! + begin: ! + block_type: CLB_IO_CLK + row_half: top + row: 0 + column: 10 + minor: 0 + end: ! + block_type: CLB_IO_CLK + row_half: top + row: 0 + column: 10 + minor: 36 + - ! + begin: ! + block_type: CLB_IO_CLK + row_half: top + row: 0 + column: 11 + minor: 0 + end: ! + block_type: CLB_IO_CLK + row_half: top + row: 0 + column: 11 + minor: 36 + - ! + begin: ! + block_type: CLB_IO_CLK + row_half: top + row: 0 + column: 12 + minor: 0 + end: ! + block_type: CLB_IO_CLK + row_half: top + row: 0 + column: 12 + minor: 36 + - ! + begin: ! + block_type: CLB_IO_CLK + row_half: top + row: 0 + column: 13 + minor: 0 + end: ! + block_type: CLB_IO_CLK + row_half: top + row: 0 + column: 13 + minor: 36 + - ! + begin: ! + block_type: CLB_IO_CLK + row_half: top + row: 0 + column: 14 + minor: 0 + end: ! + block_type: CLB_IO_CLK + row_half: top + row: 0 + column: 14 + minor: 36 + - ! + begin: ! + block_type: CLB_IO_CLK + row_half: top + row: 0 + column: 15 + minor: 0 + end: ! + block_type: CLB_IO_CLK + row_half: top + row: 0 + column: 15 + minor: 36 + - ! + begin: ! + block_type: CLB_IO_CLK + row_half: top + row: 0 + column: 16 + minor: 0 + end: ! + block_type: CLB_IO_CLK + row_half: top + row: 0 + column: 16 + minor: 36 + - ! + begin: ! + block_type: CLB_IO_CLK + row_half: top + row: 0 + column: 17 + minor: 0 + end: ! + block_type: CLB_IO_CLK + row_half: top + row: 0 + column: 17 + minor: 36 + - ! + begin: ! + block_type: CLB_IO_CLK + row_half: top + row: 0 + column: 18 + minor: 0 + end: ! + block_type: CLB_IO_CLK + row_half: top + row: 0 + column: 18 + minor: 30 + - ! + begin: ! + block_type: CLB_IO_CLK + row_half: top + row: 0 + column: 19 + minor: 0 + end: ! + block_type: CLB_IO_CLK + row_half: top + row: 0 + column: 19 + minor: 36 + - ! + begin: ! + block_type: CLB_IO_CLK + row_half: top + row: 0 + column: 20 + minor: 0 + end: ! + block_type: CLB_IO_CLK + row_half: top + row: 0 + column: 20 + minor: 36 + - ! + begin: ! + block_type: CLB_IO_CLK + row_half: top + row: 0 + column: 21 + minor: 0 + end: ! + block_type: CLB_IO_CLK + row_half: top + row: 0 + column: 21 + minor: 36 + - ! + begin: ! + block_type: CLB_IO_CLK + row_half: top + row: 0 + column: 22 + minor: 0 + end: ! + block_type: CLB_IO_CLK + row_half: top + row: 0 + column: 22 + minor: 36 + - ! + begin: ! + block_type: CLB_IO_CLK + row_half: top + row: 0 + column: 23 + minor: 0 + end: ! + block_type: CLB_IO_CLK + row_half: top + row: 0 + column: 23 + minor: 30 + - ! + begin: ! + block_type: CLB_IO_CLK + row_half: top + row: 0 + column: 24 + minor: 0 + end: ! + block_type: CLB_IO_CLK + row_half: top + row: 0 + column: 24 + minor: 36 + - ! + begin: ! + block_type: CLB_IO_CLK + row_half: top + row: 0 + column: 25 + minor: 0 + end: ! + block_type: CLB_IO_CLK + row_half: top + row: 0 + column: 25 + minor: 36 + - ! + begin: ! + block_type: CLB_IO_CLK + row_half: top + row: 0 + column: 26 + minor: 0 + end: ! + block_type: CLB_IO_CLK + row_half: top + row: 0 + column: 26 + minor: 36 + - ! + begin: ! + block_type: CLB_IO_CLK + row_half: top + row: 0 + column: 27 + minor: 0 + end: ! + block_type: CLB_IO_CLK + row_half: top + row: 0 + column: 27 + minor: 36 + - ! + begin: ! + block_type: CLB_IO_CLK + row_half: top + row: 0 + column: 28 + minor: 0 + end: ! + block_type: CLB_IO_CLK + row_half: top + row: 0 + column: 28 + minor: 36 + - ! + begin: ! + block_type: CLB_IO_CLK + row_half: top + row: 0 + column: 29 + minor: 0 + end: ! + block_type: CLB_IO_CLK + row_half: top + row: 0 + column: 29 + minor: 36 + - ! + begin: ! + block_type: CLB_IO_CLK + row_half: top + row: 0 + column: 30 + minor: 0 + end: ! + block_type: CLB_IO_CLK + row_half: top + row: 0 + column: 30 + minor: 28 + - ! + begin: ! + block_type: CLB_IO_CLK + row_half: top + row: 0 + column: 31 + minor: 0 + end: ! + block_type: CLB_IO_CLK + row_half: top + row: 0 + column: 31 + minor: 36 + - ! + begin: ! + block_type: CLB_IO_CLK + row_half: top + row: 0 + column: 32 + minor: 0 + end: ! + block_type: CLB_IO_CLK + row_half: top + row: 0 + column: 32 + minor: 36 + - ! + begin: ! + block_type: CLB_IO_CLK + row_half: top + row: 0 + column: 33 + minor: 0 + end: ! + block_type: CLB_IO_CLK + row_half: top + row: 0 + column: 33 + minor: 36 + - ! + begin: ! + block_type: CLB_IO_CLK + row_half: top + row: 0 + column: 34 + minor: 0 + end: ! + block_type: CLB_IO_CLK + row_half: top + row: 0 + column: 34 + minor: 28 + - ! + begin: ! + block_type: CLB_IO_CLK + row_half: top + row: 0 + column: 35 + minor: 0 + end: ! + block_type: CLB_IO_CLK + row_half: top + row: 0 + column: 35 + minor: 36 + - ! + begin: ! + block_type: CLB_IO_CLK + row_half: top + row: 0 + column: 36 + minor: 0 + end: ! + block_type: CLB_IO_CLK + row_half: top + row: 0 + column: 36 + minor: 36 + - ! + begin: ! + block_type: CLB_IO_CLK + row_half: top + row: 0 + column: 37 + minor: 0 + end: ! + block_type: CLB_IO_CLK + row_half: top + row: 0 + column: 37 + minor: 28 + - ! + begin: ! + block_type: CLB_IO_CLK + row_half: top + row: 0 + column: 38 + minor: 0 + end: ! + block_type: CLB_IO_CLK + row_half: top + row: 0 + column: 38 + minor: 36 + - ! + begin: ! + block_type: CLB_IO_CLK + row_half: top + row: 0 + column: 39 + minor: 0 + end: ! + block_type: CLB_IO_CLK + row_half: top + row: 0 + column: 39 + minor: 36 + - ! + begin: ! + block_type: CLB_IO_CLK + row_half: top + row: 0 + column: 40 + minor: 0 + end: ! + block_type: CLB_IO_CLK + row_half: top + row: 0 + column: 40 + minor: 36 + - ! + begin: ! + block_type: CLB_IO_CLK + row_half: top + row: 0 + column: 41 + minor: 0 + end: ! + block_type: CLB_IO_CLK + row_half: top + row: 0 + column: 41 + minor: 36 + - ! + begin: ! + block_type: CLB_IO_CLK + row_half: top + row: 0 + column: 42 + minor: 0 + end: ! + block_type: CLB_IO_CLK + row_half: top + row: 0 + column: 42 + minor: 30 + - ! + begin: ! + block_type: CLB_IO_CLK + row_half: top + row: 0 + column: 43 + minor: 0 + end: ! + block_type: CLB_IO_CLK + row_half: top + row: 0 + column: 43 + minor: 42 + - ! + begin: ! + block_type: CLB_IO_CLK + row_half: top + row: 1 + column: 0 + minor: 0 + end: ! + block_type: CLB_IO_CLK + row_half: top + row: 1 + column: 0 + minor: 42 + - ! + begin: ! + block_type: CLB_IO_CLK + row_half: top + row: 1 + column: 1 + minor: 0 + end: ! + block_type: CLB_IO_CLK + row_half: top + row: 1 + column: 1 + minor: 30 + - ! + begin: ! + block_type: CLB_IO_CLK + row_half: top + row: 1 + column: 2 + minor: 0 + end: ! + block_type: CLB_IO_CLK + row_half: top + row: 1 + column: 2 + minor: 36 + - ! + begin: ! + block_type: CLB_IO_CLK + row_half: top + row: 1 + column: 3 + minor: 0 + end: ! + block_type: CLB_IO_CLK + row_half: top + row: 1 + column: 3 + minor: 36 + - ! + begin: ! + block_type: CLB_IO_CLK + row_half: top + row: 1 + column: 4 + minor: 0 + end: ! + block_type: CLB_IO_CLK + row_half: top + row: 1 + column: 4 + minor: 36 + - ! + begin: ! + block_type: CLB_IO_CLK + row_half: top + row: 1 + column: 5 + minor: 0 + end: ! + block_type: CLB_IO_CLK + row_half: top + row: 1 + column: 5 + minor: 36 + - ! + begin: ! + block_type: CLB_IO_CLK + row_half: top + row: 1 + column: 6 + minor: 0 + end: ! + block_type: CLB_IO_CLK + row_half: top + row: 1 + column: 6 + minor: 28 + - ! + begin: ! + block_type: CLB_IO_CLK + row_half: top + row: 1 + column: 7 + minor: 0 + end: ! + block_type: CLB_IO_CLK + row_half: top + row: 1 + column: 7 + minor: 36 + - ! + begin: ! + block_type: CLB_IO_CLK + row_half: top + row: 1 + column: 8 + minor: 0 + end: ! + block_type: CLB_IO_CLK + row_half: top + row: 1 + column: 8 + minor: 36 + - ! + begin: ! + block_type: CLB_IO_CLK + row_half: top + row: 1 + column: 9 + minor: 0 + end: ! + block_type: CLB_IO_CLK + row_half: top + row: 1 + column: 9 + minor: 28 + - ! + begin: ! + block_type: CLB_IO_CLK + row_half: top + row: 1 + column: 10 + minor: 0 + end: ! + block_type: CLB_IO_CLK + row_half: top + row: 1 + column: 10 + minor: 36 + - ! + begin: ! + block_type: CLB_IO_CLK + row_half: top + row: 1 + column: 11 + minor: 0 + end: ! + block_type: CLB_IO_CLK + row_half: top + row: 1 + column: 11 + minor: 36 + - ! + begin: ! + block_type: CLB_IO_CLK + row_half: top + row: 1 + column: 12 + minor: 0 + end: ! + block_type: CLB_IO_CLK + row_half: top + row: 1 + column: 12 + minor: 36 + - ! + begin: ! + block_type: CLB_IO_CLK + row_half: top + row: 1 + column: 13 + minor: 0 + end: ! + block_type: CLB_IO_CLK + row_half: top + row: 1 + column: 13 + minor: 36 + - ! + begin: ! + block_type: CLB_IO_CLK + row_half: top + row: 1 + column: 14 + minor: 0 + end: ! + block_type: CLB_IO_CLK + row_half: top + row: 1 + column: 14 + minor: 36 + - ! + begin: ! + block_type: CLB_IO_CLK + row_half: top + row: 1 + column: 15 + minor: 0 + end: ! + block_type: CLB_IO_CLK + row_half: top + row: 1 + column: 15 + minor: 36 + - ! + begin: ! + block_type: CLB_IO_CLK + row_half: top + row: 1 + column: 16 + minor: 0 + end: ! + block_type: CLB_IO_CLK + row_half: top + row: 1 + column: 16 + minor: 36 + - ! + begin: ! + block_type: CLB_IO_CLK + row_half: top + row: 1 + column: 17 + minor: 0 + end: ! + block_type: CLB_IO_CLK + row_half: top + row: 1 + column: 17 + minor: 36 + - ! + begin: ! + block_type: CLB_IO_CLK + row_half: top + row: 1 + column: 18 + minor: 0 + end: ! + block_type: CLB_IO_CLK + row_half: top + row: 1 + column: 18 + minor: 30 + - ! + begin: ! + block_type: CLB_IO_CLK + row_half: top + row: 1 + column: 19 + minor: 0 + end: ! + block_type: CLB_IO_CLK + row_half: top + row: 1 + column: 19 + minor: 36 + - ! + begin: ! + block_type: CLB_IO_CLK + row_half: top + row: 1 + column: 20 + minor: 0 + end: ! + block_type: CLB_IO_CLK + row_half: top + row: 1 + column: 20 + minor: 36 + - ! + begin: ! + block_type: CLB_IO_CLK + row_half: top + row: 1 + column: 21 + minor: 0 + end: ! + block_type: CLB_IO_CLK + row_half: top + row: 1 + column: 21 + minor: 36 + - ! + begin: ! + block_type: CLB_IO_CLK + row_half: top + row: 1 + column: 22 + minor: 0 + end: ! + block_type: CLB_IO_CLK + row_half: top + row: 1 + column: 22 + minor: 36 + - ! + begin: ! + block_type: CLB_IO_CLK + row_half: top + row: 1 + column: 23 + minor: 0 + end: ! + block_type: CLB_IO_CLK + row_half: top + row: 1 + column: 23 + minor: 30 + - ! + begin: ! + block_type: CLB_IO_CLK + row_half: top + row: 1 + column: 24 + minor: 0 + end: ! + block_type: CLB_IO_CLK + row_half: top + row: 1 + column: 24 + minor: 36 + - ! + begin: ! + block_type: CLB_IO_CLK + row_half: top + row: 1 + column: 25 + minor: 0 + end: ! + block_type: CLB_IO_CLK + row_half: top + row: 1 + column: 25 + minor: 36 + - ! + begin: ! + block_type: CLB_IO_CLK + row_half: top + row: 1 + column: 26 + minor: 0 + end: ! + block_type: CLB_IO_CLK + row_half: top + row: 1 + column: 26 + minor: 36 + - ! + begin: ! + block_type: CLB_IO_CLK + row_half: top + row: 1 + column: 27 + minor: 0 + end: ! + block_type: CLB_IO_CLK + row_half: top + row: 1 + column: 27 + minor: 36 + - ! + begin: ! + block_type: CLB_IO_CLK + row_half: top + row: 1 + column: 28 + minor: 0 + end: ! + block_type: CLB_IO_CLK + row_half: top + row: 1 + column: 28 + minor: 36 + - ! + begin: ! + block_type: CLB_IO_CLK + row_half: top + row: 1 + column: 29 + minor: 0 + end: ! + block_type: CLB_IO_CLK + row_half: top + row: 1 + column: 29 + minor: 36 + - ! + begin: ! + block_type: CLB_IO_CLK + row_half: top + row: 1 + column: 30 + minor: 0 + end: ! + block_type: CLB_IO_CLK + row_half: top + row: 1 + column: 30 + minor: 28 + - ! + begin: ! + block_type: CLB_IO_CLK + row_half: top + row: 1 + column: 31 + minor: 0 + end: ! + block_type: CLB_IO_CLK + row_half: top + row: 1 + column: 31 + minor: 36 + - ! + begin: ! + block_type: CLB_IO_CLK + row_half: top + row: 1 + column: 32 + minor: 0 + end: ! + block_type: CLB_IO_CLK + row_half: top + row: 1 + column: 32 + minor: 36 + - ! + begin: ! + block_type: CLB_IO_CLK + row_half: top + row: 1 + column: 33 + minor: 0 + end: ! + block_type: CLB_IO_CLK + row_half: top + row: 1 + column: 33 + minor: 36 + - ! + begin: ! + block_type: CLB_IO_CLK + row_half: top + row: 1 + column: 34 + minor: 0 + end: ! + block_type: CLB_IO_CLK + row_half: top + row: 1 + column: 34 + minor: 28 + - ! + begin: ! + block_type: CLB_IO_CLK + row_half: top + row: 1 + column: 35 + minor: 0 + end: ! + block_type: CLB_IO_CLK + row_half: top + row: 1 + column: 35 + minor: 36 + - ! + begin: ! + block_type: CLB_IO_CLK + row_half: top + row: 1 + column: 36 + minor: 0 + end: ! + block_type: CLB_IO_CLK + row_half: top + row: 1 + column: 36 + minor: 36 + - ! + begin: ! + block_type: CLB_IO_CLK + row_half: top + row: 1 + column: 37 + minor: 0 + end: ! + block_type: CLB_IO_CLK + row_half: top + row: 1 + column: 37 + minor: 32 + - ! + begin: ! + block_type: CLB_IO_CLK + row_half: bottom + row: 0 + column: 0 + minor: 0 + end: ! + block_type: CLB_IO_CLK + row_half: bottom + row: 0 + column: 0 + minor: 42 + - ! + begin: ! + block_type: CLB_IO_CLK + row_half: bottom + row: 0 + column: 1 + minor: 0 + end: ! + block_type: CLB_IO_CLK + row_half: bottom + row: 0 + column: 1 + minor: 30 + - ! + begin: ! + block_type: CLB_IO_CLK + row_half: bottom + row: 0 + column: 2 + minor: 0 + end: ! + block_type: CLB_IO_CLK + row_half: bottom + row: 0 + column: 2 + minor: 36 + - ! + begin: ! + block_type: CLB_IO_CLK + row_half: bottom + row: 0 + column: 3 + minor: 0 + end: ! + block_type: CLB_IO_CLK + row_half: bottom + row: 0 + column: 3 + minor: 36 + - ! + begin: ! + block_type: CLB_IO_CLK + row_half: bottom + row: 0 + column: 4 + minor: 0 + end: ! + block_type: CLB_IO_CLK + row_half: bottom + row: 0 + column: 4 + minor: 36 + - ! + begin: ! + block_type: CLB_IO_CLK + row_half: bottom + row: 0 + column: 5 + minor: 0 + end: ! + block_type: CLB_IO_CLK + row_half: bottom + row: 0 + column: 5 + minor: 36 + - ! + begin: ! + block_type: CLB_IO_CLK + row_half: bottom + row: 0 + column: 6 + minor: 0 + end: ! + block_type: CLB_IO_CLK + row_half: bottom + row: 0 + column: 6 + minor: 28 + - ! + begin: ! + block_type: CLB_IO_CLK + row_half: bottom + row: 0 + column: 7 + minor: 0 + end: ! + block_type: CLB_IO_CLK + row_half: bottom + row: 0 + column: 7 + minor: 36 + - ! + begin: ! + block_type: CLB_IO_CLK + row_half: bottom + row: 0 + column: 8 + minor: 0 + end: ! + block_type: CLB_IO_CLK + row_half: bottom + row: 0 + column: 8 + minor: 36 + - ! + begin: ! + block_type: CLB_IO_CLK + row_half: bottom + row: 0 + column: 9 + minor: 0 + end: ! + block_type: CLB_IO_CLK + row_half: bottom + row: 0 + column: 9 + minor: 28 + - ! + begin: ! + block_type: CLB_IO_CLK + row_half: bottom + row: 0 + column: 10 + minor: 0 + end: ! + block_type: CLB_IO_CLK + row_half: bottom + row: 0 + column: 10 + minor: 36 + - ! + begin: ! + block_type: CLB_IO_CLK + row_half: bottom + row: 0 + column: 11 + minor: 0 + end: ! + block_type: CLB_IO_CLK + row_half: bottom + row: 0 + column: 11 + minor: 36 + - ! + begin: ! + block_type: CLB_IO_CLK + row_half: bottom + row: 0 + column: 12 + minor: 0 + end: ! + block_type: CLB_IO_CLK + row_half: bottom + row: 0 + column: 12 + minor: 36 + - ! + begin: ! + block_type: CLB_IO_CLK + row_half: bottom + row: 0 + column: 13 + minor: 0 + end: ! + block_type: CLB_IO_CLK + row_half: bottom + row: 0 + column: 13 + minor: 36 + - ! + begin: ! + block_type: CLB_IO_CLK + row_half: bottom + row: 0 + column: 14 + minor: 0 + end: ! + block_type: CLB_IO_CLK + row_half: bottom + row: 0 + column: 14 + minor: 36 + - ! + begin: ! + block_type: CLB_IO_CLK + row_half: bottom + row: 0 + column: 15 + minor: 0 + end: ! + block_type: CLB_IO_CLK + row_half: bottom + row: 0 + column: 15 + minor: 36 + - ! + begin: ! + block_type: CLB_IO_CLK + row_half: bottom + row: 0 + column: 16 + minor: 0 + end: ! + block_type: CLB_IO_CLK + row_half: bottom + row: 0 + column: 16 + minor: 36 + - ! + begin: ! + block_type: CLB_IO_CLK + row_half: bottom + row: 0 + column: 17 + minor: 0 + end: ! + block_type: CLB_IO_CLK + row_half: bottom + row: 0 + column: 17 + minor: 36 + - ! + begin: ! + block_type: CLB_IO_CLK + row_half: bottom + row: 0 + column: 18 + minor: 0 + end: ! + block_type: CLB_IO_CLK + row_half: bottom + row: 0 + column: 18 + minor: 30 + - ! + begin: ! + block_type: CLB_IO_CLK + row_half: bottom + row: 0 + column: 19 + minor: 0 + end: ! + block_type: CLB_IO_CLK + row_half: bottom + row: 0 + column: 19 + minor: 36 + - ! + begin: ! + block_type: CLB_IO_CLK + row_half: bottom + row: 0 + column: 20 + minor: 0 + end: ! + block_type: CLB_IO_CLK + row_half: bottom + row: 0 + column: 20 + minor: 36 + - ! + begin: ! + block_type: CLB_IO_CLK + row_half: bottom + row: 0 + column: 21 + minor: 0 + end: ! + block_type: CLB_IO_CLK + row_half: bottom + row: 0 + column: 21 + minor: 36 + - ! + begin: ! + block_type: CLB_IO_CLK + row_half: bottom + row: 0 + column: 22 + minor: 0 + end: ! + block_type: CLB_IO_CLK + row_half: bottom + row: 0 + column: 22 + minor: 36 + - ! + begin: ! + block_type: CLB_IO_CLK + row_half: bottom + row: 0 + column: 23 + minor: 0 + end: ! + block_type: CLB_IO_CLK + row_half: bottom + row: 0 + column: 23 + minor: 30 + - ! + begin: ! + block_type: CLB_IO_CLK + row_half: bottom + row: 0 + column: 24 + minor: 0 + end: ! + block_type: CLB_IO_CLK + row_half: bottom + row: 0 + column: 24 + minor: 36 + - ! + begin: ! + block_type: CLB_IO_CLK + row_half: bottom + row: 0 + column: 25 + minor: 0 + end: ! + block_type: CLB_IO_CLK + row_half: bottom + row: 0 + column: 25 + minor: 36 + - ! + begin: ! + block_type: CLB_IO_CLK + row_half: bottom + row: 0 + column: 26 + minor: 0 + end: ! + block_type: CLB_IO_CLK + row_half: bottom + row: 0 + column: 26 + minor: 36 + - ! + begin: ! + block_type: CLB_IO_CLK + row_half: bottom + row: 0 + column: 27 + minor: 0 + end: ! + block_type: CLB_IO_CLK + row_half: bottom + row: 0 + column: 27 + minor: 36 + - ! + begin: ! + block_type: CLB_IO_CLK + row_half: bottom + row: 0 + column: 28 + minor: 0 + end: ! + block_type: CLB_IO_CLK + row_half: bottom + row: 0 + column: 28 + minor: 36 + - ! + begin: ! + block_type: CLB_IO_CLK + row_half: bottom + row: 0 + column: 29 + minor: 0 + end: ! + block_type: CLB_IO_CLK + row_half: bottom + row: 0 + column: 29 + minor: 36 + - ! + begin: ! + block_type: CLB_IO_CLK + row_half: bottom + row: 0 + column: 30 + minor: 0 + end: ! + block_type: CLB_IO_CLK + row_half: bottom + row: 0 + column: 30 + minor: 28 + - ! + begin: ! + block_type: CLB_IO_CLK + row_half: bottom + row: 0 + column: 31 + minor: 0 + end: ! + block_type: CLB_IO_CLK + row_half: bottom + row: 0 + column: 31 + minor: 36 + - ! + begin: ! + block_type: CLB_IO_CLK + row_half: bottom + row: 0 + column: 32 + minor: 0 + end: ! + block_type: CLB_IO_CLK + row_half: bottom + row: 0 + column: 32 + minor: 36 + - ! + begin: ! + block_type: CLB_IO_CLK + row_half: bottom + row: 0 + column: 33 + minor: 0 + end: ! + block_type: CLB_IO_CLK + row_half: bottom + row: 0 + column: 33 + minor: 36 + - ! + begin: ! + block_type: CLB_IO_CLK + row_half: bottom + row: 0 + column: 34 + minor: 0 + end: ! + block_type: CLB_IO_CLK + row_half: bottom + row: 0 + column: 34 + minor: 28 + - ! + begin: ! + block_type: CLB_IO_CLK + row_half: bottom + row: 0 + column: 35 + minor: 0 + end: ! + block_type: CLB_IO_CLK + row_half: bottom + row: 0 + column: 35 + minor: 36 + - ! + begin: ! + block_type: CLB_IO_CLK + row_half: bottom + row: 0 + column: 36 + minor: 0 + end: ! + block_type: CLB_IO_CLK + row_half: bottom + row: 0 + column: 36 + minor: 36 + - ! + begin: ! + block_type: CLB_IO_CLK + row_half: bottom + row: 0 + column: 37 + minor: 0 + end: ! + block_type: CLB_IO_CLK + row_half: bottom + row: 0 + column: 37 + minor: 28 + - ! + begin: ! + block_type: CLB_IO_CLK + row_half: bottom + row: 0 + column: 38 + minor: 0 + end: ! + block_type: CLB_IO_CLK + row_half: bottom + row: 0 + column: 38 + minor: 36 + - ! + begin: ! + block_type: CLB_IO_CLK + row_half: bottom + row: 0 + column: 39 + minor: 0 + end: ! + block_type: CLB_IO_CLK + row_half: bottom + row: 0 + column: 39 + minor: 36 + - ! + begin: ! + block_type: CLB_IO_CLK + row_half: bottom + row: 0 + column: 40 + minor: 0 + end: ! + block_type: CLB_IO_CLK + row_half: bottom + row: 0 + column: 40 + minor: 36 + - ! + begin: ! + block_type: CLB_IO_CLK + row_half: bottom + row: 0 + column: 41 + minor: 0 + end: ! + block_type: CLB_IO_CLK + row_half: bottom + row: 0 + column: 41 + minor: 36 + - ! + begin: ! + block_type: CLB_IO_CLK + row_half: bottom + row: 0 + column: 42 + minor: 0 + end: ! + block_type: CLB_IO_CLK + row_half: bottom + row: 0 + column: 42 + minor: 30 + - ! + begin: ! + block_type: CLB_IO_CLK + row_half: bottom + row: 0 + column: 43 + minor: 0 + end: ! + block_type: CLB_IO_CLK + row_half: bottom + row: 0 + column: 43 + minor: 42 + - ! + begin: ! + block_type: BLOCK_RAM + row_half: top + row: 0 + column: 0 + minor: 0 + end: ! + block_type: BLOCK_RAM + row_half: top + row: 0 + column: 3 + minor: 0 + - ! + begin: ! + block_type: BLOCK_RAM + row_half: top + row: 1 + column: 0 + minor: 0 + end: ! + block_type: BLOCK_RAM + row_half: top + row: 1 + column: 2 + minor: 0 + - ! + begin: ! + block_type: BLOCK_RAM + row_half: bottom + row: 0 + column: 0 + minor: 0 + end: ! + block_type: BLOCK_RAM + row_half: bottom + row: 0 + column: 3 + minor: 0 diff --git a/lib/xilinx/xc7series/configuration_frame_range.cc b/lib/xilinx/xc7series/configuration_frame_range.cc index 9113005d..b4f73a5f 100644 --- a/lib/xilinx/xc7series/configuration_frame_range.cc +++ b/lib/xilinx/xc7series/configuration_frame_range.cc @@ -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::decode( !node["end"]) return false; lhs = xc7series::ConfigurationFrameRange( - node["begin"].as(), - node["end"].as()); + node["begin"].as(), + node["end"].as()); return true; } diff --git a/lib/xilinx/xc7series/configuration_test.cc b/lib/xilinx/xc7series/configuration_test.cc index a1f2a623..62d8facc 100644 --- a/lib/xilinx/xc7series/configuration_test.cc +++ b/lib/xilinx/xc7series/configuration_test.cc @@ -5,6 +5,7 @@ #include #include +#include #include #include #include @@ -106,6 +107,106 @@ TEST(ConfigurationTest, ConstructFromPacketsWithAutoincrement) { absl::Span frame_span(frame); EXPECT_EQ(test_config->part().idcode(), static_cast(0x1234)); EXPECT_EQ(test_config->frames().size(), static_cast(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(101, 0xAA)); + EXPECT_EQ(test_config->frames().at(0x4580), std::vector(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"; + } + } } diff --git a/lib/xilinx/xc7series/configuration_frame_address.cc b/lib/xilinx/xc7series/frame_address.cc similarity index 53% rename from lib/xilinx/xc7series/configuration_frame_address.cc rename to lib/xilinx/xc7series/frame_address.cc index 5bcf48af..4f885816 100644 --- a/lib/xilinx/xc7series/configuration_frame_address.cc +++ b/lib/xilinx/xc7series/frame_address.cc @@ -1,4 +1,6 @@ -#include +#include + +#include #include @@ -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(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(addr) + << "] " + << (addr.is_bottom_half_rows() ? "BOTTOM" : "TOP") + << " Row=" + << std::setw(2) << std::dec + << static_cast(addr.row_address()) + << " Column=" + << std::setw(2) << std::dec + << addr.column_address() + << " Minor=" + << std::setw(2) << std::dec + << static_cast(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::encode( - const xc7series::ConfigurationFrameAddress &rhs) { +Node convert::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(rhs.row_address()); @@ -57,9 +77,10 @@ Node convert::encode( return node; } -bool convert::decode( - const Node &node, xc7series::ConfigurationFrameAddress &lhs) { - if (node.Tag() != "xilinx/xc7series/configuration_frame_address" || +bool convert::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::decode( return false; } - lhs = prjxray::xilinx::xc7series::ConfigurationFrameAddress( + lhs = prjxray::xilinx::xc7series::FrameAddress( node["block_type"].as(), row_half, node["row"].as(), diff --git a/lib/xilinx/xc7series/configuration_frame_address_test.cc b/lib/xilinx/xc7series/frame_address_test.cc similarity index 60% rename from lib/xilinx/xc7series/configuration_frame_address_test.cc rename to lib/xilinx/xc7series/frame_address_test.cc index 3574b488..b44f5736 100644 --- a/lib/xilinx/xc7series/configuration_frame_address_test.cc +++ b/lib/xilinx/xc7series/frame_address_test.cc @@ -1,17 +1,16 @@ -#include +#include #include 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(), "BLOCK_RAM"); EXPECT_EQ(node["row_half"].as(), "top"); EXPECT_EQ(node["row"].as(), "10"); @@ -19,17 +18,17 @@ TEST(ConfigurationFrameAddressTest, YamlEncode) { EXPECT_EQ(node["minor"].as(), "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::FrameAddress address = + node.as(); EXPECT_EQ(address.block_type(), xc7series::BlockType::BLOCK_RAM); EXPECT_TRUE(address.is_bottom_half_rows()); EXPECT_EQ(address.row_address(), 0); diff --git a/lib/xilinx/xc7series/part.cc b/lib/xilinx/xc7series/part.cc index 456565af..448b6cc6 100644 --- a/lib/xilinx/xc7series/part.cc +++ b/lib/xilinx/xc7series/part.cc @@ -16,16 +16,16 @@ absl::optional Part::FromFile(const std::string &path) { } } -absl::optional -Part::GetNextConfigurationFrameAddress(ConfigurationFrameAddress address) const { +absl::optional +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 closest_address; + absl::optional closest_address; int32_t closest_distance; for (auto iter = frame_ranges_.begin(); iter != frame_ranges_.end(); diff --git a/lib/xilinx/xc7series/part_test.cc b/lib/xilinx/xc7series/part_test.cc index 0c65d7de..45c8c701 100644 --- a/lib/xilinx/xc7series/part_test.cc +++ b/lib/xilinx/xc7series/part_test.cc @@ -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(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(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); } diff --git a/tools/bitread.cc b/tools/bitread.cc index 3b81b57c..e00b4b24 100644 --- a/tools/bitread.cc +++ b/tools/bitread.cc @@ -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( - static_cast(in_file->data()), - in_file->size()); - reader = xc7series::BitstreamReader::InitWithBytes(in_bytes); + reader = xc7series::BitstreamReader::InitWithBytes( + in_file->as_bytes()); } else { std::vector bitdata; while (1) { diff --git a/tools/bittool.cc b/tools/bittool.cc index 9bcd039c..38fb8800 100644 --- a/tools/bittool.cc +++ b/tools/bittool.cc @@ -31,10 +31,8 @@ int ListConfigPackets(int argc, char *argv[]) { return 1; } - auto in_bytes = absl::Span( - static_cast(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; diff --git a/tools/frame_address_decoder.cc b/tools/frame_address_decoder.cc index 858c7232..c4a64618 100644 --- a/tools/frame_address_decoder.cc +++ b/tools/frame_address_decoder.cc @@ -2,7 +2,7 @@ #include #include -#include +#include 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 diff --git a/tools/gen_part_base_yaml.cc b/tools/gen_part_base_yaml.cc index 41cfef07..79fe183b 100644 --- a/tools/gen_part_base_yaml.cc +++ b/tools/gen_part_base_yaml.cc @@ -7,7 +7,6 @@ #include #include #include -#include #include #include #include @@ -31,10 +30,8 @@ int main(int argc, char *argv[]) { return 1; } - auto in_bytes = absl::Span( - static_cast(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;