back.rtlil: assign undriven signals to their reset value.

Fixes #35.
This commit is contained in:
whitequark 2019-05-13 07:56:11 +00:00
parent 744e33f42d
commit 921f506e69

View file

@ -3,7 +3,7 @@ import textwrap
from collections import defaultdict, OrderedDict
from contextlib import contextmanager
from ..tools import bits_for
from ..tools import bits_for, flatten
from ..hdl import ast, rec, ir, mem, xfrm
@ -844,6 +844,30 @@ def convert_fragment(builder, fragment, hierarchy):
wire_curr, wire_next = compiler_state.resolve(signal)
sync.update(wire_curr, wire_next)
# Any signals that are used but neither driven nor connected to an input port always
# assume their reset values. We need to assign the reset value explicitly, since only
# driven sync signals are handled by the logic above.
#
# Because this assignment is done at a late stage, a single Signal object can get assigned
# many times, once in each module it is used. This is a deliberate decision; the possible
# alternatives are to add ports for undriven signals (which requires choosing one module
# to drive it to reset value arbitrarily) or to replace them with their reset value (which
# removes valuable source location information).
driven = ast.SignalSet()
for domain, signals in fragment.iter_drivers():
driven.update(flatten(signal._lhs_signals() for signal in signals))
driven.update(fragment.iter_ports(dir="i"))
driven.update(fragment.iter_ports(dir="io"))
for subfragment, sub_name in fragment.subfragments:
driven.update(subfragment.iter_ports(dir="o"))
driven.update(subfragment.iter_ports(dir="io"))
for wire in compiler_state.wires:
if wire in driven:
continue
wire_curr, _ = compiler_state.wires[wire]
module.connect(wire_curr, rhs_compiler(ast.Const(wire.reset, wire.nbits)))
# Finally, collect the names we've given to our ports in RTLIL, and correlate these with
# the signals represented by these ports. If we are a submodule, this will be necessary
# to create a cell for us in the parent module.