-
Notifications
You must be signed in to change notification settings - Fork 341
[FIRRTL] Add fprintf operation #8346
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Add support for fprintf operation to FIRRTL dialect. This operation is similar to printf but writes to a file instead of stdout. The output file name is interpreted as a format string in SystemVerilog, allowing users to use %m to create unique file names per instance. The operation has the following syntax: fprintf(clock, cond, "output_file", "format_string", substitutions...)
I believe this approach will wind up with different file handles and thus different buffers if opening the same file from different modules. |
So, it's nice that you can use |
Yes, currently it's user's responsibility to give unique names for each instantiation. Users can insert |
It's really tricky to make filename depend on runtime values (so I generally don't want to support SimulationTime), but I think it's possible to support compile time constant (like hartID). Unfortunately FIRRTL doesn't have good support for parameters yet so I think it's not feasible to support near future. |
Based on the offline discussion I'm working on sharing file descriptor for the same file names in the global scope. A common way in SV is to use static class member and function, but CIRCT has neither class nor notion of static at this point so we explored the direction to introduce CIRCT system verilog library, and use it as external function. It's still necessary to clean up LowerToHW and design circt library more carefully but this is current output: `ifndef __CIRCT_LIB_LOGGING
// CIRCT Logging Library
package __circt_lib_logging;
class FileDescriptor;
static int global_id [string];
static function int get(string name);
if (!global_id.exists(name))
global_id[name] = $fopen(name);
return global_id[name];
endfunction
endclass
endpackage
`define __CIRCT_LIB_LOGGING
`endif // not def __CIRCT_LIB_LOGGING
module PrintTest(
input clock,
cond,
input [31:0] var_0
);
`ifndef SYNTHESIS
reg [31:0] fd_test_txt;
reg [31:0] fd_25m_txt;
initial begin
fd_test_txt = __circt_lib_logging::FileDescriptor::get($sformatf("test.txt"));
fd_25m_txt = __circt_lib_logging::FileDescriptor::get($sformatf("%m.txt"));
end // initial
always @(posedge clock) begin
if ((`PRINTF_COND_) & cond) begin
$fwrite(`PRINTF_FD_, "test %d\n", var_0);
$fwrite(fd_test_txt, "test %d\n", var_0);
$fwrite(fd_test_txt, "hello");
$fwrite(fd_25m_txt, "test %d\n", var_0);
end
end // always @(posedge)
`endif // not def SYNTHESIS
endmodule |
fddfd03
to
6a2b9e7
Compare
6a2b9e7
to
31dd01b
Compare
PR is now ready for review. I removed format string support in file name in the latest revision (so %m is not allowed now). This is because we can support tiny subset of format specifier (probably only %m) to guarantee that file names are static but current format string is used mostly for dynamic values (%d, %t etc). To avoid confusion currently file name is not treated as either verilog or FIRRTL format string. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
Only nits and comments. I like the final output.
UPF will be a problem here as registers can go to x
. We should track this and come up with a solution.
fd = builder.create<sv::RegOp>( | ||
builder.getIntegerType(32), | ||
builder.getStringAttr("fd_" + outputFile.getValue())); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This will have the same problem as plusargs for UPF simulations (or any simulation which introduces an external source of x
). This does not need to be solved now. However, this will mean that if we do a UPF power cycle, that suddenly all of these will try to write to an fd
which is x
.
A way to handle this is to use both an initial block and an always block. Open an issue to track this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The value will never be leaked to designs unlike plusargs, so I hope it's less problematic.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Very exciting!
This is more of an aside, but perhaps we want more specific preprocessor macros for switching off some of these "unsynthesizable" constructs since (and i need to fact check this) different emulators and more advanced prototyping systems will be able to handle different subsets of them.
@@ -4549,7 +4621,8 @@ LogicalResult FIRRTLLowering::visitStmt(RefReleaseInitialOp op) { | |||
|
|||
// Printf is a macro op that lowers to an sv.ifdef.procedural, an sv.if, | |||
// and an sv.fwrite all nested together. | |||
LogicalResult FIRRTLLowering::visitStmt(PrintFOp op) { | |||
template <class T> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: you probably need to expand the scope of the comment above?
After this is merged, should the macro |
Add support for fprintf operation to FIRRTL dialect. This operation is similar to printf but writes to a file instead of stdout. The operation has the following syntax: ``` fprintf(clock, cond, "output_file", "format_string", substitutions...) ```
Add support for fprintf operation to FIRRTL dialect. This operation is similar
to printf but writes to a file instead of stdout.
The operation has the following syntax:
fprintf(clock, cond, "output_file", "format_string", substitutions...)
Example:
Currently file name is not interpreted as format string.