Skip to content

Commit

Permalink
fhdl.verilog: declare outputs from specials, but assigned in always(*…
Browse files Browse the repository at this point in the history
…) blocks, as reg instead of wire

Fixes m-labs#119

Currently, the migen code assumes that all outputs from specials must be
wire, which is true logically. But wires can also be assigned inside
always(*) blocks, which then should be declared as regs.

Solution:
We find out all the output signals from specials (set special_outs_only).
Then we make a list which has comb statements grouped-by-target signals.
We look whether signals in this list are present in `special_outs_only`
set or not. If they are , we remove those signals from the wires set.

Signed-off-by: Rohit Singh <[email protected]>
  • Loading branch information
rohitk-singh committed Jul 5, 2018
1 parent b515b0e commit b3206e2
Showing 1 changed file with 19 additions and 0 deletions.
19 changes: 19 additions & 0 deletions migen/fhdl/verilog.py
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,25 @@ def _printheader(f, ios, name, ns, attr_translate,
targets = list_targets(f) | special_outs
wires, comb_regs = _list_comb_wires_regs(f)
wires |= special_outs

special_outs_only = list_special_ios(f, False, True, False) # Strictly outs
groups = group_by_targets(f.comb)
for g in groups:
if len(g[1]) > 1 and all(list(map(lambda x : isinstance(x, _Assign), g[1]))):
if not g[0].isdisjoint(special_outs_only):
# This means signals in special_outs_only set are being used as
# target of combinational statement, but since it has multiple
# _Assign statements, it cannot be used as single `assign`. So,
# we use an always (*) block for this, and hence these signals
# should be removed from wires set because they are now `regs`.

# Note: We do not care for inouts since they are supposed to be wires
#
# Assumption: That all `Special` modules' targets are assigned by `_Assign`
# instead of `If` or `Case` (which should ideally be true in
# all cases)
wires -= g[0] & special_outs_only

r = "module " + name + "(\n"
firstp = True
for sig in sorted(ios, key=lambda x: x.duid):
Expand Down

0 comments on commit b3206e2

Please sign in to comment.