10 #include "mlir/IR/Threading.h"
11 #include "llvm/ADT/APSInt.h"
14 using namespace circt;
15 using namespace firrtl;
18 struct LintPass :
public LintBase<LintPass> {
19 void runOnOperation()
override {
20 auto fModule = getOperation();
21 auto walkResult = fModule.walk<WalkOrder::PreOrder>([&](Operation *op) {
23 return WalkResult::skip();
24 if (isa<AssertOp, VerifAssertIntrinsicOp>(op))
25 if (checkAssert(op).failed())
26 return WalkResult::interrupt();
28 return WalkResult::advance();
30 if (walkResult.wasInterrupted())
31 return signalPassFailure();
33 markAllAnalysesPreserved();
36 LogicalResult checkAssert(Operation *op) {
38 if (
auto a = dyn_cast<AssertOp>(op)) {
39 if (
auto constant = a.getEnable().getDefiningOp<firrtl::ConstantOp>())
40 if (constant.getValue().isOne()) {
41 predicate = a.getPredicate();
43 }
else if (
auto a = dyn_cast<VerifAssertIntrinsicOp>(op))
44 predicate = a.getProperty();
48 if (
auto constant = predicate.getDefiningOp<firrtl::ConstantOp>())
49 if (constant.getValue().isZero())
50 return op->emitOpError(
51 "is guaranteed to fail simulation, as the predicate is "
53 .attachNote(constant.getLoc())
54 <<
"constant defined here";
56 if (
auto reset = predicate.getDefiningOp<firrtl::AsUIntPrimOp>())
57 if (firrtl::type_isa<ResetType, AsyncResetType>(
58 reset.getInput().getType()))
59 return op->emitOpError(
"is guaranteed to fail simulation, as the "
60 "predicate is a reset signal")
61 .attachNote(reset.getInput().getLoc())
62 <<
"reset signal defined here";
70 return std::make_unique<LintPass>();
std::unique_ptr< mlir::Pass > createLintingPass()
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.