Skip to content

Commit 984a444

Browse files
committed
[FIRRTL] Add fields to domains
Extend domains to allow for them to contain fields. These fields provide a schema of information that all domains of certain kind must have. This models information that a user must provide for an input domain or is provided for an output domain. Opt for a "struct-like" representation as opposed to using input/output ports like FIRRTL classes. That said, these are intended to be lowered to classes in a future patch. Signed-off-by: Schuyler Eldridge <[email protected]>
1 parent a1e2484 commit 984a444

File tree

7 files changed

+78
-5
lines changed

7 files changed

+78
-5
lines changed

include/circt/Dialect/FIRRTL/FIRRTLAttributes.td

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,4 +209,19 @@ def InternalPathArrayAttr
209209

210210
def LayerArrayAttr : TypedArrayRefAttrBase<SymbolRefAttr, "an array of layers">;
211211

212+
def DomainFieldAttr : AttrDef<FIRRTLDialect, "DomainField"> {
213+
let mnemonic = "domain.field";
214+
let summary = "A single field of a domain";
215+
let parameters = (
216+
ins "::mlir::StringAttr":$name,
217+
"::mlir::TypeAttr":$type
218+
);
219+
let assemblyFormat = [{
220+
`<` $name `,` $type `>`
221+
}];
222+
}
223+
224+
def DomainFieldArrayAttr :
225+
TypedArrayAttrBase<DomainFieldAttr, "an array of domain fields">;
226+
212227
#endif // CIRCT_DIALECT_FIRRTL_FIRRTLATTRIBUTES_TD

include/circt/Dialect/FIRRTL/FIRRTLStructure.td

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -614,11 +614,14 @@ def DomainOp : FIRRTLOp<"domain", [
614614
circuit. E.g., this can be used to declare a `ClockDomain` type when
615615
modeling clocks in FIRRTL Dialect.
616616
}];
617-
let arguments = (ins SymbolNameAttr:$sym_name);
617+
let arguments = (
618+
ins SymbolNameAttr:$sym_name,
619+
DefaultValuedAttr<DomainFieldArrayAttr, "{}">:$fields
620+
);
618621
let results = (outs);
619622
let regions = (region SizedRegion<1>:$body);
620623
let assemblyFormat = [{
621-
$sym_name attr-dict-with-keyword $body
624+
$sym_name ( $fields^ )? attr-dict-with-keyword $body
622625
}];
623626
}
624627

lib/Dialect/FIRRTL/Export/FIREmitter.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -644,6 +644,13 @@ void Emitter::emitDeclaration(DomainOp op) {
644644
startStatement();
645645
ps << "domain " << PPExtString(op.getSymName()) << " :";
646646
emitLocationAndNewLine(op);
647+
ps.scopedBox(PP::bbox2, [&]() {
648+
for (auto attr : op.getFields()) {
649+
auto fieldAttr = cast<DomainFieldAttr>(attr);
650+
ps << PP::newline << PPExtString(fieldAttr.getName()) << " : ";
651+
emitType(fieldAttr.getType().getValue());
652+
}
653+
});
647654
}
648655

649656
/// Emit a layer definition.

lib/Dialect/FIRRTL/Import/FIRParser.cpp

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5751,8 +5751,25 @@ ParseResult FIRCircuitParser::parseDomain(CircuitOp circuit, unsigned indent) {
57515751
info.parseOptionalInfo())
57525752
return failure();
57535753

5754+
SmallVector<Attribute> fields;
5755+
while (true) {
5756+
auto nextIndent = getIndentation();
5757+
if (!nextIndent || *nextIndent <= indent)
5758+
break;
5759+
5760+
StringAttr fieldName;
5761+
PropertyType type;
5762+
if (parseId(fieldName, "field name") ||
5763+
parseToken(FIRToken::colon, "expected ':' after field name") ||
5764+
parsePropertyType(type, "field type") || info.parseOptionalInfo())
5765+
return failure();
5766+
5767+
fields.push_back(DomainFieldAttr::get(circuit.getContext(), fieldName,
5768+
TypeAttr::get(type)));
5769+
}
5770+
57545771
auto builder = circuit.getBodyBuilder();
5755-
DomainOp::create(builder, info.getLoc(), name)
5772+
DomainOp::create(builder, info.getLoc(), name, builder.getArrayAttr(fields))
57565773
->getRegion(0)
57575774
.push_back(new Block());
57585775

test/Dialect/FIRRTL/emit-basic.mlir

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -958,6 +958,16 @@ firrtl.circuit "Foo" {
958958
// CHECK-LABEL: domain ClockDomain :
959959
firrtl.domain @ClockDomain {}
960960

961+
// CHECK-LABEL: domain PowerDomain :
962+
// CHECK-NEXT: name : String
963+
// CHECK-NEXT: voltage : Integer
964+
// CHECk-NEXT: alwaysOn : Bool
965+
firrtl.domain @PowerDomain [
966+
#firrtl.domain.field<"name", !firrtl.string>,
967+
#firrtl.domain.field<"voltage", !firrtl.integer>,
968+
#firrtl.domain.field<"alwaysOn", !firrtl.bool>
969+
] {}
970+
961971
// CHECK-LABEL: module Domains :
962972
firrtl.module @Domains(
963973
// CHECK-NEXT: input A : Domain of ClockDomain

test/Dialect/FIRRTL/parse-basic.fir

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2195,9 +2195,19 @@ circuit NullaryCat:
21952195
;// -----
21962196
FIRRTL version 5.1.0
21972197
circuit Domains:
2198-
; CHECK-LABEL: firrtl.domain @ClockDomain
2198+
; CHECK-LABEL: firrtl.domain @ClockDomain {
21992199
domain ClockDomain:
22002200

2201+
; CHECK-LABEL: firrtl.domain @PowerDomain [
2202+
; CHECK-SAME: #firrtl.domain.field<"name", !firrtl.string>
2203+
; CHECK-SAME: #firrtl.domain.field<"voltage", !firrtl.integer>
2204+
; CHECK-SAME: #firrtl.domain.field<"alwaysOn", !firrtl.bool>
2205+
; CHECK-SAME: ] {
2206+
domain PowerDomain:
2207+
name : String
2208+
voltage : Integer
2209+
alwaysOn : Bool
2210+
22012211
module Foo:
22022212
input A: Domain of ClockDomain
22032213
input a: UInt<1> domains [A]

test/Dialect/FIRRTL/round-trip.mlir

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -196,10 +196,21 @@ firrtl.module @Fprintf(
196196
firrtl.fprintf %clock, %a, "test%d.txt"(%a), "%x, %b"(%a, %reset) {name = "foo"} : !firrtl.clock, !firrtl.uint<1>, !firrtl.uint<1>, !firrtl.uint<1>, !firrtl.reset
197197
}
198198

199-
// CHECK-LABEL: firrtl.domain @ClockDomain
199+
// CHECK-LABEL: firrtl.domain @ClockDomain {
200200
firrtl.domain @ClockDomain {
201201
}
202202

203+
// CHECK-LABEL: firrtl.domain @PowerDomain [
204+
// CHECK-SAME: #firrtl.domain.field<"name", !firrtl.string>
205+
// CHECK-SAME: #firrtl.domain.field<"voltage", !firrtl.integer>
206+
// CHECK-SAME: #firrtl.domain.field<"alwaysOn", !firrtl.bool>
207+
// CHECK-SAME: ] {
208+
firrtl.domain @PowerDomain [
209+
#firrtl.domain.field<"name", !firrtl.string>,
210+
#firrtl.domain.field<"voltage", !firrtl.integer>,
211+
#firrtl.domain.field<"alwaysOn", !firrtl.bool>
212+
] {}
213+
203214
firrtl.module @DomainsSubmodule(
204215
in %A: !firrtl.domain of @ClockDomain,
205216
in %a: !firrtl.uint<1> domains [%A]

0 commit comments

Comments
 (0)