CIRCT  20.0.0git
CreateCompanionAssume.cpp
Go to the documentation of this file.
1 //===- CreateCompanionAssume.cpp - Create companion assume ----------------===//
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 //
9 // This file defines the CreateCompanionAssume pass.
10 //
11 //===----------------------------------------------------------------------===//
12 
16 #include "mlir/Pass/Pass.h"
17 
18 namespace circt {
19 namespace firrtl {
20 #define GEN_PASS_DEF_CREATECOMPANIONASSUME
21 #include "circt/Dialect/FIRRTL/Passes.h.inc"
22 } // namespace firrtl
23 } // namespace circt
24 
25 using namespace circt;
26 using namespace firrtl;
27 
28 namespace {
29 struct CreateCompanionAssumePass
30  : public circt::firrtl::impl::CreateCompanionAssumeBase<
31  CreateCompanionAssumePass> {
32  void runOnOperation() override {
33  StringAttr emptyMessage = StringAttr::get(&getContext(), "");
34  getOperation().walk([&](firrtl::AssertOp assertOp) {
35  OpBuilder builder(assertOp);
36  builder.setInsertionPointAfter(assertOp);
37  auto guards = assertOp->getAttrOfType<ArrayAttr>("guards");
38  Operation *assume;
39  bool isUnrOnlyAssert = false;
40  // Regard the assertion as UNR only if "USE_UNR_ONLY_CONSTRAINTS" is
41  // included in the guards.
42  if (guards) {
43  isUnrOnlyAssert = llvm::any_of(guards, [](Attribute attr) {
44  StringAttr strAttr = dyn_cast<StringAttr>(attr);
45  return strAttr && strAttr.getValue() == "USE_UNR_ONLY_CONSTRAINTS";
46  });
47  }
48 
49  // TODO: Currently messages are dropped to preserve the old behaviour.
50  // Copy messages once we confirmed that it works well with UNR tools.
51  if (isUnrOnlyAssert)
52  // If UNROnly, use UnclockedAssumeIntrinsicOp.
53  assume = builder.create<firrtl::UnclockedAssumeIntrinsicOp>(
54  assertOp.getLoc(), assertOp.getPredicate(), assertOp.getEnable(),
55  emptyMessage, ValueRange{}, assertOp.getName());
56  else
57  // Otherwise use concurrent assume.
58  assume = builder.create<firrtl::AssumeOp>(
59  assertOp.getLoc(), assertOp.getClock(), assertOp.getPredicate(),
60  assertOp.getEnable(), emptyMessage, ValueRange{},
61  assertOp.getName(),
62  /*isConcurrent=*/true);
63 
64  // Add a guard "USE_PROPERTY_AS_CONSTRAINT" to companion assumes.
65  SmallVector<Attribute> newGuards{
66  builder.getStringAttr("USE_PROPERTY_AS_CONSTRAINT")};
67  if (guards)
68  newGuards.append(guards.begin(), guards.end());
69  assume->setAttr("guards", builder.getArrayAttr(newGuards));
70  });
71  }
72 };
73 
74 } // end anonymous namespace
75 
76 std::unique_ptr<mlir::Pass> circt::firrtl::createCreateCompanionAssume() {
77  return std::make_unique<CreateCompanionAssumePass>();
78 }
Direction get(bool isOutput)
Returns an output direction if isOutput is true, otherwise returns an input direction.
Definition: CalyxOps.cpp:55
std::unique_ptr< mlir::Pass > createCreateCompanionAssume()
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.
Definition: DebugAnalysis.h:21