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" 
   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");
 
 
   44OpFoldResult HasBeenResetOp::fold(FoldAdaptor adaptor) {
 
   48  if (adaptor.getReset())
 
   49    return BoolAttr::get(getContext(), 
false);
 
   53  if (!adaptor.getAsync() && adaptor.getClock())
 
   54    return BoolAttr::get(getContext(), 
false);
 
   65template <
typename TargetOp, 
typename Op>
 
   66static 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());
 
 
 
   84LogicalResult AssertOp::canonicalize(AssertOp op, PatternRewriter &rewriter) {
 
   85  return AssertLikeOp::canonicalize<ClockedAssertOp>(op, rewriter);
 
   88LogicalResult AssumeOp::canonicalize(AssumeOp op, PatternRewriter &rewriter) {
 
   89  return AssertLikeOp::canonicalize<ClockedAssumeOp>(op, rewriter);
 
   92LogicalResult CoverOp::canonicalize(CoverOp op, PatternRewriter &rewriter) {
 
   93  return AssertLikeOp::canonicalize<ClockedCoverOp>(op, rewriter);
 
  100template <
typename OpTy>
 
  102  if (op.getFirstCircuit().getArgumentTypes() !=
 
  103      op.getSecondCircuit().getArgumentTypes())
 
  104    return op.emitOpError()
 
  105           << 
"block argument types of both regions must match";
 
  106  if (op.getFirstCircuit().front().getTerminator()->getOperandTypes() !=
 
  107      op.getSecondCircuit().front().getTerminator()->getOperandTypes())
 
  108    return op.emitOpError()
 
  109           << 
"types of the yielded values of both regions must match";
 
 
  118LogicalResult LogicEquivalenceCheckingOp::verifyRegions() {
 
  126LogicalResult RefinementCheckingOp::verifyRegions() {
 
  134LogicalResult BoundedModelCheckingOp::verifyRegions() {
 
  135  if (!getInit().getArgumentTypes().
empty())
 
  136    return emitOpError() << 
"init region must have no arguments";
 
  137  auto *initYieldOp = getInit().front().getTerminator();
 
  138  auto *loopYieldOp = getLoop().front().getTerminator();
 
  139  if (initYieldOp->getOperandTypes() != loopYieldOp->getOperandTypes())
 
  141           << 
"init and loop regions must yield the same types of values";
 
  142  if (initYieldOp->getOperandTypes() != getLoop().front().getArgumentTypes())
 
  144           << 
"loop region arguments must match the types of the values " 
  145              "yielded by the init and loop regions";
 
  146  size_t totalClocks = 0;
 
  147  auto circuitArgTy = getCircuit().getArgumentTypes();
 
  148  for (
auto input : circuitArgTy)
 
  149    if (isa<
seq::ClockType>(input))
 
  151  auto initYields = initYieldOp->getOperands();
 
  153  if (initYields.size() < totalClocks)
 
  155           << 
"init and loop regions must yield at least as many clock " 
  156              "values as there are clock arguments to the circuit region";
 
  157  for (
size_t i = 0; i < totalClocks; i++) {
 
  158    if (!isa<seq::ClockType>(initYieldOp->getOperand(i).getType()))
 
  160             << 
"init and loop regions must yield as many clock values as " 
  161                "there are clock arguments in the circuit region " 
  162                "before any other values";
 
  164  if (getNumRegs() > 0 && totalClocks == 0)
 
  165    return emitOpError(
"num_regs is non-zero, but the circuit region has no " 
  166                       "clock inputs to clock the registers");
 
  167  auto initialValues = getInitialValues();
 
  168  if (initialValues.size() != getNumRegs()) {
 
  170           << 
"number of initial values must match the number of registers";
 
  172  for (
auto attr : initialValues) {
 
  173    if (!isa<IntegerAttr, UnitAttr>(attr))
 
  175             << 
"initial values must be integer or unit attributes";
 
  184LogicalResult SimulationOp::verifyRegions() {
 
  185  if (getBody()->getNumArguments() != 2)
 
  186    return emitOpError() << 
"must have two block arguments";
 
  187  if (!isa<seq::ClockType>(getBody()->getArgument(0).getType()))
 
  188    return emitOpError() << 
"block argument #0 must be of type `!seq.clock`";
 
  189  if (!getBody()->getArgument(1).getType().isSignlessInteger(1))
 
  190    return emitOpError() << 
"block argument #1 must be of type `i1`";
 
  192  auto *yieldOp = getBody()->getTerminator();
 
  193  if (yieldOp->getNumOperands() != 2)
 
  194    return yieldOp->emitOpError() << 
"must have two operands";
 
  195  if (!yieldOp->getOperand(0).getType().isSignlessInteger(1))
 
  196    return yieldOp->emitOpError() << 
"operand #0 must be of type `i1`";
 
  197  if (!yieldOp->getOperand(1).getType().isSignlessInteger(1))
 
  198    return yieldOp->emitOpError() << 
"operand #1 must be of type `i1`";
 
  203void SimulationOp::getAsmBlockArgumentNames(Region ®ion,
 
  205  if (region.empty() || region.getNumArguments() != 2)
 
  207  setNameFn(region.getArgument(0), 
"clock");
 
  208  setNameFn(region.getArgument(1), 
"init");
 
  215#define GET_OP_CLASSES 
  216#include "circt/Dialect/Verif/Verif.cpp.inc" 
static InstancePath empty
 
static ClockEdge ltlToVerifClockEdge(ltl::ClockEdge ce)
 
static LogicalResult verifyCircuitRelationCheckOpRegions(OpTy &op)
 
static LogicalResult canonicalize(Op op, PatternRewriter &rewriter)
 
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.
 
function_ref< void(Value, StringRef)> OpAsmSetValueNameFn