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.
`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.
Although constructor methods can improve clarity, there are many
contexts in which it is useful to use range() as a shape: notably
Layout, but also Const and AnyConst/AnyValue. Instead of duplicating
these constructor methods everywhere (which is not even easily
possible for Layout), use casting to Shape, introduced in 6aabdc0a.
Fixes#225.
This can cause confusion:
* If the erroneous object is None, it is printed as 'None', which
appears as a string (and could be the result of converting None
to a string.)
* If the erroneous object is a string, it is printed as ''<val>'',
which is a rather strange combination of quotes.
This pattern usually produces an extremely hard to notice bug that
will usually break a design when it is triggered, but will also be
hidden unless the pathological value of a boolean switch is used.
Fixes#159.
This means that instead of:
with m.Case(0b00):
<body>
with m.Case(0b01):
<body>
it is legal to write:
with m.Case(0b00, 0b01):
<body>
with no change in semantics, and slightly nicer RTLIL or Verilog
output.
Fixes#103.