Skip to content

Commit

Permalink
[FIRRTL] Add Layer Association to Probes
Browse files Browse the repository at this point in the history
Add support for representing an optional layer in each probe type.  This
only handles storage and MLIR printing/parsing.

Signed-off-by: Schuyler Eldridge <schuyler.eldridge@sifive.com>
  • Loading branch information
seldridge committed Jan 11, 2024
1 parent ff7271b commit 48d05e8
Show file tree
Hide file tree
Showing 6 changed files with 52 additions and 19 deletions.
6 changes: 4 additions & 2 deletions include/circt/Dialect/FIRRTL/FIRRTLTypesImpl.td
Original file line number Diff line number Diff line change
Expand Up @@ -391,7 +391,8 @@ def RefImpl : FIRRTLImplType<"Ref",
}];
let parameters = (ins TypeParameter<"::circt::firrtl::FIRRTLBaseType",
"Type of reference target">:$type,
"bool":$forceable);
"bool":$forceable,
OptionalParameter<"::mlir::SymbolRefAttr">:$layer);
let genAccessors = true;
let genStorageClass = true;
let genVerifyDecl = true;
Expand All @@ -400,7 +401,8 @@ def RefImpl : FIRRTLImplType<"Ref",
let skipDefaultBuilders = true;
let builders = [
TypeBuilderWithInferredContext<(ins "::circt::firrtl::FIRRTLBaseType":$type,
CArg<"bool", "false">:$forceable)>
CArg<"bool", "false">:$forceable,
CArg<"::mlir::SymbolRefAttr", "{}">:$layer)>
];

let extraClassDeclaration = [{
Expand Down
5 changes: 3 additions & 2 deletions include/circt/Dialect/FIRRTL/FIRRTLUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,8 @@ inline FIRRTLType mapBaseType(FIRRTLType type,
return TypeSwitch<FIRRTLType, FIRRTLType>(type)
.Case<FIRRTLBaseType>([&](auto base) { return fn(base); })
.Case<RefType>([&](auto ref) {
return RefType::get(fn(ref.getType()), ref.getForceable());
return RefType::get(fn(ref.getType()), ref.getForceable(),
ref.getLayer());
});
}

Expand All @@ -250,7 +251,7 @@ mapBaseTypeNullable(FIRRTLType type,
auto result = fn(ref.getType());
if (!result)
return {};
return RefType::get(result, ref.getForceable());
return RefType::get(result, ref.getForceable(), ref.getLayer());
});
}

Expand Down
42 changes: 29 additions & 13 deletions lib/Dialect/FIRRTL/FIRRTLTypes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -105,11 +105,13 @@ static LogicalResult customTypePrinter(Type type, AsmPrinter &os) {
printNestedType(vectorType.getElementType(), os);
os << ", " << vectorType.getNumElements() << '>';
})
.Case<RefType>([&](auto refType) {
.Case<RefType>([&](RefType refType) {
if (refType.getForceable())
os << "rw";
os << "probe<";
printNestedType(refType.getType(), os);
if (auto layer = refType.getLayer())
os << ", " << layer;
os << '>';
})
.Case<StringType>([&](auto stringType) { os << "string"; })
Expand Down Expand Up @@ -329,31 +331,43 @@ static OptionalParseResult customTypeParser(AsmParser &parser, StringRef name,
// For now, support both firrtl.ref and firrtl.probe.
if (name.equals("ref") || name.equals("probe")) {
FIRRTLBaseType type;
SymbolRefAttr layer;
// Don't pass `isConst` to `parseNestedBaseType since `ref` can point to
// either `const` or non-`const` types
if (parser.parseLess() || parseNestedBaseType(type, parser) ||
parser.parseGreater())
if (parser.parseLess() || parseNestedBaseType(type, parser))
return failure();
if (parser.parseOptionalComma().succeeded())
if (parser.parseOptionalAttribute(layer).value())
return parser.emitError(parser.getNameLoc(),
"expected symbol reference");
if (parser.parseGreater())
return failure();

if (failed(RefType::verify(
[&]() { return parser.emitError(parser.getNameLoc()); }, type,
false)))
false, layer)))
return failure();

return result = RefType::get(type, false), success();
return result = RefType::get(type, false, layer), success();
}
if (name.equals("rwprobe")) {
FIRRTLBaseType type;
if (parser.parseLess() || parseNestedBaseType(type, parser) ||
parser.parseGreater())
SymbolRefAttr layer;
if (parser.parseLess() || parseNestedBaseType(type, parser))
return failure();
if (parser.parseOptionalComma().succeeded())
if (parser.parseOptionalAttribute(layer).value())
return parser.emitError(parser.getNameLoc(),
"expected symbol reference");
if (parser.parseGreater())
return failure();

if (failed(RefType::verify(
[&]() { return parser.emitError(parser.getNameLoc()); }, type,
true)))
[&]() { return parser.emitError(parser.getNameLoc()); }, type, true,
layer)))
return failure();

