transform/unroll: support for variables
authorSebastien Bourdeauducq <sebastien@milkymist.org>
Fri, 12 Oct 2012 17:54:03 +0000 (19:54 +0200)
committerSebastien Bourdeauducq <sebastien@milkymist.org>
Fri, 12 Oct 2012 17:54:03 +0000 (19:54 +0200)
examples/basic/multi_accumulator.py
migen/transform/unroll.py

index 6f7e0502b6a5705871c1e29c9df4919dde26ed13..51352cd359de8db7d8ea30e2e2a019a2d072172b 100644 (file)
@@ -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)))
index 69ec5e9c5b78853cd7c5ac538f3674430c8b4160..6e517cd187d21db62baf956ff0794d4a1462e99c 100644 (file)
@@ -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