diff --git a/passes/techmap/liberty_cache.h b/passes/techmap/liberty_cache.h index 2197f9125..8ae89947f 100644 --- a/passes/techmap/liberty_cache.h +++ b/passes/techmap/liberty_cache.h @@ -2,10 +2,12 @@ #define LIBERTY_CACHE_H #include "kernel/yosys.h" -#include -#include -#include -#include + +#ifdef YOSYS_LINK_ABC +namespace abc { + int Abc_RealMain(int argc, char *argv[]); +} +#endif YOSYS_NAMESPACE_BEGIN @@ -17,14 +19,18 @@ YOSYS_NAMESPACE_BEGIN * * Return: Path to merged SCL cache file, or empty string if conversion fails */ -#if defined(YOSYS_LINK_ABC) -inline std::string convert_liberty_files_to_merged_scl(const std::vector &, const std::string &, const std::string &) { return ""; } -#else inline std::string convert_liberty_files_to_merged_scl(const std::vector &liberty_files, const std::string &dont_use_args, const std::string &abc_exe) { if (liberty_files.empty()) return ""; + std::string cache_dir = get_base_tmpdir() + "/yosys-liberty-scl-cache"; + + if (!create_directory(cache_dir)) { + log_warning("ABC: cannot create cache directory %s, falling back to liberty format\n", cache_dir.c_str()); + return ""; + } + // Sort to ensure consistent hash regardless of order std::vector sorted_files = liberty_files; std::sort(sorted_files.begin(), sorted_files.end()); @@ -34,7 +40,7 @@ inline std::string convert_liberty_files_to_merged_scl(const std::vector= newest_mtime) { - log("ABC: Using cached merged SCL: %s (%zu files)\n", merged_scl.c_str(), liberty_files.size()); + log("ABC: using cached merged SCL: %s (%zu files)\n", merged_scl.c_str(), liberty_files.size()); need_convert = false; } } if (need_convert) { // read_lib -X cell1 -X cell2 file1 ; read_lib -X cell1 -X cell2 -m file2 ; ... ; write_scl merged.scl + std::string temp_scl = merged_scl + ".tmp"; + +#ifdef YOSYS_LINK_ABC + std::string script_path = stringf("%s/yosys_merged_scl_convert_%08x.script", cache_dir.c_str(), hash); + FILE *f = fopen(script_path.c_str(), "w"); + + if (f == NULL) { + log_warning("ABC: cannot open %s for writing, falling back to liberty format\n", script_path.c_str()); + return ""; + } + + bool first = true; + + for (const std::string &liberty_file : liberty_files) { + fprintf(f, "read_lib %s%s-w \"%s\"\n", dont_use_args.c_str(), first ? "" : "-m ", liberty_file.c_str()); + first = false; + } + + fprintf(f, "write_scl \"%s\"\n", temp_scl.c_str()); + fclose(f); + + char *abc_argv[5]; + abc_argv[0] = strdup(abc_exe.empty() ? "yosys-abc" : abc_exe.c_str()); + abc_argv[1] = strdup("-s"); + abc_argv[2] = strdup("-f"); + abc_argv[3] = strdup(script_path.c_str()); + abc_argv[4] = 0; + int ret = abc::Abc_RealMain(4, abc_argv); + free(abc_argv[0]); + free(abc_argv[1]); + free(abc_argv[2]); + free(abc_argv[3]); + remove(script_path.c_str()); + + if (ret != 0) { + log_warning("ABC: merged SCL conversion failed (ret=%d), falling back to liberty format\n", ret); + remove(temp_scl.c_str()); + return ""; + } +#else std::string abc_script; bool first = true; @@ -80,23 +116,22 @@ inline std::string convert_liberty_files_to_merged_scl(const std::vector&1", abc_exe.c_str(), abc_script.c_str()); std::string abc_output; int ret = run_command(cmd, [&abc_output](const std::string &line) { abc_output += line + "\n"; }); if (ret != 0) { - log_warning("ABC: Merged SCL conversion failed, falling back to liberty format\n"); + log_warning("ABC: merged SCL conversion failed, falling back to liberty format\n"); if (!abc_output.empty()) { - log("ABC conversion output:\n%s", abc_output.c_str()); + log("ABC: conversion output:\n%s", abc_output.c_str()); } remove(temp_scl.c_str()); return ""; } - +#endif if (rename(temp_scl.c_str(), merged_scl.c_str()) != 0) { - log_warning("ABC: Failed to rename %s to %s, falling back to liberty format\n", temp_scl.c_str(), merged_scl.c_str()); + log_warning("ABC: failed to rename %s to %s, falling back to liberty format\n", temp_scl.c_str(), merged_scl.c_str()); remove(temp_scl.c_str()); return ""; } @@ -104,8 +139,7 @@ inline std::string convert_liberty_files_to_merged_scl(const std::vector