19#include "mlir/CAPI/IR.h"
20#include "mlir/CAPI/Registration.h"
21#include "mlir/CAPI/Support.h"
22#include "llvm/Support/JSON.h"
25using namespace firrtl;
34 circt::firrtl::FIRRTLDialect)
54 return wrap(UIntType::get(
unwrap(ctx), width));
60 return wrap(SIntType::get(
unwrap(ctx), width));
76 return isa<AsyncResetType>(
unwrap(type));
84 return isa<AnalogType>(
unwrap(type));
88 return wrap(AnalogType::get(
unwrap(ctx), width));
92 return isa<FVectorType>(
unwrap(type));
96 auto baseType = cast<FIRRTLBaseType>(
unwrap(element));
97 assert(baseType &&
"element must be base type");
99 return wrap(FVectorType::get(baseType, count));
103 return wrap(cast<FVectorType>(
unwrap(vec)).getElementType());
107 return cast<FVectorType>(
unwrap(vec)).getNumElements();
111 return isa<BundleType>(
unwrap(type));
115 return isa<OpenBundleType>(
unwrap(type));
120 bool bundleCompatible =
true;
121 SmallVector<OpenBundleType::BundleElement, 4> bundleFields;
123 bundleFields.reserve(count);
125 for (
size_t i = 0; i < count; i++) {
126 auto field = fields[i];
127 auto type = cast<FIRRTLType>(
unwrap(field.type));
128 bundleFields.emplace_back(
unwrap(field.name), field.isFlip, type);
129 bundleCompatible &= isa<BundleType::ElementType>(type);
133 if (bundleCompatible) {
134 auto bundleFieldsMapped = llvm::map_range(bundleFields, [](
auto field) {
135 return BundleType::BundleElement{
136 field.name, field.isFlip, cast<BundleType::ElementType>(field.type)};
139 BundleType::get(
unwrap(ctx), llvm::to_vector(bundleFieldsMapped)));
141 return wrap(OpenBundleType::get(
unwrap(ctx), bundleFields));
145 if (
auto bundleType = dyn_cast<BundleType>(
unwrap(bundle))) {
146 return bundleType.getNumElements();
147 }
else if (
auto bundleType = dyn_cast<OpenBundleType>(
unwrap(bundle))) {
148 return bundleType.getNumElements();
150 llvm_unreachable(
"must be a bundle type");
156 auto unwrapped =
unwrap(type);
158 auto cvt = [field](
auto element) {
160 field->
isFlip = element.isFlip;
163 if (
auto bundleType = dyn_cast<BundleType>(unwrapped)) {
164 cvt(bundleType.getElement(index));
166 }
else if (
auto bundleType = dyn_cast<OpenBundleType>(unwrapped)) {
167 cvt(bundleType.getElement(index));
174 std::optional<unsigned> fieldIndex;
175 if (
auto bundleType = dyn_cast<BundleType>(
unwrap(type))) {
176 fieldIndex = bundleType.getElementIndex(
unwrap(fieldName));
177 }
else if (
auto bundleType = dyn_cast<OpenBundleType>(
unwrap(type))) {
178 fieldIndex = bundleType.getElementIndex(
unwrap(fieldName));
180 llvm_unreachable(
"must be a bundle type");
182 assert(fieldIndex.has_value() &&
"unknown field");
183 return fieldIndex.value();
189 auto baseType = dyn_cast<FIRRTLBaseType>(
unwrap(target));
190 assert(baseType &&
"target must be base type");
192 return wrap(RefType::get(baseType, forceable));
196 MlirAttribute layer) {
197 auto baseType = dyn_cast<FIRRTLBaseType>(
unwrap(target));
198 assert(baseType &&
"target must be base type");
199 auto layerAttr = dyn_cast<SymbolRefAttr>(
unwrap(layer));
200 assert(layerAttr &&
"layer must be symbol ref attribute");
202 return wrap(RefType::get(baseType, forceable, layerAttr));
206 return isa<AnyRefType>(
unwrap(type));
214 return isa<FIntegerType>(
unwrap(type));
222 return isa<DoubleType>(
unwrap(type));
230 return isa<StringType>(
unwrap(type));
253 assert(type &&
"element must be property type");
255 return wrap(ListType::get(
unwrap(ctx), type));
261 size_t numberOfElements,
263 auto nameSymbol = dyn_cast<FlatSymbolRefAttr>(
unwrap(name));
264 assert(nameSymbol &&
"name must be FlatSymbolRefAttr");
266 SmallVector<ClassElement, 4> classElements;
267 classElements.reserve(numberOfElements);
269 for (
size_t i = 0; i < numberOfElements; i++) {
270 auto element = elements[i];
273 classElements.emplace_back(
unwrap(element.name),
unwrap(element.type), dir);
275 return wrap(ClassType::get(
unwrap(ctx), nameSymbol, classElements));
279 auto baseType = type_dyn_cast<FIRRTLBaseType>(
unwrap(type));
280 assert(baseType &&
"unexpected type, must be base type");
281 return wrap(baseType.getMaskType());
292 switch (convention) {
294 value = Convention::Internal;
297 value = Convention::Scalarized;
301 return wrap(ConventionAttr::get(
unwrap(ctx), value));
306 LayerConvention value;
308 switch (convention) {
310 value = LayerConvention::Bind;
313 value = LayerConvention::Inline;
317 return wrap(LayerConventionAttr::get(
unwrap(ctx), value));
323 static_cast<std::underlying_type_t<Direction>
>(Direction::In));
325 static_cast<std::underlying_type_t<Direction>
>(Direction::Out));
330 unwrap(ctx), ArrayRef(
reinterpret_cast<const Direction *
>(dirs), count)));
334 MlirType type, MlirAttribute value) {
344 value = NameKindEnum::DroppableName;
347 value = NameKindEnum::InterestingName;
351 return wrap(NameKindEnumAttr::get(
unwrap(ctx), value));
359 value = RUWBehavior::Undefined;
362 value = RUWBehavior::Old;
365 value = RUWBehavior::New;
369 return wrap(RUWBehaviorAttr::get(
unwrap(ctx), value));
373 bool isBinary,
bool isInline) {
375 MemoryInitAttr::get(
unwrap(ctx),
unwrap(filename), isBinary, isInline));
383 value = MemDirAttr::Infer;
386 value = MemDirAttr::Read;
389 value = MemDirAttr::Write;
392 value = MemDirAttr::ReadWrite;
396 return wrap(MemDirAttrAttr::get(
unwrap(ctx), value));
403 switch (eventControl) {
405 value = EventControl::AtPosEdge;
408 value = EventControl::AtNegEdge;
411 value = EventControl::AtEdge;
415 return wrap(EventControlAttr::get(
unwrap(ctx), value));
419 MlirStringRef str, uint8_t radix) {
420 auto value = APInt{numBits,
unwrap(str), radix};
421 return wrap(IntegerAttr::get(
unwrap(type), value));
429 flowValue = Flow::None;
432 flowValue = Flow::Source;
435 flowValue = Flow::Sink;
438 flowValue = Flow::Duplex;
444 switch (flowResult) {
454 llvm_unreachable(
"invalid flow");
458 MlirContext ctx, MlirStringRef annotationsStr,
459 MlirAttribute *importedAnnotationsArray) {
460 auto annotations = json::parse(
unwrap(annotationsStr));
465 auto *ctxUnwrapped =
unwrap(ctx);
467 json::Path::Root root;
468 SmallVector<Attribute> annos;
474 *importedAnnotationsArray =
wrap(ArrayAttr::get(ctxUnwrapped, annos));
assert(baseType &&"element must be base type")
return wrap(CMemoryType::get(unwrap(ctx), baseType, numElements))
bool firrtlTypeIsAUInt(MlirType type)
Checks if this type is a unsigned integer type.
bool firrtlTypeIsASInt(MlirType type)
Checks if this type is a signed integer type.
bool firrtlTypeIsARef(MlirType type)
Checks if this type is a ref type.
bool firrtlTypeIsAString(MlirType type)
Checks if this type is a property string type.
MlirAttribute firrtlAttrGetMemDir(MlirContext ctx, FIRRTLMemDir dir)
Creates a MemDirAttr with the specified memory port direction.
MlirType firrtlTypeGetAsyncReset(MlirContext ctx)
Creates an async reset type.
MlirType firrtlTypeGetList(MlirContext ctx, MlirType elementType)
Creates a property list type with the specified element type.
bool firrtlTypeIsAClass(MlirType type)
Checks if this type is a class type.
bool firrtlTypeGetBundleFieldByIndex(MlirType type, size_t index, FIRRTLBundleField *field)
Returns the field at the specified index in the bundle type.
MlirAttribute firrtlAttrGetIntegerFromString(MlirType type, unsigned numBits, MlirStringRef str, uint8_t radix)
Creates an IntegerAttr from a string representation of integer.
MlirType firrtlTypeGetBoolean(MlirContext ctx)
Creates a property boolean type.
MlirType firrtlTypeGetDouble(MlirContext ctx)
Creates a property double type.
MlirType firrtlTypeGetPath(MlirContext ctx)
Creates a property path type.
MlirType firrtlTypeGetConstType(MlirType type, bool isConst)
Returns a const or non-const version of this type.
MlirType firrtlTypeGetString(MlirContext ctx)
Creates a property string type.
bool firrtlTypeIsAClock(MlirType type)
Checks if this type is a clock type.
MlirType firrtlTypeGetAnalog(MlirContext ctx, int32_t width)
Creates an analog type with the specified width.
MlirType firrtlTypeGetInteger(MlirContext ctx)
Creates a property integer type.
bool firrtlTypeIsAInteger(MlirType type)
Checks if this type is a property integer type.
MlirAttribute firrtlAttrGetConvention(MlirContext ctx, FIRRTLConvention convention)
Creates an ConventionAttr with the specified value.
MlirType firrtlTypeGetClock(MlirContext ctx)
Creates a clock type.
MlirType firrtlTypeGetColoredRef(MlirType target, bool forceable, MlirAttribute layer)
Creates a ref type.
MlirAttribute firrtlAttrGetLayerConvention(MlirContext ctx, FIRRTLLayerConvention convention)
Creates a LayerConventionAttr with the specified value.
MlirType firrtlTypeGetReset(MlirContext ctx)
Creates a reset type.
bool firrtlTypeIsABundle(MlirType type)
Returns true if the specified type is a bundle type.
MlirType firrtlTypeGetVector(MlirContext ctx, MlirType element, size_t count)
Creates a vector type with the specified element type and count.
MLIR_DEFINE_CAPI_DIALECT_REGISTRATION(FIRRTL, firrtl, circt::firrtl::FIRRTLDialect) bool firrtlTypeIsConst(MlirType type)
bool firrtlImportAnnotationsFromJSONRaw(MlirContext ctx, MlirStringRef annotationsStr, MlirAttribute *importedAnnotationsArray)
Deserializes a JSON value into FIRRTL Annotations.
bool firrtlTypeIsAPath(MlirType type)
Checks if this type is a property path type.
MlirType firrtlTypeGetUInt(MlirContext ctx, int32_t width)
Creates a unsigned integer type with the specified width.
MlirType firrtlTypeGetAnyRef(MlirContext ctx)
Creates an anyref type.
MlirAttribute firrtlAttrGetPortDirs(MlirContext ctx, size_t count, const FIRRTLDirection *dirs)
Creates a DenseBoolArrayAttr with the specified port directions.
bool firrtlTypeIsAReset(MlirType type)
Checks if this type is a reset type.
MlirType firrtlTypeGetClass(MlirContext ctx, MlirAttribute name, size_t numberOfElements, const FIRRTLClassElement *elements)
Creates a class type with the specified name and elements.
bool firrtlTypeIsAAnyRef(MlirType type)
Checks if this type is an anyref type.
bool firrtlTypeIsAOpenBundle(MlirType type)
Returns true if the specified type is an open bundle type.
MlirType firrtlTypeGetMaskType(MlirType type)
Returns this type with all ground types replaced with UInt<1>.
MlirType firrtlTypeGetSInt(MlirContext ctx, int32_t width)
Creates a signed integer type with the specified width.
MlirType firrtlTypeGetRef(MlirType target, bool forceable)
Creates a ref type.
MlirType firrtlTypeGetBundle(MlirContext ctx, size_t count, const FIRRTLBundleField *fields)
Creates a bundle type with the specified fields.
bool firrtlTypeIsAVector(MlirType type)
Checks if this type is a vector type.
int64_t firrtlTypeGetBitWidth(MlirType type, bool ignoreFlip)
Gets the bit width for this type, returns -1 if unknown.
MlirType firrtlTypeGetVectorElement(MlirType vec)
Returns the element type of a vector type.
MlirAttribute firrtlAttrGetEventControl(MlirContext ctx, FIRRTLEventControl eventControl)
Creates a EventControlAttr with the specified value.
bool firrtlTypeIsADouble(MlirType type)
Checks if this type is a property double type.
bool firrtlTypeIsAList(MlirType type)
Checks if this type is a property list type.
MlirAttribute firrtlAttrGetParamDecl(MlirContext ctx, MlirIdentifier name, MlirType type, MlirAttribute value)
Creates a ParamDeclAttr with the specified name, type, and value.
MlirAttribute firrtlAttrGetMemInit(MlirContext ctx, MlirIdentifier filename, bool isBinary, bool isInline)
Creates a MemoryInitAttr with the specified memory initialization information.
FIRRTLValueFlow firrtlValueFoldFlow(MlirValue value, FIRRTLValueFlow flow)
Computes the flow for a Value, value, as determined by the FIRRTL specification.
MlirAttribute firrtlAttrGetRUW(MlirContext ctx, FIRRTLRUW ruw)
Creates a RUWBehaviorAttr with the specified Read-Under-Write Behavior.
bool firrtlTypeIsAAsyncReset(MlirType type)
Checks if this type is an async reset type.
MlirAttribute firrtlAttrGetNameKind(MlirContext ctx, FIRRTLNameKind nameKind)
Creates a NameKindEnumAttr with the specified name preservation semantic.
bool firrtlTypeIsAAnalog(MlirType type)
Checks if this type is an analog type.
bool firrtlTypeIsABoolean(MlirType type)
Checks if this type is a property boolean type.
size_t firrtlTypeGetVectorNumElements(MlirType vec)
Returns the number of elements in a vector type.
unsigned firrtlTypeGetBundleFieldIndex(MlirType type, MlirStringRef fieldName)
Returns the index of the field with the specified name in the bundle type.
size_t firrtlTypeGetBundleNumFields(MlirType bundle)
Returns the number of fields in the bundle type.
MLIR_CAPI_EXPORTED bool firrtlTypeIsConst(MlirType type)
Returns true if this is a const type whose value is guaranteed to be unchanging at circuit execution ...
FIRRTLLayerConvention
Layer lowering conventions.
@ FIRRTL_LAYER_CONVENTION_INLINE
@ FIRRTL_LAYER_CONVENTION_BIND
FIRRTLValueFlow
Flow of value.
@ FIRRTL_VALUE_FLOW_SOURCE
@ FIRRTL_VALUE_FLOW_DUPLEX
FIRRTLNameKind
Name preservation.
@ FIRRTL_NAME_KIND_DROPPABLE_NAME
@ FIRRTL_NAME_KIND_INTERESTING_NAME
FIRRTLMemDir
Memory port direction.
@ FIRRTL_MEM_DIR_READ_WRITE
FIRRTLEventControl
Edge control trigger.
@ FIRRTL_EVENT_CONTROL_AT_POS_EDGE
@ FIRRTL_EVENT_CONTROL_AT_NEG_EDGE
@ FIRRTL_EVENT_CONTROL_AT_EDGE
FIRRTLDirection
Port direction.
FIRRTLRUW
Read-Under-Write behaviour.
FIRRTLConvention
Module instantiation conventions.
@ FIRRTL_CONVENTION_SCALARIZED
@ FIRRTL_CONVENTION_INTERNAL
static EvaluatorValuePtr unwrap(OMEvaluatorValue c)
mlir::DenseBoolArrayAttr packAttribute(MLIRContext *context, ArrayRef< Direction > directions)
Return a DenseBoolArrayAttr containing the packed representation of an array of directions.
Direction
This represents the direction of a single port.
Flow foldFlow(Value val, Flow accumulatedFlow=Flow::Source)
Compute the flow for a Value, val, as determined by the FIRRTL specification.
bool isConst(Type type)
Returns true if this is a 'const' type whose value is guaranteed to be unchanging at circuit executio...
bool importAnnotationsFromJSONRaw(llvm::json::Value &value, SmallVectorImpl< Attribute > &annotations, llvm::json::Path path, MLIRContext *context)
Deserialize a JSON value into FIRRTL Annotations.
std::optional< int64_t > getBitWidth(FIRRTLBaseType type, bool ignoreFlip=false)
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.
Describes a field in a bundle type.
Describes an element in a class type.
FIRRTLDirection direction