fhdl/tools: BUGFIX: fix group_by_target grouping
authorDavid Carne <davidcarne@gmail.com>
Wed, 17 Jul 2013 07:40:46 +0000 (00:40 -0700)
committerSebastien Bourdeauducq <sebastien@milkymist.org>
Wed, 17 Jul 2013 08:14:39 +0000 (10:14 +0200)
group_by_target does not properly combine target groups if statements
are presented in the order:

 ({A}, statement1)
 ({B}, statement2)
 ({A, B}, statement3)

which returns groups:

 ({A, B}, [statement1, statement3])
 ({B}, [statement2])

This patch fixes group_by_target such that the resulting group is:

 ({A, B}, [statement1, statement2, statement3])

migen/fhdl/tools.py

index 447333668f2e179aa5728382b603eef374bf560d..f2f572226eb310884afc3dca15ad4388179c84a1 100644 (file)
@@ -48,20 +48,29 @@ def list_targets(node):
        lister.visit(node)
        return lister.output_list
 
+def resort_statements(ol):
+       return [statement for i, statement in
+                       sorted(ol, key=lambda x: x[0])]
+
 def group_by_targets(sl):
        groups = []
-       for statement in flat_iteration(sl):
+       for statement_order, statement in enumerate(flat_iteration(sl)):
                targets = list_targets(statement)
-               processed = False
-               for g in groups:
-                       if not targets.isdisjoint(g[0]):
-                               g[0].update(targets)
-                               g[1].append(statement)
-                               processed = True
-                               break
-               if not processed:
-                       groups.append((targets, [statement]))
-       return groups
+
+               chk_groups = [(targets.isdisjoint(g[0]), g) for g in groups]
+               merge_groups = [g for dj, g in chk_groups if not dj]
+               groups = [g for dj, g in chk_groups if dj]
+
+               new_group = (set(targets), [(statement_order, statement)])
+
+               for g in merge_groups:
+                       new_group[0].update(g[0])
+                       new_group[1].extend(g[1])
+
+               groups.append(new_group)
+
+       return [(target, resort_statements(stmts))
+               for target, stmts in groups]
 
 def list_special_ios(f, ins, outs, inouts):
        r = set()