Skip to content

Commit

Permalink
Merge branch 'develop' into update-openfpga-v2.9.0-11NOV2024
Browse files Browse the repository at this point in the history
  • Loading branch information
coolbreeze413 committed Nov 15, 2024
2 parents 8dd1c57 + 5ea2156 commit 77f2050
Show file tree
Hide file tree
Showing 3 changed files with 207 additions and 22 deletions.
120 changes: 98 additions & 22 deletions src/Compiler/CompilerOpenFPGA_ql.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1742,32 +1742,105 @@ bool CompilerOpenFPGA_ql::Synthesize() {
}
}

// workaround for enabling usage of '-lib' option, suggested by yosyshq
// add the following line in the ys script:
fileList += std::string("verific -cfg veri_create_empty_box 1\n");

// ProjectManager::addIncludePath(const std::string& includePath)
for (auto path : ProjManager()->includePathList()) {
includes += FileUtils::AdjustPath(path) + " ";
}
fileList += "verific -vlog-incdir " + includes + "\n";
if(!includes.empty()) {
fileList += "verific -vlog-incdir " + includes + "\n";
}

// incdir:always add the project's 'sources' directory
// (works for GUI copy_to_project/ TCL copy_files_on_add cases)
std::filesystem::path design_sources_dir_path =
ProjManager()->ProjectFilesPath(ProjManager()->projectPath(),
ProjManager()->projectName(),
ProjManager()->getDesignActiveFileSet().toStdString());
fileList += "verific -vlog-incdir " + design_sources_dir_path.string() + "\n";

// incdir: if executed via TCL script, and copy_files_on_add is *not* set
// add the TCL script directory
std::filesystem::path tcl_script_dir_path =
QLSettingsManager::getTCLScriptDirPath();
if(!tcl_script_dir_path.empty()) {
if(!copyFilesOnAdd()) {
fileList += "verific -vlog-incdir " + tcl_script_dir_path.string() + "\n";
}
}

std::string libraries;
// ProjectManager::addLibraryPath(const std::string& libraryPath)
for (auto path : ProjManager()->libraryPathList()) {
libraries += FileUtils::AdjustPath(path) + " ";
}
fileList += "verific -vlog-libdir " + libraries + "\n";
if(!libraries.empty()) {
fileList += "verific -vlog-libdir " + libraries + "\n";
}

// -vlog-libdir : currently it does not solve anything, so it is commented out.
// std::filesystem::path device_yosys_modules_dir_path =
// QLDeviceManager::getInstance()->deviceYosysModulesDirPath() /
// QLDeviceManager::getInstance()->deviceYosysFamilyName();
// fileList += "verific -vlog-libdir " + device_yosys_modules_dir_path + "\n";

// recommendation by: <[email protected]>
// with the -vlog-libdir option, if verific can't find a module named "Foo",
// it will look in the given directory for a file named "Foo.v".
// if we want to use the -vlog-libdir option we would have to split
// the primitive library into one file per module.
// instead of using -vlog-libdir, we could use the existing files by
// reading them in with the -lib option like this:
// verific -vlog2k -lib /path/to/dsp_sim.v
// we should do this with all files that contain primitives that
// the user might want to instantiate manually, such as the BRAM sim files.
std::vector<std::filesystem::path> yosys_modules_pathlist =
QLDeviceManager::getInstance()->deviceYosysModulesPathList();

for (std::filesystem::path yosys_module_path : yosys_modules_pathlist) {

std::string sim_verilog_pattern = ".*_sim\\.v";

if (std::regex_match(yosys_module_path.filename().string(),
std::regex(sim_verilog_pattern, std::regex::icase))) {

fileList += std::string("verific -vlog2k -lib ") +
yosys_module_path.string() +
"\n";
}
}

// ProjectManager::addLibraryExtension(const std::string& libraryExt)
for (auto ext : ProjManager()->libraryExtensionList()) {
fileList += "verific -vlog-libext " + ext + "\n";
}

// ProjectManager::addMacro(const std::string& macroName,
// const std::string& macroValue)
std::string macros;
for (auto& macro_value : ProjManager()->macroList()) {
macros += macro_value.first + "=" + macro_value.second + " ";
}
fileList += "verific -vlog-define " + macros + "\n";
if(!macros.empty()) {
fileList += "verific -vlog-define " + macros + "\n";
}

