Commit Graph

26 Commits

Author SHA1 Message Date
Catherine 94170388a9 fmt: if enabled, group padding zeroes.
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.
2024-04-02 12:13:22 +02:00
Catherine 27cb4c52b4 fmt: allow padding characters other than `'0'` and `' '`.
When converted to Verilog, padding characters are replaced with one of
these two. Otherwise padding is performed with exactly that character.
2024-04-02 12:13:22 +02:00
Catherine ddf7b46955 fmt,cxxrtl: fix printing of non-decimal signed numbers.
Also fix interaction of `NUMERIC` justification with `show_base`.
2024-04-02 12:13:22 +02:00
Catherine 00c5b60dfd fmt,cxxrtl: add option to group digits in numbers.
The option is serialized to RTLIL as `_` (to match Python's option with
the same symbol), and sets the `group` flag. This flag inserts an `_`
symbol between each group of 3 digits (for decimal) or four digits (for
binary, hex, and octal).
2024-04-02 12:13:22 +02:00
Catherine 7b94599162 fmt,cxxrtl: add option to print numeric base (`0x`, etc).
The option is serialized to RTLIL as `#` (to match Python's and Rust's
option with the same symbol), and sets the `show_base` flag. Because
the flag is called `show_base` and not e.g. `alternate_format` (which
is what Python and Rust call it), in addition to the prefixes `0x`,
`0X`, `0o`, `0b`, the RTLIL option also prints the `0d` prefix.
2024-04-02 12:13:22 +02:00
Catherine bf5a960668 fmt,cxxrtl: add `UNICHAR` format type.
This format type is used to print an Unicode character (code point) as
its UTF-8 serialization. To this end, two UTF-8 decoders (one for fmt,
one for cxxrtl) are added for rendering. When converted to a Verilog
format specifier, `UNICHAR` degrades to `%c` with the low 7 bits of
the code point, which has equivalent behavior for inputs not exceeding
ASCII. (SystemVerilog leaves source and display encodings completely
undefined.)
2024-04-02 12:13:22 +02:00
Catherine 1780e2eb1e fmt,cxxrtl: add support for `NUMERIC` justification.
Before this commit, the existing alignments were `LEFT` and `RIGHT`,
which added the `padding` character to the right and left just before
finishing formatting. However, if `padding == '0'` and the alignment is
to the right, then the padding character (digit zero) was added after
the sign, if one is present.

After this commit, the special case for `padding == '0'` is removed,
and the new justification `NUMERIC` adds the padding character like
the justification `RIGHT`, except after the sign, if one is present.
(Space, for the `SPACE_MINUS` sign mode, counts as the sign.)
2024-04-02 12:13:22 +02:00
Catherine 6d6b138607 fmt,cxxrtl: support `{,PLUS_,SPACE_}MINUS` integer formats.
The first two were already supported with the `plus` boolean flag.
The third one is a new specifier, which is allocated the ` ` character.
In addition, `MINUS` is now allocated the `-` character, but old format
where there is no `+`, `-`, or `-` in the respective position is also
accepted for compatibility.
2024-04-02 12:13:22 +02:00
Catherine 8388846e3a fmt,cxxrtl: add support for uppercase hex format.
This is necessary for translating Python format strings in Amaranth.
2024-04-02 12:13:22 +02:00
Catherine a5441bc00c fmt: `FmtPart::{STRING→LITERAL},{CHARACTER→STRING}`.
Before this commit, the `STRING` variant inserted a literal string;
the `CHARACTER` variant inserted a string. This commit renames them
to `LITERAL` and `STRING` respectively.
2024-04-02 12:13:22 +02:00
Catherine b74d33d1b8 fmt: rename TIME to VLOG_TIME.
The behavior of these format specifiers is highly specific to Verilog
(`$time` and `$realtime` are only defined relative to `$timescale`)
and may not fit other languages well, if at all. If they choose to use
it, it is now clear what they are opting into.

