Skip to content

Commit

Permalink
[FIRRTL] Fix Grand Central mapping order
Browse files Browse the repository at this point in the history
Reverse the order in which Grand Central vector types are indexed when
generating XMRs.  Previously, the indexing order was from
highest-dimension to lowest-dimension (which is how the ordering for
Chisel, FIRRTL, and the Grand Central annotations are structured).  This
changes it to follow Verilog/C with lowest-dimension to
highest-dimension.

Signed-off-by: Schuyler Eldridge <schuyler.eldridge@sifive.com>
  • Loading branch information
seldridge committed Oct 28, 2021
1 parent bc5a347 commit ca5bfac
Show file tree
Hide file tree
Showing 2 changed files with 87 additions and 22 deletions.
48 changes: 26 additions & 22 deletions lib/Dialect/FIRRTL/Transforms/GrandCentral.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -139,20 +139,20 @@ struct GrandCentralPass : public GrandCentralBase<GrandCentralPass> {

/// Recursively examine an AugmentedType to populate the "mappings" file
/// (generate XMRs) for this interface. This does not build new interfaces.
bool traverseField(Attribute field, IntegerAttr id, Twine path);
bool traverseField(Attribute field, IntegerAttr id, Twine path, Twine index);

/// Recursively examine an AugmentedType to both build new interfaces and
/// populate a "mappings" file (generate XMRs) using `traverseField`. Return
/// the type of the field exmained.
Optional<TypeSum> computeField(Attribute field, IntegerAttr id,
StringAttr prefix, Twine path);
StringAttr prefix, Twine path, Twine index);

/// Recursively examine an AugmentedBundleType to both build new interfaces
/// and populate a "mappings" file (generate XMRs). Return none if the
/// interface is invalid.
Optional<sv::InterfaceOp> traverseBundle(AugmentedBundleTypeAttr bundle,
IntegerAttr id, StringAttr prefix,
Twine path);
Twine path, Twine index);

/// Return the module associated with this value.
FModuleLike getEnclosingModule(Value value);
Expand Down Expand Up @@ -295,7 +295,7 @@ Optional<Attribute> GrandCentralPass::fromAttr(Attribute attr) {
}

bool GrandCentralPass::traverseField(Attribute field, IntegerAttr id,
Twine path) {
Twine path, Twine index) {
return TypeSwitch<Attribute, bool>(field)
.Case<AugmentedGroundTypeAttr>([&](auto ground) {
Value leafValue = leafMap.lookup(ground.getID());
Expand All @@ -319,15 +319,16 @@ bool GrandCentralPass::traverseField(Attribute field, IntegerAttr id,
FModuleOp module =
cast<FModuleOp>(blockArg.getOwner()->getParentOp());
builder.create<sv::VerbatimOp>(
uloc, "assign " + path + " = " + srcRef +
uloc, "assign " + path + index + " = " + srcRef +
module.getPortName(blockArg.getArgNumber()) + ";");
} else {
auto leafModuleName = leafValue.getDefiningOp()
->getAttr("name")
.cast<StringAttr>()
.getValue();
builder.create<sv::VerbatimOp>(
uloc, "assign " + path + " = " + srcRef + leafModuleName + ";");
builder.create<sv::VerbatimOp>(uloc, "assign " + path + index +
" = " + srcRef +
leafModuleName + ";");
}
return true;
})
Expand All @@ -338,8 +339,8 @@ bool GrandCentralPass::traverseField(Attribute field, IntegerAttr id,
auto field = fromAttr(elements[i]);
if (!field)
return false;
notFailed &=
traverseField(field.getValue(), id, path + "[" + Twine(i) + "]");
notFailed &= traverseField(field.getValue(), id, path,
+"[" + Twine(i) + "]" + index);
}
return notFailed;
})
Expand All @@ -353,7 +354,8 @@ bool GrandCentralPass::traverseField(Attribute field, IntegerAttr id,
if (!name)
name = element.cast<DictionaryAttr>().getAs<StringAttr>("defName");
anyFailed &=
traverseField(field.getValue(), id, path + "." + name.getValue());
traverseField(field.getValue(), id,
path + index + "." + name.getValue(), Twine());
}

