diff --git a/b_asic/resources.py b/b_asic/resources.py index cf74a1ea1d6b1e65ecbfe863bd461543d99978a1..94b18b4ee0f58f01867b0b59a45a104f2e5c6b4d 100644 --- a/b_asic/resources.py +++ b/b_asic/resources.py @@ -591,6 +591,7 @@ class ProcessCollection: marker_write: str = "o", show_markers: bool = True, allow_excessive_lifetimes: bool = False, + title: Optional[str] = None, ) -> None: """ Show the process collection using the current Matplotlib backend. @@ -614,6 +615,8 @@ class ProcessCollection: allow_excessive_lifetimes : bool, default False If set to true, the plot method allows ploting collections of variables with a greater lifetime than the schedule time. + title : str, optional + Title of plot. """ fig, ax = plt.subplots() self.plot( @@ -626,6 +629,8 @@ class ProcessCollection: show_markers=show_markers, allow_excessive_lifetimes=allow_excessive_lifetimes, ) + if title: + fig.suptitle(title) fig.show() # type: ignore def create_exclusion_graph_from_ports( diff --git a/b_asic/schedule.py b/b_asic/schedule.py index 5d7c11c21e2f90bd37078146a4d2f3e7c7430541..61b5bd847f0605c2921c063bb137a5fd3c537a1e 100644 --- a/b_asic/schedule.py +++ b/b_asic/schedule.py @@ -995,7 +995,9 @@ class Schedule: """ self._plot_schedule(ax, operation_gap=operation_gap) - def show(self, operation_gap: Optional[float] = None) -> None: + def show( + self, operation_gap: Optional[float] = None, title: Optional[str] = None + ) -> None: """ Show the schedule. Will display based on the current Matplotlib backend. @@ -1004,8 +1006,13 @@ class Schedule: operation_gap : float, optional The vertical distance between operations in the schedule. The height of the operation is always 1. + title : str, optional + Figure title. """ - self._get_figure(operation_gap=operation_gap).show() + fig = self._get_figure(operation_gap=operation_gap) + if title: + fig.suptitle(title) + fig.show() def _get_figure(self, operation_gap: Optional[float] = None) -> Figure: """ diff --git a/examples/secondorderdirectformiir_architecture.py b/examples/secondorderdirectformiir_architecture.py index f10fa45f20701a0d31185bb3685b560850876d3c..d5de928fa0b596ff9c7f05b8ae5cb45947e84b79 100644 --- a/examples/secondorderdirectformiir_architecture.py +++ b/examples/secondorderdirectformiir_architecture.py @@ -39,7 +39,7 @@ sfg.set_execution_time_of_type(Addition.type_name(), 1) # %% # Create schedule schedule = Schedule(sfg, cyclic=True) -schedule.show() +schedule.show(title='Original schedule') # %% # Rescheudle to only require one adder and one multiplier @@ -48,19 +48,19 @@ schedule.move_operation('cmul5', -5) schedule.move_operation('cmul4', -4) schedule.move_operation('cmul6', -2) schedule.move_operation('cmul3', 1) -schedule.show() +schedule.show(title='Improved schedule') # %% # Extract operations and create processing elements operations = schedule.get_operations() adders = operations.get_by_type_name('add') -adders.show() +adders.show(title="Adder executions") mults = operations.get_by_type_name('cmul') -mults.show() +mults.show(title="Multiplier executions") inputs = operations.get_by_type_name('in') -inputs.show() +inputs.show(title="Input executions") outputs = operations.get_by_type_name('out') -outputs.show() +outputs.show(title="Output executions") p1 = ProcessingElement(adders, entity_name="adder") p2 = ProcessingElement(mults, entity_name="cmul") @@ -69,18 +69,17 @@ p_out = ProcessingElement(outputs, entity_name='out') # %% # Extract memory variables -# Memories mem_vars = schedule.get_memory_variables() -mem_vars.show() +mem_vars.show(title="All memory variables") direct, mem_vars = mem_vars.split_on_length() -direct.show() -mem_vars.show() +direct.show(title="Direct interconnects") +mem_vars.show(title="Non-zero time memory variables") mem_vars_set = mem_vars.split_on_ports(read_ports=1, write_ports=1, total_ports=1) memories = set() for i, mem in enumerate(mem_vars_set): memories.add(Memory(mem, entity_name=f"memory{i}")) - mem.show() + mem.show(title=f"memory{i}") # %% # Create architecture