12 using namespace circt;
17 SymbolTableCollection &symbolTable,
18 mlir::FlatSymbolRefAttr moduleName) {
19 auto module = instanceOp->getParentOfType<FModuleOp>();
20 auto referencedModule =
21 symbolTable.lookupNearestSymbolFrom<FModuleLike>(instanceOp, moduleName);
22 if (!referencedModule) {
23 return instanceOp->emitOpError(
"invalid symbol reference");
27 if (isa<ClassOp /* ClassLike */>(referencedModule))
28 return instanceOp->emitOpError(
"must instantiate a module not a class")
29 .attachNote(referencedModule.getLoc())
30 <<
"class declared here";
34 if (referencedModule == module) {
35 auto diag = instanceOp->emitOpError()
36 <<
"is a recursive instantiation of its containing module";
37 return diag.attachNote(module.getLoc())
38 <<
"containing module declared here";
42 auto emitNote = [&](InFlightDiagnostic &&diag) -> InFlightDiagnostic && {
43 diag.attachNote(referencedModule->getLoc())
44 <<
"original module declared here";
45 return std::move(diag);
50 size_t numResults = instanceOp->getNumResults();
51 size_t numExpected = referencedModule.getNumPorts();
52 if (numResults != numExpected) {
53 return emitNote(instanceOp->emitOpError()
54 <<
"has a wrong number of results; expected " << numExpected
55 <<
" but got " << numResults);
58 instanceOp->getAttrOfType<mlir::DenseBoolArrayAttr>(
"portDirections");
59 if (
static_cast<size_t>(portDirections.size()) != numExpected)
61 instanceOp->emitOpError(
"the number of port directions should be "
62 "equal to the number of results"));
64 auto portNames = instanceOp->getAttrOfType<ArrayAttr>(
"portNames");
65 if (portNames.size() != numExpected)
67 instanceOp->emitOpError(
"the number of port names should be "
68 "equal to the number of results"));
70 auto portAnnotations =
71 instanceOp->getAttrOfType<ArrayAttr>(
"portAnnotations");
72 if (portAnnotations.size() != numExpected)
74 instanceOp->emitOpError(
"the number of result annotations should be "
75 "equal to the number of results"));
78 if (portNames != referencedModule.getPortNamesAttr()) {
80 auto moduleNames = referencedModule.getPortNamesAttr();
82 if (portNames.size() != moduleNames.size()) {
83 return emitNote(instanceOp->emitOpError()
84 <<
"has a wrong number of directions; expected "
85 << moduleNames.size() <<
" but got " << portNames.size());
88 for (
size_t i = 0; i != numResults; ++i) {
89 if (portNames[i] != moduleNames[i]) {
90 return emitNote(instanceOp->emitOpError()
91 <<
"name for port " << i <<
" must be "
92 << moduleNames[i] <<
", but got " << portNames[i]);
95 llvm_unreachable(
"should have found something wrong");
99 for (
size_t i = 0; i != numResults; i++) {
100 auto resultType = instanceOp->getResult(i).getType();
101 auto expectedType = referencedModule.getPortType(i);
102 if (resultType != expectedType) {
103 return emitNote(instanceOp->emitOpError()
104 <<
"result type for " << portNames[i] <<
" must be "
105 << expectedType <<
", but got " << resultType);
110 if (portDirections != referencedModule.getPortDirectionsAttr()) {
112 auto moduleDirectionAttr = referencedModule.getPortDirectionsAttr();
114 auto expectedWidth = moduleDirectionAttr.size();
115 auto actualWidth = portDirections.size();
116 if (expectedWidth != actualWidth) {
117 return emitNote(instanceOp->emitOpError()
118 <<
"has a wrong number of directions; expected "
119 << expectedWidth <<
" but got " << actualWidth);
122 auto instanceDirs = portDirections;
123 for (
size_t i = 0; i != numResults; ++i) {
124 if (instanceDirs[i] != moduleDirectionAttr[i]) {
125 return emitNote(instanceOp->emitOpError()
126 <<
"direction for " << portNames[i] <<
" must be \""
132 llvm_unreachable(
"should have found something wrong");
136 auto instanceLayers = instanceOp->getAttrOfType<ArrayAttr>(
"layers");
137 auto moduleLayers = referencedModule.getLayersAttr();
138 if (instanceLayers != moduleLayers)
139 return emitNote(instanceOp->emitOpError()
140 <<
"layers must be " << moduleLayers <<
", but got "
static StringRef toString(Direction direction)
LogicalResult verifyReferencedModule(Operation *instanceOp, SymbolTableCollection &symbolTable, mlir::FlatSymbolRefAttr moduleName)
Verify that the instance refers to a valid FIRRTL module.
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.