12 using namespace circt;
17 SymbolTableCollection &symbolTable,
18 mlir::FlatSymbolRefAttr moduleName) {
19 auto referencedModule =
20 symbolTable.lookupNearestSymbolFrom<FModuleLike>(instanceOp, moduleName);
21 if (!referencedModule) {
22 return instanceOp->emitOpError(
"invalid symbol reference");
26 if (isa<ClassOp /* ClassLike */>(referencedModule))
27 return instanceOp->emitOpError(
"must instantiate a module not a class")
28 .attachNote(referencedModule.getLoc())
29 <<
"class declared here";
32 auto emitNote = [&](InFlightDiagnostic &&diag) -> InFlightDiagnostic && {
33 diag.attachNote(referencedModule->getLoc())
34 <<
"original module declared here";
35 return std::move(diag);
40 size_t numResults = instanceOp->getNumResults();
41 size_t numExpected = referencedModule.getNumPorts();
42 if (numResults != numExpected) {
43 return emitNote(instanceOp->emitOpError()
44 <<
"has a wrong number of results; expected " << numExpected
45 <<
" but got " << numResults);
48 instanceOp->getAttrOfType<mlir::DenseBoolArrayAttr>(
"portDirections");
49 if (
static_cast<size_t>(portDirections.size()) != numExpected)
51 instanceOp->emitOpError(
"the number of port directions should be "
52 "equal to the number of results"));
54 auto portNames = instanceOp->getAttrOfType<ArrayAttr>(
"portNames");
55 if (portNames.size() != numExpected)
57 instanceOp->emitOpError(
"the number of port names should be "
58 "equal to the number of results"));
60 auto portAnnotations =
61 instanceOp->getAttrOfType<ArrayAttr>(
"portAnnotations");
62 if (portAnnotations.size() != numExpected)
64 instanceOp->emitOpError(
"the number of result annotations should be "
65 "equal to the number of results"));
68 if (portNames != referencedModule.getPortNamesAttr()) {
70 auto moduleNames = referencedModule.getPortNamesAttr();
72 if (portNames.size() != moduleNames.size()) {
73 return emitNote(instanceOp->emitOpError()
74 <<
"has a wrong number of directions; expected "
75 << moduleNames.size() <<
" but got " << portNames.size());
78 for (
size_t i = 0; i != numResults; ++i) {
79 if (portNames[i] != moduleNames[i]) {
80 return emitNote(instanceOp->emitOpError()
81 <<
"name for port " << i <<
" must be "
82 << moduleNames[i] <<
", but got " << portNames[i]);
85 llvm_unreachable(
"should have found something wrong");
89 for (
size_t i = 0; i != numResults; i++) {
90 auto resultType = instanceOp->getResult(i).getType();
91 auto expectedType = referencedModule.getPortType(i);
92 if (resultType != expectedType) {
93 return emitNote(instanceOp->emitOpError()
94 <<
"result type for " << portNames[i] <<
" must be "
95 << expectedType <<
", but got " << resultType);
100 if (portDirections != referencedModule.getPortDirectionsAttr()) {
102 auto moduleDirectionAttr = referencedModule.getPortDirectionsAttr();
104 auto expectedWidth = moduleDirectionAttr.size();
105 auto actualWidth = portDirections.size();
106 if (expectedWidth != actualWidth) {
107 return emitNote(instanceOp->emitOpError()
108 <<
"has a wrong number of directions; expected "
109 << expectedWidth <<
" but got " << actualWidth);
112 auto instanceDirs = portDirections;
113 for (
size_t i = 0; i != numResults; ++i) {
114 if (instanceDirs[i] != moduleDirectionAttr[i]) {
115 return emitNote(instanceOp->emitOpError()
116 <<
"direction for " << portNames[i] <<
" must be \""
122 llvm_unreachable(
"should have found something wrong");
126 auto instanceLayers = instanceOp->getAttrOfType<ArrayAttr>(
"layers");
127 auto moduleLayers = referencedModule.getLayersAttr();
128 if (instanceLayers != moduleLayers)
129 return emitNote(instanceOp->emitOpError()
130 <<
"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.