Skip to content

Commit

Permalink
fmt: if enabled, group padding zeroes.
Browse files Browse the repository at this point in the history
Before this commit, the combination of `_` and `0` format characters
would produce a result like `000000001010_1010`.
After this commit, it would be `0000_0000_1010_1010`.

This has a slight quirk where a format like `{:020_b}` results in
the output `0_0000_0000_1010_1010`, which is one character longer than
requested. Python has the same behavior, and it's not clear what would
be strictly speaking correct, so Python behavior is implemented.
  • Loading branch information
whitequark authored and mwkmwkmwk committed Apr 2, 2024
1 parent 27cb4c5 commit 9417038
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 11 deletions.
22 changes: 14 additions & 8 deletions backends/cxxrtl/runtime/cxxrtl/cxxrtl.h
Original file line number Diff line number Diff line change
Expand Up @@ -1109,36 +1109,34 @@ struct fmt_part {
}
}

size_t width = Bits;
size_t val_width = Bits;
if (base != 10) {
width = 1;
val_width = 1;
for (size_t index = 0; index < Bits; index++)
if (val.bit(index))
width = index + 1;
val_width = index + 1;
}

if (base == 2) {
if (show_base)
prefix += "0b";
for (size_t index = 0; index < width; index++) {
for (size_t index = 0; index < val_width; index++) {
if (group && index > 0 && index % 4 == 0)
buf += '_';
buf += (val.bit(index) ? '1' : '0');
}
std::reverse(buf.begin(), buf.end());
} else if (base == 8 || base == 16) {
if (show_base)
prefix += (base == 16) ? (hex_upper ? "0X" : "0x") : "0o";
size_t step = (base == 16) ? 4 : 3;
for (size_t index = 0; index < width; index += step) {
for (size_t index = 0; index < val_width; index += step) {
if (group && index > 0 && index % (4 * step) == 0)
buf += '_';
uint8_t value = val.bit(index) | (val.bit(index + 1) << 1) | (val.bit(index + 2) << 2);
if (step == 4)
value |= val.bit(index + 3) << 3;
buf += (hex_upper ? "0123456789ABCDEF" : "0123456789abcdef")[value];
}
std::reverse(buf.begin(), buf.end());
} else if (base == 10) {
if (show_base)
prefix += "0d";
Expand All @@ -1158,8 +1156,16 @@ struct fmt_part {
xval = quotient;
index++;
}
std::reverse(buf.begin(), buf.end());
} else assert(false && "Unsupported base for fmt_part");
if (justify == NUMERIC && group && padding == '0') {
int group_size = base == 10 ? 3 : 4;
while (prefix.size() + buf.size() < width) {
if (buf.size() % (group_size + 1) == group_size)
buf += '_';
buf += '0';
}
}
std::reverse(buf.begin(), buf.end());
break;
}

Expand Down
12 changes: 9 additions & 3 deletions kernel/fmt.cc
Original file line number Diff line number Diff line change
Expand Up @@ -776,7 +776,6 @@ std::string Fmt::render() const
else /* if (bit == State::S0) */
buf += '0';
}
std::reverse(buf.begin(), buf.end());
} else if (part.base == 8 || part.base == 16) {
if (part.show_base)
prefix += (part.base == 16) ? (part.hex_upper ? "0X" : "0x") : "0o";
Expand Down Expand Up @@ -807,7 +806,6 @@ std::string Fmt::render() const
else
buf += (part.hex_upper ? "0123456789ABCDEF" : "0123456789abcdef")[subvalue.as_int()];
}
std::reverse(buf.begin(), buf.end());
} else if (part.base == 10) {
if (part.show_base)
prefix += "0d";
Expand All @@ -831,9 +829,17 @@ std::string Fmt::render() const
value = RTLIL::const_div(value, 10, false, false, value.size());
index++;
}
std::reverse(buf.begin(), buf.end());
}
} else log_abort();
if (part.justify == FmtPart::NUMERIC && part.group && part.padding == '0') {
int group_size = part.base == 10 ? 3 : 4;
while (prefix.size() + buf.size() < part.width) {
if (buf.size() % (group_size + 1) == group_size)
buf += '_';
buf += '0';
}
}
std::reverse(buf.begin(), buf.end());
} else if (part.type == FmtPart::STRING) {
buf = part.sig.as_const().decode_string();
} else if (part.type == FmtPart::VLOG_TIME) {
Expand Down

0 comments on commit 9417038

Please sign in to comment.