From 3155d9d21073606f2dadf17581d02ed6b63d9aae Mon Sep 17 00:00:00 2001 From: whitequark Date: Fri, 18 Jan 2019 01:27:17 +0000 Subject: [PATCH] back.rtlil: only emit each AnyConst/AnySeq cell once. These are semantically like signals, not like constants. --- nmigen/back/rtlil.py | 9 +++++++++ nmigen/hdl/ast.py | 8 ++++---- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/nmigen/back/rtlil.py b/nmigen/back/rtlil.py index 5225cf9..7c0dda7 100644 --- a/nmigen/back/rtlil.py +++ b/nmigen/back/rtlil.py @@ -227,6 +227,7 @@ class _ValueCompilerState: self.wires = ast.SignalDict() self.driven = ast.SignalDict() self.ports = ast.SignalDict() + self.anys = ast.ValueDict() self.expansions = ast.ValueDict() @@ -377,6 +378,9 @@ class _RHSValueCompiler(_ValueCompiler): return "{}'{:0{}b}".format(value.nbits, value_twos_compl, value.nbits) def on_AnyConst(self, value): + if value in self.s.anys: + return self.s.anys[value] + res_bits, res_sign = value.shape() res = self.s.rtlil.wire(width=res_bits) self.s.rtlil.cell("$anyconst", ports={ @@ -384,9 +388,13 @@ class _RHSValueCompiler(_ValueCompiler): }, params={ "WIDTH": res_bits, }, src=src(value.src_loc)) + self.s.anys[value] = res return res def on_AnySeq(self, value): + if value in self.s.anys: + return self.s.anys[value] + res_bits, res_sign = value.shape() res = self.s.rtlil.wire(width=res_bits) self.s.rtlil.cell("$anyseq", ports={ @@ -394,6 +402,7 @@ class _RHSValueCompiler(_ValueCompiler): }, params={ "WIDTH": res_bits, }, src=src(value.src_loc)) + self.s.anys[value] = res return res def on_Signal(self, value): diff --git a/nmigen/hdl/ast.py b/nmigen/hdl/ast.py index 735f412..3ae5370 100644 --- a/nmigen/hdl/ast.py +++ b/nmigen/hdl/ast.py @@ -255,7 +255,7 @@ class Const(Value): C = Const # shorthand -class AnyValue(Value): +class AnyValue(Value, DUID): def __init__(self, shape): super().__init__(src_loc_at=0) if isinstance(shape, int): @@ -1119,7 +1119,7 @@ class ValueKey: def __hash__(self): if isinstance(self.value, Const): return hash(self.value.value) - elif isinstance(self.value, Signal): + elif isinstance(self.value, (Signal, AnyValue)): return hash(self.value.duid) elif isinstance(self.value, (ClockSignal, ResetSignal)): return hash(self.value.domain) @@ -1149,7 +1149,7 @@ class ValueKey: if isinstance(self.value, Const): return self.value.value == other.value.value - elif isinstance(self.value, Signal): + elif isinstance(self.value, (Signal, AnyValue)): return self.value is other.value elif isinstance(self.value, (ClockSignal, ResetSignal)): return self.value.domain == other.value.domain @@ -1191,7 +1191,7 @@ class ValueKey: if isinstance(self.value, Const): return self.value < other.value - elif isinstance(self.value, Signal): + elif isinstance(self.value, (Signal, AnyValue)): return self.value.duid < other.value.duid elif isinstance(self.value, Slice): return (ValueKey(self.value.value) < ValueKey(other.value.value) and -- 2.30.2