mirror of https://github.com/llvm/circt.git
Add lowering for ILA Probe Intrinsic (#6415)
Co-authored-by: Fabian Schuiki <fabian@schuiki.ch>
This commit is contained in:
parent
983710360b
commit
a9f35c20a2
|
@ -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
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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>
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue