The main speedup is accomplished by avoiding a heap allocation in the common case where the final string length is less than 128. Inlining stringf & vstringf adds an additional improvement.
The main speedup comes from swithing from using a SHA1 hash to std::hash<std::string>. There is no need to use an expensive cryptographic hash for fingerprinting in this context.
This PR speeds up by roughly 17% across a wide spectrum of designs
tested at Google. Particularly for the mux generation pass.
Co-authored-by: Rasmus Larsen <rmlarsen@google.com>
Signed-off-by: Ethan Mahintorabi <ethanmoon@google.com>
This does not correctly handle an `$overwrite_tag` on a module output,
but since we currently require the user to flatten the design for
cross-module dft, this cannot be observed from within the design, only
by manually inspecting the signals in the design.
Fix mistaking the read-port and write-port indices for each other when
we are adding the partial transparency emulation to be able to merge two
write ports.
Remove superfluous curly braces in call to IdString::in to address
a compilation error (reproduced below) under GCC 9 and earlier.
kernel/cellaigs.cc:395:18: error: call to member function 'in' is ambiguous
if (cell->type.in({ID($gt), ID($ge)}))
~~~~~~~~~~~^~
./kernel/rtlil.h:383:8: note: candidate function
bool in(const std::string &rhs) const { return *this == rhs; }
^
./kernel/rtlil.h:384:8: note: candidate function
bool in(const pool &rhs) const { return rhs.co...
^
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.
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}`.
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.
The guard is optimised out on some compilers under certain conditions (eg: LTO on GCC) as constant under C++ lifetime rules.
This is because the guard type's member is invalid to access (UB) after the type has been destroyed, resulting in
`destruct_guard.ok` being unable to be `false` according to the optimiser, based on the lifetime rules.
This patch still invokes UB (all accesses to the destroyed IdString instance are), but at least the optimiser
can't reason that destruct_guard_ok cannot be false and therefore it's safe to optimise out from its guard role.
It's a repeating pattern to print an error message tied to an AST
node. Start using an 'input_error' helper for that. Among other
things this is beneficial in shortening the print lines, which tend
to be long.
Later in the check() code we check the bottom wide_log2 bits on the
address port are zeroed out. If the address port is too narrow, we crash
due to out of bounds access. Explicitly assert the address port is wide
enough, so we don't crash on input such as
read_rtlil <<EOF
module \top
wire input 1 \clk
memory width 8 size 2 \mem
cell $memwr $auto$:1:$8
parameter \PRIORITY 1'0
parameter \CLK_POLARITY 1'1
parameter \CLK_ENABLE 1'1
parameter \MEMID "\\mem"
parameter \ABITS 1'0
parameter \WIDTH 6'010000
connect \DATA 16'0000000000000000
connect \ADDR { }
connect \EN 16'0000000000000000
connect \CLK \clk
end
end
EOF
memory
The return value of the min(...) call is never used.
Looks like some leftover from some previous implementation.
Signed-off-by: Henner Zeller <h.zeller@acm.org>
Avoids errors in trailing comma handling, broken indentation and
improper escaping that is common when building JSON by manually
concatenating strings.
This contains parsing code as well as generic routines to associate the
hierarchical signals paths within a Yosys witness file to a loaded RTLIL
design, including support for memories.
This adds the xprop_decoder attribute to bwmuxes that drive the original
unencoded signals. Setundef is changed to ignore the x inputs of these
bwmuxes, so that they survive the prep script of SBY's formal flow. This
is required to make simulation (via sim) using the prep model show the
decoded x signals instead of 0/1 values made up by the solver.
This makes it possible for yosys commands to return values when invoked
as tcl commands. Right now no commands natively support this, but the
tee command can be used with json output like this:
```tcl
set stat [yosys tee -q -s result.json stat -json -top top]
dict get $stat modules \\top num_cells_by_type \$pmux
```
Or with newline separated lists like this:
```tcl
split [yosys tee -q -s result.string select -list top] "\n"
```
The new bitwise case equality (`$bweqx`) and bitwise mux (`$bwmux`)
cells enable compact encoding and decoding of 3-valued logic signals
using multiple 2-valued signals.