std::string importLibs;
auto importDesignFilesLibs = false;

// this is available only if TCL command has specified a top module library
// with -work <libname>
// set_top_module <top> ?-work <libName>?
auto topModuleLib = ProjManager()->DesignTopModuleLib();

// this is available only if TCL command has specified a design library
// with -work <libname>
// add_design_file <file list> ?type? ?-work <libName>?
auto commandsLibs = ProjManager()->DesignLibraries();

size_t filesIndex{0};
for (const auto& lang_file : ProjManager()->DesignFiles()) {
std::string lang;
Expand Down Expand Up @@ -1830,18 +1903,21 @@ bool CompilerOpenFPGA_ql::Synthesize() {
if (!libName.empty()) {
auto commandLib = "-work " + libName + " ";
designLibraries += commandLib;
if (importDesignFilesLibs && libName != topModuleLib)
if (importDesignFilesLibs && libName != topModuleLib) {
importLibs += "-L " + libName + " ";
}
}
}
}
++filesIndex;

if (designLibraries.empty())
if (designLibraries.empty()) {
fileList += "verific " + lang + " " + lang_file.second + "\n";
else
}
else {
fileList +=
"verific " + designLibraries + lang + " " + lang_file.second + "\n";
}
}
auto topModuleLibImport = std::string{};
if (!topModuleLib.empty())
Expand Down Expand Up @@ -1946,20 +2022,16 @@ bool CompilerOpenFPGA_ql::Synthesize() {
ReplaceAll(yosysScript, "${TOP_MODULE_DIRECTIVE}", "-auto-top");
}

std::string family = QLSettingsManager::getStringValue("general", "device", "family");

