diff --git a/b_asic/architecture.py b/b_asic/architecture.py
index 510a29b4bcef6e1e10b3dd798e024f5b9dc60945..28f44d96d4c0a4deb4e696b88a417e9ba3006bfb 100644
--- a/b_asic/architecture.py
+++ b/b_asic/architecture.py
@@ -5,6 +5,7 @@ from collections import defaultdict
 from io import TextIOWrapper
 from typing import Dict, Iterable, Iterator, List, Optional, Set, Tuple, Union, cast
 
+import matplotlib.pyplot as plt
 from graphviz import Digraph
 
 from b_asic.port import InputPort, OutputPort
@@ -132,6 +133,7 @@ class Resource(HardwareBlock):
         self._collection = process_collection
         self._input_count = -1
         self._output_count = -1
+        self._assignment: Optional[List[ProcessCollection]] = None
 
     def __repr__(self):
         return self.entity_name
@@ -172,6 +174,19 @@ class Resource(HardwareBlock):
         # doc-string inherited
         return self._collection.schedule_time
 
+    def show_content(self):
+        if not self.is_assigned:
+            self._collection.show()
+        else:
+            fig, ax = plt.subplots()
+            for i, pc in enumerate(self._assignment):  # type: ignore
+                pc.plot(ax=ax, row=i)
+            fig.show()  # type: ignore
+
+    @property
+    def is_assigned(self) -> bool:
+        return self._assignment is not None
+
 
 class ProcessingElement(Resource):
     """
@@ -210,6 +225,11 @@ class ProcessingElement(Resource):
         self._entity_name = entity_name
         self._input_count = ops[0].input_count
         self._output_count = ops[0].output_count
+        self._assignment = list(
+            self._collection.split_on_execution_time(heuristic="left_edge")
+        )
+        if len(self._assignment) > 1:
+            raise ValueError("Cannot map ProcessCollection to single ProcessingElement")
 
     @property
     def processes(self) -> Set[OperatorProcess]:
@@ -275,6 +295,19 @@ class Memory(Resource):
         # Add information about the iterator type
         return cast(Iterator[MemoryVariable], iter(self._collection))
 
+    def _assign_ram(self, heuristic: str = "left_edge"):
+        """
+        Perform RAM-type assignment of MemoryVariables in this Memory.
+
+        Parameters
+        ----------
+        heuristic : {'left_edge', 'graph_color'}
+            The underlying heuristic to use when performing RAM assignment.
+        """
+        self._assignment = list(
+            self._collection.split_on_execution_time(heuristic=heuristic)
+        )
+
 
 class Architecture(HardwareBlock):
     """
diff --git a/b_asic/resources.py b/b_asic/resources.py
index 8ad13879df5b798f515bceb58eec11c1bbecdc10..e6f27bb44dacbbc1aa87458a8d6cecc2ede4f419 100644
--- a/b_asic/resources.py
+++ b/b_asic/resources.py
@@ -852,7 +852,7 @@ class ProcessCollection:
             )
             return self._split_from_graph_coloring(coloring)
         elif heuristic == "left_edge":
-            raise NotImplementedError()
+            return self._left_edge_assignment()
         else:
             raise ValueError(f"Invalid heuristic '{heuristic}'")
 
@@ -989,18 +989,17 @@ class ProcessCollection:
     def __iter__(self):
         return iter(self._collection)
 
-    def graph_color_cell_assignment(
+    def _graph_color_assignment(
         self,
         coloring_strategy: str = "saturation_largest_first",
         *,
         coloring: Optional[Dict[Process, int]] = None,
-    ) -> Set["ProcessCollection"]:
+    ) -> List["ProcessCollection"]:
         """
-        Perform cell assignment of the processes in this collection using graph
-        coloring.
+        Perform assignment of the processes in this collection using graph coloring.
 
-        Two or more processes can share a single cell if, and only if, they have no
-        overlaping time alive.
+        Two or more processes can share a single resource if, and only if, they have no
+        overlaping execution time.
 
         Parameters
         ----------
@@ -1014,7 +1013,7 @@ class ProcessCollection:
 
         Returns
         -------
-        A set of ProcessCollection
+        List[ProcessCollection]
 
         """
         cell_assignment: Dict[int, ProcessCollection] = dict()
@@ -1027,19 +1026,19 @@ class ProcessCollection:
             if cell not in cell_assignment:
                 cell_assignment[cell] = ProcessCollection(set(), self._schedule_time)
             cell_assignment[cell].add_process(process)
-        return set(cell_assignment.values())
+        return list(cell_assignment.values())
 
