self.domains = OrderedDict()
self.subfragments = []
self.generated = OrderedDict()
+ self.flatten = False
def add_ports(self, *ports, dir):
assert dir in ("i", "o", "io")
for domain, signal in self.iter_drivers():
add_subfrag(driver_subfrags, signal, (None, hierarchy))
+ flatten_subfrags = set()
for i, (subfrag, name) in enumerate(self.subfragments):
+ if name is None:
+ name = "<unnamed #{}>".format(i)
+ subfrag_hierarchy = hierarchy + (name,)
+
+ if subfrag.flatten:
+ # Always flatten subfragments that explicitly request it.
+ flatten_subfrags.add((subfrag, subfrag_hierarchy))
+
if isinstance(subfrag, Instance):
# For memories (which are subfragments, but semantically a part of superfragment),
# record that this fragment is driving it.
continue
# First, recurse into subfragments and let them detect driver conflicts as well.
- if name is None:
- name = "<unnamed #{}>".format(i)
- subfrag_hierarchy = hierarchy + (name,)
subfrag_drivers, subfrag_memories = \
subfrag._resolve_hierarchy_conflicts(subfrag_hierarchy, mode)
# Find out the set of subfragments that needs to be flattened into this fragment
# to resolve driver-driver conflicts.
- flatten_subfrags = set()
def flatten_subfrags_if_needed(subfrags):
if len(subfrags) == 1:
return []
self.map_named_ports(fragment, new_fragment)
else:
new_fragment = Fragment()
+ new_fragment.flatten = fragment.flatten
self.map_ports(fragment, new_fragment)
self.map_subfragments(fragment, new_fragment)
self.map_domains(fragment, new_fragment)
"top.<unnamed #1>; hierarchy will be flattened"):
self.f1._resolve_hierarchy_conflicts(mode="warn")
+ def test_explicit_flatten(self):
+ self.f1 = Fragment()
+ self.f2 = Fragment()
+ self.f2.flatten = True
+ self.f1.add_subfragment(self.f2)
+
+ self.f1._resolve_hierarchy_conflicts(mode="silent")
+ self.assertEqual(self.f1.subfragments, [])
+
class InstanceTestCase(FHDLTestCase):
def setUp_cpu(self):