if(family == "QLF_K6N10") {
yosysScript = ReplaceAll(yosysScript, "${FAMILY}", std::string("qlf_k6n10f"));
std::string yosys_family_name =
QLDeviceManager::getInstance()->deviceYosysFamilyName();
if(!yosys_family_name.empty()) {
yosysScript =
ReplaceAll(yosysScript, "${FAMILY}", yosys_family_name);
}
else if(family == "QLF_K4N8") {
yosysScript = ReplaceAll(yosysScript, "${FAMILY}", std::string("qlf_k4n8"));
else {
ErrorMessage("Yosys Family unknown for: " + QLDeviceManager::getInstance()->convertToDeviceString());
return false;
}
// ignore unknown family, as it might be customized in the template script.
// if yosys-plugins does not recognize the family, it will throw an error anyway.
//else {
// ErrorMessage("Unknown Family Specified: " + family);
// return false;
//}


// ---------------------------------------------------------------- synth_sdc_file ++
Expand Down Expand Up @@ -2140,10 +2212,14 @@ bool CompilerOpenFPGA_ql::Synthesize() {
}

// pass in the path to the device specific yosys libraries directly.
std::string device_data_path_yosys =
(QLDeviceManager::getInstance()->deviceTypeDirPath()).string() +
std::string("/yosys/quicklogic/");
yosys_options += " -lib_path " + device_data_path_yosys;
std::string yosys_modules_dir_path_string =
(QLDeviceManager::getInstance()->deviceYosysModulesDirPath()).string();
if (yosys_modules_dir_path_string.back() != '/') {
// tack on a '/' separator if it is missing to be safe:
yosys_modules_dir_path_string += "/";
}
yosys_options += " -lib_path " +
yosys_modules_dir_path_string;

// TODO: trim yosys_options at the front
yosysScript = ReplaceAll(yosysScript, "${YOSYS_OPTIONS}", yosys_options);
Expand Down
105 changes: 105 additions & 0 deletions src/Compiler/QLDeviceManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3537,4 +3537,109 @@ std::vector<std::filesystem::path> QLDeviceManager::deviceCornerPowerDataFiles(Q
return corner_power_data_filepaths;
}


std::filesystem::path QLDeviceManager::deviceYosysModulesDirPath(QLDeviceTarget device_target) {

if( !isDeviceTargetValid(device_target) ) {
device_target = this->device_target;
}

std::filesystem::path device_yosys_modules_dir_path;

device_yosys_modules_dir_path = deviceTypeDirPath(device_target) /
"yosys" /
"quicklogic";

return device_yosys_modules_dir_path;
}


std::string QLDeviceManager::deviceYosysFamilyName(QLDeviceTarget device_target) {

// CompilerOpenFPGA_ql* compiler = static_cast<CompilerOpenFPGA_ql*>(GlobalSession->GetCompiler());

if( !isDeviceTargetValid(device_target) ) {
device_target = this->device_target;
}

std::string device_yosys_family;

if(device_target.device_variant.family == "QLF_K6N10") {
device_yosys_family = "qlf_k6n10f";
}
else if(device_target.device_variant.family == "QLF_K4N8") {
device_yosys_family = "qlf_k4n8";
}

return device_yosys_family;
}


std::vector<std::filesystem::path> QLDeviceManager::deviceYosysModulesPathList(QLDeviceTarget device_target) {

// CompilerOpenFPGA_ql* compiler = static_cast<CompilerOpenFPGA_ql*>(GlobalSession->GetCompiler());

std::vector<std::filesystem::path> yosys_modules_pathlist;

if( !isDeviceTargetValid(device_target) ) {
device_target = this->device_target;
}

std::filesystem::path device_yosys_modules_dir_path;
std::string device_yosys_family;


if(device_target.device_variant.family == "QLF_K6N10") {
device_yosys_family = "qlf_k6n10f";
}

device_yosys_modules_dir_path = deviceYosysModulesDirPath(device_target) /
device_yosys_family;

std::error_code ec;
for (const std::filesystem::directory_entry& dir_entry :
std::filesystem::recursive_directory_iterator(device_yosys_modules_dir_path,
std::filesystem::directory_options::skip_permission_denied,
ec)) {
if(ec) {
std::cout << std::string("failed listing contents of ") +
device_yosys_modules_dir_path.string() << std::endl;
return yosys_modules_pathlist;
}

if(dir_entry.is_regular_file(ec)) {

// match modules types:
std::string verilog_pattern = ".*\\.v";
std::string sv_pattern = ".*\\.sv";
std::string txt_pattern = ".*\\.txt";

if (std::regex_match(dir_entry.path().filename().string(),
std::regex(verilog_pattern, std::regex::icase))) {
yosys_modules_pathlist.push_back(dir_entry.path());
}

if (std::regex_match(dir_entry.path().filename().string(),
std::regex(sv_pattern, std::regex::icase))) {
yosys_modules_pathlist.push_back(dir_entry.path());
}

if (std::regex_match(dir_entry.path().filename().string(),
std::regex(txt_pattern, std::regex::icase))) {
yosys_modules_pathlist.push_back(dir_entry.path());
}
}

if(ec) {
std::cout << std::string("error while checking: ") + dir_entry.path().string() << std::endl;
return yosys_modules_pathlist;
}
}

// sort the entries for easier processing
std::sort(yosys_modules_pathlist.begin(),yosys_modules_pathlist.end());

return yosys_modules_pathlist;
}

} // namespace FOEDAG
4 changes: 4 additions & 0 deletions src/Compiler/QLDeviceManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,10 @@ class QLDeviceManager : public QObject {
std::filesystem::path deviceTypeDirPath(QLDeviceTarget device_target = QLDeviceTarget());
std::filesystem::path deviceVariantDirPath(QLDeviceTarget device_target = QLDeviceTarget());

std::filesystem::path deviceYosysModulesDirPath(QLDeviceTarget device_target = QLDeviceTarget());
std::string deviceYosysFamilyName(QLDeviceTarget device_target = QLDeviceTarget());
std::vector<std::filesystem::path> deviceYosysModulesPathList(QLDeviceTarget device_target = QLDeviceTarget());

std::filesystem::path deviceYosysScriptFile(QLDeviceTarget device_target = QLDeviceTarget());
std::filesystem::path deviceOpenFPGAScriptFile(QLDeviceTarget device_target = QLDeviceTarget());

Expand Down

0 comments on commit 77f2050

Please sign in to comment.