Skip to content

Commit

Permalink
WIP partial support
Browse files Browse the repository at this point in the history
  • Loading branch information
Jan Kowalewski committed Nov 24, 2020
1 parent 780b7e4 commit 6212c4a
Show file tree
Hide file tree
Showing 5 changed files with 313 additions and 14 deletions.
8 changes: 8 additions & 0 deletions lib/include/prjxray/xilinx/configuration.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,14 @@ class Configuration {
const PacketData& packet_data,
absl::optional<typename ArchType::Part>& part);

// Creates the configuration package for partial configuration
// which is later on used by the bitstream writer to generate
// the partial bitstream file.
static void createPartialConfigurationPackage(
typename ArchType::ConfigurationPackage& out_packets,
std::map<uint32_t, PacketData> cfg_packets,
absl::optional<typename ArchType::Part>& part);

// Returns the payload for a type 2 packet
// which allows for bigger payload compared to type 1.
static PacketData createType2ConfigurationPacketData(
Expand Down
45 changes: 45 additions & 0 deletions lib/include/prjxray/xilinx/frames.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,18 @@ class Frames {
void addMissingFrames(
const absl::optional<typename ArchType::Part>& part);

// Adds empty frames that are present in provided address ranges
// of a specific part. This version is used for filling missing frames
// in Partial Reconfiguration Region if there are address gaps.
// clb_*_addr - address range for CLB_IO_CLK block type
// bram_*_addr - address range for BRAM block type
void addMissingFrames(
const absl::optional<typename ArchType::Part>& part,
uint32_t clb_start_addr,
uint32_t clb_end_addr,
uint32_t bram_start_addr,
uint32_t bram_end_addr);

// Returns the map with frame addresses and corresponding data
Frames2Data& getFrames() { return frames_data_; }

Expand Down Expand Up @@ -128,6 +140,39 @@ void Frames<ArchType>::addMissingFrames(
} while (current_frame_address);
}

template <typename ArchType>
void Frames<ArchType>::addMissingFrames(
const absl::optional<typename ArchType::Part>& part,
uint32_t clb_start_addr,
uint32_t clb_end_addr,
uint32_t bram_start_addr,
uint32_t bram_end_addr) {
// CLB_IO_CLK block types are always on lower addresses,
// the region starts there and ends on BRAM addresses.
auto current_frame_address =
absl::optional<typename ArchType::FrameAddress>(
typename ArchType::FrameAddress((clb_start_addr)));
auto end_frame_address =
absl::optional<typename ArchType::FrameAddress>(
typename ArchType::FrameAddress(bram_end_addr));
do {
auto iter = frames_data_.find(*current_frame_address);
if (iter == frames_data_.end() &&
((*current_frame_address >= clb_start_addr &&
*current_frame_address <= clb_end_addr) ||
(*current_frame_address >= bram_start_addr &&
*current_frame_address <= bram_end_addr))) {
FrameData frame_data(ArchType::words_per_frame, 0);
frames_data_.insert(
std::pair<typename ArchType::FrameAddress,
FrameData>(*current_frame_address,
frame_data));
}
current_frame_address =
part->GetNextFrameAddress(*current_frame_address);
} while (*current_frame_address <= *end_frame_address);
}

} // namespace xilinx
} // namespace prjxray

Expand Down
127 changes: 127 additions & 0 deletions lib/xilinx/configuration.cc
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,16 @@ Configuration<Spartan6>::createType2ConfigurationPacketData(
return packet_data;
}

template <>
void Configuration<Spartan6>::createPartialConfigurationPackage(
Spartan6::ConfigurationPackage& out_packets,
std::map<uint32_t, PacketData> cfg_packets,
absl::optional<Spartan6::Part>& part) {
throw std::runtime_error(
"Partial bitstream generation for this architecture is not "
"supported!");
}

template <>
void Configuration<Spartan6>::createConfigurationPackage(
Spartan6::ConfigurationPackage& out_packets,
Expand Down Expand Up @@ -297,6 +307,103 @@ void Configuration<Spartan6>::createConfigurationPackage(
}
}

