From e26e4e457a3a5283dbaf50e4fc9b00a4773f329f Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Thu, 13 Aug 2026 12:54:46 +0200 Subject: [PATCH] Initial driver WIP --- CMakeLists.txt | 8 ++ kernel/CMakeLists.txt | 10 ++ kernel/yc.cc | 265 ++++++++++++++++++++++++++++++++++++++++++ libs/CMakeLists.txt | 3 +- 4 files changed, 285 insertions(+), 1 deletion(-) create mode 100644 kernel/yc.cc diff --git a/CMakeLists.txt b/CMakeLists.txt index f358655c1..f2464309d 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 e6ca435be..3574fdc52 100644 --- a/kernel/CMakeLists.txt +++ b/kernel/CMakeLists.txt @@ -189,4 +189,14 @@ if (NOT YOSYS_BUILD_PYTHON_ONLY) essentials BOOTSTRAP ) + + yosys_core(yc + yc.cc + REQUIRES + essentials + LIBRARIES + fmt::fmt + slang::slang + BOOTSTRAP + ) endif() diff --git a/kernel/yc.cc b/kernel/yc.cc new file mode 100644 index 000000000..0e6c56aa1 --- /dev/null +++ b/kernel/yc.cc @@ -0,0 +1,265 @@ +/* + * 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" + +#include +#include + +YOSYS_NAMESPACE_BEGIN +extern void (*log_warning_callback)(std::string); + +using namespace slang; + +void log_driver_callback(LogMessage msg) +{ + FILE *f = stderr; + switch (msg.severity) { + case LOG_WARNING: + fmt::print(f, fg(fmt::terminal_color::bright_yellow), "{}", msg.prefix); + fmt::print(f, fg(fmt::terminal_color::blue) | fmt::emphasis::bold, "{}", msg.message); + break; + + case LOG_ERROR: + fmt::print(f, fg(fmt::terminal_color::bright_red), "{}", msg.prefix); + fmt::print(f, fg(fmt::terminal_color::blue) | fmt::emphasis::bold, "{}", msg.message); + break; + +// case LOG_HEADER: +// fmt::print(f, fg(fmt::terminal_color::cyan) | fmt::emphasis::bold, "{}", msg.prefix); +// fmt::print(f, fg(fmt::terminal_color::white) | fmt::emphasis::bold, "{}", msg.message); +// break; +// +// case LOG_COMMENT: +// case LOG_DEBUG: +// fmt::print(f, fg(fmt::terminal_color::bright_black), "{}{}", msg.prefix, msg.message); +// break; +// +// case LOG_INFO: + default: +// fmt::print(f, "{}{}", msg.prefix, msg.message); + break; + } +} + +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) { + log_error("%s\n", message); +} + +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,--out", 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"); +} + +extern void (*log_callback)(LogMessage msg); + +int YosysDriver::run(int argc, char **argv) { + log_callback = log_driver_callback; + + addStandardArgs(); + + log_suppressed(); + + if (!cmdLine.parse(argc, argv, {})) { + for (auto& err : cmdLine.getErrors()) { + //auto loc = err.location; + printError(err.message.c_str()); + } + printError("HERE\n"); + 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; + } + + 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; +} diff --git a/libs/CMakeLists.txt b/libs/CMakeLists.txt index 076390e23..91cde8cab 100644 --- a/libs/CMakeLists.txt +++ b/libs/CMakeLists.txt @@ -19,7 +19,7 @@ block() set(FETCHCONTENT_FULLY_DISCONNECTED ON) if(NOT YOSYS_USE_BUNDLED_LIBS) - find_package(fmt 12.2 QUIET) + find_package(fmt 12.2 QUIET GLOBAL) endif() if(fmt_FOUND) set(SLANG_USE_SYSTEM_FMT ON) @@ -31,6 +31,7 @@ block() SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/fmt ) FetchContent_MakeAvailable(fmt) + add_subdirectory(fmt) endif() if(NOT YOSYS_USE_BUNDLED_LIBS)