Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add CORE clock support #1668

Merged
merged 16 commits into from
Aug 2, 2024
49 changes: 43 additions & 6 deletions src/Compiler/CompilerOpenFPGA.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -739,8 +739,12 @@ std::pair<bool, std::string> CompilerOpenFPGA::IsDeviceSizeCorrect(
return std::make_pair(false, "Architecture file: fixed_layout is missing");
for (int i = 0; i < fixedLayout.count(); i++) {
auto node = fixedLayout.at(i).toElement();
if (node.attribute("name").toStdString() == size)
return std::make_pair(true, std::string{});
if (node.attribute("name").toStdString() == size) {
std::string device_dimension =
CFG_print("%sx%s", node.attribute("width").toStdString().c_str(),
node.attribute("height").toStdString().c_str());
return std::make_pair(true, device_dimension);
}
}
return std::make_pair(false, std::string{"Device size is not correct"});
}
Expand Down Expand Up @@ -3293,7 +3297,7 @@ repack --design_constraints ${OPENFPGA_REPACK_CONSTRAINTS}

build_architecture_bitstream --verbose \
--write_file fabric_independent_bitstream.xml

build_fabric_bitstream

write_fabric_verilog --file BIT_SIM \
Expand Down Expand Up @@ -3438,15 +3442,15 @@ std::string CompilerOpenFPGA::FinishOpenFPGAScript(const std::string& script) {
// Don't skip
result = ReplaceAll(result, "${VPR_PB_PIN_FIXUP}", "off");
}
if (m_OpenFpgaBitstreamSettingFile.string().empty()) {
if (m_runtime_OpenFpgaBitstreamSettingFile.string().empty()) {
result = ReplaceAll(result, "${OPENFPGA_BITSTREAM_SETTING_FILE}", "");
} else {
result = ReplaceAll(result, "${OPENFPGA_BITSTREAM_SETTING_FILE}",
"read_openfpga_bitstream_setting -f " +
m_OpenFpgaBitstreamSettingFile.string());
m_runtime_OpenFpgaBitstreamSettingFile.string());
}
result = ReplaceAll(result, "${OPENFPGA_BITSTREAM_SETTING_FILE}",
m_OpenFpgaBitstreamSettingFile.string());
m_runtime_OpenFpgaBitstreamSettingFile.string());
result = ReplaceAll(result, "${OPENFPGA_PIN_CONSTRAINTS}",
m_OpenFpgaPinConstraintXml.string());

Expand Down Expand Up @@ -3568,6 +3572,39 @@ bool CompilerOpenFPGA::GenerateBitstream() {
// Force bitstream generation
}

// Before generating fabric bitstream script, determine the runtime bitstream
// setting file which might include the runtime design IO tile clock out
std::pair<bool, std::string> io_status = IsDeviceSizeCorrect(m_deviceSize);
if (io_status.first) {
std::filesystem::path design_edit_sdc =
FilePath(Action::Synthesis, "design_edit.sdc");
if (std::filesystem::exists(design_edit_sdc)) {
std::string command = CFG_print(
"model_config gen_bitstream_setting_xml -device_size %s -design %s "
"-pin %s "
"%s bitstream_setting.xml",
io_status.second.c_str(), design_edit_sdc.c_str(),
m_PinMapCSV.c_str(), m_OpenFpgaBitstreamSettingFile.c_str());
auto file =
ProjManager()->projectName() + "_gen_bitstream_setting_xml_cmd.tcl";
FileUtils::WriteToFile(file, command);
command = CFG_print("source %s", file.c_str());
int status = TCL_OK;
m_interp->evalCmd(command, &status);
if (status != TCL_OK) {
ErrorMessage("Design " + ProjManager()->projectName() +
" Bitstream Setting XML generation failed");
return false;
} else {
m_runtime_OpenFpgaBitstreamSettingFile = "bitstream_setting.xml";
}
} else {
m_runtime_OpenFpgaBitstreamSettingFile = m_OpenFpgaBitstreamSettingFile;
}
} else {
m_runtime_OpenFpgaBitstreamSettingFile = m_OpenFpgaBitstreamSettingFile;
}

std::string command = m_openFpgaExecutablePath.string() + " -batch -f " +
ProjManager()->projectName() + ".openfpga";

