diff --git a/lib/Dialect/FIRRTL/Transforms/InferResets.cpp b/lib/Dialect/FIRRTL/Transforms/InferResets.cpp index 1e7f1af76c87..b283ba7a321d 100644 --- a/lib/Dialect/FIRRTL/Transforms/InferResets.cpp +++ b/lib/Dialect/FIRRTL/Transforms/InferResets.cpp @@ -1299,8 +1299,16 @@ InferResetsPass::collectAnnos(FModuleOp module) { Annotation anno) { Value arg = module.getArgument(argNum); if (anno.isClass(fullAsyncResetAnnoClass)) { + if (!isa(arg.getType())) { + mlir::emitError(arg.getLoc(), "'IgnoreFullAsyncResetAnnotation' must " + "target async reset, but targets ") + << arg.getType(); + anyFailed = true; + return true; + } reset = arg; conflictingAnnos.insert({anno, reset.getLoc()}); + return true; } if (anno.isClass(ignoreFullAsyncResetAnnoClass)) { @@ -1332,7 +1340,15 @@ InferResetsPass::collectAnnos(FModuleOp module) { // At this point we know that we have a WireOp/NodeOp. Process the reset // annotations. + auto resultType = op->getResult(0).getType(); if (anno.isClass(fullAsyncResetAnnoClass)) { + if (!isa(resultType)) { + mlir::emitError(op->getLoc(), "'IgnoreFullAsyncResetAnnotation' must " + "target async reset, but targets ") + << resultType; + anyFailed = true; + return true; + } reset = op->getResult(0); conflictingAnnos.insert({anno, reset.getLoc()}); return true; diff --git a/test/Dialect/FIRRTL/infer-resets-errors.mlir b/test/Dialect/FIRRTL/infer-resets-errors.mlir index ecab5221dbde..108867feae15 100644 --- a/test/Dialect/FIRRTL/infer-resets-errors.mlir +++ b/test/Dialect/FIRRTL/infer-resets-errors.mlir @@ -163,6 +163,27 @@ firrtl.circuit "top" { } } +// ----- +// Reset annotation cannot target synchronous reset signals +firrtl.circuit "top" { + firrtl.module @top() { + // expected-error @below {{'IgnoreFullAsyncResetAnnotation' must target async reset, but targets '!firrtl.uint<1>'}} + %innerReset = firrtl.wire {annotations = [{class = "sifive.enterprise.firrtl.FullAsyncResetAnnotation"}]} : !firrtl.uint<1> + } +} + +// ----- +// Reset annotation cannot target reset signals which are inferred to be synchronous +firrtl.circuit "top" { + firrtl.module @top() { + // expected-error @below {{'IgnoreFullAsyncResetAnnotation' must target async reset, but targets '!firrtl.uint<1>'}} + %innerReset = firrtl.wire {annotations = [{class = "sifive.enterprise.firrtl.FullAsyncResetAnnotation"}]} : !firrtl.reset + %invalid = firrtl.invalidvalue : !firrtl.reset + firrtl.strictconnect %innerReset, %invalid : !firrtl.reset + } +} + + // ----- // Ignore reset annotation cannot target port firrtl.circuit "top" {