This commit also simplifies the CXXRTL code generation for these format
specifiers.
2024-01-19 15:12:05 +00:00
Catherine a33acb7cd9 cxxrtl: refactor the formatter and use a closure.
This commit achieves three roughly equally important goals:
1. To bring the rendering code in kernel/fmt.cc and in cxxrtl.h as close
   together as possible, with an ideal of only having the bigint library
   as the difference between the render functions.
2. To make the treatment of `$time` and `$realtime` in CXXRTL closer to
   the Verilog semantics, at least in the formatting code.
3. To change the code generator so that all of the `$print`-to-`string`
   conversion code is contained inside of a closure.

There are two reasons to aim for goal (3):
a. Because output redirection through definition of a global ostream
   object is neither convenient nor useful for environments where
   the output is consumed by other code rather than being printed on
   a terminal.
b. Because it may be desirable to, in some cases, ignore the `$print`
   cells that are present in the netlist based on a runtime decision.
   This is doubly true for an upcoming `$check` cell implementing
   assertions, since failing a `$check` would by default cause a crash.
2024-01-16 16:35:51 +00:00
Martin Povišer 282ce24eec fmt: Handle free-standing time arguments 2023-11-20 17:25:42 +01:00
gatecat 98b9459535 fmt: Fix C++ string assertion when buf is empty
Signed-off-by: gatecat <gatecat@ds0.me>
2023-09-12 18:12:07 +02:00
Charlotte 7f7c61c9f0 fmt: remove lzero by lowering during Verilog parse
See https://github.com/YosysHQ/yosys/pull/3721#issuecomment-1502037466
-- this reduces logic within the cell, and makes the rules that apply
much more clear.
2023-08-11 04:46:52 +02:00
Charlotte 3571bf2c2d fmt: fuzz, remove some unnecessary busywork
Removing some signed checks and logic where we've already guaranteed the
values to be positive.  Indeed, in these cases, if a negative value got
through (per my realisation in the signed fuzz harness), it would cause
an infinite loop due to flooring division.
2023-08-11 04:46:52 +02:00
Charlotte 9f9561379b fmt: format %t consistently at initial 2023-08-11 04:46:52 +02:00
Charlotte 75b44f21d1 fmt: rudimentary %m support (= %l) 2023-08-11 04:46:52 +02:00
Charlotte c382d7d3ac fmt: %t/$time support 2023-08-11 04:46:52 +02:00
Charlotte 095b093f4a cxxrtl: first pass of $print impl 2023-08-11 04:46:52 +02:00
Charlotte d9e4582558 fmt: handle part with unspecified padding in `emit_rtlil`
e.g. `$displayh(8'ha)` won't have a padding set, because it just gets
`lzero` set instead by `compute_required_decimal_places`.

It also doesn't have a width.  In this case, we can just fill in a dummy
(unused) padding.  Either space or zero would work, but space is a bit
more distinct given the width field follows.

Also omit writing the width if it's zero.  This makes the emitted ilang
a little cleaner in places; `{8:> h0u}` is the output for this example,
now.  The other possible extreme would be `{8:>00h0u}`.
2023-08-11 04:46:52 +02:00
Charlotte 1a222cb163 fmt: function name typo 2023-08-11 04:46:52 +02:00
Charlotte 289f8d42cb fmt: correct parsing of {{ and }} for brace literals 2023-08-11 04:46:52 +02:00
Charlotte 3c8f84b70b fmt: fix another overrun 2023-08-11 04:46:52 +02:00
Charlotte 28bd3a4b5d fmt: don't overrun fmt string buffer
For input like "{", "{1", etc., we would exit the loop due to
`i < fmt.size()` no longer being the case, and then check if
`++i == fmt.size()`.  That would increment i to `fmt.size() + 1`,
and so execution continues.

The intention is to move i beyond the ':', so we do it only in that
case instead.
2023-08-11 04:46:52 +02:00
whitequark 9ea241711e kernel: add format string helpers, `fmt`. 2023-08-11 04:46:52 +02:00