Extend the `ImportVerilog` conversion to support empty SystemVerilog
module definitions and instances of such modules.
To do this, add a `ImportVerilogInternals.h` header that defines a
`Context` helper struct to aid in the conversion. Similar to other
parsers and translations, the context has a builder, tracks operations,
and offers entry points to convert different nodes of the Slang AST, and
handles diagnostics and location conversion.
An annoying quirk of Slang is the fact that the top-level declarations
in an SV file are reordered and rearranged. All instantiable nodes, such
as modules, programs, or interfaces, are moved into a separate list of
top-level instances which is unordered. To allow for better testing with
FileCheck and to produce more predictable output, the helper `Context`
tracks an ordered `std::map` of the created top-level MLIR ops, indexed
by their Slang location in the input. This map is used to determine the
insertion point for new modules as the AST is converted, such that the
resulting MLIR ops are essentially in source file order.
This new conversion discards any module ports, and any module members
except for instances and stray semicolons. This is already sufficient to
create module hierarchies, and also to define modules nested in other
modules, which Slang already helpfully resolves to an instance and
outlined module definition.
This commit also adds corresponding `moore.module` and `moore.instance`
operations to capture the empty modules and instances. These will be
extended in the future to deal with all the quirks of Verilog ingestion.
Most of the module hierarchy conversion is in a new `Structure.cpp` file
in the `ImportVerilog` conversion, in preparation for future additions
of statement, expression, and type conversion in separate files.
Add an `--import-verilog` translation target for `circt-translate`. This
facilitates writing single-file test cases that don't require
configuration of the Slang language frontend.
Actually run the Slang elaboration and compilation from within
`ImportContext::importVerilog`. This will essentially do the full
frontend work to ingest Verilog, but the part that translates from the
Slang AST to CIRCT IR ops is still left to be filled in. The import will
always produce an empty MLIR module for now. However, reporting of
syntax or other errors on the Verilog side is already covered and can be
tested for.
Make `ImportVerilog` honor the `singleUnit` option by either adding all
source files to a single preprocessor (single unit), or creating a fresh
preprocessor for every single file (multiple units).
Fixes#6680.
Add the `ImportVerilogOptions` struct to capture various options that
can be passed to the Slang Verilog frontend. This covers things like
include search directories, macro definitions, top modules, time scales,
and other settings commonly found in Verilog tools. The struct is
inspired by `slang::driver::Driver::Options`, but we intentionally
create our own struct such that no Slang headers leak through into CIRCT
space.
Add corresponding command line options to `circt-verilog`, and use them
to populate an `ImportVerilogOptions` struct that can be passed to
`ImportVerilog`.
Add `importVerilog` and `preprocessVerilog` functions to `ImportVerilog`
and add corresponding options to `circt-verilog` that call the
respective import function. This commit only implements preprocessing.
This commit also adds a mechanism to bridge between the diagnostic world
of Slang and MLIR (`MlirDiagnosticClient`). This allows us to emit any
Slang-generated diagnostics as regular MLIR diagnostics, alongside any
other errors or warnings the Verilog import might generate.
Add tests for the preprocessor (with include paths and macros) and the
diagnostic bridge.
Co-authored-by: Will Dietz <will.dietz@sifive.com>
Co-authored-by: ShiZuoye <albertethon@163.com>
Co-authored-by: hunterzju <hunter_ht@zju.edu.cn>
Co-authored-by: 孙海龙 <hailong.sun@terapines.com>
Co-authored-by: Will Dietz <will.dietz@sifive.com>
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>