This was an especially insidious bug because the minus character is
valid in case values but has a completely different meaning (wildcard
rather than sign).
Fixes#559.
Commit abbebf8e used __getattr__ to proxy Value methods called on
Record. However, that did not proxy operators like __add__ because
Python looks up the special operator methods directly on the class
and does not run __getattr__ if they are missing.
Instead of using __getattr__, explicitly enumerate and wrap every
Value method that should be proxied. This also ensures backwards
compatibility if more methods are added to Value later.
Fixes#533.
I.e. on this code, which is currently not only wrongly accepted but
also results in completely unexpected RTL:
with m.If(...):
with m.Elif(...):
...
Fixes#500.
Before this commit, ArrayProxy would add sign padding (an extra bit)
a homogeneous array of signed values, or an array where all unsigned
values are smaller than the largest signed one. After this commit,
ArrayProxy would only add padding in arrays with mixed signedness
where all signed values are smaller or equal in size to the largest
unsigned value.
Fixes#476.
Co-authored-by: Pepijn de Vos <pepijndevos@gmail.com>
Preserve the original user-provided shape, while still checking
its validity. This allows Enum decoders to work when specifying
record fields with Enums.
Fixes#393.
The `ports` argument to the `convert` functions is a frequent hotspot of
beginner issues. Check to make sure it is either a list or a tuple, and
give an appropriately helpful error message if not.
Fixes#362.
The default __repr__() from typing.NamedTuple does not include
the module name, so the replacement (which uses the preferred syntax
for specifying these shapes) doesn't either.
This commit improves handling of resets in AsyncFIFO in two ways:
* First, resets no longer violate Gray counter CDC invariants.
* Second, write domain reset now empties the entire FIFO.
In some cases, it is necessary to synchronize a reset-like signal but
a new clock domain is not desirable. To address these cases, extract
the implementation of ResetSynchronizer into AsyncFFSynchronizer,
and replace ResetSynchronizer with a thin wrapper around it.
Before this commit, there was no way to do so besides creating and
assigning an intermediate signal, which could not be extracted into
a helper function due to Module statefulness.
Fixes#292.
Before this commit, doing something like:
with m.FSM():
with m.State("FOO"):
m.next = "bAR"
with m.State("BAR"):
m.next = "FOO"
would silently create an empty state `bAR` and get stuck in it until
the module is reset. This was done intentionally (in Migen, this code
would in fact miscompile), but in retrospect was clearly a bad idea;
it turns typos into bugs, while in the rare case that branching to
a completely empty state is desired, it is trivial to define one.
Fixes#315.
These are not desirable in a HDL, and currently elaborate to broken
RTLIL (after YosysHQ/yosys#1551); prohibit them completely, like
we already do for division and modulo.
Fixes#302.
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.
`Module` is an object with a lot of complex and sometimes fragile
behavior that overrides Python attribute accessors and so on.
To prevent user designs from breaking when it is changed, it is not
supposed to be inherited from (unlike in Migen), but rather returned
from the elaborate() method. This commit makes sure it will not be
inherited from by accident (most likely by users familiar with
Migen).
Fixes#286.
A property statement that is created but not added to a module is
virtually always a serious bug, since it can make formal verification
pass when it should not. Therefore, add a warning to it, similar to
UnusedElaboratable.
Doing this to all statements is possible, but many temporary ones are
created internally by nMigen, and the extensive changes required to
remove false positives are likely not worth the true positives.
We can revisit this in the future.
Fixes#303.