Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 49 additions & 4 deletions include/circt/Dialect/Sim/SimOps.td
Original file line number Diff line number Diff line change
Expand Up @@ -502,6 +502,16 @@ def FormatHierPathOp : SimOp<"fmt.hier_path", [Pure]> {
let assemblyFormat = "(`escaped` $useEscapes^)? attr-dict";
}

def TimeOp : SimOp<"time", [Pure]> {
let summary = "Current simulation time";
let description = [{
Returns the current simulation time as an `i64` value.
}];

let results = (outs I64:$result);
let assemblyFormat = "attr-dict";
}

def FormatStringConcatOp : SimOp<"fmt.concat", [Pure]> {
let summary = "Concatenate format strings";
let description = [{
Expand Down Expand Up @@ -560,11 +570,13 @@ def PrintFormattedOp : SimOp<"print"> {
}];
let arguments = (ins
FormatStringType:$input,
Optional<I32>:$stream,
ClockType:$clock,
I1:$condition
I1:$condition,
DefaultValuedAttr<BoolAttr, "false">:$usePrintfCond
Copy link
Copy Markdown
Member

@uenoku uenoku Apr 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't want to carry FIRRTL thing here. Could you try if it's possible to push PRINTF_COND to condition?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

An alternative could be to have the wrapping in PRINTF_COND be a SimToSV pass lowering option which the firtool pipeline could set. That would allow us to use the Sim ops, and then have a uniform FIRRTL-flavored emission in firtool, while still allowing other CIRCT-based tools to work with the Sim ops directly.

Or, maybe more idiomatic, we could add something like a hw.optional or hw.choice operation which allows you to pick one of a few IR regions based on a configuration parameter, which could be a macro when we emit SV. Maybe?

);
let hasCanonicalizeMethod = true;
let assemblyFormat = "$input `on` $clock `if` $condition attr-dict";
let assemblyFormat = "$input (`to` $stream^)? `on` $clock `if` $condition attr-dict";
}

def PrintFormattedProcOp : SimOp<"proc.print"> {
Expand All @@ -574,10 +586,43 @@ def PrintFormattedProcOp : SimOp<"proc.print"> {

This operation must be within a procedural region.
}];
let arguments = (ins FormatStringType:$input);
let arguments = (ins
FormatStringType:$input,
Optional<I32>:$stream,
DefaultValuedAttr<BoolAttr, "false">:$usePrintfCond
);
let hasVerifier = true;
let hasCanonicalizeMethod = true;
let assemblyFormat = "$input attr-dict";
let assemblyFormat = "$input (`to` $stream^)? attr-dict";
}

def GetFileOp : SimOp<"get_file"> {
let summary = "Get a file descriptor for a formatted file name";
let description = [{
Looks up the descriptor for a file name in a process-global mapping.
If no descriptor exists, opens the file and records the new descriptor.
}];

let arguments = (ins StrAttr:$fileNameFormat,
Variadic<AnyType>:$fileNameOperands);
let results = (outs I32:$descriptor);
let assemblyFormat = [{
$fileNameFormat `(` $fileNameOperands `)` attr-dict
`:` functional-type($fileNameOperands, results)
}];
}

def FFlushOp : SimOp<"fflush"> {
let summary = "Flush a file stream on a given clock and condition";
let arguments = (ins I32:$stream, ClockType:$clock, I1:$condition);
let assemblyFormat = "$stream `on` $clock `if` $condition attr-dict";
}

def FFlushProcOp : SimOp<"proc.fflush"> {
let summary = "Flush a file stream within a procedural region";
let arguments = (ins I32:$stream);
let hasVerifier = 1;
let assemblyFormat = "$stream attr-dict";
}

//===----------------------------------------------------------------------===//
Expand Down
Loading
Loading