14 #include "mlir/IR/Builders.h"
15 #include "mlir/IR/OpImplementation.h"
17 using namespace circt;
18 using namespace circt::interop;
24 void ProceduralInitOp::build(OpBuilder &odsBuilder, OperationState &odsState,
26 InteropMechanism interopMechanism) {
27 Region *region = odsState.addRegion();
28 region->push_back(
new Block);
29 odsState.addAttribute(
30 getInteropMechanismAttrName(odsState.name),
32 odsState.addOperands(states);
36 if (getBody()->getNumArguments() > 0)
37 return emitOpError(
"region must not have any arguments");
46 void ProceduralUpdateOp::build(OpBuilder &odsBuilder, OperationState &odsState,
47 TypeRange outputs, ValueRange inputs,
49 InteropMechanism interopMechanism) {
50 Region *region = odsState.addRegion();
52 bodyBlock->addArguments(
54 SmallVector<Location>(states.size(), odsState.location));
55 bodyBlock->addArguments(
57 SmallVector<Location>(inputs.size(), odsState.location));
58 region->push_back(bodyBlock);
59 odsState.addOperands(states);
60 odsState.addOperands(inputs);
61 odsState.addAttribute(getOperandSegmentSizesAttrName(odsState.name),
62 odsBuilder.getDenseI32ArrayAttr(
63 {(int32_t)states.size(), (int32_t)inputs.size()}));
64 odsState.addAttribute(
65 getInteropMechanismAttrName(odsState.name),
67 odsState.addTypes(outputs);
71 if (getBody()->getNumArguments() != getStates().size() + getInputs().size())
72 return emitOpError(
"region must have the same number of arguments ")
73 <<
"as inputs and states together, but got "
74 << getBody()->getNumArguments() <<
" arguments and "
75 << (getStates().size() + getInputs().size())
76 <<
" state plus input types";
78 SmallVector<Type> types{getStates().getTypes()};
79 types.append(SmallVector<Type>{getInputs().getTypes()});
80 if (getBody()->getArgumentTypes() != types)
81 return emitOpError(
"region argument types must match state types");
90 void ProceduralDeallocOp::build(OpBuilder &odsBuilder, OperationState &odsState,
92 InteropMechanism interopMechanism) {
93 Region *region = odsState.addRegion();
95 region->push_back(bodyBlock);
96 bodyBlock->addArguments(
98 SmallVector<Location>(states.size(), odsState.location));
99 odsState.addAttribute(
100 getInteropMechanismAttrName(odsState.name),
102 odsState.addOperands(states);
106 if (getBody()->getNumArguments() != getStates().size())
107 return emitOpError(
"region must have the same number of arguments ")
108 <<
"as states, but got " << getBody()->getNumArguments()
109 <<
" arguments and " << getStates().size() <<
" states";
111 if (getBody()->getArgumentTypes() != getStates().getTypes())
112 return emitOpError(
"region argument types must match state types");
122 auto *parent = getOperation()->getParentOp();
125 if (isa<ProceduralUpdateOp>(parent))
126 values = parent->getResults();
128 values = parent->getOperands();
130 if (getNumOperands() != values.size())
131 return emitOpError(
"has ")
133 <<
" operands, but enclosing interop operation requires "
134 << values.size() <<
" values";
137 llvm::enumerate(llvm::zip(getOperandTypes(), values.getTypes()))) {
138 auto [returnOperandType, parentType] = it.value();
139 if (returnOperandType != parentType)
140 return emitError() <<
"type of return operand " << it.index() <<
" ("
142 <<
") doesn't match required type (" << parentType
154 #define GET_OP_CLASSES
155 #include "circt/Dialect/Interop/Interop.cpp.inc"
156 #include "circt/Dialect/Interop/InteropEnums.cpp.inc"
static LogicalResult verify(Value clock, bool eventExists, mlir::Location loc)
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.