diff --git a/b_asic/architecture.py b/b_asic/architecture.py
index f5040cbea7125ad6697732cf6e37772a49087182..db6f6a56937fdbb87048f89fcaec3ff372233e8b 100644
--- a/b_asic/architecture.py
+++ b/b_asic/architecture.py
@@ -104,7 +104,7 @@ class Resource:
         if outputs:
             outstrs = [f"<{outstr}> {outstr}" for outstr in outputs]
             ret += f"|{{{'|'.join(outstrs)}}}"
-        return ret
+        return "{" + ret + "}"
 
     @property
     def entity_name(self) -> str:
@@ -243,16 +243,16 @@ class Architecture:
         self._memories = memories
         self._entity_name = entity_name
         self._direct_interconnects = direct_interconnects
-        self._variable_inport_to_resource: Dict[InputPort, Resource] = {}
-        self._variable_outport_to_resource: Dict[OutputPort, Resource] = {}
+        self._variable_inport_to_resource: Dict[InputPort, Tuple[Resource, int]] = {}
+        self._variable_outport_to_resource: Dict[OutputPort, Tuple[Resource, int]] = {}
         self._operation_inport_to_resource: Dict[InputPort, Resource] = {}
         self._operation_outport_to_resource: Dict[OutputPort, Resource] = {}
 
-        self._build_dicts()
-
         # Validate input and output ports
         self.validate_ports()
 
+        self._build_dicts()
+
     def _build_dicts(self):
         for pe in self.processing_elements:
             for operator in pe.processes:
@@ -264,18 +264,20 @@ class Architecture:
         for memory in self.memories:
             for mv in memory:
                 for read_port in mv.read_ports:
-                    self._variable_inport_to_resource[read_port] = memory
-                self._variable_outport_to_resource[mv.write_port] = memory
+                    self._variable_inport_to_resource[read_port] = (memory, 0)  # Fix
+                self._variable_outport_to_resource[mv.write_port] = (memory, 0)  # Fix
         if self._direct_interconnects:
             for di in self._direct_interconnects:
                 di = cast(MemoryVariable, di)
                 for read_port in di.read_ports:
-                    self._variable_inport_to_resource[
-                        read_port
-                    ] = self._operation_outport_to_resource[di.write_port]
-                    self._variable_outport_to_resource[
-                        di.write_port
-                    ] = self._operation_inport_to_resource[read_port]
+                    self._variable_inport_to_resource[read_port] = (
+                        self._operation_outport_to_resource[di.write_port],
+                        di.write_port.index,
+                    )
+                    self._variable_outport_to_resource[di.write_port] = (
+                        self._operation_inport_to_resource[read_port],
+                        read_port.index,
+                    )
 
     def validate_ports(self):
         # Validate inputs and outputs of memory variables in all the memories in this