Expand Down
1 change: 1 addition & 0 deletions src/Compiler/CompilerOpenFPGA.h
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,7 @@ class CompilerOpenFPGA : public Compiler {
std::filesystem::path m_routingGraphFile = "";
std::filesystem::path m_OpenFpgaSimSettingFile = "";
std::filesystem::path m_OpenFpgaBitstreamSettingFile = "";
std::filesystem::path m_runtime_OpenFpgaBitstreamSettingFile = "";
std::filesystem::path m_OpenFpgaRepackConstraintsFile = "";
std::filesystem::path m_OpenFpgaFabricKeyFile = "";
std::filesystem::path m_OpenFpgaPinMapXml = "";
Expand Down
1 change: 1 addition & 0 deletions src/Configuration/ModelConfig/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ add_library(
ModelConfig.cpp
ModelConfig_IO_resource.cpp
ModelConfig_IO.cpp
ModelConfig_BITSTREAM_SETTING_XML.cpp
)

###################
Expand Down
9 changes: 8 additions & 1 deletion src/Configuration/ModelConfig/ModelConfig.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "CFGCommon/CFGCommon.h"
#include "DeviceModeling/Model.h"
#include "DeviceModeling/device.h"
#include "ModelConfig_BITSTREAM_SETTING_XML.h"
#include "ModelConfig_IO.h"
#include "nlohmann_json/json.hpp"

Expand Down Expand Up @@ -911,7 +912,13 @@ void model_config_entry(CFGCommon_ARG* cmdarg) {
&cmdarg->raws[0], flag_options, options, positional_options,
{"is_unittest"}, {"netlist_ppdb", "config_mapping"},
{"property_json", "pll_workaround"}, 1);
ModelConfig_IO io(cmdarg, flag_options, options, positional_options[0]);
ModelConfig_IO io(flag_options, options, positional_options[0]);
} else if (cmdarg->raws[0] == "gen_bitstream_setting_xml") {
CFGArg::parse("model_config|gen_bitstream_setting_xml", cmdarg->raws.size(),
&cmdarg->raws[0], flag_options, options, positional_options,
{"is_unittest"}, {"device_size", "design", "pin"}, {}, 2);
ModelConfig_BITSREAM_SETTINGS_XML::gen(
flag_options, options, positional_options[0], positional_options[1]);
} else if (cmdarg->raws[0] == "backdoor") {
CFGArg::parse("model_config|gen_ppdb", cmdarg->raws.size(),
&cmdarg->raws[0], flag_options, options, positional_options,
Expand Down
148 changes: 148 additions & 0 deletions src/Configuration/ModelConfig/ModelConfig_BITSTREAM_SETTING_XML.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
/*
Copyright 2023 The Foedag team

GPL License

Copyright (c) 2023 The Open-Source FPGA Foundation

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

#include "ModelConfig_BITSTREAM_SETTING_XML.h"

#include <fstream>
#include <iostream>

namespace FOEDAG {

struct PIN_TABLE_INFO {
PIN_TABLE_INFO() {}
PIN_TABLE_INFO(uint32_t i) : fabric_clk_index(i) {}
uint32_t fabric_clk_index = 0;
uint32_t x = 0;
uint32_t y = 0;
std::string type = "";
};

/*
Generate bitstream setting XML
*/
void ModelConfig_BITSREAM_SETTINGS_XML::gen(
const std::vector<std::string>& flag_options,
const std::map<std::string, std::string>& options, const std::string& input,
const std::string& output) {
bool is_unittest = std::find(flag_options.begin(), flag_options.end(),
"is_unittest") != flag_options.end();
std::vector<std::string> device_sizes =
CFG_split_string(options.at("device_size"), "x");
if (device_sizes.size() == 2) {
uint32_t device_x = (uint32_t)(CFG_convert_string_to_u64(device_sizes[0]));
uint32_t device_y = (uint32_t)(CFG_convert_string_to_u64(device_sizes[1]));
std::ifstream design(options.at("design").c_str());
CFG_ASSERT(design.is_open() && design.good());
std::string line = "";
std::map<std::string, PIN_TABLE_INFO> location_map;
while (std::getline(design, line)) {
CFG_get_rid_trailing_whitespace(line);
if (line.size() > 0 && line.find("set_core_clk") == 0) {
std::vector<std::string> words = CFG_split_string(line, " ", 0, false);
CFG_ASSERT(words.size() == 3);
CFG_ASSERT(words[0] == "set_core_clk");
CFG_ASSERT(location_map.find(words[1]) == location_map.end());
uint32_t index = (uint32_t)(CFG_convert_string_to_u64(words[2]));
location_map[words[1]] = PIN_TABLE_INFO(index);
}
}
design.close();
if (location_map.size()) {
std::ifstream pin(options.at("pin").c_str());
CFG_ASSERT(pin.is_open() && pin.good());
while (std::getline(pin, line)) {
CFG_get_rid_trailing_whitespace(line);
std::vector<std::string> words = CFG_split_string(line, ",");
if (words.size() >= 11 && words[2].size() > 0) {
auto iter = location_map.find(words[2]);
if (iter != location_map.end()) {
iter->second.x = (uint32_t)(CFG_convert_string_to_u64(words[9]));
iter->second.y = (uint32_t)(CFG_convert_string_to_u64(words[10]));
}
}
}
pin.close();
}
std::ofstream oxml(output.c_str());
if (input.size() && std::filesystem::exists(input.c_str())) {
std::ifstream ixml(input.c_str());
CFG_ASSERT(ixml.is_open());
CFG_ASSERT(ixml.good());
if (is_unittest) {
oxml << "<!-- Original XML: Unit Test Input -->\n";
} else {
oxml << "<!-- Original XML: " << input.c_str() << " -->\n";
}
bool found_xml_end = false;
while (std::getline(ixml, line)) {
std::string xml_line = line;
CFG_get_rid_whitespace(xml_line);
if (xml_line.find("</openfpga_bitstream_setting>") == 0) {
found_xml_end = true;
break;
}
oxml << line.c_str() << "\n";
}
ixml.close();
CFG_ASSERT(found_xml_end);
} else {
oxml << "<openfpga_bitstream_setting>\n";
}
oxml << " <overwrite_bitstream>\n";
for (auto& iter : location_map) {
if ((iter.second.y == 1 || iter.second.y == (device_y - 2)) &&
iter.second.x >= 2 && iter.second.x < (device_x - 2)) {
iter.second.type = iter.second.y == 1 ? "bottom" : "top";
} else if ((iter.second.x == 1 || iter.second.x == (device_x - 2)) &&
iter.second.y >= 2 && iter.second.y < (device_y - 2)) {
iter.second.type = iter.second.x == 1 ? "left" : "right";
}
if (iter.second.type.size()) {
oxml << CFG_print(
" <!-- Location: %s, Value: %d, X: %d, Y: %d -->\n",
iter.first.c_str(), iter.second.fabric_clk_index,
iter.second.x, iter.second.y)
.c_str();
for (int i = 0; i < 4; i++) {
oxml << CFG_print(
" <bit value=\"%d\" "
"path=\"fpga_top.grid_io_%s_%d__%d_.logical_tile_io_mode_"
"io__0.mem_iopad_0_clk_0[%d]\"/>\n",
(iter.second.fabric_clk_index & (1 << i)) ? 1 : 0,
iter.second.type.c_str(), iter.second.x, iter.second.y, i)
.c_str();
}
} else {
oxml << CFG_print(
" <!-- Unknown location: %s, Value: %d, X: %d, Y: %d "
"-->\n",
iter.first.c_str(), iter.second.fabric_clk_index,
iter.second.x, iter.second.y)
.c_str();
}
}
oxml << " </overwrite_bitstream>\n";
oxml << "</openfpga_bitstream_setting>\n";
oxml.close();
}
}

} // namespace FOEDAG
44 changes: 44 additions & 0 deletions src/Configuration/ModelConfig/ModelConfig_BITSTREAM_SETTING_XML.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
Copyright 2023 The Foedag team

GPL License

Copyright (c) 2023 The Open-Source FPGA Foundation

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

#ifndef MODEL_CONFIG_BITSTREAM_SETTING_XML_H
#define MODEL_CONFIG_BITSTREAM_SETTING_XML_H

#include <Configuration/CFGCommon/CFGCommon.h>

#include <map>
#include <string>
#include <vector>

namespace FOEDAG {

class ModelConfig_BITSREAM_SETTINGS_XML {
public:
static void gen(const std::vector<std::string>& flag_options,
const std::map<std::string, std::string>& options,
const std::string& input, const std::string& output);

private:
};

} // namespace FOEDAG

#endif
2 changes: 1 addition & 1 deletion src/Configuration/ModelConfig/ModelConfig_IO.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ namespace FOEDAG {
Constructor
*/
ModelConfig_IO::ModelConfig_IO(
CFGCommon_ARG* cmdarg, const std::vector<std::string>& flag_options,
const std::vector<std::string>& flag_options,
const std::map<std::string, std::string>& options,
const std::string& output) {
std::string netlist_ppdb = options.at("netlist_ppdb");
Expand Down
4 changes: 1 addition & 3 deletions src/Configuration/ModelConfig/ModelConfig_IO.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "ModelConfig_IO_resource.h"
#include "nlohmann_json/json.hpp"

struct CFGCommon_ARG;
struct ModelConfig_IO_MSG;

// clang-format off
Expand Down Expand Up @@ -78,8 +77,7 @@ namespace FOEDAG {

class ModelConfig_IO {
public:
ModelConfig_IO(CFGCommon_ARG* cmdarg,
const std::vector<std::string>& flag_options,
ModelConfig_IO(const std::vector<std::string>& flag_options,
const std::map<std::string, std::string>& options,
const std::string& output);
~ModelConfig_IO();
Expand Down
1 change: 1 addition & 0 deletions tests/unittest/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ set(CPP_LIST
CFGCompiler/CFGCompiler_test.cpp
ModelConfig/ModelConfig_test.cpp
ModelConfig/ModelConfig_IO_test.cpp
ModelConfig/ModelConfig_BITSTREAM_SETTING_XML_test.cpp
CFGProgrammer/CFGProgrammer_test.cpp
MainWindow/PerfomanceTracker_test.cpp
MainWindow/ProjectFileComponent_test.cpp
Expand Down
Loading
Loading