CIRCT  20.0.0git
ImportVerilogInternals.h
Go to the documentation of this file.
1 //===- ImportVerilogInternals.h - Internal implementation details ---------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 // NOLINTNEXTLINE(llvm-header-guard)
10 #ifndef CONVERSION_IMPORTVERILOG_IMPORTVERILOGINTERNALS_H
11 #define CONVERSION_IMPORTVERILOG_IMPORTVERILOGINTERNALS_H
12 
15 #include "circt/Dialect/HW/HWOps.h"
17 #include "mlir/Dialect/ControlFlow/IR/ControlFlowOps.h"
18 #include "mlir/Dialect/Func/IR/FuncOps.h"
19 #include "slang/ast/ASTVisitor.h"
20 #include "llvm/ADT/ScopedHashTable.h"
21 #include "llvm/Support/Debug.h"
22 #include <map>
23 #include <queue>
24 
25 #define DEBUG_TYPE "import-verilog"
26 
27 namespace circt {
28 namespace ImportVerilog {
29 
30 using moore::Domain;
31 
32 /// Port lowering information.
33 struct PortLowering {
34  const slang::ast::PortSymbol &ast;
35  Location loc;
36  BlockArgument arg;
37 };
38 
39 /// Module lowering information.
41  moore::SVModuleOp op;
42  SmallVector<PortLowering> ports;
43  DenseMap<const slang::syntax::SyntaxNode *, const slang::ast::PortSymbol *>
45 };
46 
47 /// Function lowering information.
49  mlir::func::FuncOp op;
50 };
51 
52 /// Information about a loops continuation and exit blocks relevant while
53 /// lowering the loop's body statements.
54 struct LoopFrame {
55  /// The block to jump to from a `continue` statement.
56  Block *continueBlock;
57  /// The block to jump to from a `break` statement.
58  Block *breakBlock;
59 };
60 
61 /// A helper class to facilitate the conversion from a Slang AST to MLIR
62 /// operations. Keeps track of the destination MLIR module, builders, and
63 /// various worklists and utilities needed for conversion.
64 struct Context {
66  slang::ast::Compilation &compilation, mlir::ModuleOp intoModuleOp,
67  const slang::SourceManager &sourceManager,
71  builder(OpBuilder::atBlockEnd(intoModuleOp.getBody())),
73  Context(const Context &) = delete;
74 
75  /// Return the MLIR context.
76  MLIRContext *getContext() { return intoModuleOp.getContext(); }
77 
78  /// Convert a slang `SourceLocation` into an MLIR `Location`.
79  Location convertLocation(slang::SourceLocation loc);
80  /// Convert a slang `SourceRange` into an MLIR `Location`.
81  Location convertLocation(slang::SourceRange range);
82 
83  /// Convert a slang type into an MLIR type. Returns null on failure. Uses the
84  /// provided location for error reporting, or tries to guess one from the
85  /// given type. Types tend to have unreliable location information, so it's
86  /// generally a good idea to pass in a location.
87  Type convertType(const slang::ast::Type &type, LocationAttr loc = {});
88  Type convertType(const slang::ast::DeclaredType &type);
89 
90  /// Convert hierarchy and structure AST nodes to MLIR ops.
91  LogicalResult convertCompilation();
92  ModuleLowering *
93  convertModuleHeader(const slang::ast::InstanceBodySymbol *module);
94  LogicalResult convertModuleBody(const slang::ast::InstanceBodySymbol *module);
95  LogicalResult convertPackage(const slang::ast::PackageSymbol &package);
96  FunctionLowering *
97  declareFunction(const slang::ast::SubroutineSymbol &subroutine);
98  LogicalResult convertFunction(const slang::ast::SubroutineSymbol &subroutine);
99 
100  // Convert a statement AST node to MLIR ops.
101  LogicalResult convertStatement(const slang::ast::Statement &stmt);
102 
103  // Convert an expression AST node to MLIR ops.
104  Value convertRvalueExpression(const slang::ast::Expression &expr,
105  Type requiredType = {});
106  Value convertLvalueExpression(const slang::ast::Expression &expr);
107 
108  // Convert a slang timing control into an MLIR timing control.
109  LogicalResult convertTimingControl(const slang::ast::TimingControl &ctrl,
110  const slang::ast::Statement &stmt);
111 
112  /// Helper function to convert a value to its "truthy" boolean value.
113  Value convertToBool(Value value);
114 
115  /// Helper function to convert a value to its "truthy" boolean value and
116  /// convert it to the given domain.
117  Value convertToBool(Value value, Domain domain);
118 
119  /// Helper function to convert a value to its simple bit vector
120  /// representation, if it has one. Otherwise returns null. Also returns null
121  /// if the given value is null.
122  Value convertToSimpleBitVector(Value value);
123 
124  /// Helper function to insert the necessary operations to cast a value from
125  /// one type to another.
126  Value materializeConversion(Type type, Value value, bool isSigned,
127  Location loc);
128 
129  /// Helper function to materialize an `SVInt` as an SSA value.
130  Value materializeSVInt(const slang::SVInt &svint,
131  const slang::ast::Type &type, Location loc);
132 
133  /// Helper function to materialize a `ConstantValue` as an SSA value. Returns
134  /// null if the constant cannot be materialized.
135  Value materializeConstant(const slang::ConstantValue &constant,
136  const slang::ast::Type &type, Location loc);
137 
138  /// Convert a list of string literal arguments with formatting specifiers and
139  /// arguments to be interpolated into a `!moore.format_string` value. Returns
140  /// failure if an error occurs. Returns a null value if the formatted string
141  /// is trivially empty. Otherwise returns the formatted string.
142  FailureOr<Value> convertFormatString(
143  slang::span<const slang::ast::Expression *const> arguments, Location loc,
144  moore::IntFormat defaultFormat = moore::IntFormat::Decimal,
145  bool appendNewline = false);
146 
147  /// Evaluate the constant value of an expression.
148  slang::ConstantValue evaluateConstant(const slang::ast::Expression &expr);
149 
151  slang::ast::Compilation &compilation;
152  mlir::ModuleOp intoModuleOp;
153  const slang::SourceManager &sourceManager;
155 
156  /// The builder used to create IR operations.
157  OpBuilder builder;
158  /// A symbol table of the MLIR module we are emitting into.
159  SymbolTable symbolTable;
160 
161  /// The top-level operations ordered by their Slang source location. This is
162  /// used to produce IR that follows the source file order.
163  std::map<slang::SourceLocation, Operation *> orderedRootOps;
164 
165  /// How we have lowered modules to MLIR.
166  DenseMap<const slang::ast::InstanceBodySymbol *,
167  std::unique_ptr<ModuleLowering>>
169  /// A list of modules for which the header has been created, but the body has
170  /// not been converted yet.
171  std::queue<const slang::ast::InstanceBodySymbol *> moduleWorklist;
172 
173  /// Functions that have already been converted.
174  DenseMap<const slang::ast::SubroutineSymbol *,
175  std::unique_ptr<FunctionLowering>>
177 
178  /// A table of defined values, such as variables, that may be referred to by
179  /// name in expressions. The expressions use this table to lookup the MLIR
180  /// value that was created for a given declaration in the Slang AST node.
181  using ValueSymbols =
182  llvm::ScopedHashTable<const slang::ast::ValueSymbol *, Value>;
183  using ValueSymbolScope = ValueSymbols::ScopeTy;
185 
186  /// A stack of assignment left-hand side values. Each assignment will push its
187  /// lowered left-hand side onto this stack before lowering its right-hand
188  /// side. This allows expressions to resolve the opaque
189  /// `LValueReferenceExpression`s in the AST.
190  SmallVector<Value> lvalueStack;
191 
192  /// A stack of loop continuation and exit blocks. Each loop will push the
193  /// relevant info onto this stack, lower its loop body statements, and pop the
194  /// info off the stack again. Continue and break statements encountered as
195  /// part of the loop body statements will use this information to branch to
196  /// the correct block.
197  SmallVector<LoopFrame> loopStack;
198 
199  /// A listener called for every variable or net being read. This can be used
200  /// to collect all variables read as part of an expression or statement, for
201  /// example to populate the list of observed signals in an implicit event
202  /// control `@*`.
203  std::function<void(moore::ReadOp)> rvalueReadCallback;
204 };
205 
206 } // namespace ImportVerilog
207 } // namespace circt
208 
209 #endif // CONVERSION_IMPORTVERILOG_IMPORTVERILOGINTERNALS_H
Domain
The number of values each bit of a type can assume.
Definition: MooreTypes.h:47
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.
Definition: DebugAnalysis.h:21
Options that control how Verilog input files are parsed and processed.
Definition: ImportVerilog.h:37
A helper class to facilitate the conversion from a Slang AST to MLIR operations.
LogicalResult convertFunction(const slang::ast::SubroutineSymbol &subroutine)
Convert a function.
Definition: Structure.cpp:889
Value materializeConversion(Type type, Value value, bool isSigned, Location loc)
Helper function to insert the necessary operations to cast a value from one type to another.
ModuleLowering * convertModuleHeader(const slang::ast::InstanceBodySymbol *module)
Convert a module and its ports to an empty module op in the IR.
Definition: Structure.cpp:598
Value convertLvalueExpression(const slang::ast::Expression &expr)
Value materializeConstant(const slang::ConstantValue &constant, const slang::ast::Type &type, Location loc)
Helper function to materialize a ConstantValue as an SSA value.
SmallVector< LoopFrame > loopStack
A stack of loop continuation and exit blocks.
LogicalResult convertModuleBody(const slang::ast::InstanceBodySymbol *module)
Convert a module's body to the corresponding IR ops.
Definition: Structure.cpp:744
slang::ConstantValue evaluateConstant(const slang::ast::Expression &expr)
Evaluate the constant value of an expression.
slang::ast::Compilation & compilation
LogicalResult convertTimingControl(const slang::ast::TimingControl &ctrl, const slang::ast::Statement &stmt)
OpBuilder builder
The builder used to create IR operations.
std::queue< const slang::ast::InstanceBodySymbol * > moduleWorklist
A list of modules for which the header has been created, but the body has not been converted yet.
std::function< void(moore::ReadOp)> rvalueReadCallback
A listener called for every variable or net being read.
Context(const Context &)=delete
std::map< slang::SourceLocation, Operation * > orderedRootOps
The top-level operations ordered by their Slang source location.
Type convertType(const slang::ast::Type &type, LocationAttr loc={})
Convert a slang type into an MLIR type.
Definition: Types.cpp:167
DenseMap< const slang::ast::SubroutineSymbol *, std::unique_ptr< FunctionLowering > > functions
Functions that have already been converted.
Value materializeSVInt(const slang::SVInt &svint, const slang::ast::Type &type, Location loc)
Helper function to materialize an SVInt as an SSA value.
SmallDenseMap< slang::BufferID, StringRef > & bufferFilePaths
Value convertToBool(Value value)
Helper function to convert a value to its "truthy" boolean value.
FailureOr< Value > convertFormatString(slang::span< const slang::ast::Expression *const > arguments, Location loc, moore::IntFormat defaultFormat=moore::IntFormat::Decimal, bool appendNewline=false)
Convert a list of string literal arguments with formatting specifiers and arguments to be interpolate...
ValueSymbols::ScopeTy ValueSymbolScope
const ImportVerilogOptions & options
Value convertRvalueExpression(const slang::ast::Expression &expr, Type requiredType={})
llvm::ScopedHashTable< const slang::ast::ValueSymbol *, Value > ValueSymbols
A table of defined values, such as variables, that may be referred to by name in expressions.
Value convertToSimpleBitVector(Value value)
Helper function to convert a value to its simple bit vector representation, if it has one.
const slang::SourceManager & sourceManager
SymbolTable symbolTable
A symbol table of the MLIR module we are emitting into.
FunctionLowering * declareFunction(const slang::ast::SubroutineSymbol &subroutine)
Convert a function and its arguments to a function declaration in the IR.
Definition: Structure.cpp:816
Context(const ImportVerilogOptions &options, slang::ast::Compilation &compilation, mlir::ModuleOp intoModuleOp, const slang::SourceManager &sourceManager, SmallDenseMap< slang::BufferID, StringRef > &bufferFilePaths)
LogicalResult convertPackage(const slang::ast::PackageSymbol &package)
Convert a package and its contents.
Definition: Structure.cpp:801
LogicalResult convertCompilation()
Convert hierarchy and structure AST nodes to MLIR ops.
Definition: Structure.cpp:562
MLIRContext * getContext()
Return the MLIR context.
LogicalResult convertStatement(const slang::ast::Statement &stmt)
Definition: Statements.cpp:695
SmallVector< Value > lvalueStack
A stack of assignment left-hand side values.
DenseMap< const slang::ast::InstanceBodySymbol *, std::unique_ptr< ModuleLowering > > modules
How we have lowered modules to MLIR.
Location convertLocation(slang::SourceLocation loc)
Convert a slang SourceLocation into an MLIR Location.
Information about a loops continuation and exit blocks relevant while lowering the loop's body statem...
Block * breakBlock
The block to jump to from a break statement.
Block * continueBlock
The block to jump to from a continue statement.
DenseMap< const slang::syntax::SyntaxNode *, const slang::ast::PortSymbol * > portsBySyntaxNode
const slang::ast::PortSymbol & ast