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