-    def left_edge_cell_assignment(self) -> Dict[int, "ProcessCollection"]:
+    def _left_edge_assignment(self) -> List["ProcessCollection"]:
         """
-        Perform cell assignment of the processes in this collection using the left-edge
+        Perform assignment of the processes in this collection using the left-edge
         algorithm.
 
-        Two or more processes can share a single cell if, and only if, they have no
-        overlaping time alive.
+        Two or more processes can share a single resource if, and only if, they have no
+        overlaping execution time.
 
         Returns
         -------
-        Dict[int, ProcessCollection]
+        List[ProcessCollection]
         """
         next_empty_cell = 0
         cell_assignment: Dict[int, ProcessCollection] = dict()
@@ -1070,7 +1069,7 @@ class ProcessCollection:
                 )
                 cell_assignment[next_empty_cell].add_process(next_process)
                 next_empty_cell += 1
-        return cell_assignment
+        return [pc for pc in cell_assignment.values()]
 
     def generate_memory_based_storage_vhdl(
         self,
diff --git a/test/test_resources.py b/test/test_resources.py
index 6751879f5f9f3819c1bcd66c879245c4e7787707..b5f5b13d089b3bb527ef6079fb49c397453f68a9 100644
--- a/test/test_resources.py
+++ b/test/test_resources.py
@@ -34,27 +34,30 @@ class TestProcessCollectionPlainMemoryVariable:
     @pytest.mark.mpl_image_compare(style='mpl20')
     def test_left_edge_cell_assignment(self, simple_collection: ProcessCollection):
         fig, ax = plt.subplots(1, 2)
-        assignment = simple_collection.left_edge_cell_assignment()
-        for cell in assignment:
-            assignment[cell].plot(ax=ax[1], row=cell)  # type: ignore
+        assignment = list(simple_collection._left_edge_assignment())
+        for i, cell in enumerate(assignment):
+            cell.plot(ax=ax[1], row=i)  # type: ignore
         simple_collection.plot(ax[0])  # type:ignore
         return fig
 
     def test_cell_assignment_matrix_transposer(self):
         collection = generate_matrix_transposer(4, min_lifetime=5)
-        assignment_left_edge = collection.left_edge_cell_assignment()
-        assignment_graph_color = collection.graph_color_cell_assignment(
+        assignment_left_edge = collection._left_edge_assignment()
+        assignment_graph_color = collection.split_on_execution_time(
             coloring_strategy='saturation_largest_first'
         )
-        assert len(assignment_left_edge.keys()) == 18
+        assert len(assignment_left_edge) == 18
         assert len(assignment_graph_color) == 16
 
     def test_generate_memory_based_vhdl(self):
         for rows in [2, 3, 4, 5, 7]:
             collection = generate_matrix_transposer(rows, min_lifetime=0)
-            assignment = collection.graph_color_cell_assignment()
+            assignment = collection.split_on_execution_time(heuristic="graph_color")
             collection.generate_memory_based_storage_vhdl(
-                filename=f'b_asic/codegen/testbench/streaming_matrix_transposition_memory_{rows}x{rows}.vhdl',
+                filename=(
+                    'b_asic/codegen/testbench/'
+                    f'streaming_matrix_transposition_memory_{rows}x{rows}.vhdl'
+                ),
                 entity_name=f'streaming_matrix_transposition_memory_{rows}x{rows}',
                 assignment=assignment,
                 word_length=16,
@@ -65,22 +68,31 @@ class TestProcessCollectionPlainMemoryVariable:
             generate_matrix_transposer(
                 rows, min_lifetime=0
             ).generate_register_based_storage_vhdl(
-                filename=f'b_asic/codegen/testbench/streaming_matrix_transposition_register_{rows}x{rows}.vhdl',
+                filename=(
+                    'b_asic/codegen/testbench/streaming_matrix_transposition_'
+                    f'register_{rows}x{rows}.vhdl'
+                ),
                 entity_name=f'streaming_matrix_transposition_register_{rows}x{rows}',
                 word_length=16,
             )
 
     def test_rectangular_matrix_transposition(self):
         collection = generate_matrix_transposer(rows=4, cols=8, min_lifetime=2)
-        assignment = collection.graph_color_cell_assignment()
+        assignment = collection.split_on_execution_time(heuristic="graph_color")
         collection.generate_memory_based_storage_vhdl(
-            filename='b_asic/codegen/testbench/streaming_matrix_transposition_memory_4x8.vhdl',
+            filename=(
+                'b_asic/codegen/testbench/streaming_matrix_transposition_memory_'
+                '4x8.vhdl'
+            ),
             entity_name='streaming_matrix_transposition_memory_4x8',
             assignment=assignment,
             word_length=16,
         )
         collection.generate_register_based_storage_vhdl(
-            filename='b_asic/codegen/testbench/streaming_matrix_transposition_register_4x8.vhdl',
+            filename=(
+                'b_asic/codegen/testbench/streaming_matrix_transposition_register_'
+                '4x8.vhdl'
+            ),
             entity_name='streaming_matrix_transposition_register_4x8',
             word_length=16,
         )