From 721f1a3cc01f80ec6aebb396206bc312e194e2fd Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Fri, 7 Aug 2026 10:10:59 +0200 Subject: [PATCH] WIP --- CMakeLists.txt | 8 ++ kernel/CMakeLists.txt | 9 ++ kernel/log.cc | 5 + kernel/yc.cc | 236 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 258 insertions(+) create mode 100644 kernel/yc.cc diff --git a/CMakeLists.txt b/CMakeLists.txt index 3771394b2..c16d0b88c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -415,6 +415,7 @@ endif() yosys_expand_components(library_components essentials ${YOSYS_COMPONENTS}) if (NOT YOSYS_BUILD_PYTHON_ONLY) yosys_expand_components(driver_components driver ${YOSYS_COMPONENTS}) + yosys_expand_components(yc_components yc ${YOSYS_COMPONENTS}) endif() # Main Yosys executable (compiler driver). @@ -438,6 +439,13 @@ if (NOT YOSYS_BUILD_PYTHON_ONLY) endif() target_compile_options(yosys PRIVATE -fsanitize=undefined) + + yosys_cxx_executable(yc + OUTPUT_NAME yc + INSTALL_IF ${YOSYS_INSTALL_DRIVER} + ) + yosys_link_components(yc PRIVATE ${yc_components}) + target_compile_options(yc PRIVATE -fsanitize=undefined) endif() # Yosys components as a library. diff --git a/kernel/CMakeLists.txt b/kernel/CMakeLists.txt index 4cd76b4ff..b994b9662 100644 --- a/kernel/CMakeLists.txt +++ b/kernel/CMakeLists.txt @@ -187,4 +187,13 @@ if (NOT YOSYS_BUILD_PYTHON_ONLY) essentials BOOTSTRAP ) + + yosys_core(yc + yc.cc + REQUIRES + essentials + LIBRARIES + slang::slang + BOOTSTRAP + ) endif() diff --git a/kernel/log.cc b/kernel/log.cc index 2c3e45c2b..c06ca2bb9 100644 --- a/kernel/log.cc +++ b/kernel/log.cc @@ -251,6 +251,8 @@ void log_formatted_header(RTLIL::Design *design, std::string_view format, std::s log_files.pop_back(); } +void (*log_warning_callback)(std::string); + void log_formatted_warning(std::string_view prefix, std::string message) { log_assert(!Multithreading::active()); @@ -287,6 +289,9 @@ void log_formatted_warning(std::string_view prefix, std::string message) warning_match = true; } + if (log_warning_callback) + log_warning_callback(stringf("%s%s", prefix, message)); + if (log_warnings.count(message)) { log("%s%s", prefix, message); diff --git a/kernel/yc.cc b/kernel/yc.cc new file mode 100644 index 000000000..5e563dcd8 --- /dev/null +++ b/kernel/yc.cc @@ -0,0 +1,236 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2012 Claire Xenia Wolf + * + * 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 "slang/util/CommandLine.h" + +YOSYS_NAMESPACE_BEGIN +extern void (*log_warning_callback)(std::string); + +using namespace slang; + +void yosys_atexit() { + printf("error: %s\n", log_last_error.c_str()); +} + +void yosys_warning(std::string msg) { + printf("warning: %s\n", msg.c_str()); +} + +class YosysDriver { +public: + CommandLine cmdLine; + + struct Options { + std::optional showHelp; + std::optional showVerbose; + std::optional showVersion; + std::optional printTargets; + std::optional printDevices; + std::optional printLanguages; + std::optional printStandards; + + std::vector defines; + std::vector undefines; + std::optional topModule; + std::optional outputFile; + std::optional target; + std::optional device; + } options; + + std::vector sourceFiles; + + std::string language; + std::string standard; + + void addStandardArgs(); + int run(int argc, char **argv); + void printError(const std::string& message); +}; + +void YosysDriver::printError(const std::string& message) { + printf("error: %s\n", message.c_str()); +} + +void YosysDriver::addStandardArgs() { + cmdLine.add("-h,--help", options.showHelp, "Display available options"); + cmdLine.add("--version", options.showVersion, "Display version information and exit"); + cmdLine.add("-x", + [this](std::string_view value) { + language = value; + return ""; + }, + "Treat subsequent input files as having type ", ""); + cmdLine.add("--std", + [this](std::string_view value) { + standard = value; + return ""; + }, + "Language standard to compile for", ""); + cmdLine.add("-o", options.outputFile, "Write the design netlist to ", ""); + cmdLine.add("--top", options.topModule, + "Top-level module to instantiate " + "(instead of figuring it out automatically)", + ""); + + cmdLine.add("--target", options.target, + "Generate netlist for the given target", + ""); + cmdLine.add("--mdevice", options.device, + "For a list of available devices use '--print-supported-devices'", + ""); + cmdLine.add("-D", options.defines, + "Define preprocessor symbol to (empty if ommitted)", + "[=]", + CommandLineFlags::CommaList); + cmdLine.add("-U", options.undefines, + "Undefine preprocessor symbol ", + "", + CommandLineFlags::CommaList); + cmdLine.add("--print-languages", options.printLanguages, "Print available languages"); + cmdLine.add("--print-standards", options.printStandards, "Print available standards for language"); + cmdLine.add("--print-targets", options.printTargets, "Print available targets"); + cmdLine.add("--print-supported-devices", options.printDevices, "Print supported devices per target"); + cmdLine.add("-v,--verbose", options.showVerbose, "Verbose output"); + cmdLine.setPositional( + [this](std::string_view value) { + sourceFiles.push_back(std::string(value)); + return ""; + }, + "files"); +} + +int YosysDriver::run(int argc, char **argv) { + addStandardArgs(); + + log_suppressed(); + + if (!cmdLine.parse(argc, argv, {})) { + for (auto& err : cmdLine.getErrors()) { + //auto loc = err.location; + printError(err.message.c_str()); + } + return 1; + } + + if (options.showVerbose) { + log_files.push_back(stdout); + log_error_stderr = true; + } + + if (options.showHelp) { + printf("%s\n", cmdLine.getHelpText("Yosys compiler").c_str()); + return 0; + } + + if (options.showVersion) { + printf("%s\n", yosys_version_str); + return 0; + } + if (options.printLanguages) { + printf("Registered Languages:\n"); + printf(" verilog - Verilog (default)\n"); + printf(" sv - SystemVerilog\n"); + printf(" vhdl - VHDL\n"); + return 0; + } + if (options.printStandards) { + printf("Registered Standards for '%s':\n", "verilog"); + printf(" 1995 - Verilog 1364-1995\n"); + printf(" 2001 - Verilog 1364-2001\n"); + printf(" 2005 - Verilog 1364-2005\n"); + //printf(" 2005 - SystemVerilog 1800-2005\n"); + //printf(" 2009 - SystemVerilog 1800-2009\n"); + //printf(" 2012 - SystemVerilog 1800-2012\n"); + //printf(" 2017 - SystemVerilog 1800-2017\n"); + //printf(" 2023 - SystemVerilog 1800-2023\n"); + } + + if (options.printTargets) { + printf("Registered Targets:\n"); + printf(" ice40 - Lattice iCE 40\n"); + printf(" ecp5 - Lattice ECP5\n"); + return 0; + } + + if (!options.target) { + printError("Target is not specified."); + return 1; + } + if (options.printDevices) { + printf("Available devices for this target:\n"); + //printf(" ice40 - Lattice iCE 40\n"); + return 0; + } + + log_error_atexit = yosys_atexit; + log_warning_callback = yosys_warning; + if (!sourceFiles.size()) { + printError("no input files"); + return 2; + } + if (!options.outputFile) { + printError("no output file"); + return 2; + } + + run_pass("read -noverific"); + if (!options.defines.empty()) { + for (auto vdef : options.defines) + run_pass("read -define " + vdef); + } + if (!options.undefines.empty()) { + for (auto vdef : options.undefines) + run_pass("read -undef " + vdef); + } + + for (auto fn : sourceFiles) + run_frontend(fn.c_str(), "auto"); + + if (options.topModule) + run_pass(stringf("hierarchy -top %s", options.topModule.value())); + + run_pass(stringf("synth_%s", options.target.value())); + + run_backend(options.outputFile.value(), "auto"); + + yosys_design->check(); + for (auto it : saved_designs) + it.second->check(); + for (auto it : pushed_designs) + it->check(); + + log_flush(); + return 0; +} + +YOSYS_NAMESPACE_END + + +USING_YOSYS_NAMESPACE + +int main(int argc, char **argv) +{ + yosys_setup(); + YosysDriver driver; + int ret = driver.run(argc, argv); + yosys_shutdown(); + return ret; +}