transform/unroll_sync: autodetect in/out
authorSebastien Bourdeauducq <sebastien@milkymist.org>
Mon, 15 Oct 2012 18:32:07 +0000 (20:32 +0200)
committerSebastien Bourdeauducq <sebastien@milkymist.org>
Mon, 15 Oct 2012 18:32:07 +0000 (20:32 +0200)
examples/basic/multi_accumulator.py
migen/transform/unroll.py

index 51352cd359de8db7d8ea30e2e2a019a2d072172b..7f3cf80068d699cf2635d827dc2c67126071fc02 100644 (file)
@@ -19,5 +19,5 @@ 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, z: zs})
+sync_u = unroll_sync(sync, {x: xs, y: ysacc: accs, z: zs})
 print(verilog.convert(Fragment(sync=sync_u), ios=set(xs+ys+zs)))
index 644fe7ee1139ec578a8b83b2616265c09f6d1e30..d3a391990c2d12f29babb9a2a85e02f8f89b7dc2 100644 (file)
@@ -2,10 +2,11 @@ from itertools import repeat
 
 from migen.fhdl.structure import *
 from migen.fhdl.structure import _Operator, _Slice, _Assign, _ArrayProxy
+from migen.fhdl.tools import list_targets
 
 # y <= y + a + b
 #
-# unroll_sync(sync, {b: [b1, b2], c: [c1, c2]}, {y: [y1, y2]})
+# unroll_sync(sync, {b: [b1, b2], c: [c1, c2]y: [y1, y2]})
 #
 # ==>
 #
@@ -72,6 +73,17 @@ def _list_step_dicts(d):
                pass
        return r
 
+def _classify_repl(statements, replacements):
+       targets = list_targets(statements)
+       inputs = {}
+       outputs = {}
+       for k, v in replacements.items():
+               if k in targets:
+                       outputs[k] = v
+               else:
+                       inputs[k] = v
+       return inputs, outputs
+
 def _variable_for(s, n):
        sn = s.backtrace[-1][0]
        if isinstance(sn, str):
@@ -80,7 +92,12 @@ def _variable_for(s, n):
                name = "v"
        return Signal(s.bv, name=name, variable=True)
 
-def unroll_sync(statements, inputs, outputs):
+def unroll_sync(statements, replacements):
+       if isinstance(statements, list):
+               sl = statements
+       else:
+               sl = statements(0)
+       inputs, outputs = _classify_repl(sl, replacements)
        assert(inputs or outputs)
        if inputs:
                sd_in = _list_step_dicts(inputs)
@@ -106,10 +123,11 @@ def unroll_sync(statements, inputs, outputs):
                
                # replace signals with intermediate variables and copy statements
                io_var_dict.update(di)
-               if isinstance(statements, list):
-                       sl = statements
-               else:
-                       sl = statements(n)
+               if n: # done for n = 0 at the beginning of function
+                       if isinstance(statements, list):
+                               sl = statements
+                       else:
+                               sl = statements(n)
                r += _replace(sl, io_var_dict, do_var)
                
                # assign to output signals