13 using namespace circt;
17 Operation *instanceOp, SymbolTableCollection &symbolTable,
18 mlir::FlatSymbolRefAttr moduleName, Operation *&module) {
19 module = symbolTable.lookupNearestSymbolFrom(instanceOp, moduleName);
20 if (module ==
nullptr)
21 return instanceOp->emitError(
"Cannot find module definition '")
22 << moduleName.getValue() <<
"'";
25 if (!isa<HWModuleLike>(module))
26 return instanceOp->emitError(
"symbol reference '")
27 << moduleName.getValue() <<
"' isn't a module";
33 Location loc, ArrayAttr parameters, ArrayRef<Type> types,
34 SmallVectorImpl<Type> &resolvedTypes,
const EmitErrorFn &emitError) {
35 for (
auto type : types) {
37 if (failed(expectedType)) {
38 emitError([&](
auto &diag) {
39 diag <<
"failed to resolve parametric input of instantiated module";
45 resolvedTypes.push_back(*expectedType);
52 ArrayAttr moduleArgNames,
54 ArrayRef<Type> moduleInputTypes,
57 if (moduleInputTypes.size() != inputTypes.size()) {
58 emitError([&](
auto &diag) {
59 diag <<
"has a wrong number of operands; expected "
60 << moduleInputTypes.size() <<
" but got " << inputTypes.size();
66 if (argNames.size() != inputTypes.size()) {
67 emitError([&](
auto &diag) {
68 diag <<
"has a wrong number of input port names; expected "
69 << inputTypes.size() <<
" but got " << argNames.size();
75 for (
size_t i = 0; i != inputTypes.size(); ++i) {
76 auto expectedType = moduleInputTypes[i];
77 auto operandType = inputTypes[i];
79 if (operandType != expectedType) {
80 emitError([&](
auto &diag) {
81 diag <<
"operand type #" << i <<
" must be " << expectedType
82 <<
", but got " << operandType;
88 if (argNames[i] != moduleArgNames[i]) {
89 emitError([&](
auto &diag) {
90 diag <<
"input label #" << i <<
" must be " << moduleArgNames[i]
91 <<
", but got " << argNames[i];
102 ArrayAttr resultNames, ArrayAttr moduleResultNames, TypeRange resultTypes,
103 ArrayRef<Type> moduleResultTypes,
const EmitErrorFn &emitError) {
105 if (moduleResultTypes.size() != resultTypes.size()) {
106 emitError([&](
auto &diag) {
107 diag <<
"has a wrong number of results; expected "
108 << moduleResultTypes.size() <<
" but got " << resultTypes.size();
114 if (resultNames.size() != resultTypes.size()) {
115 emitError([&](
auto &diag) {
116 diag <<
"has a wrong number of results port labels; expected "
117 << resultTypes.size() <<
" but got " << resultNames.size();
123 for (
size_t i = 0; i != resultTypes.size(); ++i) {
124 auto expectedType = moduleResultTypes[i];
125 auto resultType = resultTypes[i];
127 if (resultType != expectedType) {
128 emitError([&](
auto &diag) {
129 diag <<
"result type #" << i <<
" must be " << expectedType
130 <<
", but got " << resultType;
136 if (resultNames[i] != moduleResultNames[i]) {
137 emitError([&](
auto &diag) {
138 diag <<
"result label #" << i <<
" must be " << moduleResultNames[i]
139 <<
", but got " << resultNames[i];
151 ArrayAttr moduleParameters,
154 auto numParameters = parameters.size();
155 if (numParameters != moduleParameters.size()) {
156 emitError([&](
auto &diag) {
157 diag <<
"expected " << moduleParameters.size() <<
" parameters but had "
164 for (
size_t i = 0; i != numParameters; ++i) {
165 auto param = cast<ParamDeclAttr>(parameters[i]);
166 auto modParam = cast<ParamDeclAttr>(moduleParameters[i]);
168 auto paramName = param.getName();
169 if (paramName != modParam.getName()) {
170 emitError([&](
auto &diag) {
171 diag <<
"parameter #" << i <<
" should have name " << modParam.getName()
172 <<
" but has name " << paramName;
178 if (param.getType() != modParam.getType()) {
179 emitError([&](
auto &diag) {
180 diag <<
"parameter " << paramName <<
" should have type "
181 << modParam.getType() <<
" but has type " << param.getType();
189 if (!param.getValue()) {
190 emitError([&](
auto &diag) {
191 diag <<
"parameter " << paramName <<
" must have a value";
202 Operation *instance, FlatSymbolRefAttr moduleRef, OperandRange inputs,
203 TypeRange results, ArrayAttr argNames, ArrayAttr resultNames,
204 ArrayAttr parameters, SymbolTableCollection &symbolTable) {
216 [&](
const std::function<bool(InFlightDiagnostic & diag)> &fn) {
217 auto diag = instance->emitOpError();
219 diag.attachNote(module->getLoc()) <<
"module declared here";
223 auto mod = cast<HWModuleLike>(module);
226 auto modResultNames =
229 ArrayRef<Type> resolvedModInputTypesRef =
getModuleType(module).getInputs();
230 SmallVector<Type> resolvedModInputTypes;
233 instance->getLoc(), parameters,
getModuleType(module).getInputs(),
234 resolvedModInputTypes, emitError)))
236 resolvedModInputTypesRef = resolvedModInputTypes;
239 argNames, modArgNames, inputs.getTypes(), resolvedModInputTypesRef,
244 ArrayRef<Type> resolvedModResultTypesRef =
getModuleType(module).getResults();
245 SmallVector<Type> resolvedModResultTypes;
248 instance->getLoc(), parameters,
getModuleType(module).getResults(),
249 resolvedModResultTypes, emitError)))
251 resolvedModResultTypesRef = resolvedModResultTypes;
254 resultNames, modResultNames, results, resolvedModResultTypesRef,
260 ArrayAttr modParameters = module->getAttrOfType<ArrayAttr>(
"parameters");
271 ArrayAttr moduleParameters,
275 for (
auto param : parameters) {
276 auto paramAttr = cast<ParamDeclAttr>(param);
277 auto value = paramAttr.getValue();
283 auto typedValue = dyn_cast<mlir::TypedAttr>(value);
285 emitError([&](
auto &diag) {
286 diag <<
"parameter " << paramAttr
287 <<
" should have a typed value; has value " << value;
293 if (typedValue.getType() != paramAttr.getType()) {
294 emitError([&](
auto &diag) {
295 diag <<
"parameter " << paramAttr <<
" should have type "
296 << paramAttr.getType() <<
"; has type " << typedValue.getType();
310 if (names && idx < names.size())
311 return cast<StringAttr>(names[idx]);
317 SmallVector<Attribute> newNames(oldNames.begin(), oldNames.end());
318 if (newNames[i] == name)
325 StringRef instanceName,
326 ArrayAttr resultNames,
327 ValueRange results) {
329 std::string name = instanceName.str() +
".";
330 size_t baseNameLen = name.size();
332 for (
size_t i = 0, e = resultNames.size(); i != e; ++i) {
333 auto resName =
getName(resultNames, i);
334 name.resize(baseNameLen);
335 if (resName && !resName.getValue().empty())
336 name += resName.getValue().str();
338 name += std::to_string(i);
339 setNameFn(results[i], name);
346 SmallVector<PortInfo> ports;
348 auto argNames = instanceOp->getAttrOfType<ArrayAttr>(
"argNames");
349 auto argTypes = moduleTy.getInputs();
350 auto argLocs = instanceOp->getAttrOfType<ArrayAttr>(
"argLocs");
352 auto resultNames = instanceOp->getAttrOfType<ArrayAttr>(
"resultNames");
353 auto resultTypes = moduleTy.getResults();
354 auto resultLocs = instanceOp->getAttrOfType<ArrayAttr>(
"resultLocs");
356 ports.reserve(argTypes.size() + resultTypes.size());
357 for (
unsigned i = 0, e = argTypes.size(); i < e; ++i) {
358 auto type = argTypes[i];
361 if (
auto inout = dyn_cast<InOutType>(type)) {
362 type = inout.getElementType();
368 loc = cast<LocationAttr>(argLocs[i]);
370 {{cast<StringAttr>(argNames[i]), type, direction}, i, emptyDict, loc});
373 for (
unsigned i = 0, e = resultTypes.size(); i < e; ++i) {
376 loc = cast<LocationAttr>(resultLocs[i]);
377 ports.push_back({{cast<StringAttr>(resultNames[i]), resultTypes[i],
Direction get(bool isOutput)
Returns an output direction if isOutput is true, otherwise returns an input direction.
LogicalResult verifyParameterStructure(ArrayAttr parameters, ArrayAttr moduleParameters, const EmitErrorFn &emitError)
Check that all the parameter values specified to the instance are structurally valid.
std::function< void(std::function< bool(InFlightDiagnostic &)>)> EmitErrorFn
Whenever the nested function returns true, a note referring to the referenced module is attached to t...
LogicalResult verifyOutputs(ArrayAttr resultNames, ArrayAttr moduleResultNames, TypeRange resultTypes, ArrayRef< Type > moduleResultTypes, const EmitErrorFn &emitError)
Verify that the list of outputs of the instance and the module match in terms of length,...
LogicalResult verifyInstanceOfHWModule(Operation *instance, FlatSymbolRefAttr moduleRef, OperandRange inputs, TypeRange results, ArrayAttr argNames, ArrayAttr resultNames, ArrayAttr parameters, SymbolTableCollection &symbolTable)
Combines verifyReferencedModule, verifyInputs, verifyOutputs, and verifyParameters.
SmallVector< PortInfo > getPortList(Operation *instanceOp)
Return the port list of an instance, based on the name, type and location attributes present on the i...
StringAttr getName(ArrayAttr names, size_t idx)
Return the name at the specified index of the ArrayAttr or null if it cannot be determined.
LogicalResult resolveParametricTypes(Location loc, ArrayAttr parameters, ArrayRef< Type > types, SmallVectorImpl< Type > &resolvedTypes, const EmitErrorFn &emitError)
Stores a resolved version of each type in.
LogicalResult verifyInputs(ArrayAttr argNames, ArrayAttr moduleArgNames, TypeRange inputTypes, ArrayRef< Type > moduleInputTypes, const EmitErrorFn &emitError)
Verify that the list of inputs of the instance and the module match in terms of length,...
ArrayAttr updateName(ArrayAttr oldNames, size_t i, StringAttr name)
Change the name at the specified index of the.
LogicalResult verifyReferencedModule(Operation *instanceOp, SymbolTableCollection &symbolTable, mlir::FlatSymbolRefAttr moduleName, Operation *&module)
Verify that the instance refers to a valid HW module.
void getAsmResultNames(OpAsmSetValueNameFn setNameFn, StringRef instanceName, ArrayAttr resultNames, ValueRange results)
Suggest a name for each result value based on the saved result names attribute.
LogicalResult verifyParameters(ArrayAttr parameters, ArrayAttr moduleParameters, const EmitErrorFn &emitError)
Verify that the parameter lists of the instance and the module match in terms of length,...
FunctionType getModuleType(Operation *module)
Return the signature for the specified module as a function type.
LogicalResult checkParameterInContext(Attribute value, Operation *module, Operation *usingOp, bool disallowParamRefs=false)
Check parameter specified by value to see if it is valid within the scope of the specified module mod...
enum PEO uint32_t mlir::FailureOr< mlir::Type > evaluateParametricType(mlir::Location loc, mlir::ArrayAttr parameters, mlir::Type type, bool emitErrors=true)
Returns a resolved version of 'type' wherein any parameter reference has been evaluated based on the ...
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.
function_ref< void(Value, StringRef)> OpAsmSetValueNameFn