Skip to content

Commit

Permalink
[FIRRTL] Use PRINTF_FD macro instead of 0x80000002 as printf fd
Browse files Browse the repository at this point in the history
updates the FIRRTLToHW conversion to use the `PRINTF_FD` macro for
specifying the file descriptor, allowing the fd to be obtained
externally. This change enhances flexibility by enabling the file
descriptor to be defined outside the conversion logic.

Signed-off-by: Clo91eaf <[email protected]>
  • Loading branch information
Clo91eaf committed Dec 12, 2024
1 parent 1462269 commit 9277795
Showing 1 changed file with 22 additions and 10 deletions.
32 changes: 22 additions & 10 deletions lib/Conversion/FIRRTLToHW/LowerToHW.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ struct FIRRTLModuleLowering;
/// This is state shared across the parallel module lowering logic.
struct CircuitLoweringState {
// Flags indicating whether the circuit uses certain header fragments.
std::atomic<bool> usedPrintfCond{false};
std::atomic<bool> usedPrintf{false};
std::atomic<bool> usedAssertVerboseCond{false};
std::atomic<bool> usedStopCond{false};

Expand Down Expand Up @@ -805,11 +805,22 @@ void FIRRTLModuleLowering::lowerFileHeader(CircuitOp op,

// Helper function to emit #ifndef guard.
auto emitGuard = [&](const char *guard, llvm::function_ref<void(void)> body) {
b.create<sv::IfDefOp>(
guard, []() {}, body);
b.create<sv::IfDefOp>(guard, []() {}, body);
};

if (state.usedPrintfCond) {
if (state.usedPrintf) {
b.create<sv::MacroDeclOp>("PRINTF_FD");
b.create<sv::MacroDeclOp>("PRINTF_FD_");
b.create<emit::FragmentOp>("PRINTF_FD_FRAGMENT", [&] {
b.create<sv::VerbatimOp>(
"\n// Users can define 'PRINTF_FD' to add a specified fd to "
"prints.");
emitGuard("PRINTF_FD_", [&]() {
emitGuardedDefine("PRINTF_FD", "PRINTF_FD_", "(`PRINTF_FD)",
"32'h80000002");
});
});

b.create<sv::MacroDeclOp>("PRINTF_COND");
b.create<sv::MacroDeclOp>("PRINTF_COND_");
b.create<emit::FragmentOp>("PRINTF_COND_FRAGMENT", [&] {
Expand Down Expand Up @@ -2589,8 +2600,7 @@ void FIRRTLLowering::addToAlwaysBlock(
auto createIfOp = [&]() {
// It is weird but intended. Here we want to create an empty sv.if
// with an else block.
insideIfOp = builder.create<sv::IfOp>(
reset, []() {}, []() {});
insideIfOp = builder.create<sv::IfOp>(reset, []() {}, []() {});
};
if (resetStyle == sv::ResetType::AsyncReset) {
sv::EventControl events[] = {clockEdge, resetEdge};
Expand Down Expand Up @@ -4416,7 +4426,8 @@ LogicalResult FIRRTLLowering::visitStmt(PrintFOp op) {
circuitState.addMacroDecl(builder.getStringAttr("SYNTHESIS"));
addToIfDefBlock("SYNTHESIS", std::function<void()>(), [&]() {
addToAlwaysBlock(clock, [&]() {
circuitState.usedPrintfCond = true;
circuitState.usedPrintf = true;
circuitState.addFragment(theModule, "PRINTF_FD_FRAGMENT");
circuitState.addFragment(theModule, "PRINTF_COND_FRAGMENT");

// Emit an "sv.if '`PRINTF_COND_ & cond' into the #ifndef.
Expand All @@ -4425,9 +4436,10 @@ LogicalResult FIRRTLLowering::visitStmt(PrintFOp op) {
ifCond = builder.createOrFold<comb::AndOp>(ifCond, cond, true);

addIfProceduralBlock(ifCond, [&]() {
// Emit the sv.fwrite, writing to stderr by default.
Value fdStderr = builder.create<hw::ConstantOp>(APInt(32, 0x80000002));
builder.create<sv::FWriteOp>(fdStderr, op.getFormatString(), operands);
// Emit the sv.fwrite, writing to fd specified by `PRINTF_FD.
Value fd =
builder.create<sv::MacroRefExprOp>(cond.getType(), "PRINTF_FD_");
builder.create<sv::FWriteOp>(fd, op.getFormatString(), operands);
});
});
});
Expand Down

0 comments on commit 9277795

Please sign in to comment.