return result = RefType::get(type, true), success();
return result = RefType::get(type, true, layer), success();
}
if (name.equals("class")) {
if (isConst)
Expand Down Expand Up @@ -2400,12 +2414,14 @@ BaseTypeAliasType::getIndexAndSubfieldID(uint64_t fieldID) const {
// RefType
//===----------------------------------------------------------------------===//

auto RefType::get(FIRRTLBaseType type, bool forceable) -> RefType {
return Base::get(type.getContext(), type, forceable);
auto RefType::get(FIRRTLBaseType type, bool forceable, SymbolRefAttr layer)
-> RefType {
return Base::get(type.getContext(), type, forceable, layer);
}

auto RefType::verify(function_ref<InFlightDiagnostic()> emitErrorFn,
FIRRTLBaseType base, bool forceable) -> LogicalResult {
FIRRTLBaseType base, bool forceable, SymbolRefAttr layer)
-> LogicalResult {
if (!base.isPassive())
return emitErrorFn() << "reference base type must be passive";
if (forceable && base.containsConst())
Expand Down
3 changes: 2 additions & 1 deletion lib/Dialect/FIRRTL/Transforms/DropConst.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@ static Type convertType(Type type) {

if (auto refType = type_dyn_cast<RefType>(type)) {
if (auto converted = convertType(refType.getType()))
return RefType::get(converted, refType.getForceable());
return RefType::get(converted, refType.getForceable(),
refType.getLayer());
}

return {};
Expand Down
3 changes: 2 additions & 1 deletion lib/Dialect/FIRRTL/Transforms/VBToBV.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,8 @@ RefType Visitor::convertType(RefType type) {
auto cached = typeMap.lookup(type);
if (cached)
return type_cast<RefType>(cached);
auto converted = RefType::get(convertType(type.getType()));
auto converted = RefType::get(convertType(type.getType()),
type.getForceable(), type.getLayer());
typeMap.insert({type, converted});
return converted;
}
Expand Down
12 changes: 12 additions & 0 deletions test/Dialect/FIRRTL/round-trip.mlir
Original file line number Diff line number Diff line change
Expand Up @@ -44,4 +44,16 @@ firrtl.module @Foo(in %clock: !firrtl.clock) {
firrtl.strictconnect %inst_clock, %clock : !firrtl.clock
}

firrtl.layer @LayerA bind {
firrtl.layer @LayerB bind {}
}

// CHECK-LABEL: firrtl.module @Layers
// CHECK-SAME: out %a: !firrtl.probe<uint<1>, @LayerA>
// CHECK-SAME: out %b: !firrtl.rwprobe<uint<1>, @LayerA::@LayerB>
firrtl.module @Layers(
out %a: !firrtl.probe<uint<1>, @LayerA>,
out %b: !firrtl.rwprobe<uint<1>, @LayerA::@LayerB>
) {}

}

0 comments on commit 48d05e8

Please sign in to comment.