From b3206e2b6bf179469f55fabf41bb2f6cea3a617e Mon Sep 17 00:00:00 2001 From: Rohit Singh Date: Thu, 5 Jul 2018 16:27:53 +0530 Subject: [PATCH] fhdl.verilog: declare outputs from specials, but assigned in always(*) blocks, as reg instead of wire Fixes #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 --- migen/fhdl/verilog.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/migen/fhdl/verilog.py b/migen/fhdl/verilog.py index ca4cb02a2..7feec1c53 100644 --- a/migen/fhdl/verilog.py +++ b/migen/fhdl/verilog.py @@ -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):