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