return anyFailed;
Expand All @@ -369,8 +371,8 @@ bool GrandCentralPass::traverseField(Attribute field, IntegerAttr id,

Optional<TypeSum> GrandCentralPass::computeField(Attribute field,
IntegerAttr id,
StringAttr prefix,
Twine path) {
StringAttr prefix, Twine path,
Twine index) {

auto unsupported = [&](StringRef name, StringRef kind) {
return VerbatimType({("// <unsupported " + kind + " type>").str(), false});
Expand All @@ -380,7 +382,7 @@ Optional<TypeSum> GrandCentralPass::computeField(Attribute field,
.Case<AugmentedGroundTypeAttr>(
[&](AugmentedGroundTypeAttr ground) -> Optional<TypeSum> {
// Traverse to generate mappings.
traverseField(field, id, path);
traverseField(field, id, path, index);
auto value = leafMap.lookup(ground.getID());
auto tpe = value.getType().cast<FIRRTLType>();
if (!tpe.isGround()) {
Expand All @@ -399,16 +401,16 @@ Optional<TypeSum> GrandCentralPass::computeField(Attribute field,
auto elements = vector.getElements();
auto firstElement = fromAttr(elements[0]);
auto elementType = computeField(firstElement.getValue(), id, prefix,
path + "[" + Twine(0) + "]");
path, "[0]" + index);
if (!elementType)
return None;

for (size_t i = 1, e = elements.size(); i != e; ++i) {
auto subField = fromAttr(elements[i]);
if (!subField)
return None;
notFailed &= traverseField(subField.getValue(), id,
path + "[" + Twine(i) + "]");
notFailed &= traverseField(subField.getValue(), id, path,
"[" + Twine(i) + "]" + index);
}

if (auto *tpe = std::get_if<Type>(&elementType.getValue()))
Expand All @@ -420,7 +422,7 @@ Optional<TypeSum> GrandCentralPass::computeField(Attribute field,
})
.Case<AugmentedBundleTypeAttr>(
[&](AugmentedBundleTypeAttr bundle) -> TypeSum {
auto iface = traverseBundle(bundle, id, prefix, path);
auto iface = traverseBundle(bundle, id, prefix, path, index);
assert(iface && iface.getValue());
return VerbatimType({getInterfaceName(prefix, bundle), true});
})
Expand Down Expand Up @@ -452,7 +454,7 @@ Optional<TypeSum> GrandCentralPass::computeField(Attribute field,
/// drive the interface. Returns false on any failure and true on success.
Optional<sv::InterfaceOp>
GrandCentralPass::traverseBundle(AugmentedBundleTypeAttr bundle, IntegerAttr id,
StringAttr prefix, Twine path) {
StringAttr prefix, Twine path, Twine index) {
auto builder = OpBuilder::atBlockEnd(getOperation().getBody());
sv::InterfaceOp iface;
builder.setInsertionPointToEnd(getOperation().getBody());
Expand All @@ -474,8 +476,9 @@ GrandCentralPass::traverseBundle(AugmentedBundleTypeAttr bundle, IntegerAttr id,
return None;

auto name = element.cast<DictionaryAttr>().getAs<StringAttr>("name");
auto elementType = computeField(field.getValue(), id, prefix,
path + "." + name.getValue());
auto elementType =
computeField(field.getValue(), id, prefix,
path + index + "." + name.getValue(), Twine());
if (!elementType)
return None;

Expand Down Expand Up @@ -951,8 +954,9 @@ void GrandCentralPass::runOnOperation() {
// Error out if this returns None (indicating that the annotation annotation
// is malformed in some way). A good error message is generated inside
// `traverseBundle` or the functions it calls.
auto iface = traverseBundle(bundle, bundle.getID(), bundle.getPrefix(),
companionIDMap.lookup(bundle.getID()).name);
auto iface =
traverseBundle(bundle, bundle.getID(), bundle.getPrefix(),
companionIDMap.lookup(bundle.getID()).name, Twine());
if (!iface) {
removalError = true;
continue;
Expand Down
61 changes: 61 additions & 0 deletions test/Dialect/FIRRTL/grand-central.mlir
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,67 @@ firrtl.circuit "InterfaceVecOfBundleType" attributes {

// -----

firrtl.circuit "VecOfVec" attributes {
annotations = [
{class = "sifive.enterprise.grandcentral.AugmentedBundleType",
defName = "Foo",
elements = [
{class = "sifive.enterprise.grandcentral.AugmentedVectorType",
description = "description of foo",
elements = [
{class = "sifive.enterprise.grandcentral.AugmentedVectorType",
description = "description of foo",
elements = [
{class = "sifive.enterprise.grandcentral.AugmentedGroundType",
id = 1 : i64,
name = "foo"},
{class = "sifive.enterprise.grandcentral.AugmentedGroundType",
id = 2 : i64,
name = "foo"}],
name = "foo"}],
name = "foo"}],
id = 0 : i64,
name = "View"},
{class = "sifive.enterprise.grandcentral.ExtractGrandCentralAnnotation",
directory = "gct-dir",
filename = "gct-dir/bindings.sv"}]} {
firrtl.module @View_companion() attributes {
annotations = [
{class = "sifive.enterprise.grandcentral.ViewAnnotation",
defName = "Foo",
id = 0 : i64,
name = "View",
type = "companion"}]} {}
firrtl.module @DUT() attributes {
annotations = [
{class = "sifive.enterprise.grandcentral.ViewAnnotation",
id = 0 : i64,
name = "view",
type = "parent"}
]} {
%a = firrtl.wire {annotations = [
{class = "sifive.enterprise.grandcentral.AugmentedGroundType",
id = 1 : i64},
{class = "sifive.enterprise.grandcentral.AugmentedGroundType",
id = 2 : i64}]} : !firrtl.uint<3>
firrtl.instance View_companion @View_companion()
}
firrtl.module @VecOfVec() {
firrtl.instance dut @DUT()
}
}

// CHECK-LABEL: firrtl.circuit "VecOfVec"

// CHECK: firrtl.module @View_mapping
// CHECK-NEXT: assign View.foo[0][0]
// CHECK-NEXT: assign View.foo[1][0]

// CHECK: sv.interface {{.+}} @Foo
// CHECK: sv.interface.signal @foo : !hw.uarray<1xuarray<2xi3>>

// -----

firrtl.circuit "InterfaceNode" attributes {
annotations = [
{class = "sifive.enterprise.grandcentral.AugmentedBundleType",
Expand Down

0 comments on commit ca5bfac

Please sign in to comment.