Skip to content

Commit

Permalink
Remove includeHierarchy from convention attr. Clean up.
Browse files Browse the repository at this point in the history
  • Loading branch information
uenoku committed Dec 5, 2024
1 parent 2bb4500 commit 110c916
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 49 deletions.
37 changes: 17 additions & 20 deletions docs/Dialects/FIRRTL/FIRRTLAnnotations.md
Original file line number Diff line number Diff line change
Expand Up @@ -323,12 +323,11 @@ Example:

### Convention

| Property | Type | Description |
| ---------------- | ------ | ---------------------------------------------------- |
| class | string | `circt.ConventionAnnotation` |
| convention | string | `scalarized` |
| target | string | Reference target |
| includeHierarchy | bool | Apply the convention to all modules in the hierarchy |
| Property | Type | Description |
| ---------- | ------ | --------------------------------------- |
| class | string | `circt.ConventionAnnotation` |
| convention | string | `scalarized` |
| target | string | Reference target |

Specify the port convention for a module. The port convention controls how a
module's ports are transformed, and how that module can be instantiated, in the
Expand All @@ -338,35 +337,33 @@ The options are:
- `scalarized`: Convert aggregate ports (i.e. vector or bundles) into multiple
ground-typed ports.

`includeHierarchy` is optional and defaults to `false`, meaning that the
convention is applied only to the specified module. If `includeHierarchy` is
`true`, the convention is applied to all modules in the hierarchy. If there are
multiple annotation instances that specify conventions, the `scalarized` convention
takes precedence over the `internal` convention.

```json
{
"class": "circt.ConventionAnnotation",
"convention": "scalarized",
"target": "~Foo|Bar",
"includeHierarchy": true
"target": "~Foo|Bar/d:Baz"
}
```

### BodyTypeLoweringAnnotation

| Property | Type | Description |
| ---------------- | ------ | ---------------------------------- |
| class | string | `circt.BodyTypeLoweringAnnotation` |
| convention | string | See `Convention` annotation |
| target | string | See `Convention` annotation |
| includeHierarchy | bool | See `Convention` annotation |
| Property | Type | Description |
| ------------------- | ------ | ---------------------------------------------------- |
| class | string | `circt.BodyTypeLoweringAnnotation` |
| convention | string | See `Convention` annotation |
| target | string | See `Convention` annotation |
| includeHierarchy | bool | Apply the convention to all modules in the hierarchy |

Specify the type lowering option for module internal signals.
This is similar to the `Convention` annotation, but for internal signals
rather than module ports. Refer to the `Convention` annotation for each
property description.

When `includeHierarchy` is `false`, it indicates the convention is applied only to
the specified module. If `includeHierarchy` is `true`, the convention is applied to
all modules in the hierarchy. If there are multiple annotation instances that specify
conventions, the `scalarized` convention takes precedence over the `internal` convention.

