10#include "slang/ast/Compilation.h"
13using namespace ImportVerilog;
20 SmallString<64> &prefix) {
21 if (symbol.kind != slang::ast::SymbolKind::Package)
24 if (!symbol.name.empty()) {
25 prefix += symbol.name;
42 BaseVisitor(
Context &context, Location loc)
43 : context(context), loc(loc), builder(context.builder) {}
46 LogicalResult visit(
const slang::ast::EmptyMemberSymbol &) {
52 LogicalResult visit(
const slang::ast::TransparentMemberSymbol &) {
57 LogicalResult visit(
const slang::ast::TypeAliasType &) {
return success(); }
58 LogicalResult visit(
const slang::ast::ForwardingTypedefSymbol &) {
63 LogicalResult visit(
const slang::ast::ExplicitImportSymbol &) {
66 LogicalResult visit(
const slang::ast::WildcardImportSymbol &) {
71 LogicalResult visit(
const slang::ast::TypeParameterSymbol &) {
76 LogicalResult visit(
const slang::ast::ElabSystemTaskSymbol &) {
81 LogicalResult visit(
const slang::ast::ParameterSymbol ¶m) {
82 visitParameter(param);
86 LogicalResult visit(
const slang::ast::SpecparamSymbol ¶m) {
87 visitParameter(param);
92 void visitParameter(
const Node ¶m) {
102 if (builder.getInsertionBlock()->getParentOp() == context.
intoModuleOp)
103 context.
orderedRootOps.insert({param.location, value.getDefiningOp()});
107 SmallString<64> paramName;
109 paramName += param.name;
111 builder.create<debug::VariableOp>(loc, builder.getStringAttr(paramName),
122struct RootVisitor :
public BaseVisitor {
123 using BaseVisitor::BaseVisitor;
124 using BaseVisitor::visit;
127 LogicalResult visit(
const slang::ast::PackageSymbol &package) {
132 LogicalResult visit(
const slang::ast::SubroutineSymbol &subroutine) {
137 template <
typename T>
138 LogicalResult visit(T &&node) {
139 mlir::emitError(loc,
"unsupported construct: ")
140 << slang::ast::toString(node.kind);
151struct PackageVisitor :
public BaseVisitor {
152 using BaseVisitor::BaseVisitor;
153 using BaseVisitor::visit;
156 LogicalResult visit(
const slang::ast::SubroutineSymbol &subroutine) {
161 template <
typename T>
162 LogicalResult visit(T &&node) {
163 mlir::emitError(loc,
"unsupported package member: ")
164 << slang::ast::toString(node.kind);
174static moore::ProcedureKind
177 case slang::ast::ProceduralBlockKind::Always:
178 return moore::ProcedureKind::Always;
179 case slang::ast::ProceduralBlockKind::AlwaysComb:
180 return moore::ProcedureKind::AlwaysComb;
181 case slang::ast::ProceduralBlockKind::AlwaysLatch:
182 return moore::ProcedureKind::AlwaysLatch;
183 case slang::ast::ProceduralBlockKind::AlwaysFF:
184 return moore::ProcedureKind::AlwaysFF;
185 case slang::ast::ProceduralBlockKind::Initial:
186 return moore::ProcedureKind::Initial;
187 case slang::ast::ProceduralBlockKind::Final:
188 return moore::ProcedureKind::Final;
190 llvm_unreachable(
"all procedure kinds handled");
195 case slang::ast::NetType::Supply0:
196 return moore::NetKind::Supply0;
197 case slang::ast::NetType::Supply1:
198 return moore::NetKind::Supply1;
199 case slang::ast::NetType::Tri:
200 return moore::NetKind::Tri;
201 case slang::ast::NetType::TriAnd:
202 return moore::NetKind::TriAnd;
203 case slang::ast::NetType::TriOr:
204 return moore::NetKind::TriOr;
205 case slang::ast::NetType::TriReg:
206 return moore::NetKind::TriReg;
207 case slang::ast::NetType::Tri0:
208 return moore::NetKind::Tri0;
209 case slang::ast::NetType::Tri1:
210 return moore::NetKind::Tri1;
211 case slang::ast::NetType::UWire:
212 return moore::NetKind::UWire;
213 case slang::ast::NetType::Wire:
214 return moore::NetKind::Wire;
215 case slang::ast::NetType::WAnd:
216 return moore::NetKind::WAnd;
217 case slang::ast::NetType::WOr:
218 return moore::NetKind::WOr;
219 case slang::ast::NetType::Interconnect:
220 return moore::NetKind::Interconnect;
221 case slang::ast::NetType::UserDefined:
222 return moore::NetKind::UserDefined;
223 case slang::ast::NetType::Unknown:
224 return moore::NetKind::Unknown;
226 llvm_unreachable(
"all net kinds handled");
230struct ModuleVisitor :
public BaseVisitor {
231 using BaseVisitor::visit;
235 StringRef blockNamePrefix;
237 ModuleVisitor(
Context &context, Location loc, StringRef blockNamePrefix =
"")
238 : BaseVisitor(context, loc), blockNamePrefix(blockNamePrefix) {}
241 LogicalResult visit(
const slang::ast::PortSymbol &) {
return success(); }
242 LogicalResult visit(
const slang::ast::MultiPortSymbol &) {
return success(); }
245 LogicalResult visit(
const slang::ast::GenvarSymbol &genvarNode) {
250 LogicalResult visit(
const slang::ast::DefParamSymbol &) {
return success(); }
254 LogicalResult visit(
const slang::ast::TypeParameterSymbol &) {
259 LogicalResult visit(
const slang::ast::InstanceSymbol &instNode) {
260 using slang::ast::ArgumentDirection;
261 using slang::ast::AssignmentExpression;
262 using slang::ast::MultiPortSymbol;
263 using slang::ast::PortSymbol;
268 auto module = moduleLowering->op;
269 auto moduleType =
module.getModuleType();
272 SymbolTable::setSymbolVisibility(module, SymbolTable::Visibility::Private);
279 portValues.reserve(moduleType.getNumPorts());
281 for (
const auto *con : instNode.getPortConnections()) {
282 const auto *expr = con->getExpression();
287 auto *port = con->port.as_if<PortSymbol>();
288 if (
auto *existingPort =
289 moduleLowering->portsBySyntaxNode.lookup(port->getSyntax()))
292 switch (port->direction) {
293 case ArgumentDirection::In: {
294 auto refType = moore::RefType::get(
295 cast<moore::UnpackedType>(context.
convertType(port->getType())));
297 if (
const auto *net =
298 port->internalSymbol->as_if<slang::ast::NetSymbol>()) {
299 auto netOp = builder.create<moore::NetOp>(
300 loc, refType, StringAttr::get(builder.getContext(), net->name),
302 auto readOp = builder.create<moore::ReadOp>(loc, netOp);
303 portValues.insert({port, readOp});
304 }
else if (
const auto *var =
306 ->as_if<slang::ast::VariableSymbol>()) {
307 auto varOp = builder.create<moore::VariableOp>(
308 loc, refType, StringAttr::get(builder.getContext(), var->name),
310 auto readOp = builder.create<moore::ReadOp>(loc, varOp);
311 portValues.insert({port, readOp});
313 return mlir::emitError(loc)
314 <<
"unsupported internal symbol for unconnected port `"
315 << port->name <<
"`";
322 case ArgumentDirection::Out:
327 return mlir::emitError(loc)
328 <<
"unsupported port `" << port->name <<
"` ("
329 << slang::ast::toString(port->kind) <<
")";
335 if (
const auto *assign = expr->as_if<AssignmentExpression>())
336 expr = &assign->left();
341 if (
auto *port = con->port.as_if<PortSymbol>()) {
343 auto value = (port->direction == ArgumentDirection::In)
348 if (
auto *existingPort =
349 moduleLowering->portsBySyntaxNode.lookup(con->port.getSyntax()))
351 portValues.insert({port, value});
358 if (
const auto *multiPort = con->port.as_if<MultiPortSymbol>()) {
364 for (
const auto *port :
llvm::reverse(multiPort->ports)) {
365 if (
auto *existingPort = moduleLowering->portsBySyntaxNode.lookup(
366 con->port.getSyntax()))
368 unsigned width = port->getType().getBitWidth();
369 auto sliceType = context.
convertType(port->getType());
372 Value slice = builder.create<moore::ExtractRefOp>(
373 loc, moore::RefType::get(cast<moore::UnpackedType>(sliceType)),
376 if (port->direction == ArgumentDirection::In)
377 slice = builder.create<moore::ReadOp>(loc, slice);
378 portValues.insert({port, slice});
384 mlir::emitError(loc) <<
"unsupported instance port `" << con->port.name
385 <<
"` (" << slang::ast::toString(con->port.kind)
391 SmallVector<Value> inputValues;
392 SmallVector<Value> outputValues;
393 inputValues.reserve(moduleType.getNumInputs());
394 outputValues.reserve(moduleType.getNumOutputs());
396 for (
auto &port : moduleLowering->ports) {
397 auto value = portValues.lookup(&port.ast);
398 if (port.ast.direction == ArgumentDirection::Out)
399 outputValues.push_back(value);
401 inputValues.push_back(value);
405 for (
auto [value, type] :
406 llvm::zip(inputValues, moduleType.getInputTypes()))
407 if (value.getType() != type)
409 builder.create<moore::ConversionOp>(value.
getLoc(), type, value);
413 for (
const auto &hierPath : context.hierPaths[&instNode.body])
414 if (auto hierValue = context.valueSymbols.lookup(hierPath.valueSym);
415 hierPath.hierName && hierPath.direction == ArgumentDirection::In)
416 inputValues.push_back(hierValue);
419 auto inputNames = builder.getArrayAttr(moduleType.getInputNames());
420 auto outputNames = builder.getArrayAttr(moduleType.getOutputNames());
421 auto inst = builder.create<moore::InstanceOp>(
422 loc, moduleType.getOutputTypes(),
423 builder.getStringAttr(Twine(blockNamePrefix) + instNode.name),
424 FlatSymbolRefAttr::get(module.getSymNameAttr()), inputValues,
425 inputNames, outputNames);
428 for (
const auto &hierPath : context.hierPaths[&instNode.body])
429 if (hierPath.idx && hierPath.direction == ArgumentDirection::
Out)
430 context.valueSymbols.insert(hierPath.valueSym,
431 inst->getResult(*hierPath.idx));
434 for (
auto [lvalue, output] :
llvm::zip(outputValues, inst.getOutputs())) {
437 Value rvalue = output;
438 auto dstType = cast<moore::RefType>(lvalue.getType()).getNestedType();
439 if (dstType != rvalue.getType())
440 rvalue = builder.create<moore::ConversionOp>(loc, dstType, rvalue);
441 builder.create<moore::ContinuousAssignOp>(loc, lvalue, rvalue);
448 LogicalResult visit(
const slang::ast::VariableSymbol &varNode) {
449 auto loweredType = context.
convertType(*varNode.getDeclaredType());
454 if (
const auto *init = varNode.getInitializer()) {
460 auto varOp = builder.create<moore::VariableOp>(
461 loc, moore::RefType::get(cast<moore::UnpackedType>(loweredType)),
462 builder.getStringAttr(Twine(blockNamePrefix) + varNode.name), initial);
468 LogicalResult visit(
const slang::ast::NetSymbol &netNode) {
469 auto loweredType = context.
convertType(*netNode.getDeclaredType());
474 if (
const auto *init = netNode.getInitializer()) {
481 if (netkind == moore::NetKind::Interconnect ||
482 netkind == moore::NetKind::UserDefined ||
483 netkind == moore::NetKind::Unknown)
484 return mlir::emitError(loc,
"unsupported net kind `")
485 << netNode.netType.name <<
"`";
487 auto netOp = builder.create<moore::NetOp>(
488 loc, moore::RefType::get(cast<moore::UnpackedType>(loweredType)),
489 builder.getStringAttr(Twine(blockNamePrefix) + netNode.name), netkind,
496 LogicalResult visit(
const slang::ast::ContinuousAssignSymbol &assignNode) {
497 if (
const auto *delay = assignNode.getDelay()) {
499 return mlir::emitError(loc,
500 "delayed continuous assignments not supported");
504 assignNode.getAssignment().as<slang::ast::AssignmentExpression>();
510 expr.right(), cast<moore::RefType>(lhs.getType()).getNestedType());
514 builder.create<moore::ContinuousAssignOp>(loc, lhs, rhs);
519 LogicalResult convertProcedure(moore::ProcedureKind kind,
520 const slang::ast::Statement &body) {
521 auto procOp = builder.create<moore::ProcedureOp>(loc, kind);
522 OpBuilder::InsertionGuard guard(builder);
523 builder.setInsertionPointToEnd(&procOp.getBody().emplaceBlock());
527 if (builder.getBlock())
528 builder.create<moore::ReturnOp>(loc);
532 LogicalResult visit(
const slang::ast::ProceduralBlockSymbol &procNode) {
536 auto *stmt = procNode.getBody().as_if<slang::ast::TimedStatement>();
537 if (procNode.procedureKind == slang::ast::ProceduralBlockKind::Always &&
539 stmt->timing.kind == slang::ast::TimingControlKind::ImplicitEvent)
540 return convertProcedure(moore::ProcedureKind::AlwaysComb, stmt->stmt);
548 LogicalResult visit(
const slang::ast::GenerateBlockSymbol &genNode) {
550 if (genNode.isUninstantiated)
554 SmallString<64> prefixBuffer;
555 auto prefix = blockNamePrefix;
556 if (!genNode.name.empty()) {
557 prefixBuffer += blockNamePrefix;
558 prefixBuffer += genNode.name;
560 prefix = prefixBuffer;
564 for (
auto &member : genNode.members())
565 if (failed(member.visit(ModuleVisitor(context, loc, prefix))))
571 LogicalResult visit(
const slang::ast::GenerateBlockArraySymbol &genArrNode) {
574 SmallString<64> prefixBuffer;
575 if (!genArrNode.name.empty()) {
576 prefixBuffer += blockNamePrefix;
577 prefixBuffer += genArrNode.name;
579 auto prefixBufferBaseLen = prefixBuffer.size();
582 for (
const auto *entry : genArrNode.entries) {
584 auto prefix = blockNamePrefix;
585 if (prefixBufferBaseLen > 0) {
586 prefixBuffer.resize(prefixBufferBaseLen);
588 if (entry->arrayIndex)
589 prefixBuffer += entry->arrayIndex->toString();
591 Twine(entry->constructIndex).toVector(prefixBuffer);
593 prefix = prefixBuffer;
597 if (failed(entry->asSymbol().visit(ModuleVisitor(context, loc, prefix))))
609 LogicalResult visit(
const slang::ast::StatementBlockSymbol &) {
615 LogicalResult visit(
const slang::ast::SequenceSymbol &seqNode) {
621 LogicalResult visit(
const slang::ast::PropertySymbol &propNode) {
626 LogicalResult visit(
const slang::ast::SubroutineSymbol &subroutine) {
631 template <
typename T>
632 LogicalResult visit(T &&node) {
633 mlir::emitError(loc,
"unsupported module member: ")
634 << slang::ast::toString(node.kind);
646LogicalResult Context::convertCompilation() {
651 for (
auto *inst : root.topInstances)
658 for (
auto *unit : root.compilationUnits) {
659 for (
const auto &member : unit->members()) {
661 if (failed(member.visit(RootVisitor(*
this, loc))))
667 SmallVector<const slang::ast::InstanceSymbol *> topInstances;
668 for (
auto *inst : root.topInstances)
674 auto *
module = moduleWorklist.front();
646LogicalResult Context::convertCompilation() {
…}
689 using slang::ast::ArgumentDirection;
690 using slang::ast::MultiPortSymbol;
691 using slang::ast::ParameterSymbol;
692 using slang::ast::PortSymbol;
693 using slang::ast::TypeParameterSymbol;
695 auto parameters =
module->parameters;
696 bool hasModuleSame =
false;
700 for (
auto const &existingModule :
modules) {
701 if (module->getDeclaringDefinition() ==
702 existingModule.getFirst()->getDeclaringDefinition()) {
703 auto moduleParameters = existingModule.getFirst()->parameters;
704 hasModuleSame =
true;
705 for (
auto it1 = parameters.begin(), it2 = moduleParameters.begin();
706 it1 != parameters.end() && it2 != moduleParameters.end();
709 if (it1 == parameters.end() || it2 == moduleParameters.end()) {
710 hasModuleSame =
false;
713 const auto *para1 = (*it1)->symbol.as_if<ParameterSymbol>();
714 const auto *para2 = (*it2)->symbol.as_if<ParameterSymbol>();
716 if ((para1 ==
nullptr) ^ (para2 ==
nullptr)) {
717 hasModuleSame =
false;
721 if (para1 !=
nullptr) {
722 hasModuleSame = para1->getValue() == para2->getValue();
725 if (para1 ==
nullptr) {
727 (*it1)->symbol.as<TypeParameterSymbol>().getTypeAlias());
729 (*it2)->symbol.as<TypeParameterSymbol>().getTypeAlias());
730 hasModuleSame = para1Type == para2Type;
736 module = existingModule.first;
745 slot = std::make_unique<ModuleLowering>();
746 auto &lowering = *slot;
749 OpBuilder::InsertionGuard g(
builder);
754 if (module->getDefinition().definitionKind !=
755 slang::ast::DefinitionKind::Module) {
756 mlir::emitError(loc) <<
"unsupported definition: "
757 <<
module->getDefinition().getKindString();
762 auto block = std::make_unique<Block>();
763 SmallVector<hw::ModulePort> modulePorts;
766 unsigned int outputIdx = 0, inputIdx = 0;
767 for (
auto *symbol :
module->getPortList()) {
768 auto handlePort = [&](const PortSymbol &port) {
769 auto portLoc = convertLocation(port.location);
773 auto portName =
builder.getStringAttr(port.name);
775 if (port.direction == ArgumentDirection::Out) {
781 if (port.direction != ArgumentDirection::In)
782 type = moore::RefType::get(cast<moore::UnpackedType>(type));
784 arg = block->addArgument(type, portLoc);
787 lowering.ports.push_back({port, portLoc, arg});
791 if (
const auto *port = symbol->as_if<PortSymbol>()) {
792 if (failed(handlePort(*port)))
794 }
else if (
const auto *multiPort = symbol->as_if<MultiPortSymbol>()) {
795 for (
auto *port : multiPort->ports)
796 if (failed(handlePort(*port)))
800 <<
"unsupported module port `" << symbol->name <<
"` ("
801 << slang::ast::toString(symbol->kind) <<
")";
807 for (
auto &hierPath : hierPaths[module]) {
808 auto hierType =
convertType(hierPath.valueSym->getType());
812 if (
auto hierName = hierPath.hierName) {
814 hierType = moore::RefType::get(cast<moore::UnpackedType>(hierType));
815 if (hierPath.direction == ArgumentDirection::Out) {
816 hierPath.idx = outputIdx++;
819 hierPath.idx = inputIdx++;
822 block->addArgument(hierType, hierLoc);
826 auto moduleType = hw::ModuleType::get(getContext(), modulePorts);
830 auto it = orderedRootOps.upper_bound(module->location);
831 if (it == orderedRootOps.end())
832 builder.setInsertionPointToEnd(intoModuleOp.getBody());
834 builder.setInsertionPoint(it->second);
838 builder.create<moore::SVModuleOp>(loc,
module->name, moduleType);
839 orderedRootOps.insert(it, {
module->location, moduleOp});
840 moduleOp.getBodyRegion().push_back(block.release());
841 lowering.op = moduleOp;
845 symbolTable.insert(moduleOp);
848 moduleWorklist.push(module);
851 for (
const auto &port : lowering.ports)
852 lowering.portsBySyntaxNode.insert({port.ast.getSyntax(), &port.ast});
861 auto &lowering = *
modules[module];
862 OpBuilder::InsertionGuard g(
builder);
863 builder.setInsertionPointToEnd(lowering.op.getBody());
871 if (hierPath.direction == slang::ast::ArgumentDirection::In && hierPath.idx)
873 lowering.op.getBody()->getArgument(*hierPath.idx));
876 for (
auto &member :
module->members()) {
877 auto loc = convertLocation(member.location);
878 if (failed(member.visit(ModuleVisitor(*
this, loc))))
885 SmallVector<Value> outputs;
886 for (
auto &port : lowering.ports) {
888 if (
auto *expr = port.ast.getInternalExpr()) {
889 value = convertLvalueExpression(*expr);
890 }
else if (port.ast.internalSymbol) {
891 if (
const auto *sym =
892 port.ast.internalSymbol->as_if<slang::ast::ValueSymbol>())
893 value = valueSymbols.lookup(sym);
896 return mlir::emitError(port.loc,
"unsupported port: `")
898 <<
"` does not map to an internal symbol or expression";
901 if (port.ast.direction == slang::ast::ArgumentDirection::Out) {
902 if (isa<moore::RefType>(value.getType()))
903 value = builder.create<moore::ReadOp>(value.getLoc(), value);
904 outputs.push_back(value);
910 Value portArg = port.arg;
911 if (port.ast.direction != slang::ast::ArgumentDirection::In)
912 portArg = builder.create<moore::ReadOp>(port.loc, port.arg);
913 builder.create<moore::ContinuousAssignOp>(port.loc, value, portArg);
918 for (
auto &hierPath : hierPaths[module])
919 if (auto hierValue = valueSymbols.lookup(hierPath.valueSym))
920 if (hierPath.direction == slang::ast::ArgumentDirection::
Out)
921 outputs.push_back(hierValue);
923 builder.create<moore::OutputOp>(lowering.op.getLoc(), outputs);
930 OpBuilder::InsertionGuard g(
builder);
933 for (
auto &member : package.members()) {
935 if (failed(member.visit(PackageVisitor(*
this, loc))))
945 using slang::ast::ArgumentDirection;
952 return lowering.get();
954 lowering = std::make_unique<FunctionLowering>();
959 OpBuilder::InsertionGuard g(
builder);
964 builder.setInsertionPoint(it->second);
967 if (subroutine.thisVar) {
968 mlir::emitError(loc) <<
"unsupported class method";
973 SmallVector<Type> inputTypes;
974 SmallVector<Type, 1> outputTypes;
976 for (
const auto *arg : subroutine.getArguments()) {
977 auto type = cast<moore::UnpackedType>(
convertType(arg->getType()));
980 if (arg->direction == ArgumentDirection::In) {
981 inputTypes.push_back(type);
983 inputTypes.push_back(moore::RefType::get(type));
987 if (!subroutine.getReturnType().isVoid()) {
988 auto type =
convertType(subroutine.getReturnType());
991 outputTypes.push_back(type);
994 auto funcType = FunctionType::get(
getContext(), inputTypes, outputTypes);
998 SmallString<64> funcName;
1000 funcName += subroutine.name;
1003 auto funcOp =
builder.create<mlir::func::FuncOp>(loc, funcName, funcType);
1004 SymbolTable::setSymbolVisibility(funcOp, SymbolTable::Visibility::Private);
1006 lowering->op = funcOp;
1012 return lowering.get();
1025 SmallVector<moore::VariableOp> argVariables;
1026 auto &block = lowering->op.getBody().emplaceBlock();
1027 for (
auto [astArg, type] :
1028 llvm::zip(subroutine.getArguments(),
1029 lowering->op.getFunctionType().getInputs())) {
1031 auto blockArg = block.addArgument(type, loc);
1033 if (isa<moore::RefType>(type)) {
1037 OpBuilder::InsertionGuard g(
builder);
1038 builder.setInsertionPointToEnd(&block);
1040 auto shadowArg =
builder.create<moore::VariableOp>(
1041 loc, moore::RefType::get(cast<moore::UnpackedType>(type)),
1042 StringAttr{}, blockArg);
1044 argVariables.push_back(shadowArg);
1049 OpBuilder::InsertionGuard g(
builder);
1050 builder.setInsertionPointToEnd(&block);
1053 if (subroutine.returnValVar) {
1054 auto type =
convertType(*subroutine.returnValVar->getDeclaredType());
1057 returnVar =
builder.create<moore::VariableOp>(
1058 lowering->op.getLoc(),
1059 moore::RefType::get(cast<moore::UnpackedType>(type)), StringAttr{},
1061 valueSymbols.insert(subroutine.returnValVar, returnVar);
1070 if (returnVar && !subroutine.getReturnType().isVoid()) {
1071 Value read =
builder.create<moore::ReadOp>(returnVar.getLoc(), returnVar);
1072 builder.create<mlir::func::ReturnOp>(lowering->op.getLoc(), read);
1074 builder.create<mlir::func::ReturnOp>(lowering->op.getLoc(), ValueRange{});
1077 if (returnVar && returnVar.use_empty())
1078 returnVar.getDefiningOp()->erase();
1080 for (
auto var : argVariables) {
1081 if (llvm::all_of(var->getUsers(),
1082 [](
auto *user) { return isa<moore::ReadOp>(user); })) {
1083 for (
auto *user : llvm::make_early_inc_range(var->getUsers())) {
1084 user->getResult(0).replaceAllUsesWith(var.getInitial());
static FIRRTLBaseType convertType(FIRRTLBaseType type)
Returns null type if no conversion is needed.
static Location convertLocation(MLIRContext *context, const slang::SourceManager &sourceManager, SmallDenseMap< slang::BufferID, StringRef > &bufferFilePaths, slang::SourceLocation loc)
Convert a slang SourceLocation to an MLIR Location.
static Location getLoc(DefSlot slot)
static moore::ProcedureKind convertProcedureKind(slang::ast::ProceduralBlockKind kind)
static void guessNamespacePrefix(const slang::ast::Symbol &symbol, SmallString< 64 > &prefix)
static moore::NetKind convertNetKind(slang::ast::NetType::NetKind kind)
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.
bool lowerAlwaysAtStarAsComb
Interpret always @(*) as always_comb.
bool debugInfo
Generate debug information in the form of debug dialect ops in the IR.
A helper class to facilitate the conversion from a Slang AST to MLIR operations.
LogicalResult convertFunction(const slang::ast::SubroutineSymbol &subroutine)
Convert a function.
ModuleLowering * convertModuleHeader(const slang::ast::InstanceBodySymbol *module)
Convert a module and its ports to an empty module op in the IR.
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.
LogicalResult convertModuleBody(const slang::ast::InstanceBodySymbol *module)
Convert a module's body to the corresponding IR ops.
slang::ast::Compilation & compilation
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::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.
DenseMap< const slang::ast::SubroutineSymbol *, std::unique_ptr< FunctionLowering > > functions
Functions that have already been converted.
ValueSymbols valueSymbols
ValueSymbols::ScopeTy ValueSymbolScope
const ImportVerilogOptions & options
Value convertRvalueExpression(const slang::ast::Expression &expr, Type requiredType={})
LogicalResult traverseInstanceBody(const slang::ast::Symbol &symbol)
mlir::ModuleOp intoModuleOp
SymbolTable symbolTable
A symbol table of the MLIR module we are emitting into.
DenseMap< const slang::ast::InstanceBodySymbol *, SmallVector< HierPathInfo > > hierPaths
Collect all hierarchical names used for the per module/instance.
FunctionLowering * declareFunction(const slang::ast::SubroutineSymbol &subroutine)
Convert a function and its arguments to a function declaration in the IR.
LogicalResult convertPackage(const slang::ast::PackageSymbol &package)
Convert a package and its contents.
MLIRContext * getContext()
Return the MLIR context.
LogicalResult convertStatement(const slang::ast::Statement &stmt)
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.
Function lowering information.
Module lowering information.