11 using namespace circt;
12 using namespace ImportVerilog;
15 struct HierPathValueExprVisitor {
22 const slang::ast::Symbol &outermostModule;
24 HierPathValueExprVisitor(
Context &context, Location loc,
25 const slang::ast::Symbol &outermostModule)
26 : context(context), loc(loc), builder(context.builder),
27 outermostModule(outermostModule) {}
30 LogicalResult visit(
const slang::ast::HierarchicalValueExpression &expr) {
31 auto *currentInstBody =
32 expr.symbol.getParentScope()->getContainingInstance();
33 auto *outermostInstBody =
34 outermostModule.as_if<slang::ast::InstanceBodySymbol>();
38 if (currentInstBody == outermostInstBody)
41 auto hierName = builder.getStringAttr(expr.symbol.name);
42 const slang::ast::InstanceBodySymbol *parentInstBody =
nullptr;
45 std::function<void(
const slang::ast::InstanceBodySymbol *,
bool)>
46 collectHierarchicalPaths = [&](
auto sym,
bool isUpward) {
54 isUpward ? slang::ast::ArgumentDirection::Out
55 : slang::ast::ArgumentDirection::In,
63 sym->parentInstance->getParentScope()->getContainingInstance();
69 if (parentInstBody && parentInstBody != outermostInstBody) {
71 builder.getStringAttr(sym->parentInstance->name +
72 llvm::Twine(
".") + hierName.getValue());
73 collectHierarchicalPaths(parentInstBody, isUpward);
76 if (parentInstBody && parentInstBody != currentInstBody)
77 collectHierarchicalPaths(parentInstBody, isUpward);
82 auto *tempInstBody = currentInstBody;
83 while (tempInstBody) {
84 tempInstBody = tempInstBody->parentInstance->getParentScope()
85 ->getContainingInstance();
86 if (tempInstBody == outermostInstBody) {
87 collectHierarchicalPaths(currentInstBody,
true);
92 hierName = builder.getStringAttr(currentInstBody->parentInstance->name +
93 llvm::Twine(
".") + hierName.getValue());
94 collectHierarchicalPaths(outermostInstBody,
false);
101 template <
typename T>
102 LogicalResult visit(T &&node) {
106 LogicalResult visitInvalid(
const slang::ast::Expression &expr) {
107 mlir::emitError(loc,
"invalid expression");
115 const slang::ast::Symbol &outermostModule) {
117 return expr.visit(HierPathValueExprVisitor(*
this, loc, outermostModule));
122 struct InstBodyVisitor {
126 InstBodyVisitor(
Context &context, Location loc)
127 : context(context), loc(loc) {}
130 LogicalResult visit(
const slang::ast::InstanceSymbol &instNode) {
135 LogicalResult visit(
const slang::ast::VariableSymbol &varNode) {
136 auto &outermostModule = varNode.getParentScope()->asSymbol();
137 if (
const auto *init = varNode.getInitializer())
144 LogicalResult visit(
const slang::ast::NetSymbol &netNode) {
145 auto &outermostModule = netNode.getParentScope()->asSymbol();
146 if (
const auto *init = netNode.getInitializer())
153 LogicalResult visit(
const slang::ast::ContinuousAssignSymbol &assignNode) {
155 assignNode.getAssignment().as<slang::ast::AssignmentExpression>();
159 auto &outermostModule = assignNode.getParentScope()->asSymbol();
160 if (expr.left().hasHierarchicalReference())
165 if (expr.right().hasHierarchicalReference())
176 template <
typename T>
177 LogicalResult visit(T &&node) {
184 if (
auto *instBodySymbol = symbol.as_if<slang::ast::InstanceBodySymbol>())
185 for (
auto &member : instBodySymbol->members()) {
187 if (failed(member.visit(InstBodyVisitor(*
this, loc))))
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.
A helper class to facilitate the conversion from a Slang AST to MLIR operations.
LogicalResult traverseInstanceBody(const slang::ast::Symbol &symbol)
DenseSet< StringAttr > sameHierPaths
It's used to collect the repeat hierarchical names on the same path.
DenseMap< const slang::ast::InstanceBodySymbol *, SmallVector< HierPathInfo > > hierPaths
Collect all hierarchical names used for the per module/instance.
LogicalResult collectHierarchicalValues(const slang::ast::Expression &expr, const slang::ast::Symbol &outermostModule)
Location convertLocation(slang::SourceLocation loc)
Convert a slang SourceLocation into an MLIR Location.
Hierarchical path information.