Skip to content

Commit a1b7ca6

Browse files
authored
[LowerToHW] Add '0' to format string width (#8354)
Add a zero width to all format string substitutions when lowering from FIRRTL to HW/SV. E.g., this will lower `%x` into `%0x`. This is almost always preferred and avoids the need for (right now) adding width specifiers to Chisel and FIRRTL. While we would like to do this, we don't want to do it as passthrough from Chisel where Chisel users write Verilog format substitutions. As @jackkoenig and I got to bottom of, there are non-standard format specifiers that people might want (e.g., `%-` for left justified) that tools support differently and we would like to figure out how to actually lower these if they matter. Signed-off-by: Schuyler Eldridge <[email protected]>
1 parent 8389379 commit a1b7ca6

File tree

6 files changed

+21
-17
lines changed

6 files changed

+21
-17
lines changed

lib/Conversion/FIRRTLToHW/LowerToHW.cpp

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4544,7 +4544,7 @@ LogicalResult FIRRTLLowering::visitStmt(PrintFOp op) {
45444544
return failure();
45454545

45464546
// Update the format string to replace "special" substitutions based on
4547-
// substitution type.
4547+
// substitution type and lower normal substitusion.
45484548
SmallString<32> formatString;
45494549
for (size_t i = 0, e = op.getFormatString().size(), subIdx = 0; i != e; ++i) {
45504550
char c = op.getFormatString()[i];
@@ -4554,17 +4554,21 @@ LogicalResult FIRRTLLowering::visitStmt(PrintFOp op) {
45544554
formatString.push_back(c);
45554555
c = op.getFormatString()[++i];
45564556
switch (c) {
4557-
// A normal substitution. Update the substitution index.
4557+
// A normal substitution. If this is a radix specifier, add an explicit
4558+
// `0` width. E.g., lower `%x` to `%0x`. Almost nobody wants the Verilog
4559+
// width behavior and this is a much saner lowering. Do not do this for
4560+
// `%c` as the spec is unclear if this is allowed.
45584561
case 'b':
4559-
case 'c':
45604562
case 'd':
45614563
case 'x':
4564+
formatString.push_back('0');
4565+
[[fallthrough]];
4566+
case 'c':
45624567
++subIdx;
4563-
break;
4568+
[[fallthrough]];
45644569
default:
4565-
break;
4570+
formatString.push_back(c);
45664571
}
4567-
formatString.push_back(c);
45684572
break;
45694573
// Maybe a "{{}}" special substitution.
45704574
case '{': {

test/Conversion/FIRRTLToHW/lower-to-hw-module.mlir

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,8 @@ firrtl.circuit "Simple" {
7272
%myext:2 = firrtl.instance myext @MyParameterizedExtModule(in in: !firrtl.uint<1>, out out: !firrtl.uint<8>)
7373

7474
// CHECK: %PRINTF_FD_ = sv.macro.ref.expr @PRINTF_FD_() : () -> i32
75-
// CHECK: sv.fwrite %PRINTF_FD_, "%x"(%xyz.out4) : i4
76-
// CHECK: sv.fwrite %PRINTF_FD_, "Something interesting! %x"(%myext.out) : i8
75+
// CHECK: sv.fwrite %PRINTF_FD_, "%0x"(%xyz.out4) : i4
76+
// CHECK: sv.fwrite %PRINTF_FD_, "Something interesting! %0x"(%myext.out) : i8
7777

7878
firrtl.connect %myext#0, %reset : !firrtl.uint<1>, !firrtl.uint<1>
7979

test/Conversion/FIRRTLToHW/lower-to-hw.mlir

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -326,8 +326,8 @@ firrtl.circuit "Simple" attributes {annotations = [{class =
326326
// input c: SInt<4>
327327
// input d: SInt<4>
328328
// printf(clock, reset, "No operands!\n")
329-
// printf(clock, reset, "Hi %x %x\n", add(a, a), b)
330-
// printf(clock, reset, "Hi signed %d %d\n", add(c, c), d)
329+
// printf(clock, reset, "Hi %0x %0x\n", add(a, a), b)
330+
// printf(clock, reset, "Hi signed %0d %0d\n", add(c, c), d)
331331

332332
// CHECK-LABEL: hw.module private @Print
333333
// CHECK-SAME: attributes {emit.fragments = [@PRINTF_FD_FRAGMENT, @PRINTF_COND_FRAGMENT]}
@@ -352,22 +352,22 @@ firrtl.circuit "Simple" attributes {annotations = [{class =
352352
// CHECK-NEXT: [[AND:%.+]] = comb.and bin %PRINTF_COND__0, %reset : i1
353353
// CHECK-NEXT: sv.if [[AND]] {
354354
// CHECK-NEXT: %PRINTF_FD_ = sv.macro.ref.expr @PRINTF_FD_() : () -> i32
355-
// CHECK-NEXT: sv.fwrite %PRINTF_FD_, "Hi %x %x\0A"([[ADD]], %b) : i5, i4
355+
// CHECK-NEXT: sv.fwrite %PRINTF_FD_, "Hi %0x %0x\0A"([[ADD]], %b) : i5, i4
356356
// CHECK-NEXT: }
357357
// CHECK-NEXT: %PRINTF_COND__1 = sv.macro.ref.expr @PRINTF_COND_() : () -> i1
358358
// CHECK-NEXT: [[AND:%.+]] = comb.and bin %PRINTF_COND__1, %reset : i1
359359
// CHECK-NEXT: sv.if [[AND]] {
360360
// CHECK-NEXT: %PRINTF_FD_ = sv.macro.ref.expr @PRINTF_FD_() : () -> i32
361361
// CHECK-NEXT: [[SUMSIGNED:%.+]] = sv.system "signed"([[ADDSIGNED]])
362362
// CHECK-NEXT: [[DSIGNED:%.+]] = sv.system "signed"(%d)
363-
// CHECK-NEXT: sv.fwrite %PRINTF_FD_, "Hi signed %d %d\0A"([[SUMSIGNED]], [[DSIGNED]]) : i5, i4
363+
// CHECK-NEXT: sv.fwrite %PRINTF_FD_, "Hi signed %0d %0d\0A"([[SUMSIGNED]], [[DSIGNED]]) : i5, i4
364364
// CHECK-NEXT: }
365365
// CHECK-NEXT: %PRINTF_COND__2 = sv.macro.ref.expr @PRINTF_COND_() : () -> i1
366366
// CHECK-NEXT: [[AND:%.+]] = comb.and bin %PRINTF_COND__2, %reset : i1
367367
// CHECK-NEXT: sv.if [[AND]] {
368368
// CHECK-NEXT: %PRINTF_FD_ = sv.macro.ref.expr @PRINTF_FD_() : () -> i32
369369
// CHECK-NEXT: [[TIME:%.+]] = sv.system.time : i64
370-
// CHECK-NEXT: sv.fwrite %PRINTF_FD_, "[%0t]: %d"([[TIME]], %a) : i64, i4
370+
// CHECK-NEXT: sv.fwrite %PRINTF_FD_, "[%0t]: %0d"([[TIME]], %a) : i64, i4
371371
// CHECK-NEXT: }
372372
// CHECK-NEXT: }
373373
// CHECK-NEXT: }

test/firtool/import-ref.fir

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ circuit TestHarness:
1717
connect dut.clock, clock
1818

1919
; CHECK: fwrite
20-
; CHECK-SAME: "%x", TestHarness.dut.`ref_DUT_read)
20+
; CHECK-SAME: "%0x", TestHarness.dut.`ref_DUT_read)
2121
printf(clock, UInt<1>(1), "%x", read(dut.read))
2222
; CHECK: initial
2323
; CHECK: force TestHarness.dut.`ref_DUT_write = 32'hDEADBEEF;

test/firtool/lower-layers.fir

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ circuit TestHarness:
132132
; CHECK: `ifndef SYNTHESIS
133133
; CHECK: always @(posedge clock) begin
134134
; CHECK: if ((`PRINTF_COND_) & reset)
135-
; CHECK: $fwrite(`PRINTF_FD_, "The last PC was: %x", dut_trace);
135+
; CHECK: $fwrite(`PRINTF_FD_, "The last PC was: %0x", dut_trace);
136136
; CHECK: end // always @(posedge)
137137
; CHECK: `endif // not def SYNTHESIS
138138
; CHECK: endmodule

test/firtool/print.fir

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ circuit PrintTest:
77
input clock : Clock
88
input cond : UInt<1>
99
input var : UInt<32>
10-
printf(clock, cond, "test %d\n", var)
10+
printf(clock, cond, "test %b %c %d %x\n", var, var, var, var)
1111

1212
; CHECK: sv.ifdef @SYNTHESIS {
1313
; CHECK-NEXT: } else {
@@ -16,7 +16,7 @@ circuit PrintTest:
1616
; CHECK-NEXT: [[COND:%.+]] = comb.and bin [[PRINTF_COND]], %cond : i1
1717
; CHECK-NEXT: sv.if [[COND]] {
1818
; CHECK-NEXT: [[PRINTF_FD:%.+]] = sv.macro.ref.expr @PRINTF_FD_() : () -> i32
19-
; CHECK-NEXT: sv.fwrite [[PRINTF_FD]], "test %d\0A"(%var) : i32
19+
; CHECK-NEXT: sv.fwrite [[PRINTF_FD]], "test %0b %c %0d %0x\0A"(%var, %var, %var, %var) : i32
2020
; CHECK-NEXT: }
2121
; CHECK-NEXT: }
2222
; CHECK-NEXT: }

0 commit comments

Comments
 (0)