Skip to content

Commit 2135596

Browse files
committed
[FIRRTL] Add domain info verification to instance ops
1 parent 49a7020 commit 2135596

File tree

3 files changed

+94
-13
lines changed

3 files changed

+94
-13
lines changed

lib/Dialect/FIRRTL/FIRRTLInstanceImplementation.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,13 @@ instance_like_impl::verifyReferencedModule(Operation *instanceOp,
6464
instanceOp->emitOpError("the number of result annotations should be "
6565
"equal to the number of results"));
6666

67+
auto domainInfo = instanceOp->getAttrOfType<ArrayAttr>("domainInfo");
68+
if (domainInfo.size() != numExpected)
69+
return emitNote(
70+
instanceOp->emitOpError()
71+
<< "has a wrong number of port domain info attributes; expected "
72+
<< numExpected << ", got " << domainInfo.size());
73+
6774
// Check that the port names match the referenced module.
6875
if (portNames != referencedModule.getPortNamesAttr()) {
6976
// We know there is an error, try to figure out whats wrong.
@@ -122,6 +129,17 @@ instance_like_impl::verifyReferencedModule(Operation *instanceOp,
122129
llvm_unreachable("should have found something wrong");
123130
}
124131

132+
// Check the domain info matches.
133+
for (size_t i = 0; i < numResults; ++i) {
134+
auto portDomainInfo = domainInfo[i];
135+
auto modulePortDomainInfo = referencedModule.getDomainInfoAttrForPort(i);
136+
if (portDomainInfo != modulePortDomainInfo)
137+
return emitNote(instanceOp->emitOpError()
138+
<< "domain info for " << portNames[i] << " must be "
139+
<< modulePortDomainInfo << ", but got "
140+
<< portDomainInfo);
141+
}
142+
125143
// Check that the instance op lists the correct layer requirements.
126144
auto instanceLayers = instanceOp->getAttrOfType<ArrayAttr>("layers");
127145
auto moduleLayers = referencedModule.getLayersAttr();

lib/Dialect/FIRRTL/FIRRTLOps.cpp

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2543,6 +2543,7 @@ void InstanceOp::build(OpBuilder &builder, OperationState &result,
25432543
} else {
25442544
portAnnotationsAttr = builder.getArrayAttr(portAnnotations);
25452545
}
2546+
25462547
ArrayAttr domainInfoAttr = module.getDomainInfoAttr();
25472548
if (domainInfoAttr.empty()) {
25482549
domainInfoAttr = builder.getArrayAttr(SmallVector<Attribute, 16>(
@@ -2881,6 +2882,13 @@ void InstanceChoiceOp::build(
28812882
portAnnotationsAttr = builder.getArrayAttr(portAnnotations);
28822883
}
28832884

2885+
// Create the domain info attribute.
2886+
ArrayAttr domainInfoAttr = defaultModule.getDomainInfoAttr();
2887+
if (domainInfoAttr.empty()) {
2888+
domainInfoAttr = builder.getArrayAttr(SmallVector<Attribute, 16>(
2889+
resultTypes.size(), builder.getArrayAttr({})));
2890+
}
2891+
28842892
// Gather the module & case names.
28852893
SmallVector<Attribute> moduleNames, caseNames;
28862894
moduleNames.push_back(SymbolRefAttr::get(defaultModule.getModuleNameAttr()));
@@ -2891,14 +2899,14 @@ void InstanceChoiceOp::build(
28912899
moduleNames.push_back(SymbolRefAttr::get(caseModule.getModuleNameAttr()));
28922900
}
28932901

2894-
return build(
2895-
builder, result, resultTypes, builder.getArrayAttr(moduleNames),
2896-
builder.getArrayAttr(caseNames), builder.getStringAttr(name),
2897-
NameKindEnumAttr::get(builder.getContext(), nameKind),
2898-
defaultModule.getPortDirectionsAttr(), defaultModule.getPortNamesAttr(),
2899-
defaultModule.getDomainInfoAttr(), builder.getArrayAttr(annotations),
2900-
portAnnotationsAttr, defaultModule.getLayersAttr(),
2901-
innerSym ? hw::InnerSymAttr::get(innerSym) : hw::InnerSymAttr());
2902+
return build(builder, result, resultTypes, builder.getArrayAttr(moduleNames),
2903+
builder.getArrayAttr(caseNames), builder.getStringAttr(name),
2904+
NameKindEnumAttr::get(builder.getContext(), nameKind),
2905+
defaultModule.getPortDirectionsAttr(),
2906+
defaultModule.getPortNamesAttr(), domainInfoAttr,
2907+
builder.getArrayAttr(annotations), portAnnotationsAttr,
2908+
defaultModule.getLayersAttr(),
2909+
innerSym ? hw::InnerSymAttr::get(innerSym) : hw::InnerSymAttr());
29022910
}
29032911

29042912
std::optional<size_t> InstanceChoiceOp::getTargetResultIndex() {
@@ -3024,7 +3032,7 @@ ParseResult InstanceChoiceOp::parse(OpAsmParser &parser,
30243032
}
30253033

30263034
if (parseModulePorts(parser, /*hasSSAIdentifiers=*/false,
3027-
/*supportsSymbols=*/false, /*supportsDomains=*/false,
3035+
/*supportsSymbols=*/false, /*supportsDomains=*/true,
30283036
entryArgs, portDirections, portNames, portTypes,
30293037
portAnnotations, portSyms, portLocs, domains))
30303038
return failure();
@@ -3165,10 +3173,9 @@ InstanceChoiceOp::erasePorts(OpBuilder &builder,
31653173
builder, getLoc(), newResultTypes, getModuleNames(), getCaseNames(),
31663174
getName(), getNameKind(),
31673175
direction::packAttribute(getContext(), newPortDirections),
3168-
ArrayAttr::get(getContext(), newPortNames),
3169-
ArrayAttr::get(getContext(), newPortDomains), getAnnotationsAttr(),
3170-
ArrayAttr::get(getContext(), newPortAnnotations), getLayers(),
3171-
getInnerSymAttr());
3176+
ArrayAttr::get(getContext(), newPortNames), newPortDomains,
3177+
getAnnotationsAttr(), ArrayAttr::get(getContext(), newPortAnnotations),
3178+
getLayers(), getInnerSymAttr());
31723179

31733180
for (unsigned oldIdx = 0, newIdx = 0, numOldPorts = getNumResults();
31743181
oldIdx != numOldPorts; ++oldIdx) {

test/Dialect/FIRRTL/errors.mlir

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3073,3 +3073,59 @@ firrtl.circuit "WrongNonDomainPortInfo" {
30733073
in %a: !firrtl.uint<1>
30743074
) attributes {domainInfo = [["hello"]]} {}
30753075
}
3076+
3077+
// -----
3078+
3079+
firrtl.circuit "WrongInstanceDomainInfo" {
3080+
firrtl.domain @ClockDomain {}
3081+
// expected-note @below {{original module declared here}}
3082+
firrtl.module @Foo(in %a: !firrtl.uint<1>) {}
3083+
firrtl.module @WrongInstanceDomainInfo() {
3084+
// expected-error @below {{'firrtl.instance' op has a wrong number of port domain info attributes; expected 1, got 0}}
3085+
%a = firrtl.instance foo {domainInfo = []} @Foo(in a: !firrtl.uint<1>)
3086+
}
3087+
}
3088+
3089+
// -----
3090+
3091+
firrtl.circuit "WrongInstanceDomainInfo" {
3092+
firrtl.domain @ClockDomain {}
3093+
// expected-note @below {{original module declared here}}
3094+
firrtl.module @Foo(
3095+
in %A : !firrtl.domain of @ClockDomain,
3096+
in %B : !firrtl.domain of @ClockDomain,
3097+
in %a : !firrtl.uint<1> domains [%A]
3098+
) {}
3099+
firrtl.module @WrongInstanceDomainInfo() {
3100+
// expected-error @below {{op domain info for "a" must be [0 : ui32], but got [1 : ui32]}}
3101+
%foo_A, %foo_B, %foo_a = firrtl.instance foo @Foo(
3102+
in A : !firrtl.domain of @ClockDomain,
3103+
in B : !firrtl.domain of @ClockDomain,
3104+
in a : !firrtl.uint<1> domains [B]
3105+
)
3106+
}
3107+
}
3108+
3109+
3110+
// -----
3111+
3112+
firrtl.circuit "WrongInstanceChoiceDomainInfo" {
3113+
firrtl.option @Platform {
3114+
firrtl.option_case @FPGA
3115+
}
3116+
firrtl.domain @ClockDomain {}
3117+
// expected-note @below {{original module declared here}}
3118+
firrtl.module @Foo(
3119+
in %A : !firrtl.domain of @ClockDomain,
3120+
in %B : !firrtl.domain of @ClockDomain,
3121+
in %a : !firrtl.uint<1> domains [%A]
3122+
) {}
3123+
firrtl.module @WrongInstanceChoiceDomainInfo() {
3124+
// expected-error @below {{op domain info for "a" must be [0 : ui32], but got [1 : ui32]}}
3125+
%foo_A, %foo_B, %foo_a = firrtl.instance_choice foo @Foo alternatives @Platform { @FPGA -> @Foo } (
3126+
in A : !firrtl.domain of @ClockDomain,
3127+
in B : !firrtl.domain of @ClockDomain,
3128+
in a : !firrtl.uint<1> domains [B]
3129+
)
3130+
}
3131+
}

0 commit comments

Comments
 (0)