@@ -350,7 +352,9 @@ class Architecture:
 
     def get_interconnects_for_pe(
         self, pe: ProcessingElement
-    ) -> Tuple[List[Dict[Resource, int]], List[Dict[Resource, int]]]:
+    ) -> Tuple[
+        List[Dict[Tuple[Resource, int], int]], List[Dict[Tuple[Resource, int], int]]
+    ]:
         """
         Return lists of dictionaries with interconnect information for a
         ProcessingElement.
@@ -402,7 +406,9 @@ class Architecture:
         return self._digraph()._repr_mimebundle_(include=["image/png"])["image/png"]
 
     def _digraph(self) -> Digraph:
+        edges = set()
         dg = Digraph(node_attr={'shape': 'record'})
+        # dg.attr(rankdir="LR")
         for i, mem in enumerate(self._memories):
             dg.node(mem.entity_name, mem._struct_def())
         for i, pe in enumerate(self._processing_elements):
@@ -410,15 +416,25 @@ class Architecture:
         for pe in self._processing_elements:
             inputs, outputs = self.get_interconnects_for_pe(pe)
             for i, inp in enumerate(inputs):
-                for source, cnt in inp.items():
-                    dg.edge(
-                        source.entity_name, f"{pe.entity_name}:in{i}", label=f"{cnt}"
+                for (source, port), cnt in inp.items():
+                    edges.add(
+                        (
+                            f"{source.entity_name}:out{port}",
+                            f"{pe.entity_name}:in{i}",
+                            f"{cnt}",
+                        )
                     )
             for o, outp in enumerate(outputs):
-                for dest, cnt in outp.items():
-                    dg.edge(
-                        f"{pe.entity_name}:out{o}", dest.entity_name, label=f"{cnt}"
+                for (dest, port), cnt in outp.items():
+                    edges.add(
+                        (
+                            f"{pe.entity_name}:out{o}",
+                            f"{dest.entity_name}:in{port}",
+                            f"{cnt}",
+                        )
                     )
+        for src, dest, cnt in edges:
+            dg.edge(src, dest, label=cnt)
         return dg
 
     @property
diff --git a/examples/secondorderdirectformiir_architecture.py b/examples/secondorderdirectformiir_architecture.py
index ee1630098ceecd655bcf4c6b55809d0ee47a104c..2cb2022484882ae45ae69f693fc2a608cc2ad4e7 100644
--- a/examples/secondorderdirectformiir_architecture.py
+++ b/examples/secondorderdirectformiir_architecture.py
@@ -84,3 +84,31 @@ for i, mem in enumerate(mem_vars_set):
 # %%
 # Create architecture
 arch = Architecture({p1, p2, p_in, p_out}, memories, direct_interconnects=direct)
+
+# %%
+# The architecture can be rendered in enriched shells.
+#
+# .. graphviz::
+#
+#        digraph {
+#             node [shape=record]
+#             memory1 [label="{{<in0> in0}|memory1|{<out0> out0}}"]
+#             memory0 [label="{{<in0> in0}|memory0|{<out0> out0}}"]
+#             memory2 [label="{{<in0> in0}|memory2|{<out0> out0}}"]
+#             in [label="{in|{<out0> out0}}"]
+#             out [label="{{<in0> in0}|out}"]
+#             cmul [label="{{<in0> in0}|cmul|{<out0> out0}}"]
+#             adder [label="{{<in0> in0|<in1> in1}|adder|{<out0> out0}}"]
+#             memory1:out0 -> adder:in1 [label=1]
+#             cmul:out0 -> adder:in0 [label=1]
+#             cmul:out0 -> memory0:in0 [label=3]
+#             memory0:out0 -> adder:in0 [label=1]
+#             adder:out0 -> adder:in1 [label=1]
+#             memory1:out0 -> cmul:in0 [label=5]
+#             memory0:out0 -> adder:in1 [label=2]
+#             adder:out0 -> memory1:in0 [label=2]
+#             adder:out0 -> out:in0 [label=1]
+#             memory2:out0 -> adder:in0 [label=2]
+#             cmul:out0 -> memory2:in0 [label=2]
+#             in:out0 -> cmul:in0 [label=1]
+#        }
diff --git a/test/test_architecture.py b/test/test_architecture.py
index b100f23f5c7a7208ebcc4ec9bf1ab326cb451b2a..e7b42e893895f1814e1a6009bd8158c9d0b6e89a 100644
--- a/test/test_architecture.py
+++ b/test/test_architecture.py
@@ -89,9 +89,9 @@ def test_architecture(schedule_direct_form_iir_lp_filter: Schedule):
             s = (
                 'digraph {\n\tnode [shape=record]\n\t'
                 + pe._entity_name
-                + ' [label="{<in0> in0|<in1> in1}|'
+                + ' [label="{{<in0> in0|<in1> in1}|'
                 + pe._entity_name
-                + '|{<out0> out0}"]\n}'
+                + '|{<out0> out0}}"]\n}'
             )
             assert pe._digraph().source in (s, s + '\n')
 
@@ -107,8 +107,8 @@ def test_architecture(schedule_direct_form_iir_lp_filter: Schedule):
     for i, memory in enumerate(memories):
         memory.set_entity_name(f"MEM{i}")
         s = (
-            'digraph {\n\tnode [shape=record]\n\tMEM0 [label="{<in0> in0}|MEM0|{<out0>'
-            ' out0}"]\n}'
+            'digraph {\n\tnode [shape=record]\n\tMEM0 [label="{{<in0> in0}|MEM0|{<out0>'
+            ' out0}}"]\n}'
         )
         assert memory._digraph().source in (s, s + '\n')