```json
{
"class": "circt.BodyTypeLoweringAnnotation",
Expand Down
64 changes: 38 additions & 26 deletions lib/Dialect/FIRRTL/Transforms/LowerAnnotations.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,7 @@ applyConventionOrTypeLoweringAnno(const AnnoPathValue &target,

auto conventionStrAttr =
tryGetAs<StringAttr>(anno, anno, "convention", loc, conventionAnnoClass);

if (!conventionStrAttr)
return failure();

Expand All @@ -305,41 +306,52 @@ applyConventionOrTypeLoweringAnno(const AnnoPathValue &target,
// Convention is internal by default so there is nothing to change
return success();

auto includeHierarchy = anno.getAs<BoolAttr>("includeHierarchy");
auto conventionAttr = ConventionAttr::get(op->getContext(), convention);
auto setConvention = [&](Operation *moduleOp) {
TypeSwitch<Operation *>(moduleOp)
.Case<FModuleOp, FExtModuleOp>([&](auto moduleOp) {
if (IsConventionAnno)
moduleOp.setConventionAttr(conventionAttr);
else
moduleOp->setDiscardableAttr("body_type_lowering", conventionAttr);
})
.Default([](auto) {});
};

if (auto moduleOp = dyn_cast<FModuleOp>(op)) {
if (includeHierarchy && includeHierarchy.getValue()) {
// If includeHierarchy is true, update the convention for all modules in
// the hierarchy.
for (auto *node :
llvm::post_order(state.instancePathCache.instanceGraph[moduleOp])) {
if (node && isa<FModuleOp, FExtModuleOp>(*node->getModule()))
setConvention(node->getModule());
}
} else {
if (IsConventionAnno) {
if (!isa<FModuleOp, FExtModuleOp>(op))
return error() << "can only target to a module or extmodule";

if (auto fmodule = dyn_cast<FModuleOp>(op)) {
// Update the convention.
setConvention(moduleOp);
fmodule.setConventionAttr(conventionAttr);
return success();
}

auto extModuleOp = cast<FExtModuleOp>(op);
extModuleOp.setConventionAttr(conventionAttr);
return success();
}

if (auto extModuleOp = dyn_cast<FExtModuleOp>(op)) {
setConvention(extModuleOp);
return success();
auto moduleOp = dyn_cast<FModuleOp>(op);

if (!moduleOp)
return error() << "can only target to a module";

// `includeHierarchy` only valid in BodyTypeLowering.
bool includeHierarchy = false;
if (auto includeHierarchyAttr = tryGetAs<BoolAttr>(
anno, anno, "includeHierarchy", loc, conventionAnnoClass))
includeHierarchy = includeHierarchyAttr.getValue();

if (includeHierarchy) {
assert(!IsConventionAnno &&
"includeHierarchy is only valid in BodyTypeLowering");
// If includeHierarchy is true, update the convention for all modules in
// the hierarchy.
for (auto *node :
llvm::post_order(state.instancePathCache.instanceGraph[moduleOp])) {
if (!node)
continue;
if (auto fmodule = dyn_cast<FModuleOp>(*node->getModule()))
fmodule->setAttr("body_type_lowering", conventionAttr);
}
} else {
// Update the convention.
moduleOp->setAttr("body_type_lowering", conventionAttr);
}

return error() << "can only target to a module or extmodule";
return success();
}

static LogicalResult applyModulePrefixAnno(const AnnoPathValue &target,
Expand Down
6 changes: 3 additions & 3 deletions test/Dialect/FIRRTL/annotations.mlir
Original file line number Diff line number Diff line change
Expand Up @@ -735,7 +735,7 @@ firrtl.circuit "Test" attributes {rawAnnotations = [

firrtl.circuit "Test" attributes {rawAnnotations =[
{class = "circt.ConventionAnnotation", target = "~Test|Test", convention = "scalarized"},
{class = "circt.BodyTypeLoweringAnnotation", target = "~Test|Test", convention = "scalarized"}
{class = "circt.BodyTypeLoweringAnnotation", target = "~Test|Test", convention = "scalarized", includeHierarchy = false}
]} {
// CHECK: attributes {body_type_lowering = #firrtl<convention scalarized>, convention = #firrtl<convention scalarized>}
firrtl.module @Test() attributes {convention = #firrtl<convention internal>} {}
Expand All @@ -744,15 +744,15 @@ firrtl.circuit "Test" attributes {rawAnnotations =[
// -----

firrtl.circuit "Test" attributes {rawAnnotations = [
{class = "circt.ConventionAnnotation", target = "~Test|Test", convention = "scalarized", includeHierarchy = true},
{class = "circt.ConventionAnnotation", target = "~Test|Test", convention = "scalarized"},
{class = "circt.BodyTypeLoweringAnnotation", target = "~Test|Test", convention = "scalarized", includeHierarchy = true}
]} {
// CHECK: @Test() attributes {body_type_lowering = #firrtl<convention scalarized>, convention = #firrtl<convention scalarized>}
firrtl.module @Test() attributes {convention = #firrtl<convention internal>} {
firrtl.instance child @Child()
}

// CHECK: @Child() attributes {body_type_lowering = #firrtl<convention scalarized>, convention = #firrtl<convention scalarized>}
// CHECK: @Child() attributes {body_type_lowering = #firrtl<convention scalarized>}
firrtl.module @Child() attributes {convention = #firrtl<convention internal>} {}

// CHECK: @Child2() {
Expand Down

0 comments on commit 110c916

Please sign in to comment.