Skip to content

Commit

Permalink
fixup! [FIRRTL] Prerequisites for Layer-Associated Probes
Browse files Browse the repository at this point in the history
  • Loading branch information
seldridge committed Jan 27, 2024
1 parent 2d479de commit d47ffe2
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 0 deletions.
1 change: 1 addition & 0 deletions include/circt/Dialect/FIRRTL/FIRRTLExpressions.td
Original file line number Diff line number Diff line change
Expand Up @@ -1239,6 +1239,7 @@ def RefResolveOp: FIRRTLExprOp<"ref.resolve",
let results = (outs FIRRTLBaseType:$result);

let hasCanonicalizer = true;
let hasVerifier = 1;

let assemblyFormat = "$ref attr-dict `:` qualified(type($ref))";
}
Expand Down
40 changes: 40 additions & 0 deletions lib/Dialect/FIRRTL/FIRRTLOps.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5810,6 +5810,46 @@ LogicalResult RefCastOp::verify() {
return success();
}

LogicalResult RefResolveOp::verify() {

SymbolRefAttr layer;
auto layerBlockOp = (*this)->getParentOfType<LayerBlockOp>();
if (layerBlockOp)
layer = layerBlockOp.getLayerName();

// The dest layer must be the same as the source layer or a parent of it.
SymbolRefAttr layerPointer = layer;
auto destLayer = getRef().getType().getLayer();
for (;;) {
if (layerPointer == destLayer)
break;

if (!layerPointer) {
if (!layer)
return emitOpError() << "cannot read from a layer-colored probe from "
"outside a layerblock";
auto diag = emitOpError()
<< "reads from a probe colored with layer '" << destLayer
<< "' from a layerblock associated with layer '" << layer
<< "'. The resolve op must be in a layerblock associated "
"with or a child of layer '"
<< destLayer << "'.";
return diag.attachNote(layerBlockOp.getLoc())
<< "the layerblock was declared here";
}

if (layerPointer.getNestedReferences().empty()) {
layerPointer = {};
continue;
}
layerPointer =
SymbolRefAttr::get(layerPointer.getRootReference(),
layerPointer.getNestedReferences().drop_back());
}

return success();
}

LogicalResult RWProbeOp::verifyInnerRefs(hw::InnerRefNamespace &ns) {
auto targetRef = getTarget();
if (targetRef.getModule() !=
Expand Down
29 changes: 29 additions & 0 deletions test/Dialect/FIRRTL/errors.mlir
Original file line number Diff line number Diff line change
Expand Up @@ -1947,6 +1947,35 @@ firrtl.circuit "IllegalRefCastDestLayerBlock" {

// -----

firrtl.circuit "IllegalRefResolve_NotInLayerBlock" {
firrtl.layer @A bind {
}
firrtl.module @IllegalRefResolve_NotInLayerBlock() {
%0 = firrtl.wire : !firrtl.probe<uint<1>, @A>
// expected-error @below {{'firrtl.ref.resolve' op cannot read from a layer-colored probe from outside a layerblock}}
%1 = firrtl.ref.resolve %0 : !firrtl.probe<uint<1>, @A>
}
}

// -----

firrtl.circuit "IllegalRefResolve_IllegalLayer" {
firrtl.layer @A bind {
}
firrtl.layer @B bind {
}
firrtl.module @IllegalRefResolve_IllegalLayer() {
%0 = firrtl.wire : !firrtl.probe<uint<1>, @A>
// expected-note @below {{the layerblock was declared here}}
firrtl.layerblock @B {
// expected-error @below {{'firrtl.ref.resolve' op reads from a probe colored with layer '@A' from a layerblock associated with layer '@B'. The resolve op must be in a layerblock associated with or a child of layer '@A'.}}
%1 = firrtl.ref.resolve %0 : !firrtl.probe<uint<1>, @A>
}
}
}

// -----

firrtl.circuit "InvalidProbeAssociationPort_SymbolDoesNotExist" {
// expected-error @below {{probe port 'a' is associated with layer '@B', but this layer was not defined}}
firrtl.module @InvalidProbeAssociationPort_SymbolDoesNotExist(out %a: !firrtl.probe<uint<1>, @B>) {
Expand Down

0 comments on commit d47ffe2

Please sign in to comment.