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