mirror of https://github.com/llvm/circt.git
[ImportVerilog] Add Slang frontend dependency (#6620)
This is the first PR in a longer chain that adds basic SV support to CIRCT. Add the Slang Verilog frontend as a CIRCT dependency. This will be the foundation for CIRCT's Verilog parsing, elaboration, type checking, and lowering to the core dialects. By default, Slang is built as a static library from scratch, which is then linked into the new `ImportVerilog` conversion. Alternatively, CIRCT can also be linked against a local Slang installation provided by the system. Add the `ImportVerilog` conversion library. This library statically links in the Slang dependency and wraps it in an exception-safe, LLVM-style API. Currently this only consists of the `getSlangVersion` function and the necessary linking flags to get it to link statically against Slang. Add the `circt-verilog` tool, which will provide a fully-flegded interface to the new `ImportVerilog` library. Later on we'll also add an MLIR translation library for single-file SV import. But in general, SV builds take a lot of command line options (macros, search paths, etc.) and multiple input files, which is why we have a dedicated tool. All the tool does at the moment is print the linked Slang version. More to come. Note that this intentionally links against **version 3** of Slang. Newer versions are available -- 4 and 5 as of this commit -- but they rely on fairly new C++ compiler features that didn't work out of the box in our CI images. We'll eventually want to upgrade, but for now Slang 3 is sufficient to get the ball rolling. See https://github.com/MikePopoloski/slang for details on Slang. Co-authored-by: ShiZuoye <albertethon@163.com> Co-authored-by: hunterzju <hunter_ht@zju.edu.cn> Co-authored-by: 孙海龙 <hailong.sun@terapines.com>
This commit is contained in:
parent
962fddb9ba
commit
3d8b7d08d9
|
@ -220,7 +220,8 @@ jobs:
|
|||
-DCMAKE_CXX_COMPILER=${{ matrix.compiler.cxx }} \
|
||||
-DLLVM_EXTERNAL_LIT=`pwd`/../llvm/build/bin/llvm-lit \
|
||||
-DCMAKE_EXPORT_COMPILE_COMMANDS=ON \
|
||||
-DLLVM_LIT_ARGS="-v"
|
||||
-DLLVM_LIT_ARGS="-v" \
|
||||
-DCIRCT_SLANG_FRONTEND_ENABLED=ON
|
||||
ninja check-circt check-circt-unit -j$(nproc)
|
||||
ninja circt-doc
|
||||
|
||||
|
|
|
@ -96,7 +96,8 @@ jobs:
|
|||
-DMLIR_ENABLE_BINDINGS_PYTHON=ON \
|
||||
-DCIRCT_BINDINGS_PYTHON_ENABLED=ON \
|
||||
-DESI_RUNTIME=ON \
|
||||
-DLLVM_LIT_ARGS="-v --show-unsupported ${{ matrix.lit-flags }}"
|
||||
-DLLVM_LIT_ARGS="-v --show-unsupported ${{ matrix.lit-flags }}" \
|
||||
-DCIRCT_SLANG_FRONTEND_ENABLED=ON
|
||||
- name: Test CIRCT
|
||||
run: |
|
||||
ninja -C build check-circt -j$(nproc)
|
||||
|
|
|
@ -89,7 +89,8 @@ jobs:
|
|||
-DMLIR_ENABLE_BINDINGS_PYTHON=ON \
|
||||
-DCIRCT_BINDINGS_PYTHON_ENABLED=ON \
|
||||
-DESI_RUNTIME=ON \
|
||||
-DLLVM_LIT_ARGS="-v --show-unsupported"
|
||||
-DLLVM_LIT_ARGS="-v --show-unsupported" \
|
||||
-DCIRCT_SLANG_FRONTEND_ENABLED=ON
|
||||
- name: Test CIRCT
|
||||
run: |
|
||||
ninja -C build check-circt -j$(nproc)
|
||||
|
|
|
@ -177,7 +177,7 @@ jobs:
|
|||
${{ steps.setup-windows.outputs.setup }}
|
||||
mkdir build
|
||||
cd build
|
||||
cmake -G Ninja -S "$(pwd)/../llvm/llvm" $EXTRA_CMAKE_ARGS -DCMAKE_BUILD_TYPE=${{ inputs.cmake_build_type }} -DBUILD_SHARED_LIBS=${{ inputs.build_shared_libs }} -DLLVM_BUILD_TOOLS=ON -DLLVM_BUILD_EXAMPLES=OFF -DLLVM_ENABLE_ASSERTIONS=${{ inputs.llvm_enable_assertions }} -DLLVM_ENABLE_PROJECTS=mlir -DLLVM_EXTERNAL_PROJECTS=circt -DLLVM_EXTERNAL_CIRCT_SOURCE_DIR=".." -DLLVM_STATIC_LINK_CXX_STDLIB=ON -DLLVM_ENABLE_TERMINFO=OFF -DLLVM_PARALLEL_LINK_JOBS=1 -DLLVM_TARGETS_TO_BUILD="host" -DLLVM_FORCE_ENABLE_STATS=${{ inputs.llvm_force_enable_stats }} -DLLVM_ENABLE_ZSTD=OFF -DVERILATOR_DISABLE=ON -DLLVM_PARALLEL_LINK_JOBS=1 -DCIRCT_RELEASE_TAG_ENABLED=ON -DCIRCT_RELEASE_TAG=firtool -DCMAKE_EXPORT_COMPILE_COMMANDS=OFF -DCMAKE_C_COMPILER=${{ inputs.cmake_c_compiler }} -DCMAKE_CXX_COMPILER=${{ inputs.cmake_cxx_compiler }} ${{ steps.configure-sccache.outputs.enable_sccache }} -DCMAKE_INSTALL_PREFIX="$(pwd)/../install" -DLLVM_INSTALL_UTILS=ON
|
||||
cmake -G Ninja -S "$(pwd)/../llvm/llvm" $EXTRA_CMAKE_ARGS -DCMAKE_BUILD_TYPE=${{ inputs.cmake_build_type }} -DBUILD_SHARED_LIBS=${{ inputs.build_shared_libs }} -DLLVM_BUILD_TOOLS=ON -DLLVM_BUILD_EXAMPLES=OFF -DLLVM_ENABLE_ASSERTIONS=${{ inputs.llvm_enable_assertions }} -DLLVM_ENABLE_PROJECTS=mlir -DLLVM_EXTERNAL_PROJECTS=circt -DLLVM_EXTERNAL_CIRCT_SOURCE_DIR=".." -DLLVM_STATIC_LINK_CXX_STDLIB=ON -DLLVM_ENABLE_TERMINFO=OFF -DLLVM_PARALLEL_LINK_JOBS=1 -DLLVM_TARGETS_TO_BUILD="host" -DLLVM_FORCE_ENABLE_STATS=${{ inputs.llvm_force_enable_stats }} -DLLVM_ENABLE_ZSTD=OFF -DVERILATOR_DISABLE=ON -DLLVM_PARALLEL_LINK_JOBS=1 -DCIRCT_RELEASE_TAG_ENABLED=ON -DCIRCT_RELEASE_TAG=firtool -DCMAKE_EXPORT_COMPILE_COMMANDS=OFF -DCMAKE_C_COMPILER=${{ inputs.cmake_c_compiler }} -DCMAKE_CXX_COMPILER=${{ inputs.cmake_cxx_compiler }} ${{ steps.configure-sccache.outputs.enable_sccache }} -DCMAKE_INSTALL_PREFIX="$(pwd)/../install" -DLLVM_INSTALL_UTILS=ON -DCIRCT_SLANG_FRONTEND_ENABLED=ON
|
||||
# Optionally test
|
||||
- name: Test CIRCT
|
||||
if: inputs.runTests
|
||||
|
|
|
@ -25,6 +25,10 @@ if(POLICY CMP0116)
|
|||
cmake_policy(SET CMP0116 OLD)
|
||||
endif()
|
||||
|
||||
if(POLICY CMP0135)
|
||||
cmake_policy(SET CMP0135 NEW)
|
||||
endif()
|
||||
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED YES)
|
||||
|
||||
|
@ -523,6 +527,62 @@ if(CIRCT_BINDINGS_TCL_ENABLED)
|
|||
message(STATUS "Found TCL executable: ${TCL_TCLSH}")
|
||||
endif()
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# slang Verilog Frontend
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
option(CIRCT_SLANG_FRONTEND_ENABLED "Enables the slang Verilog frontend." OFF)
|
||||
option(CIRCT_SLANG_BUILD_FROM_SOURCE
|
||||
"Build slang from source instead of finding an installed package" ON)
|
||||
|
||||
llvm_canonicalize_cmake_booleans(CIRCT_SLANG_FRONTEND_ENABLED)
|
||||
llvm_canonicalize_cmake_booleans(CIRCT_SLANG_BUILD_FROM_SOURCE)
|
||||
|
||||
if(CIRCT_SLANG_FRONTEND_ENABLED)
|
||||
message(STATUS "slang Verilog frontend is enabled")
|
||||
if(CIRCT_SLANG_BUILD_FROM_SOURCE)
|
||||
# Build slang as part of CIRCT (see https://sv-lang.com/building.html)
|
||||
message(STATUS "Building slang from source")
|
||||
include(FetchContent)
|
||||
FetchContent_Declare(
|
||||
slang
|
||||
URL https://github.com/MikePopoloski/slang/archive/refs/tags/v3.0.tar.gz
|
||||
URL_HASH SHA256=02d184133525f6330a32bef492761b8ff52d0a33caed08eb51733f63cddb08e3
|
||||
)
|
||||
set(FETCHCONTENT_TRY_FIND_PACKAGE_MODE "NEVER")
|
||||
|
||||
# Force Slang to be built as a static library to avoid messing around with
|
||||
# RPATHs and installing a slang dylib alongside CIRCT. The static library
|
||||
# will embed Slang into ImportVerilog.
|
||||
set(ORIGINAL_CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS})
|
||||
set(ORIGINAL_BUILD_SHARED_LIBS ${BUILD_SHARED_LIBS})
|
||||
|
||||
set(CMAKE_CXX_FLAGS "")
|
||||
set(BUILD_SHARED_LIBS OFF)
|
||||
FetchContent_MakeAvailable(slang)
|
||||
|
||||
set(CMAKE_CXX_FLAGS ${ORIGINAL_CMAKE_CXX_FLAGS})
|
||||
set(BUILD_SHARED_LIBS ${ORIGINAL_BUILD_SHARED_LIBS})
|
||||
|
||||
if(BUILD_SHARED_LIBS)
|
||||
set_target_properties(slang_slang PROPERTIES POSITION_INDEPENDENT_CODE ON)
|
||||
set_target_properties(fmt PROPERTIES POSITION_INDEPENDENT_CODE ON)
|
||||
set_target_properties(unordered_dense PROPERTIES POSITION_INDEPENDENT_CODE ON)
|
||||
endif()
|
||||
|
||||
# The following feels *very* hacky, but CMake complains about the
|
||||
# CIRCTImportVerilog target linking against slang_slang (even with PRIVATE
|
||||
# linking) without the latter being in an export set. I think we'd want to
|
||||
# statically link slang into the CIRCTImportVerilog library, but seems to be
|
||||
# harder than it ought to be.
|
||||
set_property(
|
||||
GLOBAL APPEND PROPERTY CIRCT_EXPORTS slang_slang unordered_dense fmt)
|
||||
install(TARGETS slang_slang unordered_dense fmt EXPORT CIRCTTargets)
|
||||
else()
|
||||
find_package(slang 3.0 REQUIRED)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# Directory setup
|
||||
#-------------------------------------------------------------------------------
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
//===- ImportVerilog.h - Slang Verilog frontend integration ---------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Defines the interface to the Verilog frontend.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef CIRCT_CONVERSION_IMPORTVERILOG_H
|
||||
#define CIRCT_CONVERSION_IMPORTVERILOG_H
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace circt {
|
||||
|
||||
/// Return a human-readable string describing the slang frontend version linked
|
||||
/// into CIRCT.
|
||||
std::string getSlangVersion();
|
||||
|
||||
} // namespace circt
|
||||
|
||||
#endif // CIRCT_CONVERSION_IMPORTVERILOG_H
|
|
@ -28,3 +28,7 @@ add_subdirectory(SimToSV)
|
|||
add_subdirectory(CFToHandshake)
|
||||
add_subdirectory(VerifToSV)
|
||||
add_subdirectory(CalyxNative)
|
||||
|
||||
if(CIRCT_SLANG_FRONTEND_ENABLED)
|
||||
add_subdirectory(ImportVerilog)
|
||||
endif()
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
# slang uses exceptions
|
||||
set(LLVM_REQUIRES_EH ON)
|
||||
set(LLVM_REQUIRES_RTTI ON)
|
||||
|
||||
# For ABI compatibility, define the DEBUG macro in debug builds. Slang sets this
|
||||
# internally. If we don't set this here as well, header-defined things like the
|
||||
# destructor of `Driver`, which is generated in ImportVerilog's compilation
|
||||
# unit, will destroy a different set of fields than what was potentially built
|
||||
# or modified by code compiled in the Slang compilation unit.
|
||||
add_compile_definitions($<$<CONFIG:Debug>:DEBUG>)
|
||||
|
||||
# Disable some compiler warnings caused by slang headers such that the
|
||||
# `ImportVerilog` build doesn't spew out a ton of warnings that are not related
|
||||
# to CIRCT.
|
||||
if (MSVC)
|
||||
# No idea what to put here
|
||||
else ()
|
||||
# slang uses exceptions; we intercept these in ImportVerilog
|
||||
add_compile_options(-fexceptions)
|
||||
add_compile_options(-frtti)
|
||||
# slang has some classes with virtual funcs but non-virtual destructor.
|
||||
add_compile_options(-Wno-non-virtual-dtor)
|
||||
# some other warnings we've seen
|
||||
add_compile_options(-Wno-c++98-compat-extra-semi)
|
||||
add_compile_options(-Wno-ctad-maybe-unsupported)
|
||||
add_compile_options(-Wno-cast-qual)
|
||||
# visitor switch statements cover all cases but have default
|
||||
add_compile_options(-Wno-covered-switch-default)
|
||||
endif ()
|
||||
|
||||
add_circt_translation_library(CIRCTImportVerilog
|
||||
ImportVerilog.cpp
|
||||
|
||||
LINK_LIBS PUBLIC
|
||||
MLIRTranslateLib
|
||||
PRIVATE
|
||||
slang_slang
|
||||
)
|
|
@ -0,0 +1,27 @@
|
|||
//===- ImportVerilog.cpp - Slang Verilog frontend integration -------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This implements bridging from the slang Verilog frontend to CIRCT dialects.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "circt/Conversion/ImportVerilog.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
|
||||
#include "slang/util/Version.h"
|
||||
|
||||
std::string circt::getSlangVersion() {
|
||||
std::string buffer;
|
||||
llvm::raw_string_ostream os(buffer);
|
||||
os << "slang version ";
|
||||
os << slang::VersionInfo::getMajor() << ".";
|
||||
os << slang::VersionInfo::getMinor() << ".";
|
||||
os << slang::VersionInfo::getPatch() << "+";
|
||||
os << slang::VersionInfo::getHash();
|
||||
return buffer;
|
||||
}
|
|
@ -43,6 +43,10 @@ if(CIRCT_LLHD_SIM_ENABLED)
|
|||
list(APPEND CIRCT_TEST_DEPENDS circt-llhd-signals-runtime-wrappers)
|
||||
endif()
|
||||
|
||||
if(CIRCT_SLANG_FRONTEND_ENABLED)
|
||||
list(APPEND CIRCT_TEST_DEPENDS circt-verilog)
|
||||
endif()
|
||||
|
||||
add_lit_testsuite(check-circt "Running the CIRCT regression tests"
|
||||
${CMAKE_CURRENT_BINARY_DIR}
|
||||
DEPENDS ${CIRCT_TEST_DEPENDS}
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
// RUN: circt-verilog -h | FileCheck %s --check-prefix=CHECK-HELP
|
||||
// RUN: circt-verilog --version | FileCheck %s --check-prefix=CHECK-VERSION
|
||||
// REQUIRES: slang
|
||||
|
||||
// CHECK-HELP: OVERVIEW: Verilog and SystemVerilog frontend
|
||||
// CHECK-VERSION: slang version 3.
|
|
@ -84,4 +84,9 @@ if config.llhd_sim_enabled:
|
|||
config.available_features.add('llhd-sim')
|
||||
tools.append('llhd-sim')
|
||||
|
||||
# Add circt-verilog if the Slang frontend is enabled.
|
||||
if config.slang_frontend_enabled:
|
||||
config.available_features.add('slang')
|
||||
tools.append('circt-verilog')
|
||||
|
||||
llvm_config.add_tool_substitutions(tools, tool_dirs)
|
||||
|
|
|
@ -40,6 +40,7 @@ config.esi_capnp = "@ESI_CAPNP@"
|
|||
config.zlib = "@HAVE_ZLIB@"
|
||||
config.scheduling_or_tools = "@SCHEDULING_OR_TOOLS@"
|
||||
config.llhd_sim_enabled = @CIRCT_LLHD_SIM_ENABLED@
|
||||
config.slang_frontend_enabled = @CIRCT_SLANG_FRONTEND_ENABLED@
|
||||
|
||||
# Support substitution of the tools_dir with user parameters. This is
|
||||
# used when we can't determine the tool dir at configuration time.
|
||||
|
|
|
@ -16,3 +16,7 @@ add_subdirectory(om-linker)
|
|||
add_subdirectory(py-split-input-file)
|
||||
add_subdirectory(hlstool)
|
||||
add_subdirectory(ibistool)
|
||||
|
||||
if(CIRCT_SLANG_FRONTEND_ENABLED)
|
||||
add_subdirectory(circt-verilog)
|
||||
endif()
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
add_circt_tool(circt-verilog
|
||||
circt-verilog.cpp
|
||||
)
|
||||
|
||||
llvm_update_compile_flags(circt-verilog)
|
||||
|
||||
target_link_libraries(circt-verilog PRIVATE
|
||||
CIRCTImportVerilog
|
||||
CIRCTSupport
|
||||
MLIRIR
|
||||
)
|
|
@ -0,0 +1,61 @@
|
|||
//===- circt-verilog.cpp - Getting Verilog into CIRCT ---------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file implements a utility to parse Verilog and SystemVerilog input
|
||||
// files. This builds on CIRCT's ImportVerilog library, which ultimately relies
|
||||
// on slang to do the heavy lifting.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "circt/Conversion/ImportVerilog.h"
|
||||
#include "circt/Support/Version.h"
|
||||
#include "mlir/IR/BuiltinOps.h"
|
||||
#include "mlir/Pass/PassManager.h"
|
||||
#include "llvm/Support/CommandLine.h"
|
||||
#include "llvm/Support/InitLLVM.h"
|
||||
|
||||
using namespace llvm;
|
||||
using namespace mlir;
|
||||
using namespace circt;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Implementation
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
static LogicalResult execute(MLIRContext *context) {
|
||||
// This is where we would call out to ImportVerilog to parse the input.
|
||||
return success();
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
InitLLVM y(argc, argv);
|
||||
|
||||
// Set the bug report message to indicate users should file issues on
|
||||
// llvm/circt and not llvm/llvm-project.
|
||||
setBugReportMsg(circtBugReportMsg);
|
||||
|
||||
// Print the CIRCT and Slang versions when requested.
|
||||
cl::AddExtraVersionPrinter([](raw_ostream &os) {
|
||||
os << getCirctVersion() << '\n';
|
||||
os << getSlangVersion() << '\n';
|
||||
});
|
||||
|
||||
// Register any pass manager command line options.
|
||||
registerMLIRContextCLOptions();
|
||||
registerPassManagerCLOptions();
|
||||
registerDefaultTimingManagerCLOptions();
|
||||
registerAsmPrinterCLOptions();
|
||||
|
||||
// Parse pass names in main to ensure static initialization completed.
|
||||
cl::ParseCommandLineOptions(argc, argv,
|
||||
"Verilog and SystemVerilog frontend\n");
|
||||
|
||||
// Perform the actual work and use "exit" to avoid slow context teardown.
|
||||
MLIRContext context;
|
||||
exit(failed(execute(&context)));
|
||||
}
|
Loading…
Reference in New Issue