15 #include "mlir/IR/Builders.h"
16 #include "mlir/IR/OpImplementation.h"
17 #include "mlir/IR/PatternMatch.h"
18 #include "mlir/IR/SymbolTable.h"
19 #include "mlir/IR/TypeRange.h"
20 #include "mlir/Interfaces/FunctionImplementation.h"
21 #include "mlir/Interfaces/SideEffectInterfaces.h"
22 #include "llvm/ADT/MapVector.h"
24 using namespace circt;
25 using namespace verif;
30 case ltl::ClockEdge::Pos:
31 return ClockEdge::Pos;
32 case ltl::ClockEdge::Neg:
33 return ClockEdge::Neg;
34 case ltl::ClockEdge::Both:
35 return ClockEdge::Both;
37 llvm_unreachable(
"Unknown event control kind");
44 OpFoldResult HasBeenResetOp::fold(FoldAdaptor adaptor) {
48 if (adaptor.getReset())
53 if (!adaptor.getAsync() && adaptor.getClock())
65 template <
typename TargetOp,
typename Op>
66 static LogicalResult
canonicalize(Op op, PatternRewriter &rewriter) {
68 Value
property = op.getProperty();
69 auto clockOp =
property.getDefiningOp<ltl::ClockOp>();
75 rewriter.replaceOpWithNewOp<TargetOp>(
77 clockOp.getClock(), op.getEnable(), op.getLabelAttr());
85 return AssertLikeOp::canonicalize<ClockedAssertOp>(op, rewriter);
89 return AssertLikeOp::canonicalize<ClockedAssumeOp>(op, rewriter);
93 return AssertLikeOp::canonicalize<ClockedCoverOp>(op, rewriter);
100 LogicalResult LogicEquivalenceCheckingOp::verifyRegions() {
101 if (getFirstCircuit().getArgumentTypes() !=
102 getSecondCircuit().getArgumentTypes())
103 return emitOpError() <<
"block argument types of both regions must match";
104 if (getFirstCircuit().front().getTerminator()->getOperandTypes() !=
105 getSecondCircuit().front().getTerminator()->getOperandTypes())
107 <<
"types of the yielded values of both regions must match";
116 LogicalResult BoundedModelCheckingOp::verifyRegions() {
117 if (!getInit().getArgumentTypes().
empty())
118 return emitOpError() <<
"init region must have no arguments";
119 auto *initYieldOp = getInit().front().getTerminator();
120 auto *loopYieldOp = getLoop().front().getTerminator();
121 if (initYieldOp->getOperandTypes() != loopYieldOp->getOperandTypes())
123 <<
"init and loop regions must yield the same types of values";
124 if (initYieldOp->getOperandTypes() != getLoop().front().getArgumentTypes())
126 <<
"loop region arguments must match the types of the values "
127 "yielded by the init and loop regions";
128 size_t totalClocks = 0;
129 auto circuitArgTy = getCircuit().getArgumentTypes();
130 for (
auto input : circuitArgTy)
131 if (isa<seq::ClockType>(input))
133 auto initYields = initYieldOp->getOperands();
135 if (initYields.size() < totalClocks)
137 <<
"init and loop regions must yield at least as many clock "
138 "values as there are clock arguments to the circuit region";
139 for (
size_t i = 0; i < totalClocks; i++) {
140 if (!isa<seq::ClockType>(initYieldOp->getOperand(i).getType()))
142 <<
"init and loop regions must yield as many clock values as "
143 "there are clock arguments in the circuit region "
144 "before any other values";
146 if (getNumRegs() > 0 && totalClocks == 0)
147 return emitOpError(
"num_regs is non-zero, but the circuit region has no "
148 "clock inputs to clock the registers");
149 auto initialValues = getInitialValues();
150 if (initialValues.size() != getNumRegs()) {
152 <<
"number of initial values must match the number of registers";
154 for (
auto attr : initialValues) {
155 if (!isa<IntegerAttr, UnitAttr>(attr))
157 <<
"initial values must be integer or unit attributes";
166 #define GET_OP_CLASSES
167 #include "circt/Dialect/Verif/Verif.cpp.inc"
static InstancePath empty
static ClockEdge ltlToVerifClockEdge(ltl::ClockEdge ce)
static LogicalResult canonicalize(Op op, PatternRewriter &rewriter)
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.