Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions include/circt/Dialect/FIRRTL/FIRRTLStructure.td
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,7 @@ def FMemModuleOp : FIRRTLModuleLike<"memmodule"> {
ArrayRefAttr:$portTypes,
DefaultValuedAttr<RUWBehaviorAttr,
"firrtl::RUWBehavior::Undefined">:$ruw,
OptionalAttr<MemoryInitAttr>:$init,
AnnotationArrayAttr:$annotations,
DefaultValuedAttr<LayerArrayAttr, "{}">:$layers,
DefaultValuedAttr<ArrayRefAttr, "{}">:$domainInfo
Expand All @@ -308,6 +309,7 @@ def FMemModuleOp : FIRRTLModuleLike<"memmodule"> {
"uint32_t":$writeLatency, "uint64_t":$depth,
CArg<"firrtl::RUWBehavior",
"firrtl::RUWBehavior::Undefined">:$ruw,
CArg<"firrtl::MemoryInitAttr", "{}">:$init,
CArg<"ArrayAttr", "ArrayAttr()">:$annotations,
CArg<"ArrayAttr", "ArrayAttr()">:$layers)>
];
Expand Down
4 changes: 3 additions & 1 deletion lib/Dialect/FIRRTL/FIRRTLOps.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1188,7 +1188,8 @@ void FMemModuleOp::build(OpBuilder &builder, OperationState &result,
uint32_t numReadWritePorts, uint32_t dataWidth,
uint32_t maskBits, uint32_t readLatency,
uint32_t writeLatency, uint64_t depth, RUWBehavior ruw,
ArrayAttr annotations, ArrayAttr layers) {
MemoryInitAttr init, ArrayAttr annotations,
ArrayAttr layers) {
auto *context = builder.getContext();
buildModule<FMemModuleOp>(builder, result, name, ports, annotations, layers);
auto ui32Type = IntegerType::get(context, 32, IntegerType::Unsigned);
Expand All @@ -1205,6 +1206,7 @@ void FMemModuleOp::build(OpBuilder &builder, OperationState &result,
properties.setDepth(IntegerAttr::get(ui64Type, depth));
properties.setExtraPorts(ArrayAttr::get(context, {}));
properties.setRuw(RUWBehaviorAttr::get(context, ruw));
properties.setInit(init);
}

/// Print a list of module ports in the following form:
Expand Down
85 changes: 68 additions & 17 deletions lib/Dialect/FIRRTL/Transforms/CreateSiFiveMetadata.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,18 @@ struct ObjectModelIR {
extraPortsClass = ClassOp::create(builderOM, "ExtraPortsMemorySchema",
extraPortFields, extraPortsType);

mlir::Type classFieldTypes[14] = {
mlir::Type memInitType[] = {
StringType::get(context), // filename
BoolType::get(context), // isBinary
BoolType::get(context) // isInline
};

StringRef memInitFields[3] = {"filename", "isBinary", "isInline"};

memInitFileClass = ClassOp::create(builderOM, "MemoryInitFileSchema",
memInitFields, memInitType);

mlir::Type classFieldTypes[15] = {
StringType::get(context),
FIntegerType::get(context),
FIntegerType::get(context),
Expand All @@ -117,7 +128,9 @@ struct ObjectModelIR {
context, cast<PropertyType>(
detail::getInstanceTypeForClassLike(extraPortsClass))),
ListType::get(context, cast<PropertyType>(StringType::get(context))),
};
ListType::get(context,
cast<PropertyType>(detail::getInstanceTypeForClassLike(
memInitFileClass)))};

memorySchemaClass = ClassOp::create(builderOM, "MemorySchema",
memoryParamNames, classFieldTypes);
Expand Down Expand Up @@ -359,6 +372,27 @@ struct ObjectModelIR {
}
auto extraPorts = ListCreateOp::create(
builderOM, memorySchemaClass.getPortType(24), extraPortsList);

SmallVector<Value, 1> memInitFileVec;
if (mem.getInit().has_value()) {
auto filename = createConstField(mem.getInit()->getFilename());
auto isBinary = createConstField(
BoolAttr::get(context, mem.getInit()->getIsBinary()));
auto isInline = createConstField(
BoolAttr::get(context, mem.getInit()->getIsInline()));
auto memInitFileObj =
ObjectOp::create(builderOM, memInitFileClass, "initFile");
auto inPort = ObjectSubfieldOp::create(builderOM, memInitFileObj, 0);
PropAssignOp::create(builderOM, inPort, filename);
inPort = ObjectSubfieldOp::create(builderOM, memInitFileObj, 2);
PropAssignOp::create(builderOM, inPort, isBinary);
inPort = ObjectSubfieldOp::create(builderOM, memInitFileObj, 4);
PropAssignOp::create(builderOM, inPort, isInline);
memInitFileVec.push_back(memInitFileObj);
}
auto memInitFile = ListCreateOp::create(
builderOM, memorySchemaClass.getPortType(28), memInitFileVec);

for (auto field : llvm::enumerate(memoryParamNames)) {
auto propVal = createConstField(
llvm::StringSwitch<TypedAttr>(field.value())
Expand All @@ -375,15 +409,18 @@ struct ObjectModelIR {
.Case("inDut", BoolAttr::get(context, inDut))
.Case("extraPorts", {})
.Case("preExtInstName", {})
.Case("initFile", {})
.Case("ruwBehavior", builderOM.getStringAttr(
stringifyRUWBehavior(mem.getRuw()))));
if (!propVal) {
if (field.value() == "hierarchy")
propVal = hierpaths;
else if (field.value() == "preExtInstName")
propVal = finalInstNamesList;
else
else if (field.value() == "extraPorts")
propVal = extraPorts;
else
propVal = memInitFile;
}

// The memory schema is a simple class, with input tied to output. The
Expand Down Expand Up @@ -495,15 +532,15 @@ struct ObjectModelIR {
InstanceInfo &instanceInfo;
/// Cached module namespaces.
DenseMap<Operation *, hw::InnerSymbolNamespace> &moduleNamespaces;
ClassOp memorySchemaClass, extraPortsClass;
ClassOp memorySchemaClass, extraPortsClass, memInitFileClass;
ClassOp memoryMetadataClass;
ClassOp retimeModulesMetadataClass, retimeModulesSchemaClass;
ClassOp blackBoxModulesSchemaClass, blackBoxMetadataClass;
StringRef memoryParamNames[14] = {
"name", "depth", "width", "maskBits",
"readPorts", "writePorts", "readwritePorts", "writeLatency",
"readLatency", "ruwBehavior", "hierarchy", "inDut",
"extraPorts", "preExtInstName"};
StringRef memoryParamNames[15] = {
"name", "depth", "width", "maskBits",
"readPorts", "writePorts", "readwritePorts", "writeLatency",
"readLatency", "ruwBehavior", "hierarchy", "inDut",
"extraPorts", "preExtInstName", "initFile"};
StringRef retimeModulesParamNames[1] = {"moduleName"};
StringRef blackBoxModulesParamNames[3] = {"moduleName", "inDut", "libraries"};
llvm::SmallDenseSet<StringRef> blackboxModules;
Expand Down Expand Up @@ -611,14 +648,20 @@ CreateSiFiveMetadataPass::emitMemoryMetadata(ObjectModelIR &omir) {
auto maskGranStr =
!isMasked ? "" : " mask_gran " + std::to_string(maskGran);

seqMemConfStr = (StringRef(seqMemConfStr) + "name {{" + Twine(symId) +
"}} depth " + Twine(mem.getDepth()) + " width " +
Twine(width) + " ports " + portStr + maskGranStr +
(mem.getRuw() == RUWBehavior::Undefined
? ""
: " ruw " + stringifyRUWBehavior(mem.getRuw())) +
"\n")
.str();
seqMemConfStr += ("name {{" + Twine(symId) + "}}").str();
seqMemConfStr += (" depth " + Twine(mem.getDepth())).str();
seqMemConfStr += (" width " + Twine(width)).str();
seqMemConfStr += " ports " + portStr;
seqMemConfStr += maskGranStr;
if (mem.getRuw() != RUWBehavior::Undefined)
seqMemConfStr += (" ruw " + stringifyRUWBehavior(mem.getRuw())).str();
if (mem.getInit().has_value()) {
seqMemConfStr +=
mem.getInit()->getIsBinary() ? " init-bin " : " init-hex ";
seqMemConfStr +=
("\"" + mem.getInit()->getFilename().getValue() + "\"").str();
}
seqMemConfStr += "\n";

// Do not emit any JSON for memories which are not in the DUT.
if (!instanceInfo->anyInstanceInEffectiveDesign(mem))
Expand All @@ -636,6 +679,14 @@ CreateSiFiveMetadataPass::emitMemoryMetadata(ObjectModelIR &omir) {
jsonStream.attribute("ruw_behavior", stringifyRUWBehavior(mem.getRuw()));
if (isMasked)
jsonStream.attribute("mask_granularity", (int64_t)maskGran);
if (mem.getInit().has_value()) {
jsonStream.attributeObject("init", [&] {
jsonStream.attribute("filename",
mem.getInit()->getFilename().getValue());
jsonStream.attribute("isBinary", mem.getInit()->getIsBinary());
jsonStream.attribute("isInline", mem.getInit()->getIsInline());
});
}
jsonStream.attributeArray("extra_ports", [&] {
for (auto attr : mem.getExtraPorts()) {
jsonStream.object([&] {
Expand Down
3 changes: 2 additions & 1 deletion lib/Dialect/FIRRTL/Transforms/LowerMemory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,8 @@ LowerMemoryPass::emitMemoryModule(MemOp op, const FirMemory &mem,
b, mem.loc, moduleName, ports, mem.numReadPorts, mem.numWritePorts,
mem.numReadWritePorts, mem.dataWidth, mem.maskBits, mem.readLatency,
mem.writeLatency, mem.depth,
*symbolizeRUWBehavior(static_cast<uint32_t>(mem.readUnderWrite)));
*symbolizeRUWBehavior(static_cast<uint32_t>(mem.readUnderWrite)),
mem.init);
SymbolTable::setSymbolVisibility(moduleOp, SymbolTable::Visibility::Private);
return moduleOp;
}
Expand Down
4 changes: 2 additions & 2 deletions test/Dialect/FIRRTL/SFCTests/directories.fir
Original file line number Diff line number Diff line change
Expand Up @@ -155,8 +155,8 @@ circuit TestHarness:
; MLIR_OUT: om.class.fields [[OBJ1]], [[OBJ2]], [[OBJ3]] : !om.class.type<@SitestBlackBoxModulesSchema>, !om.class.type<@SitestBlackBoxModulesSchema>, !om.class.type<@SitestBlackBoxModulesSchema>
; MLIR_OUT: }

; MLIR_OUT: om.class @MemorySchema(%basepath: !om.basepath, %name_in: !om.string, %depth_in: !om.integer, %width_in: !om.integer, %maskBits_in: !om.integer, %readPorts_in: !om.integer, %writePorts_in: !om.integer, %readwritePorts_in: !om.integer, %writeLatency_in: !om.integer, %readLatency_in: !om.integer, %ruwBehavior_in: !om.string, %hierarchy_in: !om.list<!om.path>, %inDut_in: i1, %extraPorts_in: !om.list<!om.class.type<@ExtraPortsMemorySchema>>, %preExtInstName_in: !om.list<!om.string>) -> (name: !om.string, depth: !om.integer, width: !om.integer, maskBits: !om.integer, readPorts: !om.integer, writePorts: !om.integer, readwritePorts: !om.integer, writeLatency: !om.integer, readLatency: !om.integer, ruwBehavior: !om.string, hierarchy: !om.list<!om.path>, inDut: i1, extraPorts: !om.list<!om.class.type<@ExtraPortsMemorySchema>>, preExtInstName: !om.list<!om.string>)
; MLIR_OUT: om.class.fields %name_in, %depth_in, %width_in, %maskBits_in, %readPorts_in, %writePorts_in, %readwritePorts_in, %writeLatency_in, %readLatency_in, %ruwBehavior_in, %hierarchy_in, %inDut_in, %extraPorts_in, %preExtInstName_in : !om.string, !om.integer, !om.integer, !om.integer, !om.integer, !om.integer, !om.integer, !om.integer, !om.integer, !om.string, !om.list<!om.path>, i1, !om.list<!om.class.type<@ExtraPortsMemorySchema>>, !om.list<!om.string>
; MLIR_OUT: om.class @MemorySchema(%basepath: !om.basepath, %name_in: !om.string, %depth_in: !om.integer, %width_in: !om.integer, %maskBits_in: !om.integer, %readPorts_in: !om.integer, %writePorts_in: !om.integer, %readwritePorts_in: !om.integer, %writeLatency_in: !om.integer, %readLatency_in: !om.integer, %ruwBehavior_in: !om.string, %hierarchy_in: !om.list<!om.path>, %inDut_in: i1, %extraPorts_in: !om.list<!om.class.type<@ExtraPortsMemorySchema>>, %preExtInstName_in: !om.list<!om.string>, %initFile_in: !om.list<!om.class.type<@MemoryInitFileSchema>>) -> (name: !om.string, depth: !om.integer, width: !om.integer, maskBits: !om.integer, readPorts: !om.integer, writePorts: !om.integer, readwritePorts: !om.integer, writeLatency: !om.integer, readLatency: !om.integer, ruwBehavior: !om.string, hierarchy: !om.list<!om.path>, inDut: i1, extraPorts: !om.list<!om.class.type<@ExtraPortsMemorySchema>>, preExtInstName: !om.list<!om.string>, initFile: !om.list<!om.class.type<@MemoryInitFileSchema>>)
; MLIR_OUT: om.class.fields %name_in, %depth_in, %width_in, %maskBits_in, %readPorts_in, %writePorts_in, %readwritePorts_in, %writeLatency_in, %readLatency_in, %ruwBehavior_in, %hierarchy_in, %inDut_in, %extraPorts_in, %preExtInstName_in, %initFile_in : !om.string, !om.integer, !om.integer, !om.integer, !om.integer, !om.integer, !om.integer, !om.integer, !om.integer, !om.string, !om.list<!om.path>, i1, !om.list<!om.class.type<@ExtraPortsMemorySchema>>, !om.list<!om.string>, !om.list<!om.class.type<@MemoryInitFileSchema>>
; MLIR_OUT-DAG: om.path_create instance %basepath @memHier
; MLIR_OUT-DAG: om.list_create
; MLIR_OUT-DAG: [[OBJ1:%.+]] = om.object @MemorySchema
Expand Down
Loading
Loading