Add lowering for ILA Probe Intrinsic (#6415)

Co-authored-by: Fabian Schuiki <fabian@schuiki.ch>
This commit is contained in:
Aditya Naik 2023-11-29 02:05:58 -08:00 committed by GitHub
parent 983710360b
commit a9f35c20a2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 56 additions and 2 deletions

View File

@ -919,6 +919,23 @@ def HasBeenResetIntrinsicOp : FIRRTLOp<"int.has_been_reset", [Pure]> {
let assemblyFormat = "$clock `,` $reset attr-dict `:` type($reset)";
}
def FPGAProbeIntrinsicOp : FIRRTLOp<"int.fpga_probe", []> {
let summary = "Mark a value to be observed through FPGA debugging facilities";
let description = [{
The `firrtl.int.fpga_probe` intrinsic marks a value in
the IR to be made observable through FPGA debugging facilities. Most FPGAs
offer a form of signal observation or logic analyzer to debug a design. This
operation allows the IR to indicate which signals should be made observable
for debugging. Later FPGA-specific passes may then pick this information up
and materialize the necessary logic analyzers or tool scripts.
}];
let arguments = (ins AnyType:$input, NonConstClockType:$clock);
let results = (outs);
let assemblyFormat = "$clock `,` $input attr-dict `:` type($input)";
}
//===----------------------------------------------------------------------===//
// Verbatim
//===----------------------------------------------------------------------===//

View File

@ -53,7 +53,7 @@ public:
LTLNotIntrinsicOp, LTLImplicationIntrinsicOp,
LTLEventuallyIntrinsicOp, LTLClockIntrinsicOp,
LTLDisableIntrinsicOp, Mux2CellIntrinsicOp, Mux4CellIntrinsicOp,
HasBeenResetIntrinsicOp,
HasBeenResetIntrinsicOp, FPGAProbeIntrinsicOp,
// Miscellaneous.
BitsPrimOp, HeadPrimOp, MuxPrimOp, PadPrimOp, ShlPrimOp, ShrPrimOp,
TailPrimOp, VerbatimExprOp, HWStructCastOp, BitCastOp, RefSendOp,
@ -178,6 +178,7 @@ public:
HANDLE(Mux4CellIntrinsicOp, Unhandled);
HANDLE(Mux2CellIntrinsicOp, Unhandled);
HANDLE(HasBeenResetIntrinsicOp, Unhandled);
HANDLE(FPGAProbeIntrinsicOp, Unhandled);
// Miscellaneous.
HANDLE(BitsPrimOp, Unhandled);

View File

@ -1540,6 +1540,7 @@ struct FIRRTLLowering : public FIRRTLVisitor<FIRRTLLowering, LogicalResult> {
LogicalResult visitExpr(IsXIntrinsicOp op);
LogicalResult visitExpr(PlusArgsTestIntrinsicOp op);
LogicalResult visitExpr(PlusArgsValueIntrinsicOp op);
LogicalResult visitExpr(FPGAProbeIntrinsicOp op);
LogicalResult visitExpr(SizeOfIntrinsicOp op);
LogicalResult visitExpr(ClockGateIntrinsicOp op);
LogicalResult visitExpr(LTLAndIntrinsicOp op);
@ -3550,6 +3551,12 @@ LogicalResult FIRRTLLowering::visitExpr(PlusArgsTestIntrinsicOp op) {
return setLoweringTo<sv::ReadInOutOp>(op, reg);
}
LogicalResult FIRRTLLowering::visitExpr(FPGAProbeIntrinsicOp op) {
auto operand = getLoweredValue(op.getInput());
builder.create<hw::WireOp>(operand);
return success();
}
LogicalResult FIRRTLLowering::visitExpr(PlusArgsValueIntrinsicOp op) {
auto resultType = builder.getIntegerType(1);
auto type = lowerType(op.getResult().getType());

View File

@ -603,6 +603,23 @@ static bool lowerCirctHasBeenReset(InstanceGraph &ig, FModuleLike mod) {
return true;
}
static bool lowerCirctProbe(InstanceGraph &ig, FModuleLike mod) {
// TODO add some conditions here?
for (auto *use : ig.lookup(mod)->uses()) {
auto inst = cast<InstanceOp>(use->getInstance().getOperation());
ImplicitLocOpBuilder builder(inst.getLoc(), inst);
auto clock =
builder.create<WireOp>(inst.getResult(0).getType()).getResult();
auto input =
builder.create<WireOp>(inst.getResult(1).getType()).getResult();
inst.getResult(0).replaceAllUsesWith(clock);
inst.getResult(1).replaceAllUsesWith(input);
builder.create<FPGAProbeIntrinsicOp>(clock, input);
inst.erase();
}
return true;
}
std::pair<const char *, std::function<bool(InstanceGraph &, FModuleLike)>>
intrinsics[] = {
{"circt.sizeof", lowerCirctSizeof},
@ -644,7 +661,9 @@ std::pair<const char *, std::function<bool(InstanceGraph &, FModuleLike)>>
{"circt.mux4cell", lowerCirctMuxCell<false>},
{"circt_mux4cell", lowerCirctMuxCell<false>},
{"circt.has_been_reset", lowerCirctHasBeenReset},
{"circt_has_been_reset", lowerCirctHasBeenReset}};
{"circt_has_been_reset", lowerCirctHasBeenReset},
{"circt.fpga_probe", lowerCirctProbe},
{"circt_fpga_probe", lowerCirctProbe}};
// This is the main entrypoint for the lowering pass.
void LowerIntrinsicsPass::runOnOperation() {

View File

@ -176,4 +176,14 @@ firrtl.circuit "Intrinsics" {
firrtl.strictconnect %hbr1, %0 : !firrtl.uint<1>
firrtl.strictconnect %hbr2, %1 : !firrtl.uint<1>
}
// CHECK-LABEL: hw.module @FPGAProbe
firrtl.module @FPGAProbe(
in %clock: !firrtl.clock,
in %reset: !firrtl.uint<1>,
in %in: !firrtl.uint<8>
) attributes {convention = #firrtl<convention scalarized>} {
// CHECK: hw.wire %in
firrtl.int.fpga_probe %clock, %in : !firrtl.uint<8>
}
}