/* * yosys -- Yosys Open SYnthesis Suite * * Copyright (C) 2025 Jannis Harder * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * */ #include "kernel/yosys.h" #include "passes/techmap/libparse.h" YOSYS_NAMESPACE_BEGIN // Read by convert_liberty_files_to_merged_scl() in liberty_cache.h bool scl_cache_enabled = true; std::string scl_cache_dir; YOSYS_NAMESPACE_END USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN struct LibcachePass : public Pass { LibcachePass() : Pass("libcache", "control caching of technology library data parsed from liberty files") { } void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); log(" libcache {-enable|-disable|-purge} { -all | [path]... }\n"); log("\n"); log("Controls the default and per path caching of liberty file data.\n"); log("\n"); log(" -enable Enable caching.\n"); log(" -disable Disable caching.\n"); log(" -purge Reset cache setting and forget cached data.\n"); log("\n"); log("This mode takes a list of paths as argument. If no paths are provided, this\n"); log("command does nothing. The -all option can be used to change the default cache\n"); log("setting for -enable/-disable or to reset and forget about all paths.\n"); log("\n"); log("By default caching is disabled.\n"); log("\n"); log(" libcache -scl {-enable|-disable}\n"); log("\n"); log("Controls the on-disk cache of merged SCL files that the abc and abc9 passes\n"); log("generate from liberty files. By default this caching is enabled.\n"); log("\n"); log(" libcache -scl -dir [path]\n"); log("\n"); log("Stores the merged SCL files in [path] instead of a directory of this user in\n"); log("the temp directory. means a per user directory in the temp directory.\n"); log("\n"); log(" libcache -list\n"); log("\n"); log("Displays the current cache settings and cached paths.\n"); log("\n"); log(" libcache {-verbose|-quiet}\n"); log("\n"); log("Controls cache use logging.\n"); log("\n"); log(" -verbose Enable printing info when cache is used\n"); log(" -quiet Disable printing info when cache is used (default)\n"); log("\n"); } void execute(std::vector args, RTLIL::Design *) override { bool enable = false; bool disable = false; bool purge = false; bool all = false; bool scl = false; bool list = false; bool verbose = false; bool quiet = false; bool dir = false; std::string dir_path; std::vector paths; size_t argidx; for (argidx = 1; argidx < args.size(); argidx++) { if (args[argidx] == "-enable") { enable = true; continue; } if (args[argidx] == "-disable") { disable = true; continue; } if (args[argidx] == "-scl") { scl = true; continue; } if (args[argidx] == "-purge") { purge = true; continue; } if (args[argidx] == "-all") { all = true; continue; } if (args[argidx] == "-list") { list = true; continue; } if (args[argidx] == "-verbose") { verbose = true; continue; } if (args[argidx] == "-quiet") { quiet = true; continue; } if (args[argidx] == "-dir") { if (argidx+1 >= args.size()) log_cmd_error("The -dir option needs a path.\n"); dir = true; dir_path = args[++argidx]; continue; } append_globbed(paths, args[argidx]); break; } int modes = enable + disable + purge + list + verbose + quiet + dir; if (modes == 0) log_cmd_error("At least one of -enable, -disable, -purge, -list,\n-verbose, -quiet, or -dir is required.\n"); if (modes > 1) log_cmd_error("Only one of -enable, -disable, -purge, -list,\n-verbose, -quiet, or -dir may be present.\n"); if (all && !paths.empty()) log_cmd_error("The -all option cannot be combined with a list of paths.\n"); if (list && (all || !paths.empty())) log_cmd_error("The -list mode takes no further options.\n"); if (scl && !(enable || disable || dir)) log_cmd_error("The -scl option can only be combined with -enable, -disable, or -dir.\n"); if (dir && !scl) log_cmd_error("The -dir option requires -scl.\n"); if (scl && (all || !paths.empty())) log_cmd_error("The -scl option cannot be combined with -all or a list of paths.\n"); if (!list && !all && !scl && paths.empty()) log("No paths specified, use -all to %s\n", purge ? "purge all paths" : "change the default setting"); if (list) { log("Caching is %s by default.\n", LibertyAstCache::instance.cache_by_default ? "enabled" : "disabled"); log("SCL caching is %s.\n", scl_cache_enabled ? "enabled" : "disabled"); if (scl_cache_dir.empty()) log("SCL files are cached in a directory of this user in the temp directory.\n"); else log("SCL files are cached in `%s'.\n", scl_cache_dir); for (auto const &entry : LibertyAstCache::instance.cache_path) log("Caching is %s for `%s'.\n", entry.second ? "enabled" : "disabled", entry.first); for (auto const &entry : LibertyAstCache::instance.cached) log("Data for `%s' is currently cached.\n", entry.first); } else if (enable || disable) { if (scl) { scl_cache_enabled = enable; } else if (all) { LibertyAstCache::instance.cache_by_default = enable; } else { for (auto const &path : paths) { LibertyAstCache::instance.cache_path[path] = enable; } } } else if (purge) { if (all) { LibertyAstCache::instance.cached.clear(); LibertyAstCache::instance.cache_path.clear(); } else { for (auto const &path : paths) { LibertyAstCache::instance.cached.erase(path); LibertyAstCache::instance.cache_path.erase(path); } } } else if (dir) { rewrite_filename(dir_path); if (dir_path.empty()) { scl_cache_dir.clear(); } else { scl_cache_dir = absolute_path(dir_path); if (scl_cache_dir.empty()) log_cmd_error("Cannot make `%s' an absolute path.\n", dir_path); } } else if (verbose) { LibertyAstCache::instance.verbose = true; } else if (quiet) { LibertyAstCache::instance.verbose = false; } else { log_assert(false); } } } LibcachePass; PRIVATE_NAMESPACE_END