20 #include "mlir/Pass/Pass.h"
21 #include "mlir/Transforms/DialectConversion.h"
22 #include "llvm/ADT/TypeSwitch.h"
25 #define GEN_PASS_DEF_LOWERVERIFTOSV
26 #include "circt/Conversion/Passes.h.inc"
30 using namespace circt;
32 using namespace verif;
43 matchAndRewrite(PrintOp op, OpAdaptor operands,
44 ConversionPatternRewriter &rewriter)
const override {
48 op.getLoc(), APInt(32, 0x80000001,
false));
51 dyn_cast_or_null<FormatVerilogStringOp>(op.getString().getDefiningOp());
53 return op->emitOpError() <<
"expected FormatVerilogStringOp as the "
54 "source of the formatted string";
56 rewriter.replaceOpWithNewOp<sv::FWriteOp>(
57 op, fdStdout, fstrOp.getFormatString(), fstrOp.getSubstitutions());
66 matchAndRewrite(HasBeenResetOp op, OpAdaptor operands,
67 ConversionPatternRewriter &rewriter)
const override {
68 auto i1 = rewriter.getI1Type();
69 auto constOne = rewriter.create<
hw::ConstantOp>(op.getLoc(), i1, 1);
71 auto constX = rewriter.
create<sv::ConstantXOp>(op.getLoc(), i1);
75 op.getLoc(), i1, rewriter.getStringAttr(
"hasBeenResetReg"));
77 auto clock = operands.getClock();
78 auto reset = operands.getReset();
87 rewriter.create<sv::InitialOp>(op.getLoc(), [&] {
88 auto assignOne = [&] {
89 rewriter.create<sv::BPAssignOp>(op.getLoc(),
reg, constOne);
92 rewriter.create<sv::BPAssignOp>(op.getLoc(),
reg, constX);
95 rewriter.create<sv::IfOp>(op.getLoc(), reset, assignOne, assignX);
103 Value triggerOn = op.getAsync() ? reset : clock;
104 rewriter.create<sv::AlwaysOp>(
105 op.getLoc(), sv::EventControl::AtPosEdge, triggerOn, [&] {
106 auto assignOne = [&] {
107 rewriter.create<sv::PAssignOp>(op.getLoc(),
reg, constOne);
112 rewriter.create<sv::IfOp>(op.getLoc(), reset, assignOne);
118 auto regIsOne = rewriter.createOrFold<comb::ICmpOp>(
119 op.getLoc(), comb::ICmpPredicate::ceq, regRead, constOne);
120 auto resetIsZero = rewriter.createOrFold<comb::ICmpOp>(
121 op.getLoc(), comb::ICmpPredicate::ceq, reset, constZero);
122 auto resetStartedAndEnded = rewriter.createOrFold<
comb::AndOp>(
123 op.getLoc(), regIsOne, resetIsZero,
true);
124 rewriter.replaceOpWithNewOp<hw::WireOp>(
125 op, resetStartedAndEnded, rewriter.getStringAttr(
"hasBeenReset"));
132 static sv::EventControl verifToSVEventControl(verif::ClockEdge ce) {
134 case verif::ClockEdge::Pos:
135 return sv::EventControl::AtPosEdge;
136 case verif::ClockEdge::Neg:
137 return sv::EventControl::AtNegEdge;
138 case verif::ClockEdge::Both:
139 return sv::EventControl::AtEdge;
141 llvm_unreachable(
"Unknown event control kind");
145 template <
typename Op,
typename TargetOp>
153 matchAndRewrite(Op op, OpAdaptor operands,
154 ConversionPatternRewriter &rewriter)
const override {
157 if (
auto enable = operands.getEnable()) {
159 op.getLoc(), rewriter.getI1Type(), 1);
161 rewriter.createOrFold<
comb::XorOp>(op.getLoc(), enable, constOne);
164 rewriter.replaceOpWithNewOp<TargetOp>(op, operands.getProperty(), disable,
165 operands.getLabelAttr());
173 template <
typename Op,
typename TargetOp>
181 matchAndRewrite(Op op, OpAdaptor operands,
182 ConversionPatternRewriter &rewriter)
const override {
185 if (
auto enable = operands.getEnable()) {
187 op.getLoc(), rewriter.getI1Type(), 1);
189 rewriter.createOrFold<
comb::XorOp>(op.getLoc(), enable, constOne);
193 op.getContext(), verifToSVEventControl(operands.getEdge()));
195 rewriter.replaceOpWithNewOp<TargetOp>(op, operands.getProperty(), eventattr,
196 operands.getClock(), disable,
197 operands.getLabelAttr());
210 struct VerifToSVPass :
public circt::impl::LowerVerifToSVBase<VerifToSVPass> {
211 void runOnOperation()
override;
215 void VerifToSVPass::runOnOperation() {
216 MLIRContext &context = getContext();
219 ConversionTarget target(context);
220 RewritePatternSet
patterns(&context);
222 target.addIllegalOp<PrintOp, HasBeenResetOp, verif::AssertOp, verif::AssumeOp,
223 verif::CoverOp, ClockedAssertOp, ClockedAssumeOp,
225 target.addLegalDialect<sv::SVDialect, hw::HWDialect, comb::CombDialect>();
227 PrintOpConversionPattern, HasBeenResetConversion,
228 VerifAssertLikeConversion<verif::AssertOp, AssertPropertyOp>,
229 VerifAssertLikeConversion<verif::AssumeOp, AssumePropertyOp>,
230 VerifAssertLikeConversion<verif::CoverOp, CoverPropertyOp>,
231 VerifClockedAssertLikeConversion<verif::ClockedAssertOp,
233 VerifClockedAssertLikeConversion<verif::ClockedAssumeOp,
235 VerifClockedAssertLikeConversion<verif::ClockedCoverOp, CoverPropertyOp>>(
238 if (failed(applyPartialConversion(module, target, std::move(
patterns))))
242 std::unique_ptr<OperationPass<hw::HWModuleOp>>
244 return std::make_unique<VerifToSVPass>();
def create(data_type, value)
Direction get(bool isOutput)
Returns an output direction if isOutput is true, otherwise returns an input direction.
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.
std::unique_ptr< OperationPass< hw::HWModuleOp > > createLowerVerifToSVPass()
Create the Verif to SV conversion pass.
def reg(value, clock, reset=None, reset_value=None, name=None, sym_name=None)