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