Skip to content
Merged
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
46 changes: 42 additions & 4 deletions include/circt/Dialect/Sim/SimOps.td
Original file line number Diff line number Diff line change
Expand Up @@ -561,10 +561,20 @@ def PrintFormattedOp : SimOp<"print"> {
let arguments = (ins
FormatStringType:$input,
ClockType:$clock,
I1:$condition
I1:$condition,
Optional<OutputStreamType>:$stream
);
let builders = [
OpBuilder<(ins
"Value":$input,
"Value":$clock,
"Value":$condition
), [{
build($_builder, $_state, input, clock, condition, mlir::Value());
}]>
];
let hasCanonicalizeMethod = true;
let assemblyFormat = "$input `on` $clock `if` $condition attr-dict";
let assemblyFormat = "$input `on` $clock `if` $condition (`to` $stream^)? attr-dict";
}

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

This operation must be within a procedural region.
}];
let arguments = (ins FormatStringType:$input);
let arguments = (ins
FormatStringType:$input,
Optional<OutputStreamType>:$stream
);
let builders = [
OpBuilder<(ins
"Value":$input
), [{
build($_builder, $_state, input, mlir::Value());
}]>
];
let hasVerifier = true;
let hasCanonicalizeMethod = true;
let assemblyFormat = "$input attr-dict";
let assemblyFormat = "$input (`to` $stream^)? attr-dict";
}

def GetFileOp : SimOp<"get_file", [Pure]> {
let summary = "Get an output stream for a formatted file name";
let description = [{
Resolves a file name from a `!sim.fstring` value and returns an output
stream resource that can be consumed by `sim.print` or `sim.proc.print`.
The file-name format string should be constructed using `sim.fmt.*`
operations, just like any other Sim format-string value.
The file-name format string is evaluated whenever the stream is accessed.

The concrete runtime representation and lifetime management of the returned
stream are backend-defined.
}];
Comment thread
nanjo712 marked this conversation as resolved.

let arguments = (ins FormatStringType:$fileName);
let results = (outs OutputStreamType:$result);
let assemblyFormat = "$fileName attr-dict";
}

//===----------------------------------------------------------------------===//
Expand Down
13 changes: 13 additions & 0 deletions include/circt/Dialect/Sim/SimTypes.td
Original file line number Diff line number Diff line change
Expand Up @@ -111,4 +111,17 @@ def DPIFunctionType : SimTypeDef<"DPIFunction"> {
}];
}

def OutputStreamType : SimTypeDef<"OutputStream"> {
let summary = "a type representing an output stream";
let description = [{
Represents a simulation output stream resource.
This type models the existence of a stream resource at the Sim dialect level,
while leaving its concrete representation to the lowering backend. Backends may
realize this as a file descriptor, object handle, pointer, or any other target-
specific resource representation.
}];

let mnemonic = "output_stream";
}

#endif // CIRCT_DIALECT_SIM_SIMTYPES_TD
2 changes: 2 additions & 0 deletions lib/Dialect/Sim/SimOps.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -527,6 +527,8 @@ LogicalResult FormatStringConcatOp::verify() {

LogicalResult FormatStringConcatOp::canonicalize(FormatStringConcatOp op,
PatternRewriter &rewriter) {
// Any helper literals created during canonicalization must dominate `op`.
rewriter.setInsertionPoint(op);

auto fmtStrType = FormatStringType::get(op.getContext());

Expand Down
Loading
Loading