CIRCT 24.0.0git
Loading...
Searching...
No Matches
HWModule.cpp
Go to the documentation of this file.
1//===- HWModule.cpp - HW API nanobind module ------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#include "CIRCTModules.h"
10
11#include "circt-c/Dialect/HW.h"
12
13#include "mlir-c/BuiltinAttributes.h"
14#include "mlir/Bindings/Python/NanobindAdaptors.h"
15#include "llvm/ADT/SmallString.h"
16#include "llvm/Support/raw_ostream.h"
17
18#include "NanobindUtils.h"
19#include "mlir-c/IR.h"
20#include "mlir-c/Support.h"
21#include "mlir/Bindings/Python/IRCore.h"
22#include "mlir/Bindings/Python/NanobindAdaptors.h"
23#include <nanobind/nanobind.h>
24namespace nb = nanobind;
25
26using namespace circt;
27using namespace mlir::python::nanobind_adaptors;
28using mlir::python::MLIR_BINDINGS_PYTHON_DOMAIN::DefaultingPyMlirContext;
29
30/// Populate the hw python module.
32 m.doc() = "HW dialect Python native extension";
33
34 m.def("get_bitwidth", &hwGetBitWidth);
35 m.def("get_canonical_type", &hwGetCanonicalType);
36
37 mlir_type_subclass(m, "InOutType", hwTypeIsAInOut)
38 .def_classmethod("get",
39 [](nb::object cls, MlirType innerType) {
40 return cls(hwInOutTypeGet(innerType));
41 })
42 .def_property_readonly("element_type", [](MlirType self) {
43 return hwInOutTypeGetElementType(self);
44 });
45
46 mlir_type_subclass(m, "ArrayType", hwTypeIsAArrayType)
47 .def_classmethod("get",
48 [](nb::object cls, MlirType elementType, intptr_t size) {
49 return cls(hwArrayTypeGet(elementType, size));
50 })
51 .def_property_readonly(
52 "element_type",
53 [](MlirType self) { return hwArrayTypeGetElementType(self); })
54 .def_property_readonly(
55 "size", [](MlirType self) { return hwArrayTypeGetSize(self); });
56
57 nb::enum_<HWModulePortDirection>(m, "ModulePortDirection")
58 .value("INPUT", HWModulePortDirection::Input)
59 .value("OUTPUT", HWModulePortDirection::Output)
60 .value("INOUT", HWModulePortDirection::InOut)
61 .export_values();
62
63 nb::class_<HWModulePort>(m, "ModulePort")
64 .def(nb::init<MlirAttribute, MlirType, HWModulePortDirection>());
65
66 mlir_type_subclass(m, "ModuleType", hwTypeIsAModuleType)
67 .def_classmethod(
68 "get",
69 [](nb::object cls, nb::list pyModulePorts, MlirContext ctx) {
70 std::vector<HWModulePort> modulePorts;
71 for (auto pyModulePort : pyModulePorts)
72 modulePorts.push_back(nb::cast<HWModulePort>(pyModulePort));
73
74 return cls(
75 hwModuleTypeGet(ctx, modulePorts.size(), modulePorts.data()));
76 },
77 nb::arg("cls"), nb::arg("ports"), nb::arg("context") = nb::none())
78 .def_property_readonly(
79 "input_types",
80 [](MlirType self) {
81 nb::list inputTypes;
82 intptr_t numInputs = hwModuleTypeGetNumInputs(self);
83 for (intptr_t i = 0; i < numInputs; ++i)
84 inputTypes.append(hwModuleTypeGetInputType(self, i));
85 return inputTypes;
86 })
87 .def_property_readonly(
88 "input_names",
89 [](MlirType self) {
90 std::vector<std::string> inputNames;
91 intptr_t numInputs = hwModuleTypeGetNumInputs(self);
92 for (intptr_t i = 0; i < numInputs; ++i) {
93 auto name = hwModuleTypeGetInputName(self, i);
94 inputNames.emplace_back(name.data, name.length);
95 }
96 return inputNames;
97 })
98 .def_property_readonly(
99 "output_types",
100 [](MlirType self) {
101 nb::list outputTypes;
102 intptr_t numOutputs = hwModuleTypeGetNumOutputs(self);
103 for (intptr_t i = 0; i < numOutputs; ++i)
104 outputTypes.append(hwModuleTypeGetOutputType(self, i));
105 return outputTypes;
106 })
107 .def_property_readonly("output_names", [](MlirType self) {
108 std::vector<std::string> outputNames;
109 intptr_t numOutputs = hwModuleTypeGetNumOutputs(self);
110 for (intptr_t i = 0; i < numOutputs; ++i) {
111 auto name = hwModuleTypeGetOutputName(self, i);
112 outputNames.emplace_back(name.data, name.length);
113 }
114 return outputNames;
115 });
116
117 mlir_type_subclass(m, "ParamIntType", hwTypeIsAIntType)
118 .def_classmethod(
119 "get_from_param",
120 [](nb::object cls, MlirContext ctx, MlirAttribute param) {
121 return cls(hwParamIntTypeGet(param));
122 })
123 .def_property_readonly("width", [](MlirType self) {
124 return hwParamIntTypeGetWidthAttr(self);
125 });
126
127 mlir_type_subclass(m, "StructType", hwTypeIsAStructType)
128 .def_classmethod(
129 "get",
130 [](nb::object cls, nb::list pyFieldInfos,
131 DefaultingPyMlirContext context) {
132 llvm::SmallVector<HWStructFieldInfo> mlirFieldInfos;
133 MlirContext ctx = context.resolve().get();
134
135 // Since we're just passing string refs to the type constructor,
136 // copy them into a temporary vector to give them all new addresses.
137 llvm::SmallVector<llvm::SmallString<8>> names;
138 for (size_t i = 0, e = pyFieldInfos.size(); i < e; ++i) {
139 auto tuple = nb::cast<nb::tuple>(pyFieldInfos[i]);
140 auto type = nb::cast<MlirType>(tuple[1]);
141 // Only override if the context is null.
142 if (mlirContextIsNull(ctx)) {
143 ctx = mlirTypeGetContext(type);
144 }
145 names.emplace_back(nb::cast<std::string>(tuple[0]));
146 auto nameStringRef =
147 mlirStringRefCreate(names[i].data(), names[i].size());
148 mlirFieldInfos.push_back(HWStructFieldInfo{
149 mlirIdentifierGet(ctx, nameStringRef), type});
150 }
151 if (mlirContextIsNull(ctx)) {
152 throw std::invalid_argument(
153 "StructType requires a context if no fields provided.");
154 }
155 return cls(hwStructTypeGet(ctx, mlirFieldInfos.size(),
156 mlirFieldInfos.data()));
157 },
158 nb::arg("cls"), nb::arg("fields"), nb::arg("context") = nb::none())
159 .def("get_field",
160 [](MlirType self, std::string fieldName) {
162 self, mlirStringRefCreateFromCString(fieldName.c_str()));
163 })
164 .def("get_field_index",
165 [](MlirType self, const std::string &fieldName) {
167 self, mlirStringRefCreateFromCString(fieldName.c_str()));
168 })
169 .def("get_fields", [](MlirType self) {
170 intptr_t num_fields = hwStructTypeGetNumFields(self);
171 nb::list fields;
172 for (intptr_t i = 0; i < num_fields; ++i) {
173 auto field = hwStructTypeGetFieldNum(self, i);
174 auto fieldName = mlirIdentifierStr(field.name);
175 std::string name(fieldName.data, fieldName.length);
176 fields.append(nb::make_tuple(name, field.type));
177 }
178 return fields;
179 });
180
181 mlir_type_subclass(m, "UnionType", hwTypeIsAUnionType)
182 .def_classmethod(
183 "get",
184 [](nb::object cls, nb::list pyFieldInfos) {
185 llvm::SmallVector<HWUnionFieldInfo> mlirFieldInfos;
186 MlirContext ctx;
187
188 // Since we're just passing string refs to the type constructor,
189 // copy them into a temporary vector to give them all new addresses.
190 llvm::SmallVector<llvm::SmallString<8>> names;
191 for (size_t i = 0, e = pyFieldInfos.size(); i < e; ++i) {
192 auto tuple = nb::cast<nb::tuple>(pyFieldInfos[i]);
193 if (tuple.size() < 3)
194 throw std::invalid_argument(
195 "UnionType field info must be a tuple of (name, type, "
196 "offset)");
197 auto type = nb::cast<MlirType>(tuple[1]);
198 size_t offset = nb::cast<size_t>(tuple[2]);
199 ctx = mlirTypeGetContext(type);
200 names.emplace_back(nb::cast<std::string>(tuple[0]));
201 auto nameStringRef =
202 mlirStringRefCreate(names[i].data(), names[i].size());
203 mlirFieldInfos.push_back(HWUnionFieldInfo{
204 mlirIdentifierGet(ctx, nameStringRef), type, offset});
205 }
206 return cls(hwUnionTypeGet(ctx, mlirFieldInfos.size(),
207 mlirFieldInfos.data()));
208 })
209 .def("get_field",
210 [](MlirType self, std::string fieldName) {
211 return hwUnionTypeGetField(
212 self, mlirStringRefCreateFromCString(fieldName.c_str()));
213 })
214 .def("get_field_index",
215 [](MlirType self, const std::string &fieldName) {
217 self, mlirStringRefCreateFromCString(fieldName.c_str()));
218 })
219 .def("get_fields", [](MlirType self) {
220 intptr_t num_fields = hwUnionTypeGetNumFields(self);
221 nb::list fields;
222 for (intptr_t i = 0; i < num_fields; ++i) {
223 auto field = hwUnionTypeGetFieldNum(self, i);
224 auto fieldName = mlirIdentifierStr(field.name);
225 std::string name(fieldName.data, fieldName.length);
226 fields.append(nb::make_tuple(name, field.type, field.offset));
227 }
228 return fields;
229 });
230
231 mlir_type_subclass(m, "TypeAliasType", hwTypeIsATypeAliasType)
232 .def_classmethod("get",
233 [](nb::object cls, std::string scope, std::string name,
234 MlirType innerType) {
235 return cls(hwTypeAliasTypeGet(
236 mlirStringRefCreateFromCString(scope.c_str()),
237 mlirStringRefCreateFromCString(name.c_str()),
238 innerType));
239 })
240 .def_property_readonly(
241 "canonical_type",
242 [](MlirType self) { return hwTypeAliasTypeGetCanonicalType(self); })
243 .def_property_readonly(
244 "inner_type",
245 [](MlirType self) { return hwTypeAliasTypeGetInnerType(self); })
246 .def_property_readonly("name",
247 [](MlirType self) {
248 MlirStringRef cStr =
250 return std::string(cStr.data, cStr.length);
251 })
252 .def_property_readonly("scope", [](MlirType self) {
253 MlirStringRef cStr = hwTypeAliasTypeGetScope(self);
254 return std::string(cStr.data, cStr.length);
255 });
256
257 mlir_attribute_subclass(m, "ParamDeclAttr", hwAttrIsAParamDeclAttr)
258 .def_classmethod(
259 "get",
260 [](nb::object cls, std::string name, MlirType type,
261 MlirAttribute value) {
262 return cls(hwParamDeclAttrGet(
263 mlirStringRefCreateFromCString(name.c_str()), type, value));
264 })
265 .def_classmethod("get_nodefault",
266 [](nb::object cls, std::string name, MlirType type) {
267 return cls(hwParamDeclAttrGet(
268 mlirStringRefCreateFromCString(name.c_str()), type,
269 MlirAttribute{nullptr}));
270 })
271 .def_property_readonly(
272 "value",
273 [](MlirAttribute self) { return hwParamDeclAttrGetValue(self); })
274 .def_property_readonly(
275 "param_type",
276 [](MlirAttribute self) { return hwParamDeclAttrGetType(self); })
277 .def_property_readonly("name", [](MlirAttribute self) {
278 MlirStringRef cStr = hwParamDeclAttrGetName(self);
279 return std::string(cStr.data, cStr.length);
280 });
281
282 mlir_attribute_subclass(m, "ParamDeclRefAttr", hwAttrIsAParamDeclRefAttr)
283 .def_classmethod(
284 "get",
285 [](nb::object cls, MlirContext ctx, std::string name) {
286 return cls(hwParamDeclRefAttrGet(
287 ctx, mlirStringRefCreateFromCString(name.c_str())));
288 })
289 .def_property_readonly(
290 "param_type",
291 [](MlirAttribute self) { return hwParamDeclRefAttrGetType(self); })
292 .def_property_readonly("name", [](MlirAttribute self) {
293 MlirStringRef cStr = hwParamDeclRefAttrGetName(self);
294 return std::string(cStr.data, cStr.length);
295 });
296
297 mlir_attribute_subclass(m, "ParamVerbatimAttr", hwAttrIsAParamVerbatimAttr)
298 .def_classmethod("get", [](nb::object cls, MlirAttribute text) {
299 return cls(hwParamVerbatimAttrGet(text));
300 });
301
302 mlir_attribute_subclass(m, "OutputFileAttr", hwAttrIsAOutputFileAttr)
303 .def_classmethod(
304 "get_from_filename",
305 [](nb::object cls, MlirAttribute fileName, bool excludeFromFileList,
306 bool includeReplicatedOp) {
308 fileName, excludeFromFileList, includeReplicatedOp));
309 })
310 .def_property_readonly("filename", [](MlirAttribute self) {
311 MlirStringRef cStr = hwOutputFileGetFileName(self);
312 return std::string(cStr.data, cStr.length);
313 });
314
315 mlir_attribute_subclass(m, "InnerSymAttr", hwAttrIsAInnerSymAttr)
316 .def_classmethod("get",
317 [](nb::object cls, MlirAttribute symName) {
318 return cls(hwInnerSymAttrGet(symName));
319 })
320 .def_property_readonly("symName", [](MlirAttribute self) {
321 return hwInnerSymAttrGetSymName(self);
322 });
323
324 mlir_attribute_subclass(m, "InnerRefAttr", hwAttrIsAInnerRefAttr)
325 .def_classmethod(
326 "get",
327 [](nb::object cls, MlirAttribute moduleName, MlirAttribute innerSym) {
328 return cls(hwInnerRefAttrGet(moduleName, innerSym));
329 })
330 .def_property_readonly(
331 "module",
332 [](MlirAttribute self) { return hwInnerRefAttrGetModule(self); })
333 .def_property_readonly("name", [](MlirAttribute self) {
334 return hwInnerRefAttrGetName(self);
335 });
336}
MlirType elementType
Definition CHIRRTL.cpp:29
static std::unique_ptr< Context > context
MLIR_CAPI_EXPORTED MlirType hwStructTypeGet(MlirContext ctx, intptr_t numElements, HWStructFieldInfo const *elements)
Creates an HW struct type in the context associated with the elements.
Definition HW.cpp:161
MLIR_CAPI_EXPORTED intptr_t hwModuleTypeGetNumOutputs(MlirType type)
Get an HW module type's number of outputs.
Definition HW.cpp:124
MLIR_CAPI_EXPORTED MlirStringRef hwOutputFileGetFileName(MlirAttribute outputFile)
Definition HW.cpp:377
MLIR_CAPI_EXPORTED MlirType hwParamDeclAttrGetType(MlirAttribute decl)
Definition HW.cpp:330
MLIR_CAPI_EXPORTED MlirAttribute hwOutputFileGetFromFileName(MlirAttribute text, bool excludeFromFileList, bool includeReplicatedOp)
Definition HW.cpp:369
MLIR_CAPI_EXPORTED MlirAttribute hwInnerRefAttrGet(MlirAttribute moduleName, MlirAttribute innerSym)
Definition HW.cpp:301
MLIR_CAPI_EXPORTED bool hwTypeIsAArrayType(MlirType)
If the type is an HW array.
Definition HW.cpp:46
MLIR_CAPI_EXPORTED MlirAttribute hwParamIntTypeGetWidthAttr(MlirType)
Definition HW.cpp:66
MLIR_CAPI_EXPORTED MlirAttribute hwInnerRefAttrGetModule(MlirAttribute)
Definition HW.cpp:312
MLIR_CAPI_EXPORTED MlirType hwModuleTypeGetInputType(MlirType type, intptr_t index)
Get an HW module type's input type at a specific index.
Definition HW.cpp:116
MLIR_CAPI_EXPORTED int64_t hwGetBitWidth(MlirType)
Return the hardware bit width of a type.
Definition HW.cpp:38
MLIR_CAPI_EXPORTED HWUnionFieldInfo hwUnionTypeGetFieldNum(MlirType unionType, unsigned idx)
Definition HW.cpp:231
MLIR_CAPI_EXPORTED MlirType hwTypeAliasTypeGet(MlirStringRef scope, MlirStringRef name, MlirType innerType)
Definition HW.cpp:245
MLIR_CAPI_EXPORTED MlirType hwModuleTypeGet(MlirContext ctx, intptr_t numPorts, HWModulePort const *ports)
Creates an HW module type.
Definition HW.cpp:84
MLIR_CAPI_EXPORTED MlirAttribute hwInnerSymAttrGetSymName(MlirAttribute)
Definition HW.cpp:293
MLIR_CAPI_EXPORTED MlirType hwGetCanonicalType(MlirType type)
Recursively remove HW type aliases from a type and its subelements.
Definition HW.cpp:40
MLIR_CAPI_EXPORTED MlirAttribute hwStructTypeGetFieldIndex(MlirType structType, MlirStringRef fieldName)
Definition HW.cpp:177
MLIR_CAPI_EXPORTED HWStructFieldInfo hwStructTypeGetFieldNum(MlirType structType, unsigned idx)
Definition HW.cpp:190
MLIR_CAPI_EXPORTED MlirType hwArrayTypeGet(MlirType element, size_t size)
Creates a fixed-size HW array type in the context associated with element.
Definition HW.cpp:48
MLIR_CAPI_EXPORTED MlirType hwParamIntTypeGet(MlirAttribute parameter)
Definition HW.cpp:62
MLIR_CAPI_EXPORTED MlirAttribute hwParamDeclAttrGetValue(MlirAttribute decl)
Definition HW.cpp:333
MLIR_CAPI_EXPORTED bool hwTypeIsATypeAliasType(MlirType)
If the type is an HW type alias.
Definition HW.cpp:241
MLIR_CAPI_EXPORTED MlirType hwTypeAliasTypeGetCanonicalType(MlirType typeAlias)
Definition HW.cpp:257
MLIR_CAPI_EXPORTED MlirStringRef hwTypeAliasTypeGetName(MlirType typeAlias)
Definition HW.cpp:267
MLIR_CAPI_EXPORTED intptr_t hwModuleTypeGetNumInputs(MlirType type)
Get an HW module type's number of inputs.
Definition HW.cpp:112
MLIR_CAPI_EXPORTED bool hwTypeIsAIntType(MlirType)
If the type is an HW int.
Definition HW.cpp:60
MLIR_CAPI_EXPORTED MlirAttribute hwInnerRefAttrGetName(MlirAttribute)
Definition HW.cpp:308
MLIR_CAPI_EXPORTED bool hwAttrIsAInnerRefAttr(MlirAttribute)
Definition HW.cpp:297
MLIR_CAPI_EXPORTED MlirAttribute hwUnionTypeGetFieldIndex(MlirType unionType, MlirStringRef fieldName)
Definition HW.cpp:218
MLIR_CAPI_EXPORTED MlirAttribute hwInnerSymAttrGet(MlirAttribute symName)
Definition HW.cpp:285
MLIR_CAPI_EXPORTED MlirType hwStructTypeGetField(MlirType structType, MlirStringRef fieldName)
Definition HW.cpp:172
MLIR_CAPI_EXPORTED intptr_t hwUnionTypeGetNumFields(MlirType unionType)
Definition HW.cpp:226
MLIR_CAPI_EXPORTED MlirType hwTypeAliasTypeGetInnerType(MlirType typeAlias)
Definition HW.cpp:262
MLIR_CAPI_EXPORTED MlirStringRef hwModuleTypeGetInputName(MlirType type, intptr_t index)
Get an HW module type's input name at a specific index.
Definition HW.cpp:120
MLIR_CAPI_EXPORTED bool hwAttrIsAParamDeclRefAttr(MlirAttribute)
Definition HW.cpp:337
MLIR_CAPI_EXPORTED bool hwAttrIsAOutputFileAttr(MlirAttribute)
Definition HW.cpp:365
MLIR_CAPI_EXPORTED MlirAttribute hwParamDeclAttrGet(MlirStringRef name, MlirType type, MlirAttribute value)
Definition HW.cpp:319
MLIR_CAPI_EXPORTED MlirType hwUnionTypeGetField(MlirType unionType, MlirStringRef fieldName)
Definition HW.cpp:213
MLIR_CAPI_EXPORTED MlirStringRef hwTypeAliasTypeGetScope(MlirType typeAlias)
Definition HW.cpp:272
MLIR_CAPI_EXPORTED bool hwTypeIsAStructType(MlirType)
If the type is an HW struct.
Definition HW.cpp:157
MLIR_CAPI_EXPORTED bool hwAttrIsAInnerSymAttr(MlirAttribute)
Definition HW.cpp:281
MLIR_CAPI_EXPORTED bool hwTypeIsAInOut(MlirType type)
If the type is an HW inout.
Definition HW.cpp:78
MLIR_CAPI_EXPORTED MlirType hwInOutTypeGetElementType(MlirType)
Returns the element type of an inout type.
Definition HW.cpp:74
MLIR_CAPI_EXPORTED MlirStringRef hwParamDeclRefAttrGetName(MlirAttribute decl)
Definition HW.cpp:348
MLIR_CAPI_EXPORTED MlirStringRef hwModuleTypeGetOutputName(MlirType type, intptr_t index)
Get an HW module type's output name at a specific index.
Definition HW.cpp:132
MLIR_CAPI_EXPORTED MlirType hwUnionTypeGet(MlirContext ctx, intptr_t numElements, HWUnionFieldInfo const *elements)
Creates an HW union type in the context associated with the elements.
Definition HW.cpp:201
MLIR_CAPI_EXPORTED MlirType hwInOutTypeGet(MlirType element)
Creates an HW inout type in the context associated with element.
Definition HW.cpp:70
MLIR_CAPI_EXPORTED MlirType hwArrayTypeGetElementType(MlirType)
returns the element type of an array type
Definition HW.cpp:52
MLIR_CAPI_EXPORTED bool hwAttrIsAParamVerbatimAttr(MlirAttribute)
Definition HW.cpp:355
MLIR_CAPI_EXPORTED bool hwAttrIsAParamDeclAttr(MlirAttribute)
Definition HW.cpp:316
MLIR_CAPI_EXPORTED bool hwTypeIsAModuleType(MlirType type)
If the type is an HW module type.
Definition HW.cpp:80
MLIR_CAPI_EXPORTED MlirAttribute hwParamDeclRefAttrGet(MlirContext ctx, MlirStringRef cName)
Definition HW.cpp:341
MLIR_CAPI_EXPORTED intptr_t hwStructTypeGetNumFields(MlirType structType)
Definition HW.cpp:185
MLIR_CAPI_EXPORTED MlirType hwModuleTypeGetOutputType(MlirType type, intptr_t index)
Get an HW module type's output type at a specific index.
Definition HW.cpp:128
MLIR_CAPI_EXPORTED bool hwTypeIsAUnionType(MlirType)
If the type is an HW union.
Definition HW.cpp:199
MLIR_CAPI_EXPORTED intptr_t hwArrayTypeGetSize(MlirType)
returns the size of an array type
Definition HW.cpp:56
MLIR_CAPI_EXPORTED MlirStringRef hwParamDeclAttrGetName(MlirAttribute decl)
Definition HW.cpp:327
MLIR_CAPI_EXPORTED MlirAttribute hwParamVerbatimAttrGet(MlirAttribute text)
Definition HW.cpp:358
MLIR_CAPI_EXPORTED MlirType hwParamDeclRefAttrGetType(MlirAttribute decl)
Definition HW.cpp:351
Direction get(bool isOutput)
Returns an output direction if isOutput is true, otherwise returns an input direction.
Definition CalyxOps.cpp:56
void populateDialectHWSubmodule(nanobind::module_ &m)
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.