CIRCT  20.0.0git
Lint.cpp
Go to the documentation of this file.
1 //===- Lint.cpp -------------------------------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
11 #include "mlir/IR/Threading.h"
12 #include "mlir/Pass/Pass.h"
13 #include "llvm/ADT/APSInt.h"
14 
15 namespace circt {
16 namespace firrtl {
17 #define GEN_PASS_DEF_LINT
18 #include "circt/Dialect/FIRRTL/Passes.h.inc"
19 } // namespace firrtl
20 } // namespace circt
21 
22 using namespace mlir;
23 using namespace circt;
24 using namespace firrtl;
25 
26 namespace {
27 struct LintPass : public circt::firrtl::impl::LintBase<LintPass> {
28  void runOnOperation() override {
29  auto fModule = getOperation();
30  auto walkResult = fModule.walk<WalkOrder::PreOrder>([&](Operation *op) {
31  if (isa<WhenOp>(op))
32  return WalkResult::skip();
33  if (isa<AssertOp, VerifAssertIntrinsicOp>(op))
34  if (checkAssert(op).failed())
35  return WalkResult::interrupt();
36 
37  return WalkResult::advance();
38  });
39  if (walkResult.wasInterrupted())
40  return signalPassFailure();
41 
42  markAllAnalysesPreserved();
43  };
44 
45  LogicalResult checkAssert(Operation *op) {
46  Value predicate;
47  if (auto a = dyn_cast<AssertOp>(op)) {
48  if (auto constant = a.getEnable().getDefiningOp<firrtl::ConstantOp>())
49  if (constant.getValue().isOne()) {
50  predicate = a.getPredicate();
51  }
52  } else if (auto a = dyn_cast<VerifAssertIntrinsicOp>(op))
53  predicate = a.getProperty();
54 
55  if (!predicate)
56  return success();
57  if (auto constant = predicate.getDefiningOp<firrtl::ConstantOp>())
58  if (constant.getValue().isZero())
59  return op->emitOpError(
60  "is guaranteed to fail simulation, as the predicate is "
61  "constant false")
62  .attachNote(constant.getLoc())
63  << "constant defined here";
64 
65  if (auto reset = predicate.getDefiningOp<firrtl::AsUIntPrimOp>())
66  if (firrtl::type_isa<ResetType, AsyncResetType>(
67  reset.getInput().getType()))
68  return op->emitOpError("is guaranteed to fail simulation, as the "
69  "predicate is a reset signal")
70  .attachNote(reset.getInput().getLoc())
71  << "reset signal defined here";
72 
73  return success();
74  }
75 };
76 } // namespace
77 
78 std::unique_ptr<Pass> firrtl::createLintingPass() {
79  return std::make_unique<LintPass>();
80 }
std::unique_ptr< mlir::Pass > createLintingPass()
Definition: Lint.cpp:78
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.
Definition: DebugAnalysis.h:21