This change achieves two related goals.
First, default_rst is no longer assumed to be synchronous to
default_clk, which is the safer option, since it can be connected to
e.g. buttons on some evaluation boards.
Second, since the power-on / configuration reset is inherently
asynchronous to any user clock, the default create_missing_domain()
behavior is to use a reset synchronizer with `0` as input. Since,
like all reset synchronizers, it uses Signal(reset=1) for its
synchronization stages, after power-on reset it keeps its subordinate
clock domain in reset, and releases it after fabric flops start
toggling.
The latter change is helpful to architectures that lack an end-of-
configuration signal, i.e. most of them. ECP5 was already using
a similar scheme (and is not changed here). Xilinx devices with EOS
use EOS to drive a BUFGMUX, which is more efficient than using
a global reset when the design does not need one; Xilinx devices
without EOS use the new scheme. iCE40 requires a post-configuration
timer because of BRAM silicon bug, and was changed to add a reset
synchronizer if user clock is provided.
The write port priority in Yosys is derived directly from the order
in which the ports are declared in the Verilog frontend. It is being
removed for several reasons:
1. It is not clear if it works correctly for all cases (FFRAM,
LUTRAM, BRAM).
2. Although it is roundtripped via Verilog with correct simulation
semantics, the resulting code has a high chance of being
interpreted incorrectly by Xilinx tools.
3. It cannot be roundtripped via FIRRTL, which is an alternative
backend that is an interesting future option. (FIRRTL leaves
write collision completely undefined.)
3. It is a niche feature that, if it is needed, can be completely
replaced using an explicit comparator, priority encoder, and
write enable gating circuit. (This is what Xilinx recommends
for handling this case.)
In the future we should extend nMigen's formal verification to assert
that a write collision does not happen.
Although useful for debugging, most external tools often complain
about such attributes (with notable exception of Vivado). As such,
it is better to emit Verilog with these attributes into a separate
file such as `design.debug.v` and only emit the attributes that were
explicitly placed by the user to `design.v`.
This still leaves the (*init*) attribute. See #220 for details.
Since we use hertz elsewhere, this provides for easy conversions.
Also, cast the delay to string before applying it in xilinx_7series,
to avoid stripping the fractional digits.
Closes#234.
Almost no code would specify Signal(_, name) as a positional argument
on purpose, but forgetting parens and accidentally placing signedness
into the name position is so common that we had a test for it.
Unless exact_depth=True is specified.
The logic introduced in this commit is idempotent: that is, if one
uses the depth of one AsyncFIFOBuffered in the constructor of another
AsyncFIFOBuffered, they will end up with the same depth. More naive
logic would result in an unbounded, quadratic growth with each such
step.
Fixes#219.
These functions were originally changed in 3ed51938, in an attempt
to make them take one cycle instead of two. However, this does not
actually work because of drawbacks of the simulator interface.
Avoid committing to any specific implementation for now, and instead
make them compat-only extensions.
Before this commit, it was possible to set and get clock constraints
placed on Pin objects. This was not a very good implementation, since
it relied on matching the identity of the provided Pin object to
a previously requested one. The only reason it worked like that is
deficiencies in nextpnr.
Since then, nextpnr has been fixed to allow setting constraints on
arbitrary nets. Correspondingly, backends that are using Synplify
were changed to use [get_nets] instead of [get_ports] in SDC files.
However, in some situations, Synplify does not allow specifying
ports in [get_nets]. (In fact, nextpnr had a similar problem, but
it has also been fixed.)
The simplest way to address this is to refer to the interior net
(after the input buffer), which always works. The only downside
of this is that requesting a clock as a raw pin using
platform.request("clk", dir="-")
and directly applying a constraint to it could fail in some cases.
This is not a significant issue.