From 34b1f1a1ac1fe72020edce4558a3fdacb603e7c8 Mon Sep 17 00:00:00 2001 From: whitequark Date: Mon, 13 May 2019 07:56:11 +0000 Subject: [PATCH] back.rtlil: assign undriven signals to their reset value. Fixes #35. --- nmigen/back/rtlil.py | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/nmigen/back/rtlil.py b/nmigen/back/rtlil.py index b5a0efc..12415b3 100644 --- a/nmigen/back/rtlil.py +++ b/nmigen/back/rtlil.py @@ -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. -- 2.30.2