diff --git a/lib/Dialect/FIRRTL/FIRRTLInstanceImplementation.cpp b/lib/Dialect/FIRRTL/FIRRTLInstanceImplementation.cpp index 2e3c72b394e3..013b89da7b67 100644 --- a/lib/Dialect/FIRRTL/FIRRTLInstanceImplementation.cpp +++ b/lib/Dialect/FIRRTL/FIRRTLInstanceImplementation.cpp @@ -64,6 +64,13 @@ instance_like_impl::verifyReferencedModule(Operation *instanceOp, instanceOp->emitOpError("the number of result annotations should be " "equal to the number of results")); + auto domainInfo = instanceOp->getAttrOfType("domainInfo"); + if (domainInfo.size() != numExpected) + return emitNote( + instanceOp->emitOpError() + << "has a wrong number of port domain info attributes; expected " + << numExpected << ", got " << domainInfo.size()); + // Check that the port names match the referenced module. if (portNames != referencedModule.getPortNamesAttr()) { // We know there is an error, try to figure out whats wrong. @@ -122,6 +129,17 @@ instance_like_impl::verifyReferencedModule(Operation *instanceOp, llvm_unreachable("should have found something wrong"); } + // Check the domain info matches. + for (size_t i = 0; i < numResults; ++i) { + auto portDomainInfo = domainInfo[i]; + auto modulePortDomainInfo = referencedModule.getDomainInfoAttrForPort(i); + if (portDomainInfo != modulePortDomainInfo) + return emitNote(instanceOp->emitOpError() + << "domain info for " << portNames[i] << " must be " + << modulePortDomainInfo << ", but got " + << portDomainInfo); + } + // Check that the instance op lists the correct layer requirements. auto instanceLayers = instanceOp->getAttrOfType("layers"); auto moduleLayers = referencedModule.getLayersAttr(); diff --git a/test/Dialect/FIRRTL/errors.mlir b/test/Dialect/FIRRTL/errors.mlir index 7c5786e8e83c..5e6e40eb27bc 100644 --- a/test/Dialect/FIRRTL/errors.mlir +++ b/test/Dialect/FIRRTL/errors.mlir @@ -3143,3 +3143,58 @@ firrtl.circuit "NonPropertyTypeInDomainField" { firrtl.domain @Foo ["bar", !firrtl.uint<1>] firrtl.module @NonPropertyTypeInDomainField() {} } + +// ----- + +firrtl.circuit "WrongInstanceDomainInfo" { + firrtl.domain @ClockDomain + // expected-note @below {{original module declared here}} + firrtl.module @Foo(in %a: !firrtl.uint<1>) {} + firrtl.module @WrongInstanceDomainInfo() { + // expected-error @below {{'firrtl.instance' op has a wrong number of port domain info attributes; expected 1, got 0}} + %a = firrtl.instance foo {domainInfo = []} @Foo(in a: !firrtl.uint<1>) + } +} + +// ----- + +firrtl.circuit "WrongInstanceDomainInfo" { + firrtl.domain @ClockDomain + // expected-note @below {{original module declared here}} + firrtl.module @Foo( + in %A : !firrtl.domain of @ClockDomain, + in %B : !firrtl.domain of @ClockDomain, + in %a : !firrtl.uint<1> domains [%A] + ) {} + firrtl.module @WrongInstanceDomainInfo() { + // expected-error @below {{op domain info for "a" must be [0 : ui32], but got [1 : ui32]}} + %foo_A, %foo_B, %foo_a = firrtl.instance foo @Foo( + in A : !firrtl.domain of @ClockDomain, + in B : !firrtl.domain of @ClockDomain, + in a : !firrtl.uint<1> domains [B] + ) + } +} + +// ----- + +firrtl.circuit "WrongInstanceChoiceDomainInfo" { + firrtl.option @Platform { + firrtl.option_case @FPGA + } + firrtl.domain @ClockDomain + // expected-note @below {{original module declared here}} + firrtl.module @Foo( + in %A : !firrtl.domain of @ClockDomain, + in %B : !firrtl.domain of @ClockDomain, + in %a : !firrtl.uint<1> domains [%A] + ) {} + firrtl.module @WrongInstanceChoiceDomainInfo() { + // expected-error @below {{op domain info for "a" must be [0 : ui32], but got [1 : ui32]}} + %foo_A, %foo_B, %foo_a = firrtl.instance_choice foo @Foo alternatives @Platform { @FPGA -> @Foo } ( + in A : !firrtl.domain of @ClockDomain, + in B : !firrtl.domain of @ClockDomain, + in a : !firrtl.uint<1> domains [B] + ) + } +}