From eacba52fba973d91671e827746d1b016427d29e9 Mon Sep 17 00:00:00 2001 From: Sebastien Bourdeauducq Date: Fri, 12 Oct 2012 19:54:03 +0200 Subject: [PATCH] transform/unroll: support for variables --- examples/basic/multi_accumulator.py | 12 ++++++++---- migen/transform/unroll.py | 24 ++++++++++++++++++------ 2 files changed, 26 insertions(+), 10 deletions(-) diff --git a/examples/basic/multi_accumulator.py b/examples/basic/multi_accumulator.py index 6f7e0502..51352cd3 100644 --- a/examples/basic/multi_accumulator.py +++ b/examples/basic/multi_accumulator.py @@ -4,16 +4,20 @@ from migen.fhdl import verilog x = Signal(BV(4)) y = Signal(BV(4)) -acc = Signal(BV(4)) +acc = Signal(BV(4), variable=True) +z = Signal() sync = [ - acc.eq(acc + x + y) + If(acc == 2, acc.eq(3)), + acc.eq(acc + x + y), + z.eq(acc == 0) ] n = 5 xs = [Signal(BV(4)) for i in range(n)] ys = [Signal(BV(4)) for i in range(n)] accs = [Signal(BV(4)) for i in range(n)] +zs = [Signal() for i in range(n)] -sync_u = unroll_sync(sync, {x: xs, y: ys}, {acc: accs}) -print(verilog.convert(Fragment(sync=sync_u), ios=set(xs+ys+accs))) +sync_u = unroll_sync(sync, {x: xs, y: ys}, {acc: accs, z: zs}) +print(verilog.convert(Fragment(sync=sync_u), ios=set(xs+ys+zs))) diff --git a/migen/transform/unroll.py b/migen/transform/unroll.py index 69ec5e9c..6e517cd1 100644 --- a/migen/transform/unroll.py +++ b/migen/transform/unroll.py @@ -80,15 +80,27 @@ def _variable_for(s, n): def unroll_sync(sync, inputs, outputs): sd_in = _list_step_dicts(inputs) sd_out = _list_step_dicts(outputs) - - do_var_old = sd_out[-1] + r = [] + io_var_dict = sd_out[-1].copy() for n, (di, do) in enumerate(zip(sd_in, sd_out)): do_var = dict((k, _variable_for(v, n)) for k, v in do.items()) - di_plus_do_var_old = di.copy() - di_plus_do_var_old.update(do_var_old) - r += _replace(sync, di_plus_do_var_old, do_var) + + # initialize variables + for k, v in io_var_dict.items(): + if k.variable: + r.append(do_var[k].eq(io_var_dict[k])) + io_var_dict[k] = do_var[k] + + + # replace signals with intermediate variables and copy statements + io_var_dict.update(di) + r += _replace(sync, io_var_dict, do_var) + + # assign to output signals r += [v.eq(do_var[k]) for k, v in do.items()] - do_var_old = do_var + + # prepare the next i+o dictionary + io_var_dict = do_var.copy() return r -- 2.30.2