template <>
void Configuration<Series7>::createPartialConfigurationPackage(
Series7::ConfigurationPackage& out_packets,
std::map<uint32_t, PacketData> cfg_packets,
absl::optional<Series7::Part>& part) {
using ArchType = Series7;
using ConfigurationRegister = ArchType::ConfRegType;
out_packets.emplace_back(new NopPacket<ConfigurationRegister>());
out_packets.emplace_back(
new ConfigurationPacketWithPayload<1, ConfigurationRegister>(
ConfigurationPacket<ConfigurationRegister>::Opcode::Write,
ConfigurationRegister::CMD,
{static_cast<uint32_t>(xc7series::Command::RCRC)}));
out_packets.emplace_back(new NopPacket<ConfigurationRegister>());
out_packets.emplace_back(new NopPacket<ConfigurationRegister>());

out_packets.emplace_back(
new ConfigurationPacketWithPayload<1, ConfigurationRegister>(
ConfigurationPacket<ConfigurationRegister>::Opcode::Write,
ConfigurationRegister::IDCODE, {part->idcode()}));
out_packets.emplace_back(
new ConfigurationPacketWithPayload<1, ConfigurationRegister>(
ConfigurationPacket<ConfigurationRegister>::Opcode::Write,
ConfigurationRegister::CMD,
{static_cast<uint32_t>(xc7series::Command::NOP)}));
out_packets.emplace_back(
new ConfigurationPacketWithPayload<1, ConfigurationRegister>(
ConfigurationPacket<ConfigurationRegister>::Opcode::Write,
ConfigurationRegister::MASK, {0x100}));
out_packets.emplace_back(
new ConfigurationPacketWithPayload<1, ConfigurationRegister>(
ConfigurationPacket<ConfigurationRegister>::Opcode::Write,
ConfigurationRegister::CTL0, {0x100}));
out_packets.emplace_back(
new ConfigurationPacketWithPayload<1, ConfigurationRegister>(
ConfigurationPacket<ConfigurationRegister>::Opcode::Write,
ConfigurationRegister::MASK, {0x400}));
out_packets.emplace_back(
new ConfigurationPacketWithPayload<1, ConfigurationRegister>(
ConfigurationPacket<ConfigurationRegister>::Opcode::Write,
ConfigurationRegister::CTL0, {0x400}));

out_packets.emplace_back(
new ConfigurationPacketWithPayload<1, ConfigurationRegister>(
ConfigurationPacket<ConfigurationRegister>::Opcode::Write,
ConfigurationRegister::CMD,
{static_cast<uint32_t>(xc7series::Command::WCFG)}));
out_packets.emplace_back(new NopPacket<ConfigurationRegister>());

// Generate data packets for each address space
std::map<uint32_t, PacketData>::iterator it;
for (auto& it : cfg_packets) {
out_packets.emplace_back(
new ConfigurationPacketWithPayload<1, ConfigurationRegister>(
ConfigurationPacket<ConfigurationRegister>::Opcode::Write,
ConfigurationRegister::FAR, {it.first}));
out_packets.emplace_back(new NopPacket<ConfigurationRegister>());

out_packets.emplace_back(new ConfigurationPacket<ConfigurationRegister>(
TYPE1, ConfigurationPacket<ConfigurationRegister>::Opcode::Write,
ConfigurationRegister::FDRI, {}));
out_packets.emplace_back(new ConfigurationPacket<ConfigurationRegister>(
TYPE2, ConfigurationPacket<ConfigurationRegister>::Opcode::Write,
ConfigurationRegister::FDRI, it.second));
}

// Finalization sequence
out_packets.emplace_back(
new ConfigurationPacketWithPayload<1, ConfigurationRegister>(
ConfigurationPacket<ConfigurationRegister>::Opcode::Write,
ConfigurationRegister::MASK, {0x100}));
out_packets.emplace_back(
new ConfigurationPacketWithPayload<1, ConfigurationRegister>(
ConfigurationPacket<ConfigurationRegister>::Opcode::Write,
ConfigurationRegister::CTL0, {0x0}));
out_packets.emplace_back(
new ConfigurationPacketWithPayload<1, ConfigurationRegister>(
ConfigurationPacket<ConfigurationRegister>::Opcode::Write,
ConfigurationRegister::FAR, {0x3be0000}));
out_packets.emplace_back(
new ConfigurationPacketWithPayload<1, ConfigurationRegister>(
ConfigurationPacket<ConfigurationRegister>::Opcode::Write,
ConfigurationRegister::CMD,
{static_cast<uint32_t>(xc7series::Command::RCRC)}));
out_packets.emplace_back(new NopPacket<ConfigurationRegister>());
out_packets.emplace_back(new NopPacket<ConfigurationRegister>());
out_packets.emplace_back(
new ConfigurationPacketWithPayload<1, ConfigurationRegister>(
ConfigurationPacket<ConfigurationRegister>::Opcode::Write,
ConfigurationRegister::CMD,
{static_cast<uint32_t>(xc7series::Command::DESYNC)}));
for (int ii = 0; ii < 400; ++ii) {
out_packets.emplace_back(
new NopPacket<ConfigurationRegister>());
}
}

