CIRCT 20.0.0git
Loading...
Searching...
No Matches
LTLToCore.cpp
Go to the documentation of this file.
1//===- LTLToCore.cpp -----------------------------------------------------===//
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// Converts LTL and Verif operations to Core operations
10//
11//===----------------------------------------------------------------------===//
12
25#include "mlir/Dialect/Func/IR/FuncOps.h"
26#include "mlir/Dialect/LLVMIR/LLVMDialect.h"
27#include "mlir/Dialect/SCF/IR/SCF.h"
28#include "mlir/Pass/Pass.h"
29#include "mlir/Transforms/DialectConversion.h"
30#include "llvm/Support/MathExtras.h"
31
32namespace circt {
33#define GEN_PASS_DEF_LOWERLTLTOCORE
34#include "circt/Conversion/Passes.h.inc"
35} // namespace circt
36
37using namespace mlir;
38using namespace circt;
39using namespace hw;
40
41//===----------------------------------------------------------------------===//
42// Conversion patterns
43//===----------------------------------------------------------------------===//
44
45namespace {
46struct HasBeenResetOpConversion : OpConversionPattern<verif::HasBeenResetOp> {
47 using OpConversionPattern<verif::HasBeenResetOp>::OpConversionPattern;
48
49 // HasBeenReset generates a 1 bit register that is set to one once the reset
50 // has been raised and lowered at at least once.
51 LogicalResult
52 matchAndRewrite(verif::HasBeenResetOp op, OpAdaptor adaptor,
53 ConversionPatternRewriter &rewriter) const override {
54 auto i1 = rewriter.getI1Type();
55 // Generate the constant used to set the register value
56 Value constZero = seq::createConstantInitialValue(
57 rewriter, op->getLoc(), rewriter.getIntegerAttr(i1, 0));
58
59 // Generate the constant used to enegate the
60 Value constOne = rewriter.create<hw::ConstantOp>(op.getLoc(), i1, 1);
61
62 // Create a backedge for the register to be used in the OrOp
63 circt::BackedgeBuilder bb(rewriter, op.getLoc());
64 circt::Backedge reg = bb.get(rewriter.getI1Type());
65
66 // Generate an or between the reset and the register's value to store
67 // whether or not the reset has been active at least once
68 Value orReset =
69 rewriter.create<comb::OrOp>(op.getLoc(), adaptor.getReset(), reg);
70
71 // This register should not be reset, so we give it dummy reset and resetval
72 // operands to fit the build signature
73 Value reset, resetval;
74
75 // Finally generate the register to set the backedge
76 reg.setValue(rewriter.create<seq::CompRegOp>(
77 op.getLoc(), orReset,
78 rewriter.createOrFold<seq::ToClockOp>(op.getLoc(), adaptor.getClock()),
79 rewriter.getStringAttr("hbr"), reset, resetval, constZero,
80 InnerSymAttr{} // inner_sym
81 ));
82
83 // We also need to consider the case where we are currently in a reset cycle
84 // in which case our hbr register should be down-
85 // Practically this means converting it to (and hbr (not reset))
86 Value notReset =
87 rewriter.create<comb::XorOp>(op.getLoc(), adaptor.getReset(), constOne);
88 rewriter.replaceOpWithNewOp<comb::AndOp>(op, reg, notReset);
89
90 return success();
91 }
92};
93
94} // namespace
95
96//===----------------------------------------------------------------------===//
97// Lower LTL To Core pass
98//===----------------------------------------------------------------------===//
99
100namespace {
101struct LowerLTLToCorePass
102 : public circt::impl::LowerLTLToCoreBase<LowerLTLToCorePass> {
103 LowerLTLToCorePass() = default;
104 void runOnOperation() override;
105};
106} // namespace
107
108// Simply applies the conversion patterns defined above
109void LowerLTLToCorePass::runOnOperation() {
110
111 // Set target dialects: We don't want to see any ltl or verif that might
112 // come from an AssertProperty left in the result
113 ConversionTarget target(getContext());
114 target.addLegalDialect<hw::HWDialect>();
115 target.addLegalDialect<comb::CombDialect>();
116 target.addLegalDialect<sv::SVDialect>();
117 target.addLegalDialect<seq::SeqDialect>();
118 target.addLegalDialect<ltl::LTLDialect>();
119 target.addLegalDialect<verif::VerifDialect>();
120 target.addIllegalOp<verif::HasBeenResetOp>();
121
122 // Create type converters, mostly just to convert an ltl property to a bool
123 mlir::TypeConverter converter;
124
125 // Convert the ltl property type to a built-in type
126 converter.addConversion([](IntegerType type) { return type; });
127 converter.addConversion([](ltl::PropertyType type) {
128 return IntegerType::get(type.getContext(), 1);
129 });
130 converter.addConversion([](ltl::SequenceType type) {
131 return IntegerType::get(type.getContext(), 1);
132 });
133
134 // Basic materializations
135 converter.addTargetMaterialization(
136 [&](mlir::OpBuilder &builder, mlir::Type resultType,
137 mlir::ValueRange inputs, mlir::Location loc) -> mlir::Value {
138 if (inputs.size() != 1)
139 return Value();
140 return builder
141 .create<UnrealizedConversionCastOp>(loc, resultType, inputs[0])
142 ->getResult(0);
143 });
144
145 converter.addSourceMaterialization(
146 [&](mlir::OpBuilder &builder, mlir::Type resultType,
147 mlir::ValueRange inputs, mlir::Location loc) -> mlir::Value {
148 if (inputs.size() != 1)
149 return Value();
150 return builder
151 .create<UnrealizedConversionCastOp>(loc, resultType, inputs[0])
152 ->getResult(0);
153 });
154
155 // Create the operation rewrite patters
156 RewritePatternSet patterns(&getContext());
157 patterns.add<HasBeenResetOpConversion>(converter, patterns.getContext());
158
159 // Apply the conversions
160 if (failed(
161 applyPartialConversion(getOperation(), target, std::move(patterns))))
162 return signalPassFailure();
163}
164
165// Basic default constructor
166std::unique_ptr<mlir::Pass> circt::createLowerLTLToCorePass() {
167 return std::make_unique<LowerLTLToCorePass>();
168}
Instantiate one of these and use it to build typed backedges.
Backedge is a wrapper class around a Value.
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.
std::unique_ptr< mlir::Pass > createLowerLTLToCorePass()
Definition hw.py:1
reg(value, clock, reset=None, reset_value=None, name=None, sym_name=None)
Definition seq.py:21