* Add invert= argument to DiffPairs() constructor, like in Pins().
* Make PinsN() and DiffPairsN() pass invert= to the corresponding
construtor instead of mutating.
Before this commit, `_check_feature(valid_xdrs=0)` would mean that
XDR buffers are not supported. Only `_check_feature(valid_xdrs=())`
was intended to be an indicator of that.
When a port component is skipped, it should appear neither in the RTL
nor in the constraint file. However, passing around components of
differential ports explicitly makes that harder.
Fixes#456.
Supersedes #457.
Co-authored-by: Jean THOMAS <git0@pub.jeanthomas.me>
For unknown reasons, Quartus treats {foo} and "foo" in completely
different ways, which is not true for normal Tcl code; specifically,
it preserves the braces if they are used. Because of this, since
commit 6cee2804, the vendor.intel package was completely broken.
It's not very nice to add more internal mutable state to Platform
related classes, but our whole approach for Platform is inherently
stateful, and other solutions (like changing every individual vendor
platform to check for unused signals) are even worse.
Fixes#374.
Before this commit, there was only occasional quoting of some names
used in any Tcl files. (I'm not sure what I was thinking.)
After this commit, any substs that may include Tcl special characters
are escaped. This does not include build names (which are explicitly
restricted to ASCII to avoid this problem), or attribute names (which
are chosen from a predefined set). Ideally we'd use a more principled
approach but Jinja2 does not support custom escaping mechanisms.
Note that Vivado restricts clock names to a more restrictive set that
forbids using Tcl special characters even when escaped.
Fixes#375.
By default, if an operation produces an undefined value (a Jinja2
concept that corresponds to Python's KeyError, AttributeError, etc)
then this value may be printed in a template, which is a nop. This
behavior can hide bugs.
This commit changes the Jinja2 behavior to raise an error instead of
producing an undefined value in all cases. (We produce undefined
values deliberately in a few places. Those are unaffected; it is OK
to use several kinds of undefined values in one Jinja2 environment.)
Fixes#337.
For most toolchains, these are functionally identical, although ports
tend to work a bit better, being the common case. For Vivado, though,
it is necessary to place them on the port because its timing analyzer
considers input buffer delay.
Fixes#301.
Since commit 7257c20a, platform code calls create_missing_domains()
before _propagate_domains_up() (as a part of prepare() call). Since
commit a7be3b48, without a platform, create_missing_domains() is
calle after _propagate_domains_up(); because of that, it adds
the missing domain to the fragment. When platform code then calls
prepare() again, this causes an assertion failure.
The true intent behind the platform code being written this way is
that it *overrides* a part of prepare()'s mechanism. Because it was
not changed when prepare() was modified in 7257c20a, the override,
which happened to work by coincidence, stopped working. This is
now fixed by inlining the relevant parts of Fragment.prepare() into
Platform.prepare().
This is not a great solution, but given the amount of breakage this
causes (no platform-using code works), it is acceptable for now.
Fixes#307.
Now environment variable overrides no longer infect the build scripts.
_toolchain.overrides is dropped as probably misguided in the first place.
Fixes#251.
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.
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.
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.
It's not practical to detect tools within the toolchain environment
for various reasons, so just assume the tools are there if the user
says they are.
Before this commit, the tools would be searched outside the toolchain
environment, which of course would always fail for Vivado, ISE, etc.
Platform.prepare() was completely broken after addition of local
clock domains, and only really worked before by a series of
accidents because there was a circular dependency between creation
of missing domains, fragment preparation, and insertion of pin
subfragments.
This commit untangles the dependency by adding a separate public
method Fragment.create_missing_domains(), used in build.plat.
It also makes DomainCollector consider both used and defined domains,
such that it will work on fragments before domain propagation, since
create_missing_domains() can be called by user code before prepare().
The fragment driving missing clock domain is not flattened anymore,
because flattening does not work well combined with local domains.
On Xilinx devices, flip-flops are reset to their initial state with
an internal global reset network, but this network is deasserted
asynchronously to user clocks. Use BUFGCE and STARTUP to hold default
clock low until after GWE is deasserted.