From 61b6a9dfe7803e438583dfec22e2d953f7b76758 Mon Sep 17 00:00:00 2001 From: Rick Altherr Date: Thu, 1 Feb 2018 12:19:00 -0800 Subject: [PATCH 01/32] xc7patch: use ECC calculation from lib Signed-off-by: Rick Altherr --- tools/xc7patch.cc | 30 ++---------------------------- 1 file changed, 2 insertions(+), 28 deletions(-) diff --git a/tools/xc7patch.cc b/tools/xc7patch.cc index 3e0c549f..4237315e 100644 --- a/tools/xc7patch.cc +++ b/tools/xc7patch.cc @@ -11,6 +11,7 @@ #include #include #include +#include #include DEFINE_string(part_file, "", "Definition file for target 7-series part"); @@ -111,36 +112,9 @@ int main(int argc, char* argv[]) { uint32_t ecc = 0; for (size_t ii = 0; ii < frame_data.size(); ++ii) { - uint32_t word = frame_data[ii]; - uint32_t offset = ii * 32; - if (ii > 0x25) { - offset += 0x1360; - } else if (ii > 0x6) { - offset += 0x1340; - } else { - offset += 0x1320; - } - - // Mask out where the ECC should be. - if (ii == 0x32) { - word &= 0xFFFFE000; - } - - for (int jj = 0; jj < 32; ++jj) { - if ((word & 1) == 1) { - ecc ^= offset + jj; - } - word >>= 1; - } + ecc = xc7series::icap_ecc(ii, frame_data[ii], ecc); } - uint32_t v = ecc & 0xFFF; - v ^= v >> 8; - v ^= v >> 4; - v ^= v >> 2; - v ^= v >> 1; - ecc ^= (v & 1) << 12; - // Replace the old ECC with the new. frame_data[0x32] &= 0xFFFFE000; frame_data[0x32] |= (ecc & 0x1FFF); From f5099113e666bb98f326c09384108b97b3c24aa2 Mon Sep 17 00:00:00 2001 From: Rick Altherr Date: Thu, 1 Feb 2018 12:29:01 -0800 Subject: [PATCH 02/32] xc7patch: remove disabled debug code Signed-off-by: Rick Altherr --- tools/xc7patch.cc | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/tools/xc7patch.cc b/tools/xc7patch.cc index 4237315e..fc4bc6ad 100644 --- a/tools/xc7patch.cc +++ b/tools/xc7patch.cc @@ -120,18 +120,6 @@ int main(int argc, char* argv[]) { frame_data[0x32] |= (ecc & 0x1FFF); } -#if 0 - for (auto& frame : frames) { - std::cout << "0x" << std::hex - << static_cast(frame.first) << " "; - - for (auto& word : frame.second) { - std::cout << "0x" << std::hex << word << ","; - } - - std::cout << std::endl; - } -#endif std::vector out_packets; // Generate a single type 2 packet that writes everything at once. @@ -158,12 +146,6 @@ int main(int argc, char* argv[]) { 2, xc7series::ConfigurationPacket::Opcode::Write, xc7series::ConfigurationRegister::FDRI, packet_data)); -#if 0 - for (auto& packet : out_packets) { - std::cout << packet << std::endl; - } -#endif - // Write bitstream. xc7series::BitstreamWriter out_bitstream_writer(out_packets); std::ofstream out_file(FLAGS_output_file); From 43b70caf03aae086a96fda2f8465ec478ac77fcd Mon Sep 17 00:00:00 2001 From: Rick Altherr Date: Thu, 1 Feb 2018 12:11:25 -0800 Subject: [PATCH 03/32] xc7series: Dynamically allocate config packets when writing bitstreams ConfigurationPacket assumes that the payload data is owned by someone else. For frame data, that is generally true. For initialization and finalization sequences, those payloads need to be created and managed. Instead, dynamically allocate packets which allows for using subclasses of ConfigurationPacket that store the payload with the packet. Signed-off-by: Rick Altherr --- .../xilinx/xc7series/bitstream_writer.h | 2 +- lib/xilinx/xc7series/bitstream_writer.cc | 6 +-- lib/xilinx/xc7series/bitstream_writer_test.cc | 38 +++++++++++-------- tools/xc7patch.cc | 8 ++-- 4 files changed, 32 insertions(+), 22 deletions(-) diff --git a/lib/include/prjxray/xilinx/xc7series/bitstream_writer.h b/lib/include/prjxray/xilinx/xc7series/bitstream_writer.h index ae0634d7..806cc9a2 100644 --- a/lib/include/prjxray/xilinx/xc7series/bitstream_writer.h +++ b/lib/include/prjxray/xilinx/xc7series/bitstream_writer.h @@ -23,7 +23,7 @@ namespace xc7series { class BitstreamWriter { public: typedef std::array header_t; - typedef std::vector packets_t; + typedef std::vector> packets_t; // Only defined if a packet exists typedef absl::optional> op_data_t; typedef absl::Span::iterator data_iterator_t; diff --git a/lib/xilinx/xc7series/bitstream_writer.cc b/lib/xilinx/xc7series/bitstream_writer.cc index 3a7da30d..eb388ca5 100644 --- a/lib/xilinx/xc7series/bitstream_writer.cc +++ b/lib/xilinx/xc7series/bitstream_writer.cc @@ -28,7 +28,7 @@ BitstreamWriter::BitstreamWriter(const packets_t& packets) BitstreamWriter::packet_iterator BitstreamWriter::iterator::packet_begin() { // itr_packets = packets.begin(); - const ConfigurationPacket& packet = *itr_packets_; + const ConfigurationPacket& packet = **itr_packets_; return BitstreamWriter::packet_iterator( &packet, BitstreamWriter::packet_iterator::STATE_HEADER, @@ -36,7 +36,7 @@ BitstreamWriter::packet_iterator BitstreamWriter::iterator::packet_begin() { } BitstreamWriter::packet_iterator BitstreamWriter::iterator::packet_end() { - const ConfigurationPacket& packet = *itr_packets_; + const ConfigurationPacket& packet = **itr_packets_; return BitstreamWriter::packet_iterator( &packet, BitstreamWriter::packet_iterator::STATE_END, @@ -138,7 +138,7 @@ BitstreamWriter::iterator BitstreamWriter::begin() { if (itr_packets != packets_.end()) { // op_packet_itr = packet_begin(); // FIXME: de-duplicate this - const ConfigurationPacket& packet = *itr_packets; + const ConfigurationPacket& packet = **itr_packets; packet_iterator packet_itr = packet_iterator(&packet, packet_iterator::STATE_HEADER, packet.data().begin()); diff --git a/lib/xilinx/xc7series/bitstream_writer_test.cc b/lib/xilinx/xc7series/bitstream_writer_test.cc index 752fa4c9..be2d41ec 100644 --- a/lib/xilinx/xc7series/bitstream_writer_test.cc +++ b/lib/xilinx/xc7series/bitstream_writer_test.cc @@ -50,7 +50,8 @@ void dump_packets(xc7series::BitstreamWriter writer, bool nl = true) { } // Special all 0's -void AddType0(std::vector& packets) { +void AddType0( + std::vector>& packets) { // InitWithWords doesn't like type 0 /* static std::vector words{0x00000000}; @@ -61,27 +62,32 @@ void AddType0(std::vector& packets) { static std::vector words{}; absl::Span word_span(words); // CRC is config value 0 - packets.push_back(xc7series::ConfigurationPacket( + packets.emplace_back(new xc7series::ConfigurationPacket( 0, xc7series::ConfigurationPacket::NOP, xc7series::ConfigurationRegister::CRC, word_span)); } -void AddType1(std::vector& packets) { +void AddType1( + std::vector>& packets) { static std::vector words{MakeType1(0x2, 0x3, 2), 0xAA, 0xBB}; absl::Span word_span(words); auto packet = xc7series::ConfigurationPacket::InitWithWords(word_span); - packets.push_back(*(packet.second)); + packets.emplace_back( + new xc7series::ConfigurationPacket(*(packet.second))); } // Empty -void AddType1E(std::vector& packets) { +void AddType1E( + std::vector>& packets) { static std::vector words{MakeType1(0x2, 0x3, 0)}; absl::Span word_span(words); auto packet = xc7series::ConfigurationPacket::InitWithWords(word_span); - packets.push_back(*(packet.second)); + packets.emplace_back( + new xc7series::ConfigurationPacket(*(packet.second))); } -void AddType2(std::vector& packets) { +void AddType2( + std::vector>& packets) { // Type 1 packet with address // Without this InitWithWords will fail on type 2 xc7series::ConfigurationPacket* packet1; @@ -90,8 +96,9 @@ void AddType2(std::vector& packets) { absl::Span word_span(words); auto packet1_pair = xc7series::ConfigurationPacket::InitWithWords(word_span); - packets.push_back(*(packet1_pair.second)); - packet1 = &packets[0]; + packets.emplace_back( + new xc7series::ConfigurationPacket(*(packet1_pair.second))); + packet1 = packets[0].get(); } // Type 2 packet with data { @@ -100,13 +107,14 @@ void AddType2(std::vector& packets) { absl::Span word_span(words); auto packet = xc7series::ConfigurationPacket::InitWithWords( word_span, packet1); - packets.push_back(*(packet.second)); + packets.emplace_back( + new xc7series::ConfigurationPacket(*(packet.second))); } } // Empty packets should produce just the header TEST(BitstreamWriterTest, WriteHeader) { - std::vector packets; + std::vector> packets; xc7series::BitstreamWriter writer(packets); std::vector words(writer.begin(), writer.end()); @@ -120,7 +128,7 @@ TEST(BitstreamWriterTest, WriteHeader) { } TEST(BitstreamWriterTest, WriteType0) { - std::vector packets; + std::vector> packets; AddType0(packets); xc7series::BitstreamWriter writer(packets); // dump_packets(writer, false); @@ -133,7 +141,7 @@ TEST(BitstreamWriterTest, WriteType0) { EXPECT_EQ(words, ref); } TEST(BitstreamWriterTest, WriteType1) { - std::vector packets; + std::vector> packets; AddType1(packets); xc7series::BitstreamWriter writer(packets); // dump_packets(writer, false); @@ -147,7 +155,7 @@ TEST(BitstreamWriterTest, WriteType1) { } TEST(BitstreamWriterTest, WriteType2) { - std::vector packets; + std::vector> packets; AddType2(packets); xc7series::BitstreamWriter writer(packets); // dump_packets(writer, false); @@ -164,7 +172,7 @@ TEST(BitstreamWriterTest, WriteType2) { } TEST(BitstreamWriterTest, WriteMulti) { - std::vector packets; + std::vector> packets; AddType1(packets); AddType1E(packets); AddType2(packets); diff --git a/tools/xc7patch.cc b/tools/xc7patch.cc index fc4bc6ad..b3ebf6ff 100644 --- a/tools/xc7patch.cc +++ b/tools/xc7patch.cc @@ -120,7 +120,8 @@ int main(int argc, char* argv[]) { frame_data[0x32] |= (ecc & 0x1FFF); } - std::vector out_packets; + std::vector> + out_packets; // Generate a single type 2 packet that writes everything at once. std::vector packet_data; @@ -139,10 +140,11 @@ int main(int argc, char* argv[]) { } packet_data.insert(packet_data.end(), 202, 0); - out_packets.push_back(xc7series::ConfigurationPacket( + // Frame data write + out_packets.emplace_back(new xc7series::ConfigurationPacket( 1, xc7series::ConfigurationPacket::Opcode::Write, xc7series::ConfigurationRegister::FDRI, {})); - out_packets.push_back(xc7series::ConfigurationPacket( + out_packets.emplace_back(new xc7series::ConfigurationPacket( 2, xc7series::ConfigurationPacket::Opcode::Write, xc7series::ConfigurationRegister::FDRI, packet_data)); From 2a1154ec169f48ba23a04f01199c2d674f2cecf4 Mon Sep 17 00:00:00 2001 From: Rick Altherr Date: Thu, 1 Feb 2018 12:20:02 -0800 Subject: [PATCH 04/32] lib: xc7series: config packet subclass that owns the payload Signed-off-by: Rick Altherr --- .../configuration_packet_with_payload.h | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 lib/include/prjxray/xilinx/xc7series/configuration_packet_with_payload.h diff --git a/lib/include/prjxray/xilinx/xc7series/configuration_packet_with_payload.h b/lib/include/prjxray/xilinx/xc7series/configuration_packet_with_payload.h new file mode 100644 index 00000000..bdcdc3c3 --- /dev/null +++ b/lib/include/prjxray/xilinx/xc7series/configuration_packet_with_payload.h @@ -0,0 +1,33 @@ +#ifndef PRJXRAY_LIB_XILINX_XC7SERIES_g_CONFIGURATION_PACKET_WITH_PAYLOAD_H +#define PRJXRAY_LIB_XILINX_XC7SERIES_g_CONFIGURATION_PACKET_WITH_PAYLOAD_H + +#include + +#include +#include +#include +#include + +namespace prjxray { +namespace xilinx { +namespace xc7series { + +template +class ConfigurationPacketWithPayload : public ConfigurationPacket { + public: + ConfigurationPacketWithPayload( + Opcode op, + ConfigurationRegister reg, + const std::array& payload) + : ConfigurationPacket(1, op, reg, absl::Span(payload_)), + payload_(std::move(payload)) {} + + private: + std::array payload_; +}; // namespace xc7series + +} // namespace xc7series +} // namespace xilinx +} // namespace prjxray + +#endif // PRJXRAY_LIB_XILINX_XC7SERIES_g_CONFIGURATION_PACKET_WITH_PAYLOAD_H From ab1e60c037629751ab28ffa07dd4f554ff8a49bc Mon Sep 17 00:00:00 2001 From: Rick Altherr Date: Thu, 1 Feb 2018 12:20:48 -0800 Subject: [PATCH 05/32] lib: xc7series: add undocumented register used in init sequence Signed-off-by: Rick Altherr --- lib/include/prjxray/xilinx/xc7series/configuration_register.h | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/include/prjxray/xilinx/xc7series/configuration_register.h b/lib/include/prjxray/xilinx/xc7series/configuration_register.h index 9f75a090..4fbc5d4c 100644 --- a/lib/include/prjxray/xilinx/xc7series/configuration_register.h +++ b/lib/include/prjxray/xilinx/xc7series/configuration_register.h @@ -25,6 +25,7 @@ enum class ConfigurationRegister : unsigned int { COR1 = 0x0e, WBSTAR = 0x10, TIMER = 0x11, + UNKNOWN = 0x13, BOOTSTS = 0x16, CTL1 = 0x18, BSPI = 0x1F, From 80004a373708f261ba73cc985de17e4f67fbf3b9 Mon Sep 17 00:00:00 2001 From: Rick Altherr Date: Thu, 1 Feb 2018 12:21:22 -0800 Subject: [PATCH 06/32] lib: xc7series: config packet subclass for NOPs Signed-off-by: Rick Altherr --- .../prjxray/xilinx/xc7series/nop_packet.h | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 lib/include/prjxray/xilinx/xc7series/nop_packet.h diff --git a/lib/include/prjxray/xilinx/xc7series/nop_packet.h b/lib/include/prjxray/xilinx/xc7series/nop_packet.h new file mode 100644 index 00000000..65339883 --- /dev/null +++ b/lib/include/prjxray/xilinx/xc7series/nop_packet.h @@ -0,0 +1,24 @@ +#ifndef PRJXRAY_LIB_XILINX_XC7SERIES_NOP_PACKET_H +#define PRJXRAY_LIB_XILINX_XC7SERIES_NOP_PACKET_H + +#include +#include + +namespace prjxray { +namespace xilinx { +namespace xc7series { + +class NopPacket : public ConfigurationPacket { + public: + NopPacket() + : ConfigurationPacket(1, + Opcode::NOP, + ConfigurationRegister::CRC, + {}) {} +}; + +} // namespace xc7series +} // namespace xilinx +} // namespace prjxray + +#endif // PRJXRAY_LIB_XILINX_XC7SERIES_NOP_PACKET_H From a4fb9ff7d8369ab7472c290bbc00cd6416f56a8e Mon Sep 17 00:00:00 2001 From: Rick Altherr Date: Thu, 1 Feb 2018 12:25:45 -0800 Subject: [PATCH 07/32] lib: xc7series: define known CMD register values Signed-off-by: Rick Altherr --- .../prjxray/xilinx/xc7series/command.h | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 lib/include/prjxray/xilinx/xc7series/command.h diff --git a/lib/include/prjxray/xilinx/xc7series/command.h b/lib/include/prjxray/xilinx/xc7series/command.h new file mode 100644 index 00000000..2ff16e86 --- /dev/null +++ b/lib/include/prjxray/xilinx/xc7series/command.h @@ -0,0 +1,34 @@ +#ifndef PRJXRAY_LIB_XILINX_XC7SERIES_COMMAND_H_ +#define PRJXRAY_LIB_XILINX_XC7SERIES_COMMAND_H_ + +namespace prjxray { +namespace xilinx { +namespace xc7series { + +enum class Command : uint32_t { + NOP = 0x0, + WCFG = 0x1, + MFW = 0x2, + LFRM = 0x3, + RCFG = 0x4, + START = 0x5, + RCAP = 0x6, + RCRC = 0x7, + AGHIGH = 0x8, + SWITCH = 0x9, + GRESTORE = 0xA, + SHUTDOWN = 0xB, + GCAPTURE = 0xC, + DESYNC = 0xD, + IPROG = 0xF, + CRCC = 0x10, + LTIMER = 0x11, + BSPI_READ = 0x12, + FALL_EDGE = 0x13, +}; + +} // namespace xc7series +} // namespace xilinx +} // namespace prjxray + +#endif // PRJXRAY_LIB_XILINX_XC7SERIES_COMMAND_H_ From 0fc3ba04009fd0de4accdfd9338f29e15bece321 Mon Sep 17 00:00:00 2001 From: Rick Altherr Date: Thu, 1 Feb 2018 12:27:39 -0800 Subject: [PATCH 08/32] lib: xc7series: implement builder pattern for generating COR0 values Signed-off-by: Rick Altherr --- .../xc7series/configuration_options_0_value.h | 122 ++++++++++++++++++ 1 file changed, 122 insertions(+) create mode 100644 lib/include/prjxray/xilinx/xc7series/configuration_options_0_value.h diff --git a/lib/include/prjxray/xilinx/xc7series/configuration_options_0_value.h b/lib/include/prjxray/xilinx/xc7series/configuration_options_0_value.h new file mode 100644 index 00000000..1b7c1c13 --- /dev/null +++ b/lib/include/prjxray/xilinx/xc7series/configuration_options_0_value.h @@ -0,0 +1,122 @@ +#ifndef PRJXRAY_LIB_XILINX_XC7SERIES_CONFIGURATION_OPTIONS_0_VALUE_H +#define PRJXRAY_LIB_XILINX_XC7SERIES_CONFIGURATION_OPTIONS_0_VALUE_H + +#include +#include +#include + +namespace prjxray { +namespace xilinx { +namespace xc7series { + +class ConfigurationOptions0Value { + public: + enum class StartupClockSource : uint32_t { + CCLK = 0x0, + User = 0x1, + JTAG = 0x2, + }; + + enum class SignalReleaseCycle : uint32_t { + Phase1 = 0x0, + Phase2 = 0x1, + Phase3 = 0x2, + Phase4 = 0x3, + Phase5 = 0x4, + Phase6 = 0x5, + TrackDone = 0x6, + Keep = 0x7, + }; + + enum class StallCycle : uint32_t { + Phase0 = 0x0, + Phase1 = 0x1, + Phase2 = 0x2, + Phase3 = 0x3, + Phase4 = 0x4, + Phase5 = 0x5, + Phase6 = 0x6, + NoWait = 0x7, + }; + + ConfigurationOptions0Value() : value_(0) {} + + operator uint32_t() const { return value_; } + + ConfigurationOptions0Value& SetUseDonePinAsPowerdownStatus( + bool enabled) { + value_ = bit_field_set(value_, 27, 27, enabled ? 1 : 0); + return *this; + } + + ConfigurationOptions0Value& SetAddPipelineStageForDoneIn(bool enabled) { + value_ = bit_field_set(value_, 25, 25, enabled ? 1 : 0); + return *this; + } + + ConfigurationOptions0Value& SetDriveDoneHigh(bool enabled) { + value_ = bit_field_set(value_, 24, 24, enabled); + return *this; + } + + ConfigurationOptions0Value& SetReadbackIsSingleShot(bool enabled) { + value_ = bit_field_set(value_, 23, 23, enabled); + return *this; + } + + ConfigurationOptions0Value& SetCclkFrequency(uint32_t mhz) { + value_ = bit_field_set(value_, 22, 17, mhz); + return *this; + } + + ConfigurationOptions0Value& SetStartupClockSource( + StartupClockSource source) { + value_ = bit_field_set(value_, 16, 15, + static_cast(source)); + return *this; + } + + ConfigurationOptions0Value& SetReleaseDonePinAtStartupCycle( + SignalReleaseCycle cycle) { + value_ = + bit_field_set(value_, 14, 12, static_cast(cycle)); + return *this; + } + + ConfigurationOptions0Value& SetStallAtStartupCycleUntilDciMatch( + StallCycle cycle) { + value_ = + bit_field_set(value_, 11, 9, static_cast(cycle)); + return *this; + }; + + ConfigurationOptions0Value& SetStallAtStartupCycleUntilMmcmLock( + StallCycle cycle) { + value_ = + bit_field_set(value_, 8, 6, static_cast(cycle)); + return *this; + }; + + ConfigurationOptions0Value& SetReleaseGtsSignalAtStartupCycle( + SignalReleaseCycle cycle) { + value_ = + bit_field_set(value_, 5, 3, static_cast(cycle)); + return *this; + } + + ConfigurationOptions0Value& SetReleaseGweSignalAtStartupCycle( + SignalReleaseCycle cycle) { + value_ = + bit_field_set(value_, 2, 0, static_cast(cycle)); + return *this; + } + + private: + uint32_t value_; +}; // namespace xc7series + +} // namespace xc7series +} // namespace xilinx +} // namespace prjxray + +#endif // PRJXRAY_LIB_XILINX_XC7SERIES_CONFIGURATION_OPTIONS_0_VALUE_H From b7d01aa9f607a7a503626546b33591fb463078d8 Mon Sep 17 00:00:00 2001 From: Rick Altherr Date: Thu, 1 Feb 2018 12:30:33 -0800 Subject: [PATCH 09/32] xc7patch: generate init and final sequences in output bitstream Bitstreams generated by xc7patch can now be directly loaded into parts via Vivado's Hardware Manager (bitstream must have .bin suffix) or by flashing into a boot FLASH. Signed-off-by: Rick Altherr --- tools/xc7patch.cc | 158 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 158 insertions(+) diff --git a/tools/xc7patch.cc b/tools/xc7patch.cc index b3ebf6ff..245d6e65 100644 --- a/tools/xc7patch.cc +++ b/tools/xc7patch.cc @@ -10,8 +10,12 @@ #include #include #include +#include #include +#include +#include #include +#include #include DEFINE_string(part_file, "", "Definition file for target 7-series part"); @@ -140,6 +144,104 @@ int main(int argc, char* argv[]) { } packet_data.insert(packet_data.end(), 202, 0); + // Initialization sequence + out_packets.emplace_back(new xc7series::NopPacket()); + out_packets.emplace_back( + new xc7series::ConfigurationPacketWithPayload<1>( + xc7series::ConfigurationPacket::Opcode::Write, + xc7series::ConfigurationRegister::TIMER, {0x0})); + out_packets.emplace_back( + new xc7series::ConfigurationPacketWithPayload<1>( + xc7series::ConfigurationPacket::Opcode::Write, + xc7series::ConfigurationRegister::WBSTAR, {0x0})); + out_packets.emplace_back( + new xc7series::ConfigurationPacketWithPayload<1>( + xc7series::ConfigurationPacket::Opcode::Write, + xc7series::ConfigurationRegister::CMD, + {static_cast(xc7series::Command::NOP)})); + out_packets.emplace_back(new xc7series::NopPacket()); + out_packets.emplace_back( + new xc7series::ConfigurationPacketWithPayload<1>( + xc7series::ConfigurationPacket::Opcode::Write, + xc7series::ConfigurationRegister::CMD, + {static_cast(xc7series::Command::RCRC)})); + out_packets.emplace_back(new xc7series::NopPacket()); + out_packets.emplace_back(new xc7series::NopPacket()); + out_packets.emplace_back( + new xc7series::ConfigurationPacketWithPayload<1>( + xc7series::ConfigurationPacket::Opcode::Write, + xc7series::ConfigurationRegister::UNKNOWN, {0x0})); + + // Configuration Options 0 + out_packets.emplace_back(new xc7series::ConfigurationPacketWithPayload< + 1>( + xc7series::ConfigurationPacket::Opcode::Write, + xc7series::ConfigurationRegister::COR0, + {xc7series::ConfigurationOptions0Value() + .SetAddPipelineStageForDoneIn(true) + .SetReleaseDonePinAtStartupCycle( + xc7series::ConfigurationOptions0Value::SignalReleaseCycle:: + Phase4) + .SetStallAtStartupCycleUntilDciMatch( + xc7series::ConfigurationOptions0Value::StallCycle::NoWait) + .SetStallAtStartupCycleUntilMmcmLock( + xc7series::ConfigurationOptions0Value::StallCycle::NoWait) + .SetReleaseGtsSignalAtStartupCycle( + xc7series::ConfigurationOptions0Value::SignalReleaseCycle:: + Phase5) + .SetReleaseGweSignalAtStartupCycle( + xc7series::ConfigurationOptions0Value::SignalReleaseCycle:: + Phase6)})); + + out_packets.emplace_back( + new xc7series::ConfigurationPacketWithPayload<1>( + xc7series::ConfigurationPacket::Opcode::Write, + xc7series::ConfigurationRegister::COR1, {0x0})); + out_packets.emplace_back( + new xc7series::ConfigurationPacketWithPayload<1>( + xc7series::ConfigurationPacket::Opcode::Write, + xc7series::ConfigurationRegister::IDCODE, {part->idcode()})); + out_packets.emplace_back( + new xc7series::ConfigurationPacketWithPayload<1>( + xc7series::ConfigurationPacket::Opcode::Write, + xc7series::ConfigurationRegister::CMD, + {static_cast(xc7series::Command::SWITCH)})); + out_packets.emplace_back(new xc7series::NopPacket()); + out_packets.emplace_back( + new xc7series::ConfigurationPacketWithPayload<1>( + xc7series::ConfigurationPacket::Opcode::Write, + xc7series::ConfigurationRegister::MASK, {0x401})); + out_packets.emplace_back( + new xc7series::ConfigurationPacketWithPayload<1>( + xc7series::ConfigurationPacket::Opcode::Write, + xc7series::ConfigurationRegister::CTL0, {0x501})); + out_packets.emplace_back( + new xc7series::ConfigurationPacketWithPayload<1>( + xc7series::ConfigurationPacket::Opcode::Write, + xc7series::ConfigurationRegister::MASK, {0x0})); + out_packets.emplace_back( + new xc7series::ConfigurationPacketWithPayload<1>( + xc7series::ConfigurationPacket::Opcode::Write, + xc7series::ConfigurationRegister::CTL1, {0x0})); + out_packets.emplace_back(new xc7series::NopPacket()); + out_packets.emplace_back(new xc7series::NopPacket()); + out_packets.emplace_back(new xc7series::NopPacket()); + out_packets.emplace_back(new xc7series::NopPacket()); + out_packets.emplace_back(new xc7series::NopPacket()); + out_packets.emplace_back(new xc7series::NopPacket()); + out_packets.emplace_back(new xc7series::NopPacket()); + out_packets.emplace_back(new xc7series::NopPacket()); + out_packets.emplace_back( + new xc7series::ConfigurationPacketWithPayload<1>( + xc7series::ConfigurationPacket::Opcode::Write, + xc7series::ConfigurationRegister::FAR, {0x0})); + out_packets.emplace_back( + new xc7series::ConfigurationPacketWithPayload<1>( + xc7series::ConfigurationPacket::Opcode::Write, + xc7series::ConfigurationRegister::CMD, + {static_cast(xc7series::Command::WCFG)})); + out_packets.emplace_back(new xc7series::NopPacket()); + // Frame data write out_packets.emplace_back(new xc7series::ConfigurationPacket( 1, xc7series::ConfigurationPacket::Opcode::Write, @@ -148,6 +250,62 @@ int main(int argc, char* argv[]) { 2, xc7series::ConfigurationPacket::Opcode::Write, xc7series::ConfigurationRegister::FDRI, packet_data)); + // Finalization sequence + out_packets.emplace_back( + new xc7series::ConfigurationPacketWithPayload<1>( + xc7series::ConfigurationPacket::Opcode::Write, + xc7series::ConfigurationRegister::CMD, + {static_cast(xc7series::Command::RCRC)})); + out_packets.emplace_back(new xc7series::NopPacket()); + out_packets.emplace_back(new xc7series::NopPacket()); + out_packets.emplace_back( + new xc7series::ConfigurationPacketWithPayload<1>( + xc7series::ConfigurationPacket::Opcode::Write, + xc7series::ConfigurationRegister::CMD, + {static_cast(xc7series::Command::GRESTORE)})); + out_packets.emplace_back(new xc7series::NopPacket()); + out_packets.emplace_back( + new xc7series::ConfigurationPacketWithPayload<1>( + xc7series::ConfigurationPacket::Opcode::Write, + xc7series::ConfigurationRegister::CMD, + {static_cast(xc7series::Command::LFRM)})); + for (int ii = 0; ii < 100; ++ii) { + out_packets.emplace_back(new xc7series::NopPacket()); + } + out_packets.emplace_back( + new xc7series::ConfigurationPacketWithPayload<1>( + xc7series::ConfigurationPacket::Opcode::Write, + xc7series::ConfigurationRegister::CMD, + {static_cast(xc7series::Command::START)})); + out_packets.emplace_back(new xc7series::NopPacket()); + out_packets.emplace_back( + new xc7series::ConfigurationPacketWithPayload<1>( + xc7series::ConfigurationPacket::Opcode::Write, + xc7series::ConfigurationRegister::FAR, {0x3be0000})); + out_packets.emplace_back( + new xc7series::ConfigurationPacketWithPayload<1>( + xc7series::ConfigurationPacket::Opcode::Write, + xc7series::ConfigurationRegister::MASK, {0x501})); + out_packets.emplace_back( + new xc7series::ConfigurationPacketWithPayload<1>( + xc7series::ConfigurationPacket::Opcode::Write, + xc7series::ConfigurationRegister::CTL0, {0x501})); + out_packets.emplace_back( + new xc7series::ConfigurationPacketWithPayload<1>( + xc7series::ConfigurationPacket::Opcode::Write, + xc7series::ConfigurationRegister::CMD, + {static_cast(xc7series::Command::RCRC)})); + out_packets.emplace_back(new xc7series::NopPacket()); + out_packets.emplace_back(new xc7series::NopPacket()); + out_packets.emplace_back( + new xc7series::ConfigurationPacketWithPayload<1>( + xc7series::ConfigurationPacket::Opcode::Write, + xc7series::ConfigurationRegister::CMD, + {static_cast(xc7series::Command::DESYNC)})); + for (int ii = 0; ii < 400; ++ii) { + out_packets.emplace_back(new xc7series::NopPacket()); + } + // Write bitstream. xc7series::BitstreamWriter out_bitstream_writer(out_packets); std::ofstream out_file(FLAGS_output_file); From 3d33f101bc850a17a2b8540fc70d5ed772d9be83 Mon Sep 17 00:00:00 2001 From: Rick Altherr Date: Thu, 1 Feb 2018 12:32:19 -0800 Subject: [PATCH 10/32] xc7patch: Generate Xilinx BIT header in output bitstream Xilinx tools generate and expect an additional header to be added to the bitstream. This header is the only difference between .bit and .bin files and is not required by the part in any way. OpenOCD only supports reading .bit files so the easiest path to a using FOSS tools from FASM down is to generate a .bit header in xc7patch's output. To distinguish xc7patch-generated files from Xilinx-generated files, the source file field includes a Generator tag indicating that the bitstream was produced by xc7patch. Vivado uses the same technique to record the Vivado version in a Version tag. Signed-off-by: Rick Altherr --- tools/CMakeLists.txt | 1 + tools/xc7patch.cc | 67 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 68 insertions(+) diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt index 06dc18c0..85023a91 100644 --- a/tools/CMakeLists.txt +++ b/tools/CMakeLists.txt @@ -21,6 +21,7 @@ target_link_libraries(gen_part_base_yaml add_executable(xc7patch xc7patch.cc) target_link_libraries(xc7patch absl::strings + absl::time gflags libprjxray ) diff --git a/tools/xc7patch.cc b/tools/xc7patch.cc index 245d6e65..9ea3962d 100644 --- a/tools/xc7patch.cc +++ b/tools/xc7patch.cc @@ -5,7 +5,10 @@ #include #include +#include #include +#include +#include #include #include #include @@ -18,6 +21,7 @@ #include #include +DEFINE_string(part_name, "", ""); DEFINE_string(part_file, "", "Definition file for target 7-series part"); DEFINE_string(bitstream_file, "", @@ -315,6 +319,61 @@ int main(int argc, char* argv[]) { return 1; } + // Xilinx BIT header. + // Sync header + std::vector bit_header{0x0, 0x9, 0x0f, 0xf0, 0x0f, + 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, + 0x00, 0x00, 0x01, 'a'}; + auto build_source = absl::StrCat(FLAGS_frm_file, ";Generator=xc7patch"); + bit_header.push_back( + static_cast((build_source.size() + 1) >> 8)); + bit_header.push_back(static_cast(build_source.size() + 1)); + bit_header.insert(bit_header.end(), build_source.begin(), + build_source.end()); + bit_header.push_back(0x0); + + // Source file. + bit_header.push_back('b'); + bit_header.push_back( + static_cast((FLAGS_part_name.size() + 1) >> 8)); + bit_header.push_back(static_cast(FLAGS_part_name.size() + 1)); + bit_header.insert(bit_header.end(), FLAGS_part_name.begin(), + FLAGS_part_name.end()); + bit_header.push_back(0x0); + + // Build timestamp. + auto build_time = absl::Now(); + auto build_date_string = + absl::FormatTime("%E4Y/%m/%d", build_time, absl::UTCTimeZone()); + auto build_time_string = + absl::FormatTime("%H:%M:%S", build_time, absl::UTCTimeZone()); + + bit_header.push_back('c'); + bit_header.push_back( + static_cast((build_date_string.size() + 1) >> 8)); + bit_header.push_back( + static_cast(build_date_string.size() + 1)); + bit_header.insert(bit_header.end(), build_date_string.begin(), + build_date_string.end()); + bit_header.push_back(0x0); + + bit_header.push_back('d'); + bit_header.push_back( + static_cast((build_time_string.size() + 1) >> 8)); + bit_header.push_back( + static_cast(build_time_string.size() + 1)); + bit_header.insert(bit_header.end(), build_time_string.begin(), + build_time_string.end()); + bit_header.push_back(0x0); + + bit_header.insert(bit_header.end(), {'e', 0x0, 0x0, 0x0, 0x0}); + out_file.write(reinterpret_cast(bit_header.data()), + bit_header.size()); + + auto end_of_header_pos = out_file.tellp(); + auto header_data_length_pos = + end_of_header_pos - static_cast(4); + for (uint32_t word : out_bitstream_writer) { out_file.put((word >> 24) & 0xFF); out_file.put((word >> 16) & 0xFF); @@ -322,5 +381,13 @@ int main(int argc, char* argv[]) { out_file.put((word)&0xFF); } + uint32_t length_of_data = out_file.tellp() - end_of_header_pos; + + out_file.seekp(header_data_length_pos); + out_file.put((length_of_data >> 24) & 0xFF); + out_file.put((length_of_data >> 16) & 0xFF); + out_file.put((length_of_data >> 8) & 0xFF); + out_file.put((length_of_data)&0xFF); + return 0; } From 6b7af3b1686b82773c9b09e0f2692196896b4dc1 Mon Sep 17 00:00:00 2001 From: Rick Altherr Date: Thu, 1 Feb 2018 12:38:02 -0800 Subject: [PATCH 11/32] minitests: partial_reconfig_flow: always save ROI bitstreams Signed-off-by: Rick Altherr --- minitests/partial_reconfig_flow/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/minitests/partial_reconfig_flow/Makefile b/minitests/partial_reconfig_flow/Makefile index f451f815..58df3cfc 100644 --- a/minitests/partial_reconfig_flow/Makefile +++ b/minitests/partial_reconfig_flow/Makefile @@ -1,4 +1,4 @@ -.PRECIOUS: harness_impl.dcp %_impl.dcp %.bit +.PRECIOUS: harness_impl.dcp %_impl.dcp %.bit %_roi_partial.bit # Top-level target for generating a programmable bitstream. Given a .fasm # file, calling make with the .fasm extension replaced with _hand_crafted.bit From ad150af4dfafadeab2b2ec29ca0e2aead91f411f Mon Sep 17 00:00:00 2001 From: Rick Altherr Date: Thu, 1 Feb 2018 10:16:36 -0800 Subject: [PATCH 12/32] minitests: partial_reconfig_flow: Remove init/final sequence hacks Now that xc7series generates proper .bit files, the hacks need to be removed. Signed-off-by: Rick Altherr --- minitests/partial_reconfig_flow/Makefile | 41 ++---------------------- 1 file changed, 3 insertions(+), 38 deletions(-) diff --git a/minitests/partial_reconfig_flow/Makefile b/minitests/partial_reconfig_flow/Makefile index 58df3cfc..239cac4f 100644 --- a/minitests/partial_reconfig_flow/Makefile +++ b/minitests/partial_reconfig_flow/Makefile @@ -6,49 +6,14 @@ # ready for programming to a board. For example, # 'make inv_hand_crafted.bit' will generate a bitstream that includes the # design from roi_noninv.fasm. -%_hand_crafted.bit: init_sequence.bit %_no_headers.bin final_sequence.bin - cat $^ > $@ - -%_no_headers.bin: %_patched.bin - # WARNING: these values need to be tweaked if anything about the - # Vivado-generated design changes. - xxd -p -s 0x18 $< | xxd -r -p - $@ - -%_patched.bin: %_roi_partial.frm harness.bit +%_hand_crafted.bit: %_roi_partial.frm harness.bit ${XRAY_TOOLS_DIR}/xc7patch \ - --part_file ${XRAY_PART_YAML} \ + --part_name "${XRAY_PART}" \ + --part_file "${XRAY_PART_YAML}" \ --bitstream_file harness.bit \ --frm_file $< \ --output_file $@ -# xc7patch currently only generates the actual frame writes which is -# insufficient to program a device. Grab the initialization and finalization -# sequences from the harness bitstream so they can be tacked on to the -# xc7patch-generated bitstream to create a programmable bitstream. -# -# The offsets used below were determined by manually inspecting -# harness.bit with a hex editor. init_sequence.bit is the beginning of -# the file until just before the actual frame data is sent via a write to FDRI. -# final_sequence.bin is from just after the frame data write to the end of the -# file. Note that final_sequence.bin normally includes at least one CRC check. -# The sed command replaces any CRC checks with a Reset CRC command which is the -# same behavior as setting BITSTREAM.GENERAL.CRC to Disabled. These offset -# should not change unless you alter the bitstream format used (i.e. setting -# BITSTREAM.GENERAL.DEBUGBITSTREAM or BITSTREAM.GENERAL.PERFRAMECRC to YES). -init_sequence.bit: harness.bit - # WARNING: these values need to be tweaked if anything about the - # Vivado-generated design changes. - xxd -p -l 0x147 $< | xxd -r -p - $@ - -final_sequence.bin: harness.bit - # WARNING: these values need to be tweaked if anything about the - # Vivado-generated design changes. - xxd -p -s 0x216abf $< | \ - tr -d '\n' | \ - sed -e 's/30000001.\{8\}/3000800100000007/g' | \ - fold -w 40 | \ - xxd -r -p - $@ - # Generate a suitable harness by using Vivado's partial reconfiguration # feature. inv.v is used as a sample reconfiguration design as one is # required to generate a partial reconfiguration design. From d5a6726e3019fa60e368dbf2275aee3a472d4be6 Mon Sep 17 00:00:00 2001 From: Rick Altherr Date: Thu, 1 Feb 2018 12:03:32 -0800 Subject: [PATCH 13/32] minitests: roi_harness: Remove init/final sequence hacks Signed-off-by: Rick Altherr --- minitests/roi_harness/fasm2bit.sh | 21 ++------------------- 1 file changed, 2 insertions(+), 19 deletions(-) diff --git a/minitests/roi_harness/fasm2bit.sh b/minitests/roi_harness/fasm2bit.sh index 3e7798c9..5beb90f5 100755 --- a/minitests/roi_harness/fasm2bit.sh +++ b/minitests/roi_harness/fasm2bit.sh @@ -30,28 +30,11 @@ echo "Out .bit: $bit_out" ${XRAY_DIR}/tools/fasm2frame.py $fasm_in roi_partial.frm ${XRAY_TOOLS_DIR}/xc7patch \ + --part_name ${XRAY_PART} \ --part_file ${XRAY_PART_YAML} \ --bitstream_file $bit_in \ --frm_file roi_partial.frm \ - --output_file patched.bin - -# WARNING: these values need to be tweaked if anything about the -# Vivado-generated design changes. -xxd -p -l 0x147 $bit_in | xxd -r -p - init_sequence.bit - -# WARNING: these values need to be tweaked if anything about the -# Vivado-generated design changes. -xxd -p -s 0x18 patched.bin | xxd -r -p - no_headers.bin - -# WARNING: these values need to be tweaked if anything about the -# Vivado-generated design changes. -xxd -p -s 0x216abf $bit_in | \ - tr -d '\n' | \ - sed -e 's/30000001.\{8\}/3000800100000007/g' | \ - fold -w 40 | \ - xxd -r -p - final_sequence.bin - -cat init_sequence.bit no_headers.bin final_sequence.bin >$bit_out + --output_file $bit_out #openocd -f $XRAY_DIR/utils/openocd/board-digilent-basys3.cfg -c "init; pld load 0 $bit_out; exit" From 1fc306b147175d4163ae6ec3c48a4613699e1b1e Mon Sep 17 00:00:00 2001 From: Rick Altherr Date: Mon, 5 Feb 2018 16:07:16 -0800 Subject: [PATCH 14/32] docs: Initial setup for Sphinx-based documentation Signed-off-by: Rick Altherr --- docs/.gitignore | 1 + docs/Makefile | 20 ++++++ docs/conf.py | 179 ++++++++++++++++++++++++++++++++++++++++++++++++ docs/index.rst | 19 +++++ 4 files changed, 219 insertions(+) create mode 100644 docs/.gitignore create mode 100644 docs/Makefile create mode 100644 docs/conf.py create mode 100644 docs/index.rst diff --git a/docs/.gitignore b/docs/.gitignore new file mode 100644 index 00000000..e35d8850 --- /dev/null +++ b/docs/.gitignore @@ -0,0 +1 @@ +_build diff --git a/docs/Makefile b/docs/Makefile new file mode 100644 index 00000000..d8bf25c3 --- /dev/null +++ b/docs/Makefile @@ -0,0 +1,20 @@ +# Minimal makefile for Sphinx documentation +# + +# You can set these variables from the command line. +SPHINXOPTS = +SPHINXBUILD = sphinx-build +SPHINXPROJ = ProjectX-Ray +SOURCEDIR = . +BUILDDIR = _build + +# Put it first so that "make" without argument is like "make help". +help: + @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + +.PHONY: help Makefile + +# Catch-all target: route all unknown targets to Sphinx using the new +# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) \ No newline at end of file diff --git a/docs/conf.py b/docs/conf.py new file mode 100644 index 00000000..9d14b725 --- /dev/null +++ b/docs/conf.py @@ -0,0 +1,179 @@ +# -*- coding: utf-8 -*- +# +# Project X-Ray documentation build configuration file, created by +# sphinx-quickstart on Mon Feb 5 11:04:37 2018. +# +# This file is execfile()d with the current directory set to its +# containing dir. +# +# Note that not all possible configuration values are present in this +# autogenerated file. +# +# All configuration values have a default; values that are commented out +# serve to show the default. + +import os +import re + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +# +# import os +# import sys +# sys.path.insert(0, os.path.abspath('.')) + +# -- General configuration ------------------------------------------------ + +# If your documentation needs a minimal Sphinx version, state it here. +# +# needs_sphinx = '1.0' + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. +extensions = [ + 'sphinx.ext.imgmath', 'sphinx.ext.autodoc', 'sphinx.ext.doctest', + 'sphinx.ext.autosummary', 'sphinx.ext.napoleon', 'sphinx.ext.todo' +] + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +# The suffix(es) of source filenames. +# You can specify multiple suffix as a list of string: +# +# source_suffix = ['.rst', '.md'] +source_suffix = '.rst' + +# The master toctree document. +master_doc = 'index' + +# General information about the project. +project = u'Project X-Ray' +copyright = u'2018, SymbiFlow Team' +author = u'SymbiFlow Team' + +# The version info for the project you're documenting, acts as replacement for +# |version| and |release|, also used in various other places throughout the +# built documents. +# +# The full version, including alpha/beta/rc tags. +release = re.sub('^v', '', os.popen('git describe ').read().strip()) +# The short X.Y version. +version = release + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +# +# This is also used if you do content translation via gettext catalogs. +# Usually you set "language" from the command line for these cases. +language = None + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +# This patterns also effect to html_static_path and html_extra_path +exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = 'sphinx' + +# If true, `todo` and `todoList` produce output, else they produce nothing. +todo_include_todos = True + +# -- Options for HTML output ---------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +# +html_theme = 'sphinx_rtd_theme' + +# Theme options are theme-specific and customize the look and feel of a theme +# further. For a list of options available for each theme, see the +# documentation. +# +# html_theme_options = {} + +# Enable github links when not on readthedocs +on_rtd = os.environ.get('READTHEDOCS', None) == 'True' +if not on_rtd: + html_context = { + "display_github": True, # Integrate GitHub + "github_user": "symbiflow", # Username + "github_repo": "prjxray", # Repo name + "github_version": "master", # Version + "conf_py_path": "/doc/", + } + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = ['_static'] + +# Custom sidebar templates, must be a dictionary that maps document names +# to template names. +# +# This is required for the alabaster theme +# refs: http://alabaster.readthedocs.io/en/latest/installation.html#sidebars +html_sidebars = { + '**': [ + 'relations.html', # needs 'show_related': True theme option to display + 'searchbox.html', + ] +} + +# -- Options for HTMLHelp output ------------------------------------------ + +# Output file base name for HTML help builder. +htmlhelp_basename = 'prjxray' + +# -- Options for LaTeX output --------------------------------------------- + +latex_elements = { + # The paper size ('letterpaper' or 'a4paper'). + # + # 'papersize': 'letterpaper', + + # The font size ('10pt', '11pt' or '12pt'). + # + # 'pointsize': '10pt', + + # Additional stuff for the LaTeX preamble. + # + # 'preamble': '', + + # Latex figure (float) alignment + # + # 'figure_align': 'htbp', +} + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, +# author, documentclass [howto, manual, or own class]). +latex_documents = [ + ( + master_doc, 'ProjectX-Ray.tex', u'Project X-Ray Documentation', + u'SymbiFlow Team', 'manual'), +] + +# -- Options for manual page output --------------------------------------- + +# One entry per manual page. List of tuples +# (source start file, name, description, authors, manual section). +man_pages = [ + (master_doc, 'projectx-ray', u'Project X-Ray Documentation', [author], 1) +] + +# -- Options for Texinfo output ------------------------------------------- + +# Grouping the document tree into Texinfo files. List of tuples +# (source start file, target name, title, author, +# dir menu entry, description, category) +texinfo_documents = [ + ( + master_doc, 'ProjectX-Ray', u'Project X-Ray Documentation', author, + 'ProjectX-Ray', 'One line description of project.', 'Miscellaneous'), +] + +# Example configuration for intersphinx: refer to the Python standard library. +intersphinx_mapping = {'https://docs.python.org/': None} diff --git a/docs/index.rst b/docs/index.rst new file mode 100644 index 00000000..0f4b2898 --- /dev/null +++ b/docs/index.rst @@ -0,0 +1,19 @@ +.. Project X-Ray documentation master file, created by + sphinx-quickstart on Mon Feb 5 11:04:37 2018. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + +Welcome to Project X-Ray +========================================= + +`Project X-Ray`_ documents the `Xilinx`_ 7-Series FPGA architecture to enable +development of open-source tools. Our goal is to provide sufficient information +to develop a free and open Verilog to bitstream toolchain for these devices. + +.. _Project X-Ray: https://github.com/SymbiFlow/prjxray +.. _Xilinx: http://www.xilinx.com/ + +.. toctree:: + :maxdepth: 2 + :caption: Xilinx 7-series Architecture + From dd5305a2717ae82423345818ba4e0f0e3baaf936 Mon Sep 17 00:00:00 2001 From: Rick Altherr Date: Mon, 5 Feb 2018 16:08:20 -0800 Subject: [PATCH 15/32] docs: Define some terms Tried to merge definitions from wiki/Glossary and my understandings of terms related to architecture and configuration. Signed-off-by: Rick Altherr --- docs/architecture/glossary.rst | 67 ++++++++++++++++++++++++++++++++++ docs/index.rst | 1 + 2 files changed, 68 insertions(+) create mode 100644 docs/architecture/glossary.rst diff --git a/docs/architecture/glossary.rst b/docs/architecture/glossary.rst new file mode 100644 index 00000000..ab798595 --- /dev/null +++ b/docs/architecture/glossary.rst @@ -0,0 +1,67 @@ +Glossary +======================== + +.. glossary:: + + basic element + BEL + basic logic element + BLE + For example a LUT5, LUT6, CARRY4, or MUX, but not PIPs. + + BELs come in two types: + + * Basic BEL - A logic unit which does things. + * Routing BEL - A unit which is statically configured at the routing time. + + + bitstream + Binary data that is directly loaded into an FPGA to perform configuration. + Contains configuration :term:`frames ` as well as programming + sequences and other commands required to load and activate same. + + column + Collection of :term:`tiles ` physically organized as a vertical line. + + configurable logic block + CLB + Basic building block of logic. + + frame + Fundamental unit of configuration data consisting of 101 :term:`words `. + + half + Portion of a device defined by a virtual line dividing the two sets of global + clock buffers present in a device. The two halves are simply referred to as + the top and bottom halves. + + node + Collection of :term:`wires ` spanning one or more tiles. + + programmable interconnect point + PIP + Connection point between two wires in a tile that may be enabled or + disabled by the configuration. + + horizontal clock row + Portion of a device including 12 horizontal clocks and the 50 interconnect + and function tiles associated with them. A :term:`half` contains one or + more horizontal clock rows and each half may have a different number of + rows. + + site + Portion of a tile where :term:`BELs ` can be placed. :term:`Slices + ` in a :term:`CLB` tile are sites. + + slice + Portion of a :term:`CLB` tile that contains :term:`BELs `. + + tile + Fundamental unit of physical structure containing a single type of + resource or function. + + wire + Physical wire within a :term:`tile`. + + word + 32-bits stored in big-endian order. Fundamental unit of :term:`bitstream` format. diff --git a/docs/index.rst b/docs/index.rst index 0f4b2898..51041785 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -17,3 +17,4 @@ to develop a free and open Verilog to bitstream toolchain for these devices. :maxdepth: 2 :caption: Xilinx 7-series Architecture + architecture/glossary From beb8e0bcf98eca075a1a8cda8a666658f5661347 Mon Sep 17 00:00:00 2001 From: Rick Altherr Date: Mon, 5 Feb 2018 16:10:11 -0800 Subject: [PATCH 16/32] docs: overview of 7-Series architecture Describes the top-level physical structure. Signed-off-by: Rick Altherr --- docs/architecture/overview.rst | 33 +++++++++++++++++++++++++++++++++ docs/index.rst | 1 + 2 files changed, 34 insertions(+) create mode 100644 docs/architecture/overview.rst diff --git a/docs/architecture/overview.rst b/docs/architecture/overview.rst new file mode 100644 index 00000000..fb58e60b --- /dev/null +++ b/docs/architecture/overview.rst @@ -0,0 +1,33 @@ +.. _architecture_overview-label: + +Overview +======== + +.. todo:: add diagrams. + +Xilinx 7-Series architecture utilizes a hierarchical design of chainable +structures to scale across the Spartan, Artix, Kintex, and Virtex product +lines. This documentation focuses on the Artix and Kintex devices and omits +some concepts introduced in Virtex devices. + +At the top-level, 7-Series devices are divided into two :term:`halves ` +by a virtual horizontal line separating two sets of global clock buffers +(BUFGs). While global clocks can be connected such that they span both sets of +BUFGs, the two halves defined by this division are treated as separate entities +as related to configuration. The halves are referred to simply as the top and +bottom halves. + +Each halves is next divided vertically into one or more :term:`horizontal clock +rows `, numbered outward from the global clock buffer +dividing line. Each horizontal clock row contains 12 clock lines that extend +across the device perpendicular to the global clock spine. Similar to the +global clock spine, each horizontal clock row is divided into two halves by two +sets of horizontal clock buffers (BUFHs), one on each side of the global clock +spine, yielding two :term:`clock domains `. Horizontal clocks +may be used within a single clock domain, connected to span both clock domains +in a horizontal clock row, or connected to global clocks. + +Clock domains have a fixed height of 50 :term:`interconnect tiles +` centered around the horizontal clock lines (25 above, 25 +below). Various function tiles, such as :term:`CLBs `, are attached to interconnect +tiles. diff --git a/docs/index.rst b/docs/index.rst index 51041785..78c1bd01 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -17,4 +17,5 @@ to develop a free and open Verilog to bitstream toolchain for these devices. :maxdepth: 2 :caption: Xilinx 7-series Architecture + architecture/overview architecture/glossary From d1ea210dba4f609ff5eec66640194cd69f8e06e3 Mon Sep 17 00:00:00 2001 From: Rick Altherr Date: Mon, 5 Feb 2018 17:51:20 -0800 Subject: [PATCH 17/32] Tweak .gitignore so database settings.sh is tracked Signed-off-by: Rick Altherr --- .gitignore | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 05e207ba..28f10758 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ /build/ .Xil -database/* +# Ignore database directories _except_ for their settings +database/*/* +!database/*/settings.sh From 7980e069dd18b8abc75de2959c475ad94a2dc2c0 Mon Sep 17 00:00:00 2001 From: Rick Altherr Date: Mon, 5 Feb 2018 17:51:32 -0800 Subject: [PATCH 18/32] Rename 'make go' to 'make build' Signed-off-by: Rick Altherr --- Makefile | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index 297b666e..088c7b50 100644 --- a/Makefile +++ b/Makefile @@ -1,11 +1,9 @@ -JOBS ?= $(shell nproc) -JOBS ?= 2 CLANG_FORMAT ?= clang-format -go: +build: git submodule update --init --recursive mkdir -p build - cd build; cmake ..; make -j$(JOBS) + cd build; cmake ..; $(MAKE) format: find . -name \*.cc -and -not -path './third_party/*' -and -not -path './.git/*' -exec $(CLANG_FORMAT) -style=file -i {} \; From 47811acccdf3d74faa15fda4b095b466bfed25cd Mon Sep 17 00:00:00 2001 From: Rick Altherr Date: Mon, 5 Feb 2018 17:51:33 -0800 Subject: [PATCH 19/32] Top-level clean target Signed-off-by: Rick Altherr --- Makefile | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Makefile b/Makefile index 088c7b50..acc911e2 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,7 @@ CLANG_FORMAT ?= clang-format +.PHONY: format clean + build: git submodule update --init --recursive mkdir -p build @@ -9,3 +11,7 @@ format: find . -name \*.cc -and -not -path './third_party/*' -and -not -path './.git/*' -exec $(CLANG_FORMAT) -style=file -i {} \; find . -name \*.h -and -not -path './third_party/*' -and -not -path './.git/*' -exec $(CLANG_FORMAT) -style=file -i {} \; find . -name \*.py -and -not -path './third_party/*' -and -not -path './.git/*' -exec yapf -p -i {} \; + +clean: + $(MAKE) -C fuzzers clean + rm -rf build From 5d103c0498233e35773fdd2714ba706094a632f6 Mon Sep 17 00:00:00 2001 From: Rick Altherr Date: Mon, 5 Feb 2018 17:51:35 -0800 Subject: [PATCH 20/32] Makefile rules for generating complete databases Signed-off-by: Rick Altherr --- Makefile | 6 +++++- database/Makefile | 10 ++++++++++ database/Makefile.database | 15 +++++++++++++++ 3 files changed, 30 insertions(+), 1 deletion(-) create mode 100644 database/Makefile create mode 100644 database/Makefile.database diff --git a/Makefile b/Makefile index acc911e2..2028b5d9 100644 --- a/Makefile +++ b/Makefile @@ -1,17 +1,21 @@ CLANG_FORMAT ?= clang-format -.PHONY: format clean +.PHONY: database format clean build: git submodule update --init --recursive mkdir -p build cd build; cmake ..; $(MAKE) +database: build + $(MAKE) -C $@ + format: find . -name \*.cc -and -not -path './third_party/*' -and -not -path './.git/*' -exec $(CLANG_FORMAT) -style=file -i {} \; find . -name \*.h -and -not -path './third_party/*' -and -not -path './.git/*' -exec $(CLANG_FORMAT) -style=file -i {} \; find . -name \*.py -and -not -path './third_party/*' -and -not -path './.git/*' -exec yapf -p -i {} \; clean: + $(MAKE) -C database clean $(MAKE) -C fuzzers clean rm -rf build diff --git a/database/Makefile b/database/Makefile new file mode 100644 index 00000000..99fab407 --- /dev/null +++ b/database/Makefile @@ -0,0 +1,10 @@ +.NOTPARALLEL: + +SUBDIRS := $(patsubst %/,%, $(wildcard */)) + +.PHONY: $(SUBDIRS) + +$(MAKECMDGOALS): $(SUBDIRS) + +$(SUBDIRS): + $(MAKE) -C $@ -f ../Makefile.database $(MAKECMDGOALS) diff --git a/database/Makefile.database b/database/Makefile.database new file mode 100644 index 00000000..2e407968 --- /dev/null +++ b/database/Makefile.database @@ -0,0 +1,15 @@ +.PHONY: all clean + +all: tilegrid.json + +# Small dance to say that there is a single recipe that is run once to generate +# multiple files. +tileconn.json tilegrid.json: fuzzers +.INTERMEDIATE: fuzzers +fuzzers: SHELL:=/bin/bash +fuzzers: settings.sh + source settings.sh && $(MAKE) -C ../../fuzzers all + +clean: + rm -f *.db tileconn.json tilegrid.json *.yaml + rm -rf html From f4ddb607cb26cca034826669a05e2a6a12aa2b9a Mon Sep 17 00:00:00 2001 From: Rick Altherr Date: Mon, 5 Feb 2018 17:51:36 -0800 Subject: [PATCH 21/32] Dockerfile for building database from scratch Runs all fuzzers to construct a database from scratch. Raw and HTML versions of database are packaged into a docker image that serves the files via nginx. Signed-off-by: Rick Altherr --- Dockerfile | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 Dockerfile diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 00000000..a2544951 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,12 @@ +ARG DEV_ENV_IMAGE + +FROM ${DEV_ENV_IMAGE} AS db_builder +ARG NUM_PARALLEL_JOBS=1 + +COPY . /source +RUN cd /source && make -j${NUM_PARALLEL_JOBS} database +RUN find /source/database -mindepth 1 -maxdepth 1 -type d -exec /source/htmlgen/htmlgen.py --settings={}/settings.sh --output=/output/html \; +RUN mkdir -p /output/raw && find /source/database -mindepth 1 -maxdepth 1 -type d -exec cp -R {} /output/raw \; + +FROM nginx:alpine +COPY --from=db_builder /output /usr/share/nginx/html From 7b81b6734be5c16dd77bc772eb975409fa07b9b4 Mon Sep 17 00:00:00 2001 From: Rick Altherr Date: Mon, 5 Feb 2018 17:51:37 -0800 Subject: [PATCH 22/32] Google Cloud Builder configuration for database generation Signed-off-by: Rick Altherr --- .gcloudignore | 15 +++++++++++++++ cloudbuild.yaml | 21 +++++++++++++++++++++ 2 files changed, 36 insertions(+) create mode 100644 .gcloudignore create mode 100644 cloudbuild.yaml diff --git a/.gcloudignore b/.gcloudignore new file mode 100644 index 00000000..ef2ea2e4 --- /dev/null +++ b/.gcloudignore @@ -0,0 +1,15 @@ +# This file specifies files that are *not* uploaded to Google Cloud Platform +# using gcloud. It follows the same syntax as .gitignore, with the addition of +# "#!include" directives (which insert the entries of the given .gitignore-style +# file at that point). +# +# For more information, run: +# $ gcloud topic gcloudignore +# +.gcloudignore +#!include:.gitignore + +# Don't bother uploading files not needed to generate a database. +experiments +minitests +vagrant diff --git a/cloudbuild.yaml b/cloudbuild.yaml new file mode 100644 index 00000000..c3f12bcc --- /dev/null +++ b/cloudbuild.yaml @@ -0,0 +1,21 @@ +steps: +- name: 'gcr.io/cloud-builders/docker' + args: + - 'build' + - '--build-arg' + - 'DEV_ENV_IMAGE=${_DEV_ENV_IMAGE}' + - '--build-arg' + - 'NUM_PARALLEL_JOBS=${_NUM_CPUS}' + - '-t' + - '${_GCR_ZONE}/$PROJECT_ID/${_IMAGE_NAME}:${TAG_NAME}' + - '.' +options: + disk_size_gb: 1000 + machine_type: N1_HIGHCPU_32 +timeout: '21600s' +substitutions: + _GCR_ZONE: 'gcr.io' + _IMAGE_NAME: 'prjxray-db' + _NUM_CPUS: '16' +images: + - '${_GCR_ZONE}/$PROJECT_ID/${_IMAGE_NAME}:${TAG_NAME}' From 13a44b273d8830d6ac2961836142b387d53bfebe Mon Sep 17 00:00:00 2001 From: Rick Altherr Date: Tue, 6 Feb 2018 10:48:27 -0800 Subject: [PATCH 23/32] docs: Fix poor grammar Signed-off-by: Rick Altherr --- docs/architecture/overview.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/architecture/overview.rst b/docs/architecture/overview.rst index fb58e60b..ec66cfb1 100644 --- a/docs/architecture/overview.rst +++ b/docs/architecture/overview.rst @@ -17,7 +17,7 @@ BUFGs, the two halves defined by this division are treated as separate entities as related to configuration. The halves are referred to simply as the top and bottom halves. -Each halves is next divided vertically into one or more :term:`horizontal clock +Each half is next divided vertically into one or more :term:`horizontal clock rows `, numbered outward from the global clock buffer dividing line. Each horizontal clock row contains 12 clock lines that extend across the device perpendicular to the global clock spine. Similar to the From d5c9bcabdb7ccc08df17956a167c4f18d7ea38f1 Mon Sep 17 00:00:00 2001 From: Rick Altherr Date: Wed, 7 Feb 2018 14:36:16 -0800 Subject: [PATCH 24/32] Add sphinx modules needed for docs to PIP requirements file Signed-off-by: Rick Altherr --- requirements.txt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 612ba388..f16b1bd9 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,2 +1,5 @@ -yapf futures +sphinx +sphinx_rtd_theme +sphinx-autobuild +yapf From 0970edb3841c5f61b855da06d062523bb618738a Mon Sep 17 00:00:00 2001 From: Rick Altherr Date: Wed, 7 Feb 2018 14:27:02 -0800 Subject: [PATCH 25/32] docs: Make target for live reloading during editing Target starts sphinx-autobuild which watches the source files and rebuilds the output on writes. Output is served via a local HTTP server that injects code to refresh the page when a new version is available. Saving a source file triggers the browser to reload the page generated. Signed-off-by: Rick Altherr --- docs/Makefile | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/docs/Makefile b/docs/Makefile index d8bf25c3..b52c6680 100644 --- a/docs/Makefile +++ b/docs/Makefile @@ -4,6 +4,7 @@ # You can set these variables from the command line. SPHINXOPTS = SPHINXBUILD = sphinx-build +SPHINXAUTOBUILD = sphinx-autobuild SPHINXPROJ = ProjectX-Ray SOURCEDIR = . BUILDDIR = _build @@ -12,9 +13,12 @@ BUILDDIR = _build help: @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) -.PHONY: help Makefile +livehtml: + @$(SPHINXAUTOBUILD) -b html --ignore \*.swp --ignore \*~ $(SPHINXOPTS) "$(SOURCEDIR)" "$(BUILDDIR)/html" + +.PHONY: help livereload Makefile # Catch-all target: route all unknown targets to Sphinx using the new # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). %: Makefile - @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) \ No newline at end of file + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) From e6a3bdc0edebe269d613765c164f2bd199e1fb8f Mon Sep 17 00:00:00 2001 From: Rick Altherr Date: Wed, 7 Feb 2018 14:30:46 -0800 Subject: [PATCH 26/32] docs: configuration addressing section and rough notes for others Describes how frame addressing relates to physical chip structure. Rough notes on how frames are loaded into the device and the packet format used to operate that state machine. Signed-off-by: Rick Altherr --- docs/architecture/bitstream_format.rst | 43 ++++++++ docs/architecture/configuration.rst | 130 +++++++++++++++++++++++++ docs/architecture/glossary.rst | 5 + docs/index.rst | 2 + 4 files changed, 180 insertions(+) create mode 100644 docs/architecture/bitstream_format.rst create mode 100644 docs/architecture/configuration.rst diff --git a/docs/architecture/bitstream_format.rst b/docs/architecture/bitstream_format.rst new file mode 100644 index 00000000..5c74fb21 --- /dev/null +++ b/docs/architecture/bitstream_format.rst @@ -0,0 +1,43 @@ +Bitstream format +================ + +.. todo:: + Expand on rough notes + +* Specific byte pattern at beginning of file to allow hardware to determine + width of bus providing configuration data. +* Rest of file is 32-bit big-endian words +* All data before 32-bit synchronization word (0xAA995566) is ignored by + configuration state machine +* Packetized format used to perform register reads/writes + * Three packet header types + + * Type 0 packets exist only when performing zero-fill between rows + * Type 1 used for writes up to 4096 words + * Type 2 expands word count field to 27 bits by omitting register address + * Type 2 must always be proceeded by Type 1 which sets register address + + * NOP packets are used for inserting required delays + * Most registers only accept 1 word of data + * Allowed register operations depends on interface used to send packets + + * Writing LOUT via JTAG is treated as a bad command + * Single-frame FDRI writes via JTAG fail + +* CRC + + * Calculated automatically from writes: register address and data written + * Expected value is written to CRC register + * If there is a mismatch, error is flagged in status register + * Writes to CRC register can be safely removed from a bitstream + * Alternatively, replace with write to command register to reset calculated + CRC value + +* Xilinx BIT header + + * Additional information about how bitstream was generated + * Unofficially documented at + http://www.fpga-faq.com/FAQ_Pages/0026_Tell_me_about_bit_files.htm + * Really does require NULL-terminated Pascal strings + * Having this header is the distinction between .bin and .bit in Vivado + * Is ignored entirely by devices diff --git a/docs/architecture/configuration.rst b/docs/architecture/configuration.rst new file mode 100644 index 00000000..e75174f5 --- /dev/null +++ b/docs/architecture/configuration.rst @@ -0,0 +1,130 @@ +Configuration +============= + +Within an FPGA, various memories (latches, block RAMs, distributed RAMs) +contain the state of signal routing, :term:`BEL` configuration, and runtime +storage. Configuration is the process of loading an initial state into all of +these memories both to define the intended logic operations as well as set +initial data for runtime memories. Note that the same mechanisms used for +configuration are also capable of reading out the active state of these +memories as well. This can be used to examine the contents of a block RAM or +other memory at any point in the device's operation. + +Addressing +---------------- +As described in :ref:`architecture_overview-label`, 7-Series FPGAs are constructed +out of :term:`tiles ` organized into :term:`clock domains `. Each tile contains a set of :term:`BELs ` and the memories used +to configure them. Uniquely addressing each of these memories +involves first identifying the :term:`horizontal clock row`, then the tile within +that row, and finally the specific bit within the tile. + +:term:`Horizontal clock row` addressing follows the hierarchical structure described +in :ref:`architecture_overview-label` with a single bit used to indicate top or bottom half +and a 5-bit integer to encode the row number. Within the row, tiles are connected to +one or more configuration busses depending on the type of tile and what configuration +memories it contains. These busses are identified by a 3-bit integer: + ++---------+-------------------+---------------------+ +| Address | Name | Connected tile type | ++=========+===================+=====================+ +| 000 | CLB, I/O, CLB | Interconnect (INT) | ++---------+-------------------+---------------------+ +| 001 | Block RAM content | Block RAM (BRAM) | ++---------+-------------------+---------------------+ +| 010 | CFG_CLB | ??? | ++---------+-------------------+---------------------+ + +Within each bus, the connected tiles are organized into columns. A column roughly +corresponds to a physical vertical line of tiles perpendicular to and centered over +the horizontal clock row. Each column contains varying amounts of configuration data +depending on the types of tiles attached to that column. Regardless of the amount, +a column's configuration data is organized into a multiple of :term:`frames `. +Each frame consists of 101 words with 100 words for the connected tiles and 1 word for +the horizontal clock row. The 7-bit address used to identify a specific frame within +the column is called the minor address. + +Putting all these pieces together, a 32-bit frame address is constructed: + ++-----------------+-------+ +| Field | Bits | ++=================+=======+ +| Reserved | 31:26 | ++-----------------+-------+ +| Bus | 25:23 | ++-----------------+-------+ +| Top/Bottom Half | 22 | ++-----------------+-------+ +| Row | 21:17 | ++-----------------+-------+ +| Column | 16:7 | ++-----------------+-------+ +| Minor | 6:0 | ++-----------------+-------+ + +CLB, I/O, CLB +^^^^^^^^^^^^^ + +Columns on this bus are comprised of 50 directly-attached interconnect tiles with various +kinds of tiles connected behind them. Frames are striped across the interconnect tiles +with each tile receiving 2 words out of the frame. The number of frames in a column +depends on the type of tiles connected behind the interconnect. For example, interconnect +tiles always have 26 frames and a CLBL tile has an additional 12 frames so a column of CLBs +will have 36 frames. + +Block RAM content +^^^^^^^^^^^^^^^^^ + +As the name says, this bus provides access to the Block RAM contents. Block RAM configuration +data is accessed via the CLB, I/O, CLB bus. The mapping of frame words to memory locations is +not currently understood. + +CFG_CLB +^^^^^^^ + +While mentioned in a few places, this bus type has not been seen in any bitstreams for Artix7 +so far. + +Loading sequence +---------------------- + +.. todo:: + + Expand on these rough notes. + +* Device is configured via a state machine controlled via a set of registers +* CRC of register writes is checked against expected values to verify data + integrity during transmission. +* Before writing frame data: + + * IDCODE for configuration's target device is checked against actual device + * Watchdog timer is disabled + * Start-up sequence clock is selected and configured + * Start-up signal assertion timing is configured + * Interconnect is placed into Hi-Z state + +* Data is then written by: + + * Loading a starting address + * Selecting the write configuration command + * Writing configuration data to data input register + + * Writes must be in multiples of the frame size + * Multi-frame writes trigger autoincrementing of the frame address + * Autoincrement can be disabled via bit in COR1 register. + * At the end of a row, 2 frames of zeros must be inserted before data for the next row. + +* After the write has finished, the device is restarted by: + + * Strobing a signal to activate IOB/CLB configuration flip-flops + * Reactivate interconnect + * Arms start-up sequence to run after desync + * Desynchronizes the device from the configuration port + +* Status register provides detail of start-up phases and which signals are asserted + +Other +----- +* ECC of frame data is contained in word 50 alongside horizontal clock row configuration +* Loading will succeed even with incorrect ECC data +* ECC is primarily used for runtime bit-flip detection diff --git a/docs/architecture/glossary.rst b/docs/architecture/glossary.rst index ab798595..ef29cec2 100644 --- a/docs/architecture/glossary.rst +++ b/docs/architecture/glossary.rst @@ -20,6 +20,11 @@ Glossary Contains configuration :term:`frames ` as well as programming sequences and other commands required to load and activate same. + clock domain + Portion of a :term:`horizontal clock row` to one side of the global clock + spine. Often refers to :term:`tiles ` that are associated with these + clocks. + column Collection of :term:`tiles ` physically organized as a vertical line. diff --git a/docs/index.rst b/docs/index.rst index 78c1bd01..81041af0 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -18,4 +18,6 @@ to develop a free and open Verilog to bitstream toolchain for these devices. :caption: Xilinx 7-series Architecture architecture/overview + architecture/configuration + architecture/bitstream_format architecture/glossary From 46c1eef15b49241a89909a79a8b7182b315f399e Mon Sep 17 00:00:00 2001 From: Davide Date: Tue, 13 Feb 2018 17:00:04 +0100 Subject: [PATCH 27/32] renamed all README.txt files to README.md Signed-off-by: Davide --- fuzzers/005-tilegrid/{README.txt => README.md} | 0 fuzzers/011-ffconfig/{README.txt => README.md} | 0 fuzzers/012-clbn5ffmux/{README.txt => README.md} | 0 fuzzers/013-clbncy0/{README.txt => README.md} | 0 fuzzers/014-ffsrcemux/{README.txt => README.md} | 0 fuzzers/015-clbnffmux/{README.txt => README.md} | 0 fuzzers/016-clbnoutmux/{README.txt => README.md} | 0 fuzzers/017-clbprecyinit/{README.txt => README.md} | 0 fuzzers/018-clbram/{README.txt => README.md} | 0 fuzzers/019-ndi1mux/{README.txt => README.md} | 0 minitests/bram/{README.txt => README.md} | 0 minitests/clb_bused/{README.txt => README.md} | 0 minitests/clb_ffcfg/{README.txt => README.md} | 0 minitests/clb_muxf8/{README.txt => README.md} | 0 minitests/clb_n5ffmux/{README.txt => README.md} | 0 minitests/clb_ncy0/{README.txt => README.md} | 0 minitests/clb_ndi1mux/{README.txt => README.md} | 0 minitests/clb_nffmux/{README.txt => README.md} | 0 minitests/clb_noutmux/{README.txt => README.md} | 0 minitests/clb_ram/{README.txt => README.md} | 0 minitests/fixedpnr/{README.txt => README.md} | 0 minitests/picorv32-v/{README.txt => README.md} | 0 minitests/picorv32-y/{README.txt => README.md} | 0 minitests/roi_harness/{README.txt => README.md} | 0 24 files changed, 0 insertions(+), 0 deletions(-) rename fuzzers/005-tilegrid/{README.txt => README.md} (100%) rename fuzzers/011-ffconfig/{README.txt => README.md} (100%) rename fuzzers/012-clbn5ffmux/{README.txt => README.md} (100%) rename fuzzers/013-clbncy0/{README.txt => README.md} (100%) rename fuzzers/014-ffsrcemux/{README.txt => README.md} (100%) rename fuzzers/015-clbnffmux/{README.txt => README.md} (100%) rename fuzzers/016-clbnoutmux/{README.txt => README.md} (100%) rename fuzzers/017-clbprecyinit/{README.txt => README.md} (100%) rename fuzzers/018-clbram/{README.txt => README.md} (100%) rename fuzzers/019-ndi1mux/{README.txt => README.md} (100%) rename minitests/bram/{README.txt => README.md} (100%) rename minitests/clb_bused/{README.txt => README.md} (100%) rename minitests/clb_ffcfg/{README.txt => README.md} (100%) rename minitests/clb_muxf8/{README.txt => README.md} (100%) rename minitests/clb_n5ffmux/{README.txt => README.md} (100%) rename minitests/clb_ncy0/{README.txt => README.md} (100%) rename minitests/clb_ndi1mux/{README.txt => README.md} (100%) rename minitests/clb_nffmux/{README.txt => README.md} (100%) rename minitests/clb_noutmux/{README.txt => README.md} (100%) rename minitests/clb_ram/{README.txt => README.md} (100%) rename minitests/fixedpnr/{README.txt => README.md} (100%) rename minitests/picorv32-v/{README.txt => README.md} (100%) rename minitests/picorv32-y/{README.txt => README.md} (100%) rename minitests/roi_harness/{README.txt => README.md} (100%) diff --git a/fuzzers/005-tilegrid/README.txt b/fuzzers/005-tilegrid/README.md similarity index 100% rename from fuzzers/005-tilegrid/README.txt rename to fuzzers/005-tilegrid/README.md diff --git a/fuzzers/011-ffconfig/README.txt b/fuzzers/011-ffconfig/README.md similarity index 100% rename from fuzzers/011-ffconfig/README.txt rename to fuzzers/011-ffconfig/README.md diff --git a/fuzzers/012-clbn5ffmux/README.txt b/fuzzers/012-clbn5ffmux/README.md similarity index 100% rename from fuzzers/012-clbn5ffmux/README.txt rename to fuzzers/012-clbn5ffmux/README.md diff --git a/fuzzers/013-clbncy0/README.txt b/fuzzers/013-clbncy0/README.md similarity index 100% rename from fuzzers/013-clbncy0/README.txt rename to fuzzers/013-clbncy0/README.md diff --git a/fuzzers/014-ffsrcemux/README.txt b/fuzzers/014-ffsrcemux/README.md similarity index 100% rename from fuzzers/014-ffsrcemux/README.txt rename to fuzzers/014-ffsrcemux/README.md diff --git a/fuzzers/015-clbnffmux/README.txt b/fuzzers/015-clbnffmux/README.md similarity index 100% rename from fuzzers/015-clbnffmux/README.txt rename to fuzzers/015-clbnffmux/README.md diff --git a/fuzzers/016-clbnoutmux/README.txt b/fuzzers/016-clbnoutmux/README.md similarity index 100% rename from fuzzers/016-clbnoutmux/README.txt rename to fuzzers/016-clbnoutmux/README.md diff --git a/fuzzers/017-clbprecyinit/README.txt b/fuzzers/017-clbprecyinit/README.md similarity index 100% rename from fuzzers/017-clbprecyinit/README.txt rename to fuzzers/017-clbprecyinit/README.md diff --git a/fuzzers/018-clbram/README.txt b/fuzzers/018-clbram/README.md similarity index 100% rename from fuzzers/018-clbram/README.txt rename to fuzzers/018-clbram/README.md diff --git a/fuzzers/019-ndi1mux/README.txt b/fuzzers/019-ndi1mux/README.md similarity index 100% rename from fuzzers/019-ndi1mux/README.txt rename to fuzzers/019-ndi1mux/README.md diff --git a/minitests/bram/README.txt b/minitests/bram/README.md similarity index 100% rename from minitests/bram/README.txt rename to minitests/bram/README.md diff --git a/minitests/clb_bused/README.txt b/minitests/clb_bused/README.md similarity index 100% rename from minitests/clb_bused/README.txt rename to minitests/clb_bused/README.md diff --git a/minitests/clb_ffcfg/README.txt b/minitests/clb_ffcfg/README.md similarity index 100% rename from minitests/clb_ffcfg/README.txt rename to minitests/clb_ffcfg/README.md diff --git a/minitests/clb_muxf8/README.txt b/minitests/clb_muxf8/README.md similarity index 100% rename from minitests/clb_muxf8/README.txt rename to minitests/clb_muxf8/README.md diff --git a/minitests/clb_n5ffmux/README.txt b/minitests/clb_n5ffmux/README.md similarity index 100% rename from minitests/clb_n5ffmux/README.txt rename to minitests/clb_n5ffmux/README.md diff --git a/minitests/clb_ncy0/README.txt b/minitests/clb_ncy0/README.md similarity index 100% rename from minitests/clb_ncy0/README.txt rename to minitests/clb_ncy0/README.md diff --git a/minitests/clb_ndi1mux/README.txt b/minitests/clb_ndi1mux/README.md similarity index 100% rename from minitests/clb_ndi1mux/README.txt rename to minitests/clb_ndi1mux/README.md diff --git a/minitests/clb_nffmux/README.txt b/minitests/clb_nffmux/README.md similarity index 100% rename from minitests/clb_nffmux/README.txt rename to minitests/clb_nffmux/README.md diff --git a/minitests/clb_noutmux/README.txt b/minitests/clb_noutmux/README.md similarity index 100% rename from minitests/clb_noutmux/README.txt rename to minitests/clb_noutmux/README.md diff --git a/minitests/clb_ram/README.txt b/minitests/clb_ram/README.md similarity index 100% rename from minitests/clb_ram/README.txt rename to minitests/clb_ram/README.md diff --git a/minitests/fixedpnr/README.txt b/minitests/fixedpnr/README.md similarity index 100% rename from minitests/fixedpnr/README.txt rename to minitests/fixedpnr/README.md diff --git a/minitests/picorv32-v/README.txt b/minitests/picorv32-v/README.md similarity index 100% rename from minitests/picorv32-v/README.txt rename to minitests/picorv32-v/README.md diff --git a/minitests/picorv32-y/README.txt b/minitests/picorv32-y/README.md similarity index 100% rename from minitests/picorv32-y/README.txt rename to minitests/picorv32-y/README.md diff --git a/minitests/roi_harness/README.txt b/minitests/roi_harness/README.md similarity index 100% rename from minitests/roi_harness/README.txt rename to minitests/roi_harness/README.md From 10e2cd6cabbd2d1886d4410cf831d1155fe581d4 Mon Sep 17 00:00:00 2001 From: Tim 'mithro' Ansell Date: Mon, 5 Feb 2018 16:41:10 -0800 Subject: [PATCH 28/32] Rename flip-flop muxes to make Vivado GUI names. CLBLL_L.SLICEL_X0.AFF.DMUX -> CLBLL_L.SLICEL_X0.AFFMUX CLBLL_L.SLICEL_X0.AMUX -> CLBLL_L.SLICEL_X0.AOUTMUX Signed-off-by: Tim 'mithro' Ansell --- fuzzers/015-clbnffmux/README.md | 66 +++++++++++++++--------------- fuzzers/015-clbnffmux/generate.py | 4 +- fuzzers/016-clbnoutmux/README.md | 66 +++++++++++++++--------------- fuzzers/016-clbnoutmux/generate.py | 4 +- 4 files changed, 70 insertions(+), 70 deletions(-) diff --git a/fuzzers/015-clbnffmux/README.md b/fuzzers/015-clbnffmux/README.md index 820fcf39..f67ed3b6 100644 --- a/fuzzers/015-clbnffmux/README.md +++ b/fuzzers/015-clbnffmux/README.md @@ -1,42 +1,42 @@ Purpose: -Document AFFMUX family of CLB muxes +Document nFFMUX family of CLB muxes Algorithm: Outcome: -CLB.SLICE_X0.AFF.DMUX.B0 30_00 -CLB.SLICE_X0.AFF.DMUX.B1 30_01 -CLB.SLICE_X0.AFF.DMUX.B2 30_02 -CLB.SLICE_X0.AFF.DMUX.B3 30_03 -CLB.SLICE_X0.BFF.DMUX.B0 30_27 -CLB.SLICE_X0.BFF.DMUX.B1 30_26 -CLB.SLICE_X0.BFF.DMUX.B2 30_25 -CLB.SLICE_X0.BFF.DMUX.B3 30_24 -CLB.SLICE_X0.CFF.DMUX.B0 30_35 -CLB.SLICE_X0.CFF.DMUX.B1 30_36 -CLB.SLICE_X0.CFF.DMUX.B2 30_37 -CLB.SLICE_X0.CFF.DMUX.B3 30_38 -CLB.SLICE_X0.DFF.DMUX.B0 30_62 -CLB.SLICE_X0.DFF.DMUX.B1 30_61 -CLB.SLICE_X0.DFF.DMUX.B2 30_60 -CLB.SLICE_X0.DFF.DMUX.B3 30_59 -CLB.SLICE_X1.AFF.DMUX.B0 31_00 -CLB.SLICE_X1.AFF.DMUX.B1 31_01 -CLB.SLICE_X1.AFF.DMUX.B2 31_02 -CLB.SLICE_X1.AFF.DMUX.B3 30_04 -CLB.SLICE_X1.BFF.DMUX.B0 31_25 -CLB.SLICE_X1.BFF.DMUX.B1 31_27 -CLB.SLICE_X1.BFF.DMUX.B2 31_26 -CLB.SLICE_X1.BFF.DMUX.B3 31_24 -CLB.SLICE_X1.CFF.DMUX.B0 31_35 -CLB.SLICE_X1.CFF.DMUX.B1 31_38 -CLB.SLICE_X1.CFF.DMUX.B2 31_37 -CLB.SLICE_X1.CFF.DMUX.B3 31_36 -CLB.SLICE_X1.DFF.DMUX.B0 30_58 -CLB.SLICE_X1.DFF.DMUX.B1 31_61 -CLB.SLICE_X1.DFF.DMUX.B2 31_62 -CLB.SLICE_X1.DFF.DMUX.B3 31_60 +CLB.SLICE_X0.AFFMUX.B0 30_00 +CLB.SLICE_X0.AFFMUX.B1 30_01 +CLB.SLICE_X0.AFFMUX.B2 30_02 +CLB.SLICE_X0.AFFMUX.B3 30_03 +CLB.SLICE_X0.BFFMUX.B0 30_27 +CLB.SLICE_X0.BFFMUX.B1 30_26 +CLB.SLICE_X0.BFFMUX.B2 30_25 +CLB.SLICE_X0.BFFMUX.B3 30_24 +CLB.SLICE_X0.CFFMUX.B0 30_35 +CLB.SLICE_X0.CFFMUX.B1 30_36 +CLB.SLICE_X0.CFFMUX.B2 30_37 +CLB.SLICE_X0.CFFMUX.B3 30_38 +CLB.SLICE_X0.DFFMUX.B0 30_62 +CLB.SLICE_X0.DFFMUX.B1 30_61 +CLB.SLICE_X0.DFFMUX.B2 30_60 +CLB.SLICE_X0.DFFMUX.B3 30_59 +CLB.SLICE_X1.AFFMUX.B0 31_00 +CLB.SLICE_X1.AFFMUX.B1 31_01 +CLB.SLICE_X1.AFFMUX.B2 31_02 +CLB.SLICE_X1.AFFMUX.B3 30_04 +CLB.SLICE_X1.BFFMUX.B0 31_25 +CLB.SLICE_X1.BFFMUX.B1 31_27 +CLB.SLICE_X1.BFFMUX.B2 31_26 +CLB.SLICE_X1.BFFMUX.B3 31_24 +CLB.SLICE_X1.CFFMUX.B0 31_35 +CLB.SLICE_X1.CFFMUX.B1 31_38 +CLB.SLICE_X1.CFFMUX.B2 31_37 +CLB.SLICE_X1.CFFMUX.B3 31_36 +CLB.SLICE_X1.DFFMUX.B0 30_58 +CLB.SLICE_X1.DFFMUX.B1 31_61 +CLB.SLICE_X1.DFFMUX.B2 31_62 +CLB.SLICE_X1.DFFMUX.B3 31_60 diff --git a/fuzzers/015-clbnffmux/generate.py b/fuzzers/015-clbnffmux/generate.py index 38fd2a80..79b49912 100644 --- a/fuzzers/015-clbnffmux/generate.py +++ b/fuzzers/015-clbnffmux/generate.py @@ -52,7 +52,7 @@ for l in f: src = which + "X" # add the 1-tag for this connection - tag = "%sFF.DMUX.%s" % (which, src) + tag = "%sFFMUX.%s" % (which, src) segmk.addtag(loc, tag, 1) # remove this MUX from the cache, preventing generation of 0-tags for this MUX @@ -65,7 +65,7 @@ for loc, muxes in cache.items(): if src == "F7" and which not in "AC": continue if src == "F8" and which not in "B": continue if src == "AX": src = which + "X" - tag = "%sFF.DMUX.%s" % (which, src) + tag = "%sFFMUX.%s" % (which, src) segmk.addtag(loc, tag, 0) diff --git a/fuzzers/016-clbnoutmux/README.md b/fuzzers/016-clbnoutmux/README.md index 6bcb8088..d0e31619 100644 --- a/fuzzers/016-clbnoutmux/README.md +++ b/fuzzers/016-clbnoutmux/README.md @@ -1,43 +1,43 @@ Purpose: -Document AOUTMUX family of CLB muxes +Document nOUTMUX family of CLB muxes TODO: document O6 Algorithm: Outcome: -CLB.SLICE_X0.AMUX.B0 30_11 -CLB.SLICE_X0.AMUX.B1 30_08 -CLB.SLICE_X0.AMUX.B2 30_06 -CLB.SLICE_X0.AMUX.B3 30_07 -CLB.SLICE_X0.BMUX.B0 30_20 -CLB.SLICE_X0.BMUX.B1 30_21 -CLB.SLICE_X0.BMUX.B2 30_22 -CLB.SLICE_X0.BMUX.B3 30_23 -CLB.SLICE_X0.CMUX.B0 30_45 -CLB.SLICE_X0.CMUX.B1 30_44 -CLB.SLICE_X0.CMUX.B2 30_40 -CLB.SLICE_X0.CMUX.B3 30_43 -CLB.SLICE_X0.DMUX.B0 30_56 -CLB.SLICE_X0.DMUX.B1 30_51 -CLB.SLICE_X0.DMUX.B2 30_52 -CLB.SLICE_X0.DMUX.B3 30_57 -CLB.SLICE_X1.AMUX.B0 31_09 -CLB.SLICE_X1.AMUX.B1 31_07 -CLB.SLICE_X1.AMUX.B2 31_10 -CLB.SLICE_X1.AMUX.B3 30_05 -CLB.SLICE_X1.BMUX.B0 31_20 -CLB.SLICE_X1.BMUX.B1 30_28 -CLB.SLICE_X1.BMUX.B2 31_21 -CLB.SLICE_X1.BMUX.B3 30_29 -CLB.SLICE_X1.CMUX.B0 31_43 -CLB.SLICE_X1.CMUX.B1 30_42 -CLB.SLICE_X1.CMUX.B2 31_40 -CLB.SLICE_X1.CMUX.B3 30_41 -CLB.SLICE_X1.DMUX.B0 31_56 -CLB.SLICE_X1.DMUX.B1 30_53 -CLB.SLICE_X1.DMUX.B2 31_57 -CLB.SLICE_X1.DMUX.B3 31_53 +CLB.SLICE_X0.AOUTMUX.B0 30_11 +CLB.SLICE_X0.AOUTMUX.B1 30_08 +CLB.SLICE_X0.AOUTMUX.B2 30_06 +CLB.SLICE_X0.AOUTMUX.B3 30_07 +CLB.SLICE_X0.BOUTMUX.B0 30_20 +CLB.SLICE_X0.BOUTMUX.B1 30_21 +CLB.SLICE_X0.BOUTMUX.B2 30_22 +CLB.SLICE_X0.BOUTMUX.B3 30_23 +CLB.SLICE_X0.COUTMUX.B0 30_45 +CLB.SLICE_X0.COUTMUX.B1 30_44 +CLB.SLICE_X0.COUTMUX.B2 30_40 +CLB.SLICE_X0.COUTMUX.B3 30_43 +CLB.SLICE_X0.DOUTMUX.B0 30_56 +CLB.SLICE_X0.DOUTMUX.B1 30_51 +CLB.SLICE_X0.DOUTMUX.B2 30_52 +CLB.SLICE_X0.DOUTMUX.B3 30_57 +CLB.SLICE_X1.AOUTMUX.B0 31_09 +CLB.SLICE_X1.AOUTMUX.B1 31_07 +CLB.SLICE_X1.AOUTMUX.B2 31_10 +CLB.SLICE_X1.AOUTMUX.B3 30_05 +CLB.SLICE_X1.BOUTMUX.B0 31_20 +CLB.SLICE_X1.BOUTMUX.B1 30_28 +CLB.SLICE_X1.BOUTMUX.B2 31_21 +CLB.SLICE_X1.BOUTMUX.B3 30_29 +CLB.SLICE_X1.COUTMUX.B0 31_43 +CLB.SLICE_X1.COUTMUX.B1 30_42 +CLB.SLICE_X1.COUTMUX.B2 31_40 +CLB.SLICE_X1.COUTMUX.B3 30_41 +CLB.SLICE_X1.DOUTMUX.B0 31_56 +CLB.SLICE_X1.DOUTMUX.B1 30_53 +CLB.SLICE_X1.DOUTMUX.B2 31_57 +CLB.SLICE_X1.DOUTMUX.B3 31_53 From manual O6 testing diff --git a/fuzzers/016-clbnoutmux/generate.py b/fuzzers/016-clbnoutmux/generate.py index 7c8dda15..ede555f0 100644 --- a/fuzzers/016-clbnoutmux/generate.py +++ b/fuzzers/016-clbnoutmux/generate.py @@ -52,7 +52,7 @@ for l in f: src = which + "5Q" # add the 1-tag for this connection - tag = "%sMUX.%s" % (which, src) + tag = "%sOUTMUX.%s" % (which, src) segmk.addtag(loc, tag, 1) # remove this MUX from the cache, preventing generation of 0-tags for this MUX @@ -65,7 +65,7 @@ for loc, muxes in cache.items(): if src == "F7" and which not in "AC": continue if src == "F8" and which not in "B": continue if src == "5Q": src = which + "5Q" - tag = "%sMUX.%s" % (which, src) + tag = "%sOUTMUX.%s" % (which, src) segmk.addtag(loc, tag, 0) From 90ec237f56b0e55dc239ab92ea7d2847bd7fe65e Mon Sep 17 00:00:00 2001 From: Tim 'mithro' Ansell Date: Mon, 5 Feb 2018 17:22:18 -0800 Subject: [PATCH 29/32] Fixing htmlgen for name changes. Signed-off-by: Tim 'mithro' Ansell --- htmlgen/htmlgen.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/htmlgen/htmlgen.py b/htmlgen/htmlgen.py index 3b933fd1..eb010ed2 100755 --- a/htmlgen/htmlgen.py +++ b/htmlgen/htmlgen.py @@ -202,6 +202,7 @@ for segname, segdata in grid["segments"].items(): routebits[segtype][bit].add(bit_name) def add_single_bit(line): + print(line) bit_name, bit_pos = line.split() assert bit_pos[0] != "!" segbits[segtype][bit_name] = bit_pos @@ -211,7 +212,7 @@ for segname, segdata in grid["segments"].items(): print(" loading %s segbits." % segtype) with db_open("segbits_%s.db" % segtype) as f: for line in f: - if re.search(r"(\.[ABCD]MUX\.)|(\.PRECYINIT\.)", line): + if re.search(r"(\.[ABCD](FF|OUT)MUX\.)|(\.PRECYINIT\.)", line): add_pip_bits(line) else: add_single_bit(line) @@ -578,12 +579,12 @@ function oml() { bgcolor = "#4466bb" label = "LH" elif re.match( - "^CLBL[LM]_[LR].SLICE[LM]_X[01].[ABCD]FF.DMUX", + "^CLBL[LM]_[LR].SLICE[LM]_X[01].[ABCD]FFMUX", bn): bgcolor = "#88aaff" label = "DMX" elif re.match( - "^CLBL[LM]_[LR].SLICE[LM]_X[01].[ABCD]MUX", + "^CLBL[LM]_[LR].SLICE[LM]_X[01].[ABCD]OUTMUX", bn): bgcolor = "#aa88ff" label = "OMX" From cf64309ee3d4d20bea5a4af462b2d55c3b08c2a3 Mon Sep 17 00:00:00 2001 From: Tim 'mithro' Ansell Date: Mon, 5 Feb 2018 17:55:21 -0800 Subject: [PATCH 30/32] Make n5FFMUX match Vivado GUI. CLBLL_L.SLICEL_X0.D5FF.MUX.A -> CLBLL_L.SLICEL_X0.D5FFMUX.IN_A CLBLL_L.SLICEL_X0.D5FF.MUX.B -> CLBLL_L.SLICEL_X0.D5FFMUX.IN_B Signed-off-by: Tim 'mithro' Ansell --- fuzzers/012-clbn5ffmux/generate.py | 4 ++-- htmlgen/htmlgen.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/fuzzers/012-clbn5ffmux/generate.py b/fuzzers/012-clbn5ffmux/generate.py index 6c44af1c..e2e5a7d9 100644 --- a/fuzzers/012-clbn5ffmux/generate.py +++ b/fuzzers/012-clbn5ffmux/generate.py @@ -26,7 +26,7 @@ for l in f: # Theory: there is one bit for each mux positon # In each config 3 muxes are in one position, other 3 are in another inv = int(i == n) - segmk.addtag(loc, "%c5FF.MUX.A" % which, def_a ^ inv) - segmk.addtag(loc, "%c5FF.MUX.B" % which, 1 ^ def_a ^ inv) + segmk.addtag(loc, "%c5FFMUX.IN_A" % which, def_a ^ inv) + segmk.addtag(loc, "%c5FFMUX.IN_B" % which, 1 ^ def_a ^ inv) segmk.compile() segmk.write() diff --git a/htmlgen/htmlgen.py b/htmlgen/htmlgen.py index eb010ed2..8f1641b6 100755 --- a/htmlgen/htmlgen.py +++ b/htmlgen/htmlgen.py @@ -212,7 +212,7 @@ for segname, segdata in grid["segments"].items(): print(" loading %s segbits." % segtype) with db_open("segbits_%s.db" % segtype) as f: for line in f: - if re.search(r"(\.[ABCD](FF|OUT)MUX\.)|(\.PRECYINIT\.)", line): + if re.search(r"(\.[ABCD](5?FF|OUT)MUX\.)|(\.PRECYINIT\.)", line): add_pip_bits(line) else: add_single_bit(line) From 21a33e50a199eb013ccf3260b243be5b3a71e516 Mon Sep 17 00:00:00 2001 From: Tim 'mithro' Ansell Date: Tue, 6 Feb 2018 09:52:10 -0800 Subject: [PATCH 31/32] Fix wrapping. Signed-off-by: Tim 'mithro' Ansell --- htmlgen/htmlgen.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/htmlgen/htmlgen.py b/htmlgen/htmlgen.py index 8f1641b6..fdc78d3b 100755 --- a/htmlgen/htmlgen.py +++ b/htmlgen/htmlgen.py @@ -212,7 +212,8 @@ for segname, segdata in grid["segments"].items(): print(" loading %s segbits." % segtype) with db_open("segbits_%s.db" % segtype) as f: for line in f: - if re.search(r"(\.[ABCD](5?FF|OUT)MUX\.)|(\.PRECYINIT\.)", line): + if re.search(r"(\.[ABCD](5?FF|OUT)MUX\.)|(\.PRECYINIT\.)", + line): add_pip_bits(line) else: add_single_bit(line) From dff0413a684c70b3de5629d8e959de2101fe6fd5 Mon Sep 17 00:00:00 2001 From: John McMaster Date: Tue, 13 Feb 2018 16:53:26 -0800 Subject: [PATCH 32/32] ndi1mux: dont add to slicel Signed-off-by: John McMaster --- fuzzers/019-ndi1mux/Makefile | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/fuzzers/019-ndi1mux/Makefile b/fuzzers/019-ndi1mux/Makefile index 1a7faa6e..5e13cafb 100644 --- a/fuzzers/019-ndi1mux/Makefile +++ b/fuzzers/019-ndi1mux/Makefile @@ -3,11 +3,9 @@ SPECIMENS := $(addprefix specimen_,$(shell seq -f '%03.0f' $(N))) SPECIMENS_OK := $(addsuffix /OK,$(SPECIMENS)) database: $(SPECIMENS_OK) - ${XRAY_SEGMATCH} -o seg_clblx.segbits $(addsuffix /segdata_clbl[lm]_[lr].txt,$(SPECIMENS)) + ${XRAY_SEGMATCH} -o seg_clblx.segbits $(addsuffix /segdata_clblm_[lr].txt,$(SPECIMENS)) pushdb: - ${XRAY_MERGEDB} clbll_l seg_clblx.segbits - ${XRAY_MERGEDB} clbll_r seg_clblx.segbits ${XRAY_MERGEDB} clblm_l seg_clblx.segbits ${XRAY_MERGEDB} clblm_r seg_clblx.segbits