template <>
void Configuration<Series7>::createConfigurationPackage(
Series7::ConfigurationPackage& out_packets,
Expand Down Expand Up @@ -469,6 +576,16 @@ void Configuration<Series7>::createConfigurationPackage(
}
}

template <>
void Configuration<UltraScale>::createPartialConfigurationPackage(
UltraScale::ConfigurationPackage& out_packets,
std::map<uint32_t, PacketData> cfg_packets,
absl::optional<UltraScale::Part>& part) {
throw std::runtime_error(
"Partial bitstream generation for this architecture is not "
"supported!");
}

template <>
void Configuration<UltraScale>::createConfigurationPackage(
UltraScale::ConfigurationPackage& out_packets,
Expand Down Expand Up @@ -630,6 +747,16 @@ void Configuration<UltraScale>::createConfigurationPackage(
}
}

template <>
void Configuration<UltraScalePlus>::createPartialConfigurationPackage(
UltraScalePlus::ConfigurationPackage& out_packets,
std::map<uint32_t, PacketData> cfg_packets,
absl::optional<UltraScalePlus::Part>& part) {
throw std::runtime_error(
"Partial bitstream generation for this architecture is not "
"supported!");
}

template <>
void Configuration<UltraScalePlus>::createConfigurationPackage(
UltraScalePlus::ConfigurationPackage& out_packets,
Expand Down
63 changes: 63 additions & 0 deletions lib/xilinx/tests/xc7series/configuration_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -318,3 +318,66 @@ TEST(ConfigurationTest, CheckForPaddingFrames) {
EXPECT_EQ(frame.second, frames.getFrames().at(frame.first));
}
}

//TEST(ConfigurationTest, CreatePartialConfigurationPackage) {
// namespace xilinx = prjxray::xilinx;
// // Generate blocks in the same (3rd) column
// std::vector<xc7series::FrameAddress> test_part_addresses = {
// xc7series::FrameAddress(xc7series::BlockType::CLB_IO_CLK, false, 0,
// 3, 0),
// xc7series::FrameAddress(xc7series::BlockType::CLB_IO_CLK, false, 1,
// 3, 0),
// xc7series::FrameAddress(xc7series::BlockType::CLB_IO_CLK, false, 2,
// 3, 0),
// xc7series::FrameAddress(xc7series::BlockType::BLOCK_RAM, false, 0,
// 3, 0),
// xc7series::FrameAddress(xc7series::BlockType::BLOCK_RAM, false, 1,
// 3, 0)};
//
// auto test_part = absl::optional<xc7series::Part>(
// xc7series::Part(0x1234, test_part_addresses));
//
// Frames<Series7> frames;
// frames.getFrames().emplace(std::make_pair(
// test_part_addresses.at(0), std::vector<uint32_t>(101, 0xAA)));
// frames.getFrames().emplace(std::make_pair(
// test_part_addresses.at(1), std::vector<uint32_t>(101, 0xBB)));
// frames.getFrames().emplace(std::make_pair(
// test_part_addresses.at(2), std::vector<uint32_t>(101, 0xCC)));
// frames.getFrames().emplace(std::make_pair(
// test_part_addresses.at(3), std::vector<uint32_t>(101, 0xDD)));
// frames.getFrames().emplace(std::make_pair(
// test_part_addresses.at(4), std::vector<uint32_t>(101, 0xEE)));
// ASSERT_EQ(frames.getFrames().size(), 5);
//
// Configuration<Series7>::PacketData packet_data =
// Configuration<Series7>::createType2ConfigurationPacketData(
// frames.getFrames(), test_part);
//
// Series7::ConfigurationPackage full_configuration_package;
// Series7::ConfigurationPackage partial_configuration_package;
//
// xilinx::Configuration<Series7>::createConfigurationPackage(
// full_configuration_package, packet_data, test_part);
//
// uint32_t far_address = (uint32_t)frames.getFrames().begin()->first;
// xilinx::Configuration<Series7>::createPartialConfigurationPackage(
// partial_configuration_package, packet_data, test_part, far_address);
//
// // Full bitstream should have a FAR packet with a FAR address set to 0
// for (auto& cfg : full_configuration_package) {
// if (cfg.get()->address() == Series7ConfigurationRegister::FAR) {
// EXPECT_EQ(cfg.get()->data()[0], 0);
// break;
// }
// }
//
// // Partial bitstream should have a FAR packet with a correct FAR address
// // which can be other than 0
// for (auto& cfg : partial_configuration_package) {
// if (cfg.get()->address() == Series7ConfigurationRegister::FAR) {
// EXPECT_EQ(cfg.get()->data()[0], 0x180);
// break;
// }
// }
//}
Loading

0 comments on commit 6212c4a

Please sign in to comment.