diff --git a/b_asic/GUI/__init__.py b/b_asic/GUI/__init__.py
index 89256ec9340dbc331d5ddc58488e7a126907dde7..d0a06579bd007da30e5e5f5b3dcc67261934eddf 100644
--- a/b_asic/GUI/__init__.py
+++ b/b_asic/GUI/__init__.py
@@ -5,4 +5,4 @@ Graphical user interface for B-ASIC.
 
 from b_asic.GUI.main_window import start_editor
 
-__all__ = ['start_editor']
+__all__ = ["start_editor"]
diff --git a/b_asic/GUI/main_window.py b/b_asic/GUI/main_window.py
index f0c05be77dfe2d17b6e0d0409db2df5f489c0ff3..1a4419c1c7b0ecd52a9aa820ef5778e44488f212 100644
--- a/b_asic/GUI/main_window.py
+++ b/b_asic/GUI/main_window.py
@@ -104,14 +104,14 @@ class SFGMainWindow(QMainWindow):
 
         # Create toolbar
         self._toolbar = self.addToolBar("Toolbar")
-        self._toolbar.addAction(get_icon('open'), "Load SFG", self.load_work)
-        self._toolbar.addAction(get_icon('save'), "Save SFG", self.save_work)
+        self._toolbar.addAction(get_icon("open"), "Load SFG", self.load_work)
+        self._toolbar.addAction(get_icon("save"), "Save SFG", self.save_work)
         self._toolbar.addSeparator()
         self._toolbar.addAction(
-            get_icon('new-sfg'), "Create SFG", self.create_sfg_from_toolbar
+            get_icon("new-sfg"), "Create SFG", self.create_sfg_from_toolbar
         )
         self._toolbar.addAction(
-            get_icon('close'), "Clear workspace", self._clear_workspace
+            get_icon("close"), "Clear workspace", self._clear_workspace
         )
 
         # Create status bar
@@ -142,18 +142,18 @@ class SFGMainWindow(QMainWindow):
 
         self._ui.actionShowPC.triggered.connect(self._show_precedence_graph)
         self._ui.actionSimulateSFG.triggered.connect(self.simulate_sfg)
-        self._ui.actionSimulateSFG.setIcon(get_icon('sim'))
+        self._ui.actionSimulateSFG.setIcon(get_icon("sim"))
 
         # About menu
         self._ui.faqBASIC.triggered.connect(self.display_faq_page)
         self._ui.faqBASIC.setShortcut(QKeySequence("Ctrl+?"))
-        self._ui.faqBASIC.setIcon(get_icon('faq'))
+        self._ui.faqBASIC.setIcon(get_icon("faq"))
         self._ui.aboutBASIC.triggered.connect(self.display_about_page)
-        self._ui.aboutBASIC.setIcon(get_icon('about'))
+        self._ui.aboutBASIC.setIcon(get_icon("about"))
         self._ui.keybindsBASIC.triggered.connect(self.display_keybindings_page)
-        self._ui.keybindsBASIC.setIcon(get_icon('keys'))
+        self._ui.keybindsBASIC.setIcon(get_icon("keys"))
         self._ui.documentationBASIC.triggered.connect(self._open_documentation)
-        self._ui.documentationBASIC.setIcon(get_icon('docs'))
+        self._ui.documentationBASIC.setIcon(get_icon("docs"))
 
         # Operation lists
         self._ui.core_operations_list.itemClicked.connect(
@@ -166,20 +166,20 @@ class SFGMainWindow(QMainWindow):
             self._on_list_widget_item_clicked
         )
         self._ui.save_menu.triggered.connect(self.save_work)
-        self._ui.save_menu.setIcon(get_icon('save'))
+        self._ui.save_menu.setIcon(get_icon("save"))
         self._ui.save_menu.setShortcut(QKeySequence("Ctrl+S"))
         self._ui.load_menu.triggered.connect(self.load_work)
-        self._ui.load_menu.setIcon(get_icon('open'))
+        self._ui.load_menu.setIcon(get_icon("open"))
         self._ui.load_menu.setShortcut(QKeySequence("Ctrl+O"))
         self._ui.load_operations.triggered.connect(self.add_namespace)
-        self._ui.load_operations.setIcon(get_icon('add-operations'))
+        self._ui.load_operations.setIcon(get_icon("add-operations"))
         self._ui.exit_menu.triggered.connect(self.exit_app)
-        self._ui.exit_menu.setIcon(get_icon('quit'))
+        self._ui.exit_menu.setIcon(get_icon("quit"))
         self._ui.select_all.triggered.connect(self._select_all)
         self._ui.select_all.setShortcut(QKeySequence("Ctrl+A"))
-        self._ui.select_all.setIcon(get_icon('all'))
+        self._ui.select_all.setIcon(get_icon("all"))
         self._ui.unselect_all.triggered.connect(self._unselect_all)
-        self._ui.unselect_all.setIcon(get_icon('none'))
+        self._ui.unselect_all.setIcon(get_icon("none"))
         self._shortcut_signal = QShortcut(QKeySequence(Qt.Key_Space), self)
         self._shortcut_signal.activated.connect(self._connect_callback)
         self._create_recent_file_actions_and_menus()
@@ -208,13 +208,13 @@ class SFGMainWindow(QMainWindow):
 
         # Zoom to fit
         self._ui.view_menu.addSeparator()
-        self._zoom_to_fit_action = QAction(get_icon('zoom-to-fit'), "Zoom to &fit")
+        self._zoom_to_fit_action = QAction(get_icon("zoom-to-fit"), "Zoom to &fit")
         self._zoom_to_fit_action.triggered.connect(self._zoom_to_fit)
         self._ui.view_menu.addAction(self._zoom_to_fit_action)
 
         # Toggle full screen
         self._fullscreen_action = QAction(
-            get_icon('full-screen'), "Toggle f&ull screen"
+            get_icon("full-screen"), "Toggle f&ull screen"
         )
         self._fullscreen_action.setCheckable(True)
         self._fullscreen_action.triggered.connect(self._toggle_fullscreen)
@@ -397,10 +397,10 @@ class SFGMainWindow(QMainWindow):
         """Callback for toggling full screen mode."""
         if self.isFullScreen():
             self.showNormal()
-            self._fullscreen_action.setIcon(get_icon('full-screen'))
+            self._fullscreen_action.setIcon(get_icon("full-screen"))
         else:
             self.showFullScreen()
-            self._fullscreen_action.setIcon(get_icon('full-screen-exit'))
+            self._fullscreen_action.setIcon(get_icon("full-screen-exit"))
 
     def _update_recent_file_list(self):
         settings = QSettings()
diff --git a/b_asic/architecture.py b/b_asic/architecture.py
index d020cf6989e24c4326a07e30721df958d8554418..99625a644d8551cbd637baf805846835d6b0b360 100644
--- a/b_asic/architecture.py
+++ b/b_asic/architecture.py
@@ -68,7 +68,7 @@ class HardwareBlock:
             The entity name.
         """
         if not is_valid_vhdl_identifier(entity_name):
-            raise ValueError(f'{entity_name} is not a valid VHDL identifier')
+            raise ValueError(f"{entity_name} is not a valid VHDL identifier")
         self._entity_name = entity_name
 
     def write_code(self, path: str) -> None:
@@ -171,13 +171,13 @@ class Resource(HardwareBlock):
         return iter(self._collection)
 
     def _digraph(self) -> Digraph:
-        dg = Digraph(node_attr={'shape': 'box'})
+        dg = Digraph(node_attr={"shape": "box"})
         dg.node(
             self.entity_name,
             self._struct_def(),
-            style='filled',
+            style="filled",
             fillcolor=self._color,
-            fontname='Times New Roman',
+            fontname="Times New Roman",
         )
         return dg
 
@@ -199,18 +199,18 @@ class Resource(HardwareBlock):
         table_width = max(len(inputs), len(outputs), 1)
         if inputs:
             in_strs = [
-                f'<TD COLSPAN="{int(table_width/len(inputs))}"'
+                f'<TD COLSPAN="{int(table_width / len(inputs))}"'
                 f' PORT="{in_str}">{in_str}</TD>'
                 for in_str in inputs
             ]
             ret += f"<TR>{''.join(in_strs)}</TR>"
         ret += (
             f'<TR><TD COLSPAN="{table_width}">'
-            f'<B>{self.entity_name}{self._info()}</B></TD></TR>'
+            f"<B>{self.entity_name}{self._info()}</B></TD></TR>"
         )
         if outputs:
             out_strs = [
-                f'<TD COLSPAN="{int(table_width/len(outputs))}"'
+                f'<TD COLSPAN="{int(table_width / len(outputs))}"'
                 f' PORT="{out_str}">{out_str}</TD>'
                 for out_str in outputs
             ]
@@ -274,7 +274,7 @@ class Resource(HardwareBlock):
     def is_assigned(self) -> bool:
         return self._assignment is not None
 
-    def assign(self, heuristic: str = 'left_edge'):
+    def assign(self, heuristic: str = "left_edge"):
         """
         Perform assignment of processes to resource.
 
@@ -556,7 +556,7 @@ class Memory(Resource):
     def _info(self) -> str:
         if self.is_assigned:
             if self._memory_type == "RAM":
-                plural_s = 's' if len(self._assignment) >= 2 else ''
+                plural_s = "s" if len(self._assignment) >= 2 else ""
                 return f": (RAM, {len(self._assignment)} cell{plural_s})"
             else:
                 pass
@@ -858,7 +858,7 @@ of :class:`~b_asic.architecture.ProcessingElement`
         elif resource in self.processing_elements:
             self.processing_elements.remove(cast(ProcessingElement, resource))
         else:
-            raise ValueError('Resource not in architecture')
+            raise ValueError("Resource not in architecture")
 
     def assign_resources(self, heuristic: str = "left_edge") -> None:
         """
@@ -951,7 +951,7 @@ of :class:`~b_asic.architecture.ProcessingElement`
         colored : bool, default: True
             Whether to color the nodes.
         """
-        dg = Digraph(node_attr={'shape': 'box'})
+        dg = Digraph(node_attr={"shape": "box"})
         dg.attr(splines=splines)
         # Setup colors
         pe_color = (
@@ -988,26 +988,26 @@ of :class:`~b_asic.architecture.ProcessingElement`
         if cluster:
             # Add subgraphs
             if len(self._memories):
-                with dg.subgraph(name='cluster_memories') as c:
+                with dg.subgraph(name="cluster_memories") as c:
                     for mem in self._memories:
                         c.node(
                             mem.entity_name,
                             mem._struct_def(),
-                            style='filled',
+                            style="filled",
                             fillcolor=memory_color,
-                            fontname='Times New Roman',
+                            fontname="Times New Roman",
                         )
                     label = "Memory" if len(self._memories) <= 1 else "Memories"
                     c.attr(label=label, bgcolor=memory_cluster_color)
-            with dg.subgraph(name='cluster_pes') as c:
+            with dg.subgraph(name="cluster_pes") as c:
                 for pe in self._processing_elements:
-                    if pe._type_name not in ('in', 'out'):
+                    if pe._type_name not in ("in", "out"):
                         c.node(
                             pe.entity_name,
                             pe._struct_def(),
-                            style='filled',
+                            style="filled",
                             fillcolor=pe_color,
-                            fontname='Times New Roman',
+                            fontname="Times New Roman",
                         )
                 label = (
                     "Processing element"
@@ -1016,39 +1016,39 @@ of :class:`~b_asic.architecture.ProcessingElement`
                 )
                 c.attr(label=label, bgcolor=pe_cluster_color)
             if io_cluster:
-                with dg.subgraph(name='cluster_io') as c:
+                with dg.subgraph(name="cluster_io") as c:
                     for pe in self._processing_elements:
-                        if pe._type_name in ('in', 'out'):
+                        if pe._type_name in ("in", "out"):
                             c.node(
                                 pe.entity_name,
                                 pe._struct_def(),
-                                style='filled',
+                                style="filled",
                                 fillcolor=io_color,
-                                fontname='Times New Roman',
+                                fontname="Times New Roman",
                             )
                     c.attr(label="IO", bgcolor=io_cluster_color)
             else:
                 for pe in self._processing_elements:
-                    if pe._type_name in ('in', 'out'):
+                    if pe._type_name in ("in", "out"):
                         dg.node(
                             pe.entity_name,
                             pe._struct_def(),
-                            style='filled',
+                            style="filled",
                             fillcolor=io_color,
-                            fontname='Times New Roman',
+                            fontname="Times New Roman",
                         )
         else:
             for mem in self._memories:
                 dg.node(
                     mem.entity_name,
                     mem._struct_def(),
-                    style='filled',
+                    style="filled",
                     fillcolor=memory_color,
-                    fontname='Times New Roman',
+                    fontname="Times New Roman",
                 )
             for pe in self._processing_elements:
                 dg.node(
-                    pe.entity_name, pe._struct_def(), style='filled', fillcolor=pe_color
+                    pe.entity_name, pe._struct_def(), style="filled", fillcolor=pe_color
                 )
 
         # Create list of interconnects
@@ -1103,9 +1103,9 @@ of :class:`~b_asic.architecture.ProcessingElement`
                     dg.node(
                         name,
                         ret + "</TABLE>>",
-                        style='filled',
+                        style="filled",
                         fillcolor=mux_color,
-                        fontname='Times New Roman',
+                        fontname="Times New Roman",
                     )
                     # Add edge from mux output to resource input
                     dg.edge(f"{name}:out0", destination_str)
@@ -1115,8 +1115,8 @@ of :class:`~b_asic.architecture.ProcessingElement`
             original_src_str = src_str
             if len(destination_counts) > 1 and branch_node:
                 branch = f"{src_str}_branch".replace(":", "")
-                dg.node(branch, shape='point')
-                dg.edge(src_str, branch, arrowhead='none')
+                dg.node(branch, shape="point")
+                dg.edge(src_str, branch, arrowhead="none")
                 src_str = branch
             for destination_str, cnt_str in destination_counts:
                 if multiplexers and len(destination_list[destination_str]) > 1:
diff --git a/b_asic/codegen/testbench/test.py b/b_asic/codegen/testbench/test.py
index d0f455886ebd6ba03804b3614b0d68c7f4415b16..b7471e968865ede8facf868d9bbe13ee86b520a0 100755
--- a/b_asic/codegen/testbench/test.py
+++ b/b_asic/codegen/testbench/test.py
@@ -8,12 +8,12 @@ from vunit import VUnit
 # Absolute path of the testbench directory
 testbench_path = dirname(abspath(__file__))
 
-vu = VUnit.from_argv(argv=['--output-path', f'{testbench_path}/vunit_out'] + argv[1:])
+vu = VUnit.from_argv(argv=["--output-path", f"{testbench_path}/vunit_out"] + argv[1:])
 
 lib = vu.add_library("lib")
 lib.add_source_files(
     [
-        f'{testbench_path}/*.vhdl',
+        f"{testbench_path}/*.vhdl",
     ]
 )
 lib.set_compile_option("modelsim.vcom_flags", ["-2008"])
diff --git a/b_asic/codegen/vhdl/__init__.py b/b_asic/codegen/vhdl/__init__.py
index 2cce156aac66e7e720f2113c99f4515507eb2217..203450754601e8323ff6f397247e2ae9d2cae172 100644
--- a/b_asic/codegen/vhdl/__init__.py
+++ b/b_asic/codegen/vhdl/__init__.py
@@ -13,7 +13,7 @@ def write(
     indent_level: int,
     text: str,
     *,
-    end: str = '\n',
+    end: str = "\n",
     start: Optional[str] = None,
 ):
     """
@@ -39,7 +39,7 @@ def write(
     """
     if start is not None:
         f.write(start)
-    f.write(f'{VHDL_TAB*indent_level}{text}{end}')
+    f.write(f"{VHDL_TAB * indent_level}{text}{end}")
 
 
 def write_lines(f: TextIO, lines: List[Union[Tuple[int, str], Tuple[int, str, str]]]):
@@ -65,4 +65,4 @@ def write_lines(f: TextIO, lines: List[Union[Tuple[int, str], Tuple[int, str, st
         elif len(tpl) == 3:
             write(f, indent_level=tpl[0], text=str(tpl[1]), end=str(tpl[2]))
         else:
-            raise ValueError('All tuples in list `lines` must have length 2 or 3')
+            raise ValueError("All tuples in list `lines` must have length 2 or 3")
diff --git a/b_asic/codegen/vhdl/architecture.py b/b_asic/codegen/vhdl/architecture.py
index 439ae4ba8a72bda37fac17b7b9f874af6beb62fa..524f8c9b72915a8a51292da69d1b39689b1e0957 100644
--- a/b_asic/codegen/vhdl/architecture.py
+++ b/b_asic/codegen/vhdl/architecture.py
@@ -77,94 +77,94 @@ def memory_based_storage(
     )  # Next power-of-two
 
     # Write architecture header
-    write(f, 0, f'architecture {architecture_name} of {entity_name} is', end='\n\n')
+    write(f, 0, f"architecture {architecture_name} of {entity_name} is", end="\n\n")
 
     #
     # Architecture declarative region begin
     #
-    write(f, 1, '-- HDL memory description')
+    write(f, 1, "-- HDL memory description")
     common.constant_declaration(
-        f, name='MEM_WL', signal_type='integer', value=word_length, name_pad=16
+        f, name="MEM_WL", signal_type="integer", value=word_length, name_pad=16
     )
     common.constant_declaration(
-        f, name='MEM_DEPTH', signal_type='integer', value=mem_depth, name_pad=16
+        f, name="MEM_DEPTH", signal_type="integer", value=mem_depth, name_pad=16
     )
     common.type_declaration(
-        f, 'mem_type', 'array(0 to MEM_DEPTH-1) of std_logic_vector(MEM_WL-1 downto 0)'
+        f, "mem_type", "array(0 to MEM_DEPTH-1) of std_logic_vector(MEM_WL-1 downto 0)"
     )
     common.signal_declaration(
         f,
-        name='memory',
-        signal_type='mem_type',
+        name="memory",
+        signal_type="mem_type",
         name_pad=18,
-        vivado_ram_style='distributed',  # Xilinx Vivado distributed RAM
+        vivado_ram_style="distributed",  # Xilinx Vivado distributed RAM
     )
 
     # Schedule time counter
-    write(f, 1, '-- Schedule counter', start='\n')
+    write(f, 1, "-- Schedule counter", start="\n")
     common.constant_declaration(
         f,
-        name='SCHEDULE_CNT_LEN',
-        signal_type='integer',
+        name="SCHEDULE_CNT_LEN",
+        signal_type="integer",
         value=ceil(log2(schedule_time)),
         name_pad=16,
     )
     common.signal_declaration(
         f,
-        name='schedule_cnt',
-        signal_type='unsigned(SCHEDULE_CNT_LEN-1 downto 0)',
+        name="schedule_cnt",
+        signal_type="unsigned(SCHEDULE_CNT_LEN-1 downto 0)",
         name_pad=18,
     )
     for i in range(adr_pipe_depth):
         common.signal_declaration(
             f,
-            name=f'schedule_cnt{i+1}',
-            signal_type='unsigned(SCHEDULE_CNT_LEN-1 downto 0)',
+            name=f"schedule_cnt{i + 1}",
+            signal_type="unsigned(SCHEDULE_CNT_LEN-1 downto 0)",
             name_pad=18,
         )
     common.constant_declaration(
         f,
-        name='ADR_LEN',
-        signal_type='integer',
-        value=f'SCHEDULE_CNT_LEN-({int(log2(adr_mux_size))}*{adr_pipe_depth})',
+        name="ADR_LEN",
+        signal_type="integer",
+        value=f"SCHEDULE_CNT_LEN-({int(log2(adr_mux_size))}*{adr_pipe_depth})",
         name_pad=16,
     )
     common.alias_declaration(
         f,
-        name='schedule_cnt_adr',
-        signal_type='unsigned(ADR_LEN-1 downto 0)',
-        value='schedule_cnt(ADR_LEN-1 downto 0)',
+        name="schedule_cnt_adr",
+        signal_type="unsigned(ADR_LEN-1 downto 0)",
+        value="schedule_cnt(ADR_LEN-1 downto 0)",
         name_pad=19,
     )
 
     # Address generation signals
-    write(f, 1, '-- Memory address generation', start='\n')
+    write(f, 1, "-- Memory address generation", start="\n")
     for i in range(read_ports):
         common.signal_declaration(
-            f, f'read_port_{i}', 'std_logic_vector(MEM_WL-1 downto 0)', name_pad=18
+            f, f"read_port_{i}", "std_logic_vector(MEM_WL-1 downto 0)", name_pad=18
         )
         common.signal_declaration(
-            f, f'read_adr_{i}', 'integer range 0 to MEM_DEPTH-1', name_pad=18
+            f, f"read_adr_{i}", "integer range 0 to MEM_DEPTH-1", name_pad=18
         )
-        common.signal_declaration(f, f'read_en_{i}', 'std_logic', name_pad=18)
+        common.signal_declaration(f, f"read_en_{i}", "std_logic", name_pad=18)
     for i in range(write_ports):
         common.signal_declaration(
-            f, f'write_port_{i}', 'std_logic_vector(MEM_WL-1 downto 0)', name_pad=18
+            f, f"write_port_{i}", "std_logic_vector(MEM_WL-1 downto 0)", name_pad=18
         )
         common.signal_declaration(
-            f, f'write_adr_{i}', 'integer range 0 to MEM_DEPTH-1', name_pad=18
+            f, f"write_adr_{i}", "integer range 0 to MEM_DEPTH-1", name_pad=18
         )
-        common.signal_declaration(f, f'write_en_{i}', 'std_logic', name_pad=18)
+        common.signal_declaration(f, f"write_en_{i}", "std_logic", name_pad=18)
 
     # Address generation mutltiplexing signals
-    write(f, 1, '-- Address generation multiplexing signals', start='\n')
+    write(f, 1, "-- Address generation multiplexing signals", start="\n")
     for write_port_idx in range(write_ports):
         for depth in range(adr_pipe_depth + 1):
             for rom in range(total_roms // adr_mux_size**depth):
                 common.signal_declaration(
                     f,
-                    f'write_adr_{write_port_idx}_{depth}_{rom}',
-                    signal_type='integer range 0 to MEM_DEPTH-1',
+                    f"write_adr_{write_port_idx}_{depth}_{rom}",
+                    signal_type="integer range 0 to MEM_DEPTH-1",
                     name_pad=18,
                 )
     for write_port_idx in range(write_ports):
@@ -172,8 +172,8 @@ def memory_based_storage(
             for rom in range(total_roms // adr_mux_size**depth):
                 common.signal_declaration(
                     f,
-                    f'write_en_{write_port_idx}_{depth}_{rom}',
-                    signal_type='std_logic',
+                    f"write_en_{write_port_idx}_{depth}_{rom}",
+                    signal_type="std_logic",
                     name_pad=18,
                 )
     for read_port_idx in range(read_ports):
@@ -181,17 +181,17 @@ def memory_based_storage(
             for rom in range(total_roms // adr_mux_size**depth):
                 common.signal_declaration(
                     f,
-                    f'read_adr_{read_port_idx}_{depth}_{rom}',
-                    signal_type='integer range 0 to MEM_DEPTH-1',
+                    f"read_adr_{read_port_idx}_{depth}_{rom}",
+                    signal_type="integer range 0 to MEM_DEPTH-1",
                     name_pad=18,
                 )
 
     # Input sync signals
     if input_sync:
-        write(f, 1, '-- Input synchronization', start='\n')
+        write(f, 1, "-- Input synchronization", start="\n")
         for i in range(read_ports):
             common.signal_declaration(
-                f, f'p_{i}_in_sync', 'std_logic_vector(WL-1 downto 0)', name_pad=18
+                f, f"p_{i}_in_sync", "std_logic_vector(WL-1 downto 0)", name_pad=18
             )
 
     #
@@ -199,86 +199,86 @@ def memory_based_storage(
     #
 
     # Schedule counter
-    write(f, 0, 'begin', start='\n', end='\n\n')
-    write(f, 1, '-- Schedule counter')
-    common.synchronous_process_prologue(f=f, name='schedule_cnt_proc', clk='clk')
+    write(f, 0, "begin", start="\n", end="\n\n")
+    write(f, 1, "-- Schedule counter")
+    common.synchronous_process_prologue(f=f, name="schedule_cnt_proc", clk="clk")
     write_lines(
         f,
         [
-            (3, 'if rst = \'1\' then'),
+            (3, "if rst = '1' then"),
             (4, "schedule_cnt <= (others => '0');"),
-            (3, 'else'),
-            (4, 'if en = \'1\' then'),
-            (5, f'if schedule_cnt = {schedule_time-1} then'),
+            (3, "else"),
+            (4, "if en = '1' then"),
+            (5, f"if schedule_cnt = {schedule_time - 1} then"),
             (6, "schedule_cnt <= (others => '0');"),
-            (5, 'else'),
-            (6, 'schedule_cnt <= schedule_cnt + 1;'),
-            (5, 'end if;'),
-            (4, 'end if;'),
+            (5, "else"),
+            (6, "schedule_cnt <= schedule_cnt + 1;"),
+            (5, "end if;"),
+            (4, "end if;"),
         ],
     )
     for i in range(adr_pipe_depth):
         if i == 0:
-            write(f, 4, 'schedule_cnt1 <= schedule_cnt;')
+            write(f, 4, "schedule_cnt1 <= schedule_cnt;")
         else:
-            write(f, 4, f'schedule_cnt{i+1} <= schedule_cnt{i};')
-    write(f, 3, 'end if;')
+            write(f, 4, f"schedule_cnt{i + 1} <= schedule_cnt{i};")
+    write(f, 3, "end if;")
     common.synchronous_process_epilogue(
         f=f,
-        name='schedule_cnt_proc',
-        clk='clk',
+        name="schedule_cnt_proc",
+        clk="clk",
     )
 
     # Input synchronization
     if input_sync:
-        write(f, 1, '-- Input synchronization', start='\n')
+        write(f, 1, "-- Input synchronization", start="\n")
         common.synchronous_process_prologue(
             f=f,
-            name='input_sync_proc',
-            clk='clk',
+            name="input_sync_proc",
+            clk="clk",
         )
         for i in range(read_ports):
-            write(f, 3, f'p_{i}_in_sync <= p_{i}_in;')
+            write(f, 3, f"p_{i}_in_sync <= p_{i}_in;")
         common.synchronous_process_epilogue(
             f=f,
-            name='input_sync_proc',
-            clk='clk',
+            name="input_sync_proc",
+            clk="clk",
         )
 
     # Infer the memory
-    write(f, 1, '-- Memory', start='\n')
+    write(f, 1, "-- Memory", start="\n")
     common.asynchronous_read_memory(
         f=f,
-        clk='clk',
-        name=f'mem_{0}_proc',
+        clk="clk",
+        name=f"mem_{0}_proc",
         read_ports={
-            (f'read_port_{i}', f'read_adr_{i}', f'read_en_{i}')
+            (f"read_port_{i}", f"read_adr_{i}", f"read_en_{i}")
             for i in range(read_ports)
         },
         write_ports={
-            (f'write_port_{i}', f'write_adr_{i}', f'write_en_{i}')
+            (f"write_port_{i}", f"write_adr_{i}", f"write_en_{i}")
             for i in range(write_ports)
         },
     )
-    write(f, 1, f'read_adr_0 <= read_adr_0_{adr_pipe_depth}_0;')
-    write(f, 1, f'write_adr_0 <= write_adr_0_{adr_pipe_depth}_0;')
-    write(f, 1, f'write_en_0 <= write_en_0_{adr_pipe_depth}_0;')
+    write(f, 1, f"read_adr_0 <= read_adr_0_{adr_pipe_depth}_0;")
+    write(f, 1, f"write_adr_0 <= write_adr_0_{adr_pipe_depth}_0;")
+    write(f, 1, f"write_en_0 <= write_en_0_{adr_pipe_depth}_0;")
     if input_sync:
-        write(f, 1, 'write_port_0 <= p_0_in_sync;')
+        write(f, 1, "write_port_0 <= p_0_in_sync;")
     else:
-        write(f, 1, 'write_port_0 <= p_0_in;')
+        write(f, 1, "write_port_0 <= p_0_in;")
 
     # Input and output assignments
-    write(f, 1, '-- Input and output assignments', start='\n')
+    write(f, 1, "-- Input and output assignments", start="\n")
     p_zero_exec = filter(
         lambda p: p.execution_time == 0, (p for pc in assignment for p in pc)
     )
     common.synchronous_process_prologue(
         f,
-        clk='clk',
-        name='output_reg_proc',
+        clk="clk",
+        name="output_reg_proc",
     )
-    write(f, 3, 'case to_integer(schedule_cnt) is')
+    write(f, 3, "case to_integer(schedule_cnt) is")
     for p in p_zero_exec:
         if input_sync:
             write_time = (p.start_time + 1) % schedule_time
@@ -286,32 +286,32 @@ def memory_based_storage(
                 write(
                     f,
                     4,
-                    f'when {write_time}+{adr_pipe_depth} => p_0_out <= p_0_in_sync;',
+                    f"when {write_time}+{adr_pipe_depth} => p_0_out <= p_0_in_sync;",
                 )
             else:
-                write(f, 4, f'when {write_time} => p_0_out <= p_0_in_sync;')
+                write(f, 4, f"when {write_time} => p_0_out <= p_0_in_sync;")
         else:
             write_time = (p.start_time) % schedule_time
-            write(f, 4, f'when {write_time} => p_0_out <= p_0_in;')
+            write(f, 4, f"when {write_time} => p_0_out <= p_0_in;")
     write_lines(
         f,
         [
-            (4, 'when others => p_0_out <= read_port_0;'),
-            (3, 'end case;'),
+            (4, "when others => p_0_out <= read_port_0;"),
+            (3, "end case;"),
         ],
     )
     common.synchronous_process_epilogue(
         f,
-        clk='clk',
-        name='output_reg_proc',
+        clk="clk",
+        name="output_reg_proc",
     )
 
     #
     # ROM Write address generation
     #
-    write(f, 1, '--', start='\n')
-    write(f, 1, '-- Memory write address generation', start='')
-    write(f, 1, '--', end='\n')
+    write(f, 1, "--", start="\n")
+    write(f, 1, "-- Memory write address generation", start="")
+    write(f, 1, "--", end="\n")
 
     # Extract all the write addresses
     write_list: List[Optional[Tuple[int, MemoryVariable]]] = [
@@ -321,7 +321,7 @@ def memory_based_storage(
         for mv in collection:
             mv = cast(MemoryVariable, mv)
             if mv.start_time >= schedule_time:
-                raise ValueError('start_time greater than schedule_time')
+                raise ValueError("start_time greater than schedule_time")
             if mv.execution_time:
                 write_list[mv.start_time] = (i, mv)
 
@@ -334,32 +334,32 @@ def memory_based_storage(
             common.process_prologue(
                 f, sensitivity_list="schedule_cnt_adr", name="mem_write_address_proc"
             )
-        write(f, 3, 'case to_integer(schedule_cnt_adr) is')
+        write(f, 3, "case to_integer(schedule_cnt_adr) is")
         list_start_idx = rom * elements_per_rom
         list_stop_idx = list_start_idx + elements_per_rom
         for i, mv in filter(None, write_list[list_start_idx:list_stop_idx]):
             write_lines(
                 f,
                 [
-                    (4, f'-- {mv!r}'),
+                    (4, f"-- {mv!r}"),
                     (
                         4,
                         (
-                            f'when {mv.start_time % schedule_time} mod'
-                            f' {elements_per_rom} =>'
+                            f"when {mv.start_time % schedule_time} mod"
+                            f" {elements_per_rom} =>"
                         ),
                     ),
-                    (5, f'write_adr_0_{0}_{rom} <= {i};'),
-                    (5, f'write_en_0_{0}_{rom} <= \'1\';'),
+                    (5, f"write_adr_0_{0}_{rom} <= {i};"),
+                    (5, f"write_en_0_{0}_{rom} <= '1';"),
                 ],
             )
         write_lines(
             f,
             [
-                (4, 'when others =>'),
-                (5, f'write_adr_0_{0}_{rom} <= 0;'),
-                (5, f'write_en_0_{0}_{rom} <= \'0\';'),
-                (3, 'end case;'),
+                (4, "when others =>"),
+                (5, f"write_adr_0_{0}_{rom} <= 0;"),
+                (5, f"write_en_0_{0}_{rom} <= '0';"),
+                (3, "end case;"),
             ],
         )
         if input_sync:
@@ -377,16 +377,16 @@ def memory_based_storage(
     for layer in range(adr_pipe_depth):
         for mux_idx in range(total_roms // adr_mux_size ** (layer + 1)):
             common.synchronous_process_prologue(
-                f, clk='clk', name=f'mem_write_address_proc{layer+1}_{mux_idx}'
+                f, clk="clk", name=f"mem_write_address_proc{layer + 1}_{mux_idx}"
             )
             write(
                 f,
                 3,
                 (
-                    f'case to_integer(schedule_cnt{layer+1}('
-                    f'ADR_LEN+{layer*bits_per_mux + bits_per_mux - 1} downto '
-                    f'ADR_LEN+{layer*bits_per_mux}'
-                    ')) is'
+                    f"case to_integer(schedule_cnt{layer + 1}("
+                    f"ADR_LEN+{layer * bits_per_mux + bits_per_mux - 1} downto "
+                    f"ADR_LEN+{layer * bits_per_mux}"
+                    ")) is"
                 ),
             )
             for in_idx in range(adr_mux_size):
@@ -395,26 +395,26 @@ def memory_based_storage(
                     f,
                     4,
                     (
-                        f'-- {adr_mux_size}-to-1 MUX layer: '
-                        f'layer={layer}, MUX={mux_idx}, input={in_idx}'
+                        f"-- {adr_mux_size}-to-1 MUX layer: "
+                        f"layer={layer}, MUX={mux_idx}, input={in_idx}"
                     ),
                 )
                 write_lines(
                     f,
                     [
-                        (4, f'when {in_idx} =>'),
+                        (4, f"when {in_idx} =>"),
                         (
                             5,
                             (
-                                f'write_adr_0_{layer+1}_{mux_idx} <='
-                                f' write_adr_0_{layer}_{out_idx};'
+                                f"write_adr_0_{layer + 1}_{mux_idx} <="
+                                f" write_adr_0_{layer}_{out_idx};"
                             ),
                         ),
                         (
                             5,
                             (
-                                f'write_en_0_{layer+1}_{mux_idx} <='
-                                f' write_en_0_{layer}_{out_idx};'
+                                f"write_en_0_{layer + 1}_{mux_idx} <="
+                                f" write_en_0_{layer}_{out_idx};"
                             ),
                         ),
                     ],
@@ -422,23 +422,23 @@ def memory_based_storage(
             write_lines(
                 f,
                 [
-                    (4, 'when others =>'),
-                    (5, f'write_adr_0_{layer+1}_{mux_idx} <= 0;'),
-                    (5, f'write_en_0_{layer+1}_{mux_idx} <= \'0\';'),
-                    (3, 'end case;'),
+                    (4, "when others =>"),
+                    (5, f"write_adr_0_{layer + 1}_{mux_idx} <= 0;"),
+                    (5, f"write_en_0_{layer + 1}_{mux_idx} <= '0';"),
+                    (3, "end case;"),
                 ],
             )
             common.synchronous_process_epilogue(
-                f, clk='clk', name=f'mem_write_address_proc{layer+1}_{mux_idx}'
+                f, clk="clk", name=f"mem_write_address_proc{layer + 1}_{mux_idx}"
             )
             write(f, 1, "")
 
     #
     # ROM read address generation
     #
-    write(f, 1, '--', start='\n')
-    write(f, 1, '-- Memory read address generation', start='')
-    write(f, 1, '--', end='\n')
+    write(f, 1, "--", start="\n")
+    write(f, 1, "-- Memory read address generation", start="")
+    write(f, 1, "--", end="\n")
 
     # Extract all the read addresses
     read_list: List[Optional[Tuple[int, MemoryVariable]]] = [
@@ -461,7 +461,7 @@ def memory_based_storage(
             common.process_prologue(
                 f, sensitivity_list="schedule_cnt_adr", name="mem_read_address_proc"
             )
-        write(f, 3, 'case to_integer(schedule_cnt_adr) is')
+        write(f, 3, "case to_integer(schedule_cnt_adr) is")
         list_start_idx = rom * elements_per_rom
         list_stop_idx = list_start_idx + elements_per_rom
         for idx in range(list_start_idx, list_stop_idx):
@@ -474,17 +474,17 @@ def memory_based_storage(
                 write_lines(
                     f,
                     [
-                        (4, f'-- {mv!r}'),
-                        (4, f'when {idx} mod {elements_per_rom} =>'),
-                        (5, f'read_adr_0_{0}_{rom} <= {i};'),
+                        (4, f"-- {mv!r}"),
+                        (4, f"when {idx} mod {elements_per_rom} =>"),
+                        (5, f"read_adr_0_{0}_{rom} <= {i};"),
                     ],
                 )
         write_lines(
             f,
             [
-                (4, 'when others =>'),
-                (5, f'read_adr_0_{0}_{rom} <= 0;'),
-                (3, 'end case;'),
+                (4, "when others =>"),
+                (5, f"read_adr_0_{0}_{rom} <= 0;"),
+                (3, "end case;"),
             ],
         )
         if input_sync:
@@ -502,16 +502,16 @@ def memory_based_storage(
     for layer in range(adr_pipe_depth):
         for mux_idx in range(total_roms // adr_mux_size ** (layer + 1)):
             common.synchronous_process_prologue(
-                f, clk='clk', name=f'mem_read_address_proc{layer+1}_{mux_idx}'
+                f, clk="clk", name=f"mem_read_address_proc{layer + 1}_{mux_idx}"
             )
             write(
                 f,
                 3,
                 (
-                    f'case to_integer(schedule_cnt{layer+1}('
-                    f'ADR_LEN+{layer*bits_per_mux + bits_per_mux - 1} downto '
-                    f'ADR_LEN+{layer*bits_per_mux}'
-                    ')) is'
+                    f"case to_integer(schedule_cnt{layer + 1}("
+                    f"ADR_LEN+{layer * bits_per_mux + bits_per_mux - 1} downto "
+                    f"ADR_LEN+{layer * bits_per_mux}"
+                    ")) is"
                 ),
             )
             for in_idx in range(adr_mux_size):
@@ -520,19 +520,19 @@ def memory_based_storage(
                     f,
                     4,
                     (
-                        f'-- {adr_mux_size}-to-1 MUX layer: '
-                        f'layer={layer}, MUX={mux_idx}, input={in_idx}'
+                        f"-- {adr_mux_size}-to-1 MUX layer: "
+                        f"layer={layer}, MUX={mux_idx}, input={in_idx}"
                     ),
                 )
                 write_lines(
                     f,
                     [
-                        (4, f'when {in_idx} =>'),
+                        (4, f"when {in_idx} =>"),
                         (
                             5,
                             (
-                                f'read_adr_0_{layer+1}_{mux_idx} <='
-                                f' read_adr_0_{layer}_{out_idx};'
+                                f"read_adr_0_{layer + 1}_{mux_idx} <="
+                                f" read_adr_0_{layer}_{out_idx};"
                             ),
                         ),
                     ],
@@ -540,17 +540,17 @@ def memory_based_storage(
             write_lines(
                 f,
                 [
-                    (4, 'when others =>'),
-                    (5, f'read_adr_0_{layer+1}_{mux_idx} <= 0;'),
-                    (3, 'end case;'),
+                    (4, "when others =>"),
+                    (5, f"read_adr_0_{layer + 1}_{mux_idx} <= 0;"),
+                    (3, "end case;"),
                 ],
             )
             common.synchronous_process_epilogue(
-                f, clk='clk', name=f'mem_read_address_proc{layer+1}_{mux_idx}'
+                f, clk="clk", name=f"mem_read_address_proc{layer + 1}_{mux_idx}"
             )
             write(f, 1, "")
 
-    write(f, 0, f'end architecture {architecture_name};', start='\n')
+    write(f, 0, f"end architecture {architecture_name};", start="\n")
 
 
 def register_based_storage(
@@ -594,86 +594,86 @@ def register_based_storage(
     # Architecture declarative region begin
     #
     # Write architecture header
-    write(f, 0, f'architecture {architecture_name} of {entity_name} is', end='\n\n')
+    write(f, 0, f"architecture {architecture_name} of {entity_name} is", end="\n\n")
 
     # Schedule time counter
-    write(f, 1, '-- Schedule counter')
+    write(f, 1, "-- Schedule counter")
     common.signal_declaration(
         f,
-        name='schedule_cnt',
-        signal_type=f'integer range 0 to {schedule_time}-1',
+        name="schedule_cnt",
+        signal_type=f"integer range 0 to {schedule_time}-1",
         name_pad=18,
-        default_value='0',
+        default_value="0",
     )
 
     # Shift register
-    write(f, 1, '-- Shift register', start='\n')
+    write(f, 1, "-- Shift register", start="\n")
     common.type_declaration(
         f,
-        name='shift_reg_type',
-        alias=f'array(0 to {reg_cnt}-1) of std_logic_vector(WL-1 downto 0)',
+        name="shift_reg_type",
+        alias=f"array(0 to {reg_cnt}-1) of std_logic_vector(WL-1 downto 0)",
     )
     common.signal_declaration(
         f,
-        name='shift_reg',
-        signal_type='shift_reg_type',
+        name="shift_reg",
+        signal_type="shift_reg_type",
         name_pad=18,
     )
 
     # Back edge mux decoder
-    write(f, 1, '-- Back-edge mux select signal', start='\n')
+    write(f, 1, "-- Back-edge mux select signal", start="\n")
     common.signal_declaration(
         f,
-        name='back_edge_mux_sel',
-        signal_type=f'integer range 0 to {len(back_edges)}',
+        name="back_edge_mux_sel",
+        signal_type=f"integer range 0 to {len(back_edges)}",
         name_pad=18,
     )
 
     # Output mux selector
-    write(f, 1, '-- Output mux select signal', start='\n')
+    write(f, 1, "-- Output mux select signal", start="\n")
     common.signal_declaration(
         f,
-        name='out_mux_sel',
-        signal_type=f'integer range 0 to {len(output_regs) - 1}',
+        name="out_mux_sel",
+        signal_type=f"integer range 0 to {len(output_regs) - 1}",
         name_pad=18,
     )
 
     #
     # Architecture body begin
     #
-    write(f, 0, 'begin', start='\n', end='\n\n')
-    write(f, 1, '-- Schedule counter')
+    write(f, 0, "begin", start="\n", end="\n\n")
+    write(f, 1, "-- Schedule counter")
     common.synchronous_process_prologue(
         f=f,
-        name='schedule_cnt_proc',
-        clk='clk',
+        name="schedule_cnt_proc",
+        clk="clk",
     )
     write_lines(
         f,
         [
-            (4, 'if en = \'1\' then'),
-            (5, f'if schedule_cnt = {schedule_time}-1 then'),
-            (6, 'schedule_cnt <= 0;'),
-            (5, 'else'),
-            (6, 'schedule_cnt <= schedule_cnt + 1;'),
-            (5, 'end if;'),
-            (4, 'end if;'),
+            (4, "if en = '1' then"),
+            (5, f"if schedule_cnt = {schedule_time}-1 then"),
+            (6, "schedule_cnt <= 0;"),
+            (5, "else"),
+            (6, "schedule_cnt <= schedule_cnt + 1;"),
+            (5, "end if;"),
+            (4, "end if;"),
         ],
     )
     common.synchronous_process_epilogue(
         f=f,
-        name='schedule_cnt_proc',
-        clk='clk',
+        name="schedule_cnt_proc",
+        clk="clk",
     )
 
     # Shift register back-edge decoding
-    write(f, 1, '-- Shift register back-edge decoding', start='\n')
+    write(f, 1, "-- Shift register back-edge decoding", start="\n")
     common.synchronous_process_prologue(
         f,
-        clk='clk',
-        name='shift_reg_back_edge_decode_proc',
+        clk="clk",
+        name="shift_reg_back_edge_decode_proc",
     )
-    write(f, 3, 'case schedule_cnt is')
+    write(f, 3, "case schedule_cnt is")
     for time, entry in enumerate(forward_backward_table):
         if entry.back_edge_to:
             assert len(entry.back_edge_to) == 1
@@ -682,104 +682,104 @@ def register_based_storage(
                 write_lines(
                     f,
                     [
-                        (4, f'when {(time-1)%schedule_time} =>'),
-                        (5, f'-- ({src} -> {dst})'),
-                        (5, f'back_edge_mux_sel <= {mux_idx};'),
+                        (4, f"when {(time - 1) % schedule_time} =>"),
+                        (5, f"-- ({src} -> {dst})"),
+                        (5, f"back_edge_mux_sel <= {mux_idx};"),
                     ],
                 )
     write_lines(
         f,
         [
-            (4, 'when others =>'),
-            (5, 'back_edge_mux_sel <= 0;'),
-            (3, 'end case;'),
+            (4, "when others =>"),
+            (5, "back_edge_mux_sel <= 0;"),
+            (3, "end case;"),
         ],
     )
     common.synchronous_process_epilogue(
         f,
-        clk='clk',
-        name='shift_reg_back_edge_decode_proc',
+        clk="clk",
+        name="shift_reg_back_edge_decode_proc",
     )
 
     # Shift register multiplexer logic
-    write(f, 1, '-- Multiplexers for shift register', start='\n')
+    write(f, 1, "-- Multiplexers for shift register", start="\n")
     common.synchronous_process_prologue(
         f,
-        clk='clk',
-        name='shift_reg_proc',
+        clk="clk",
+        name="shift_reg_proc",
     )
     if sync_rst:
-        write(f, 3, 'if rst = \'1\' then')
+        write(f, 3, "if rst = '1' then")
         for reg_idx in range(reg_cnt):
-            write(f, 4, f'shift_reg({reg_idx}) <= (others => \'0\');')
-        write(f, 3, 'else')
+            write(f, 4, f"shift_reg({reg_idx}) <= (others => '0');")
+        write(f, 3, "else")
 
     write_lines(
         f,
         [
-            (3, '-- Default case'),
-            (3, 'shift_reg(0) <= p_0_in;'),
+            (3, "-- Default case"),
+            (3, "shift_reg(0) <= p_0_in;"),
         ],
     )
     for reg_idx in range(1, reg_cnt):
-        write(f, 3, f'shift_reg({reg_idx}) <= shift_reg({reg_idx-1});')
-    write(f, 3, 'case back_edge_mux_sel is')
+        write(f, 3, f"shift_reg({reg_idx}) <= shift_reg({reg_idx - 1});")
+    write(f, 3, "case back_edge_mux_sel is")
     for edge, mux_sel in back_edge_table.items():
         write_lines(
             f,
             [
-                (4, f'when {mux_sel} =>'),
-                (5, f'shift_reg({edge[1]}) <= shift_reg({edge[0]});'),
+                (4, f"when {mux_sel} =>"),
+                (5, f"shift_reg({edge[1]}) <= shift_reg({edge[0]});"),
             ],
         )
     write_lines(
         f,
         [
-            (4, 'when others => null;'),
-            (3, 'end case;'),
+            (4, "when others => null;"),
+            (3, "end case;"),
         ],
     )
 
     if sync_rst:
-        write(f, 3, 'end if;')
+        write(f, 3, "end if;")
 
     common.synchronous_process_epilogue(
         f,
-        clk='clk',
-        name='shift_reg_proc',
+        clk="clk",
+        name="shift_reg_proc",
     )
 
     # Output multiplexer decoding logic
-    write(f, 1, '-- Output multiplexer decoding logic', start='\n')
-    common.synchronous_process_prologue(f, clk='clk', name='out_mux_decode_proc')
-    write(f, 3, 'case schedule_cnt is')
+    write(f, 1, "-- Output multiplexer decoding logic", start="\n")
+    common.synchronous_process_prologue(f, clk="clk", name="out_mux_decode_proc")
+    write(f, 3, "case schedule_cnt is")
     for i, entry in enumerate(forward_backward_table):
         if entry.outputs_from is not None:
             sel = output_mux_table[entry.outputs_from]
-            write(f, 4, f'when {(i-1)%schedule_time} =>')
-            write(f, 5, f'out_mux_sel <= {sel};')
-    write(f, 3, 'end case;')
-    common.synchronous_process_epilogue(f, clk='clk', name='out_mux_decode_proc')
+            write(f, 4, f"when {(i - 1) % schedule_time} =>")
+            write(f, 5, f"out_mux_sel <= {sel};")
+    write(f, 3, "end case;")
+    common.synchronous_process_epilogue(f, clk="clk", name="out_mux_decode_proc")
 
     # Output multiplexer logic
-    write(f, 1, '-- Output multiplexer', start='\n')
+    write(f, 1, "-- Output multiplexer", start="\n")
     common.synchronous_process_prologue(
         f,
-        clk='clk',
-        name='out_mux_proc',
+        clk="clk",
+        name="out_mux_proc",
     )
-    write(f, 3, 'case out_mux_sel is')
+    write(f, 3, "case out_mux_sel is")
     for reg_i, mux_i in output_mux_table.items():
-        write(f, 4, f'when {mux_i} =>')
+        write(f, 4, f"when {mux_i} =>")
         if reg_i < 0:
-            write(f, 5, f'p_0_out <= p_{-1-reg_i}_in;')
+            write(f, 5, f"p_0_out <= p_{-1 - reg_i}_in;")
         else:
-            write(f, 5, f'p_0_out <= shift_reg({reg_i});')
-    write(f, 3, 'end case;')
+            write(f, 5, f"p_0_out <= shift_reg({reg_i});")
+    write(f, 3, "end case;")
     common.synchronous_process_epilogue(
         f,
-        clk='clk',
-        name='out_mux_proc',
+        clk="clk",
+        name="out_mux_proc",
     )
 
-    write(f, 0, f'end architecture {architecture_name};', start='\n')
+    write(f, 0, f"end architecture {architecture_name};", start="\n")
diff --git a/b_asic/codegen/vhdl/common.py b/b_asic/codegen/vhdl/common.py
index 7baeedf3b694271f6293176e96ec36c551117c26..198eb2d6f86093eed05c7e2a1d1ab1d00eaa9f8d 100644
--- a/b_asic/codegen/vhdl/common.py
+++ b/b_asic/codegen/vhdl/common.py
@@ -22,25 +22,25 @@ def b_asic_preamble(f: TextIO):
     # Try to acquire the current git commit hash
     git_commit_id = None
     try:
-        process = Popen(['git', 'rev-parse', '--short', 'HEAD'], stdout=PIPE)
-        git_commit_id = process.communicate()[0].decode('utf-8').strip()
+        process = Popen(["git", "rev-parse", "--short", "HEAD"], stdout=PIPE)
+        git_commit_id = process.communicate()[0].decode("utf-8").strip()
     except:  # noqa: E722
         pass
     write_lines(
         f,
         [
-            (0, '--'),
-            (0, '-- This code was automatically generated by the B-ASIC toolbox.'),
-            (0, f'-- Code generation timestamp: ({datetime.now()})'),
+            (0, "--"),
+            (0, "-- This code was automatically generated by the B-ASIC toolbox."),
+            (0, f"-- Code generation timestamp: ({datetime.now()})"),
         ],
     )
     if git_commit_id:
-        write(f, 0, f'-- B-ASIC short commit hash: {git_commit_id}')
+        write(f, 0, f"-- B-ASIC short commit hash: {git_commit_id}")
     write_lines(
         f,
         [
-            (0, '-- URL: https://gitlab.liu.se/da/B-ASIC'),
-            (0, '--', '\n\n'),
+            (0, "-- URL: https://gitlab.liu.se/da/B-ASIC"),
+            (0, "--", "\n\n"),
         ],
     )
 
@@ -64,12 +64,12 @@ def ieee_header(
     numeric_std : bool, default: True
         Include the numeric_std header.
     """
-    write(f, 0, 'library ieee;')
+    write(f, 0, "library ieee;")
     if std_logic_1164:
-        write(f, 0, 'use ieee.std_logic_1164.all;')
+        write(f, 0, "use ieee.std_logic_1164.all;")
     if numeric_std:
-        write(f, 0, 'use ieee.numeric_std.all;')
-    write(f, 0, '')
+        write(f, 0, "use ieee.numeric_std.all;")
+    write(f, 0, "")
 
 
 def signal_declaration(
@@ -111,15 +111,15 @@ def signal_declaration(
     """
     # Spacing of VHDL signals declaration always with a single tab
     name_pad = name_pad or 0
-    write(f, 1, f'signal {name:<{name_pad}} : {signal_type}', end='')
+    write(f, 1, f"signal {name:<{name_pad}} : {signal_type}", end="")
     if default_value is not None:
-        write(f, 0, f' := {default_value}', end='')
-    write(f, 0, ';')
+        write(f, 0, f" := {default_value}", end="")
+    write(f, 0, ";")
     if vivado_ram_style is not None:
         write_lines(
             f,
             [
-                (1, 'attribute ram_style : string;'),
+                (1, "attribute ram_style : string;"),
                 (1, f'attribute ram_style of {name} : signal is "{vivado_ram_style}";'),
             ],
         )
@@ -127,7 +127,7 @@ def signal_declaration(
         write_lines(
             f,
             [
-                (1, 'attribute ramstyle : string;'),
+                (1, "attribute ramstyle : string;"),
                 (1, f'attribute ramstyle of {name} : signal is "{quartus_ram_style}";'),
             ],
         )
@@ -141,7 +141,7 @@ def alias_declaration(
     name_pad: Optional[int] = None,
 ):
     name_pad = name_pad or 0
-    write(f, 1, f'alias {name:<{name_pad}} : {signal_type} is {value};')
+    write(f, 1, f"alias {name:<{name_pad}} : {signal_type} is {value};")
 
 
 def constant_declaration(
@@ -168,7 +168,7 @@ def constant_declaration(
         An optional left padding value applied to the name.
     """
     name_pad = 0 if name_pad is None else name_pad
-    write(f, 1, f'constant {name:<{name_pad}} : {signal_type} := {str(value)};')
+    write(f, 1, f"constant {name:<{name_pad}} : {signal_type} := {str(value)};")
 
 
 def type_declaration(
@@ -188,7 +188,7 @@ def type_declaration(
     alias : str
         The type to tie the new name to.
     """
-    write(f, 1, f'type {name} is {alias};')
+    write(f, 1, f"type {name} is {alias};")
 
 
 def process_prologue(
@@ -214,10 +214,10 @@ def process_prologue(
         An optional name for the process.
     """
     if name is not None:
-        write(f, indent, f'{name}: process({sensitivity_list})')
+        write(f, indent, f"{name}: process({sensitivity_list})")
     else:
-        write(f, indent, f'process({sensitivity_list})')
-    write(f, indent, 'begin')
+        write(f, indent, f"process({sensitivity_list})")
+    write(f, indent, "begin")
 
 
 def process_epilogue(
@@ -243,10 +243,10 @@ def process_epilogue(
         An optional name of the ending process.
     """
     _ = sensitivity_list
-    write(f, indent, 'end process', end="")
+    write(f, indent, "end process", end="")
     if name is not None:
-        write(f, 0, ' ' + name, end="")
-    write(f, 0, ';')
+        write(f, 0, " " + name, end="")
+    write(f, 0, ";")
 
 
 def synchronous_process_prologue(
@@ -275,7 +275,7 @@ def synchronous_process_prologue(
         An optional name for the process.
     """
     process_prologue(f, sensitivity_list=clk, indent=indent, name=name)
-    write(f, indent + 1, 'if rising_edge(clk) then')
+    write(f, indent + 1, "if rising_edge(clk) then")
 
 
 def synchronous_process_epilogue(
@@ -302,7 +302,7 @@ def synchronous_process_epilogue(
         An optional name for the process.
     """
     _ = clk
-    write(f, indent + 1, 'end if;')
+    write(f, indent + 1, "end if;")
     process_epilogue(f, sensitivity_list=clk, indent=indent, name=name)
 
 
@@ -333,9 +333,9 @@ def synchronous_process(
         An optional name for the process.
     """
     synchronous_process_prologue(f, clk, indent, name)
-    for line in body.split('\n'):
+    for line in body.split("\n"):
         if len(line):
-            write(f, indent + 2, f'{line}')
+            write(f, indent + 2, f"{line}")
     synchronous_process_epilogue(f, clk, indent, name)
 
 
@@ -369,18 +369,18 @@ def synchronous_memory(
         write_lines(
             f,
             [
-                (3, f'if {read_enable} = \'1\' then'),
-                (4, f'{read_name} <= memory({address});'),
-                (3, 'end if;'),
+                (3, f"if {read_enable} = '1' then"),
+                (4, f"{read_name} <= memory({address});"),
+                (3, "end if;"),
             ],
         )
     for write_name, address, we in write_ports:
         write_lines(
             f,
             [
-                (3, f'if {we} = \'1\' then'),
-                (4, f'memory({address}) <= {write_name};'),
-                (3, 'end if;'),
+                (3, f"if {we} = '1' then"),
+                (4, f"memory({address}) <= {write_name};"),
+                (3, "end if;"),
             ],
         )
     synchronous_process_epilogue(f, clk=clk, name=name)
@@ -416,14 +416,14 @@ def asynchronous_read_memory(
         write_lines(
             f,
             [
-                (3, f'if {we} = \'1\' then'),
-                (4, f'memory({address}) <= {write_name};'),
-                (3, 'end if;'),
+                (3, f"if {we} = '1' then"),
+                (4, f"memory({address}) <= {write_name};"),
+                (3, "end if;"),
             ],
         )
     synchronous_process_epilogue(f, clk=clk, name=name)
     for read_name, address, _ in read_ports:
-        write(f, 1, f'{read_name} <= memory({address});')
+        write(f, 1, f"{read_name} <= memory({address});")
 
 
 def is_valid_vhdl_identifier(identifier: str) -> bool:
@@ -447,7 +447,7 @@ def is_valid_vhdl_identifier(identifier: str) -> bool:
     # * A basic identifier consists only of letters, digits, and underlines.
     # * A basic identifier is not a reserved VHDL keyword
     is_basic_identifier = (
-        re.fullmatch(pattern=r'[a-zA-Z][0-9a-zA-Z_]*', string=identifier) is not None
+        re.fullmatch(pattern=r"[a-zA-Z][0-9a-zA-Z_]*", string=identifier) is not None
     )
     return is_basic_identifier and not is_vhdl_reserved_keyword(identifier)
 
diff --git a/b_asic/codegen/vhdl/entity.py b/b_asic/codegen/vhdl/entity.py
index 40a7caf7078c0a5e22308e394f95469b7ba18ce5..9a53e4a44f4389767bdab2e5eae12650219bacdd 100644
--- a/b_asic/codegen/vhdl/entity.py
+++ b/b_asic/codegen/vhdl/entity.py
@@ -31,12 +31,12 @@ def memory_based_storage(
     write_lines(
         f,
         [
-            (0, f'entity {entity_name} is'),
-            (1, 'generic('),
-            (2, '-- Data word length'),
-            (2, f'WL : integer := {word_length}'),
-            (1, ');'),
-            (1, 'port('),
+            (0, f"entity {entity_name} is"),
+            (1, "generic("),
+            (2, "-- Data word length"),
+            (2, f"WL : integer := {word_length}"),
+            (1, ");"),
+            (1, "port("),
         ],
     )
 
@@ -44,38 +44,38 @@ def memory_based_storage(
     write_lines(
         f,
         [
-            (2, '-- Clock, synchronous reset and enable signals'),
-            (2, 'clk : in std_logic;'),
-            (2, 'rst : in std_logic;'),
-            (2, 'en  : in std_logic;'),
-            (0, ''),
+            (2, "-- Clock, synchronous reset and enable signals"),
+            (2, "clk : in std_logic;"),
+            (2, "rst : in std_logic;"),
+            (2, "en  : in std_logic;"),
+            (0, ""),
         ],
     )
 
     # Write the input port specification
-    f.write(f'{2*VHDL_TAB}-- Memory port I/O\n')
+    f.write(f"{2 * VHDL_TAB}-- Memory port I/O\n")
     read_ports: set[Port] = {
         read_port for mv in collection for read_port in mv.read_ports
     }  # type: ignore
     for read_port in read_ports:
         port_name = read_port if isinstance(read_port, int) else read_port.name
-        port_name = 'p_' + str(port_name) + '_in'
-        f.write(f'{2*VHDL_TAB}{port_name} : in std_logic_vector(WL-1 downto 0);\n')
+        port_name = "p_" + str(port_name) + "_in"
+        f.write(f"{2 * VHDL_TAB}{port_name} : in std_logic_vector(WL-1 downto 0);\n")
 
     # Write the output port specification
     write_ports: Set[Port] = {mv.write_port for mv in collection}  # type: ignore
     for idx, write_port in enumerate(write_ports):
         port_name = write_port if isinstance(write_port, int) else write_port.name
-        port_name = 'p_' + str(port_name) + '_out'
-        f.write(f'{2*VHDL_TAB}{port_name} : out std_logic_vector(WL-1 downto 0)')
+        port_name = "p_" + str(port_name) + "_out"
+        f.write(f"{2 * VHDL_TAB}{port_name} : out std_logic_vector(WL-1 downto 0)")
         if idx == len(write_ports) - 1:
-            f.write('\n')
+            f.write("\n")
         else:
-            f.write(';\n')
+            f.write(";\n")
 
     # Write ending of the port header
-    f.write(f'{VHDL_TAB});\n')
-    f.write(f'end entity {entity_name};\n\n')
+    f.write(f"{VHDL_TAB});\n")
+    f.write(f"end entity {entity_name};\n\n")
 
 
 def register_based_storage(
diff --git a/b_asic/core_operations.py b/b_asic/core_operations.py
index faf5d31daf1a3e038d353086d55a0634f1322520..a879edec3c3da1f6cc732beed1dce31c3768e666 100644
--- a/b_asic/core_operations.py
+++ b/b_asic/core_operations.py
@@ -1302,7 +1302,7 @@ class SymmetricTwoportAdaptor(AbstractOperation):
         if -1 <= value <= 1:
             self.set_param("value", value)
         else:
-            raise ValueError('value must be between -1 and 1 (inclusive)')
+            raise ValueError("value must be between -1 and 1 (inclusive)")
 
     def swap_io(self) -> None:
         # Swap inputs and outputs and change sign of coefficient
diff --git a/b_asic/gui_utils/about_window.py b/b_asic/gui_utils/about_window.py
index 893c1b74db2f0d1fdc42b87acd91eba96a9c493c..91a7522d3fdf4345564b19b3c5b2f987611dcd43 100644
--- a/b_asic/gui_utils/about_window.py
+++ b/b_asic/gui_utils/about_window.py
@@ -52,11 +52,11 @@ class AboutWindow(QDialog):
             " Toolbox__\n\n*Construct, simulate and analyze signal processing"
             " algorithms aimed at implementation on an ASIC or"
             " FPGA.*\n\nB-ASIC is developed by the <a"
-            " href=\"https://liu.se/en/organisation/liu/isy/elda\">Division of"
+            ' href="https://liu.se/en/organisation/liu/isy/elda">Division of'
             " Electronics and Computer Engineering</a> at <a"
-            " href=\"https://liu.se/?l=en\">Linköping University</a>,"
+            ' href="https://liu.se/?l=en">Linköping University</a>,'
             " Sweden.\n\nB-ASIC is released under the <a"
-            " href=\"https://gitlab.liu.se/da/B-ASIC/-/blob/master/LICENSE\">"
+            ' href="https://gitlab.liu.se/da/B-ASIC/-/blob/master/LICENSE">'
             "MIT-license</a>"
             " and any extension to the program should follow that same"
             f" license.\n\n*Version: {__version__}*\n\nCopyright 2020-2025,"
@@ -78,10 +78,10 @@ class AboutWindow(QDialog):
 
         label3 = QLabel(
             'Additional resources: <a href="https://da.gitlab-pages.liu.se/B-ASIC/">'
-            'documentation</a>,'
+            "documentation</a>,"
             ' <a href="https://gitlab.liu.se/da/B-ASIC/">git repository</a>,'
             ' <a href="https://gitlab.liu.se/da/B-ASIC/-/issues">report issues and'
-            ' suggestions</a>.'
+            " suggestions</a>."
         )
         label3.setOpenExternalLinks(True)
         label3.linkHovered.connect(self._hover_text)
diff --git a/b_asic/gui_utils/color_button.py b/b_asic/gui_utils/color_button.py
index 56e5058adbda23ba99e3de2732546e165b847616..b47a248bfbb39d54b83b1d1db4b19fe2c6c82322 100644
--- a/b_asic/gui_utils/color_button.py
+++ b/b_asic/gui_utils/color_button.py
@@ -19,7 +19,7 @@ class ColorButton(QPushButton):
         Additional arguments are passed to QPushButton.
     """
 
-    __slots__ = ('_color', '_default')
+    __slots__ = ("_color", "_default")
     _color: None | QColor
     _color_changed = Signal(QColor)
 
diff --git a/b_asic/gui_utils/icons.py b/b_asic/gui_utils/icons.py
index 4bd348a886bb12d8a81716f208d4d9382db3af13..2940e1c752425137a696baa29e1e13edce579efc 100644
--- a/b_asic/gui_utils/icons.py
+++ b/b_asic/gui_utils/icons.py
@@ -3,39 +3,39 @@
 import qtawesome
 
 ICONS = {
-    'save': 'mdi6.content-save',
-    'save-as': 'mdi6.content-save-edit',
-    'undo': 'mdi6.undo',
-    'redo': 'mdi6.redo',
-    'new': 'mdi6.file-outline',
-    'open': 'mdi6.folder-open',
-    'import': 'mdi6.import',
-    'legend': 'mdi6.map-legend',
-    'close': 'mdi6.close',
-    'all': 'mdi6.select-all',
-    'none': 'mdi6.select-remove',
-    'new-sfg': 'ph.selection-plus',
-    'plot-schedule': 'mdi6.chart-gantt',
-    'increase-timeresolution': 'ph.clock-clockwise',
-    'decrease-timeresolution': 'ph.clock-counter-clockwise',
-    'quit': 'ph.power',
-    'info': 'ph.info',
-    'gitlab': 'ph.gitlab-logo-simple',
-    'docs': 'ph.book',
-    'about': 'ph.question',
-    'keys': 'ph.keyboard',
-    'add-operations': 'ph.math-operations',
-    'zoom-to-fit': 'mdi6.fit-to-page',
-    'faq': 'mdi6.frequently-asked-questions',
-    'sim': 'mdi6.chart-line',
-    'reorder': ('msc.graph-left', {'rotated': -90}),
-    'full-screen': 'mdi6.fullscreen',
-    'full-screen-exit': 'mdi6.fullscreen-exit',
-    'warning': 'fa5s.exclamation-triangle',
-    'port-numbers': 'fa5s.hashtag',
-    'swap': 'fa5s.arrows-alt-v',
-    'asap': 'fa5s.fast-backward',
-    'alap': 'fa5s.fast-forward',
+    "save": "mdi6.content-save",
+    "save-as": "mdi6.content-save-edit",
+    "undo": "mdi6.undo",
+    "redo": "mdi6.redo",
+    "new": "mdi6.file-outline",
+    "open": "mdi6.folder-open",
+    "import": "mdi6.import",
+    "legend": "mdi6.map-legend",
+    "close": "mdi6.close",
+    "all": "mdi6.select-all",
+    "none": "mdi6.select-remove",
+    "new-sfg": "ph.selection-plus",
+    "plot-schedule": "mdi6.chart-gantt",
+    "increase-timeresolution": "ph.clock-clockwise",
+    "decrease-timeresolution": "ph.clock-counter-clockwise",
+    "quit": "ph.power",
+    "info": "ph.info",
+    "gitlab": "ph.gitlab-logo-simple",
+    "docs": "ph.book",
+    "about": "ph.question",
+    "keys": "ph.keyboard",
+    "add-operations": "ph.math-operations",
+    "zoom-to-fit": "mdi6.fit-to-page",
+    "faq": "mdi6.frequently-asked-questions",
+    "sim": "mdi6.chart-line",
+    "reorder": ("msc.graph-left", {"rotated": -90}),
+    "full-screen": "mdi6.fullscreen",
+    "full-screen-exit": "mdi6.fullscreen-exit",
+    "warning": "fa5s.exclamation-triangle",
+    "port-numbers": "fa5s.hashtag",
+    "swap": "fa5s.arrows-alt-v",
+    "asap": "fa5s.fast-backward",
+    "alap": "fa5s.fast-forward",
 }
 
 
diff --git a/b_asic/gui_utils/plot_window.py b/b_asic/gui_utils/plot_window.py
index 4a9b0d585c340505386c920e7bd7fbe23df333ee..242203326b0d50ad239365640c75de509dbc748b 100644
--- a/b_asic/gui_utils/plot_window.py
+++ b/b_asic/gui_utils/plot_window.py
@@ -77,7 +77,7 @@ class PlotWindow(QWidget):
                 m = 4
             elif re.fullmatch("[0-9]+", key):
                 m = 3
-                key2 = 'o' + key
+                key2 = "o" + key
             elif re.fullmatch("t[0-9]+", key):
                 m = 2
             else:
@@ -91,18 +91,18 @@ class PlotWindow(QWidget):
                     initially_checked.append(key2)
             else:
                 # The same again, but split into several lines
-                dict_to_sort[m + 1 / (n + 1)] = key2 + '_re'
-                dict_to_sort[m + 1 / (n + 2)] = key2 + '_im'
-                dict_to_sort[m + 1 / (n + 3)] = key2 + '_mag'
-                dict_to_sort[m + 1 / (n + 4)] = key2 + '_ang'
-                updated_result[key2 + '_re'] = np.real(result)
-                updated_result[key2 + '_im'] = np.imag(result)
-                updated_result[key2 + '_mag'] = np.absolute(result)
-                updated_result[key2 + '_ang'] = np.angle(result)
+                dict_to_sort[m + 1 / (n + 1)] = key2 + "_re"
+                dict_to_sort[m + 1 / (n + 2)] = key2 + "_im"
+                dict_to_sort[m + 1 / (n + 3)] = key2 + "_mag"
+                dict_to_sort[m + 1 / (n + 4)] = key2 + "_ang"
+                updated_result[key2 + "_re"] = np.real(result)
+                updated_result[key2 + "_im"] = np.imag(result)
+                updated_result[key2 + "_mag"] = np.absolute(result)
+                updated_result[key2 + "_ang"] = np.angle(result)
                 n = n + 4
                 if m == 3:  # output
-                    initially_checked.append(key2 + '_re')
-                    initially_checked.append(key2 + '_im')
+                    initially_checked.append(key2 + "_re")
+                    initially_checked.append(key2 + "_im")
 
         key_order = list(dict(sorted(dict_to_sort.items(), reverse=True)).values())
 
@@ -145,10 +145,10 @@ class PlotWindow(QWidget):
 
         # Add two buttons for selecting all/none:
         hlayout = QHBoxLayout()
-        self._button_all = QPushButton(get_icon('all'), "&All")
+        self._button_all = QPushButton(get_icon("all"), "&All")
         self._button_all.clicked.connect(self._button_all_click)
         hlayout.addWidget(self._button_all)
-        self._button_none = QPushButton(get_icon('none'), "&None")
+        self._button_none = QPushButton(get_icon("none"), "&None")
         self._button_none.clicked.connect(self._button_none_click)
         hlayout.addWidget(self._button_none)
         listlayout.addLayout(hlayout)
@@ -173,7 +173,7 @@ class PlotWindow(QWidget):
         self._legend_checkbox = QCheckBox("&Legend")
         self._legend_checkbox.stateChanged.connect(self._legend_checkbox_change)
         self._legend_checkbox.setCheckState(Qt.CheckState.Checked)
-        self._legend_checkbox.setIcon(get_icon('legend'))
+        self._legend_checkbox.setIcon(get_icon("legend"))
         listlayout.addWidget(self._legend_checkbox)
         # self.ontop_checkbox = QCheckBox("&On top")
         # self.ontop_checkbox.stateChanged.connect(self._ontop_checkbox_change)
@@ -185,7 +185,7 @@ class PlotWindow(QWidget):
         listlayout.addWidget(relim_button)
 
         # Add "Close" buttons
-        button_close = QPushButton(get_icon('close'), "&Close", self)
+        button_close = QPushButton(get_icon("close"), "&Close", self)
         button_close.clicked.connect(self.close)
         listlayout.addWidget(button_close)
         self._relim()
@@ -231,8 +231,8 @@ class PlotWindow(QWidget):
     def _relim(self, event=None):
         self._plot_axes.relim(True)
         self._plot_axes.autoscale(True)
-        self._plot_axes.autoscale(axis='x', tight=True)
-        self._plot_axes.autoscale(axis='y')
+        self._plot_axes.autoscale(axis="x", tight=True)
+        self._plot_axes.autoscale(axis="y")
         self._plot_canvas.draw()
 
 
@@ -263,15 +263,15 @@ def start_simulation_dialog(
 # Simple test of the dialog
 if __name__ == "__main__":
     sim_res = {
-        '0': [0.5, 0.6, 0.5, 0],
-        '1': [0.0, 1.0 + 0.3j, 0.5, 0.1j],
-        'add1': [0.5, 0.5, 0, 0],
-        'cmul1': [0, 0.5, 0, 0],
-        'cmul2': [0.5, 0, 0, 0],
-        'in1': [1, 0, 0, 0],
-        'in2': [0.1, 2, 0, 0],
-        't1': [0, 1, 0, 0],
-        't2': [0, 0, 1, 0],
-        't3': [0, 0, 0, 1],
+        "0": [0.5, 0.6, 0.5, 0],
+        "1": [0.0, 1.0 + 0.3j, 0.5, 0.1j],
+        "add1": [0.5, 0.5, 0, 0],
+        "cmul1": [0, 0.5, 0, 0],
+        "cmul2": [0.5, 0, 0, 0],
+        "in1": [1, 0, 0, 0],
+        "in2": [0.1, 2, 0, 0],
+        "t1": [0, 1, 0, 0],
+        "t2": [0, 0, 1, 0],
+        "t3": [0, 0, 0, 1],
     }
     start_simulation_dialog(sim_res, "Test data")
diff --git a/b_asic/logger.py b/b_asic/logger.py
index 2a948ce3941c03d4c2fe121adda8ee0ad4036d5f..96f89df6dc9aeb59b180df46bceb4cca1a7c1682 100644
--- a/b_asic/logger.py
+++ b/b_asic/logger.py
@@ -46,6 +46,7 @@ Log Uncaught Exceptions:
 ------------------------
 To log uncaught exceptions, implement the following in your program.
   `sys.excepthook = logger.log_exceptions`"""
+
 import logging
 import logging.handlers
 import os
diff --git a/b_asic/research/interleaver.py b/b_asic/research/interleaver.py
index 296accea628fc4e4b2ee19f4628cf70dbbefa55b..1232c2bf2e7b7e779b09f0301e98d20f22f0ceb3 100644
--- a/b_asic/research/interleaver.py
+++ b/b_asic/research/interleaver.py
@@ -108,7 +108,7 @@ def generate_matrix_transposer(
     if (rows * cols // parallelism) * parallelism != rows * cols:
         raise ValueError(
             f"parallelism ({parallelism}) must be an integer multiple of rows*cols"
-            f" ({rows}*{cols} = {rows*cols})"
+            f" ({rows}*{cols} = {rows * cols})"
         )
 
     inputorders = []
@@ -129,7 +129,7 @@ def generate_matrix_transposer(
             PlainMemoryVariable(
                 *inputorder,
                 {outputorders[i][1]: outputorders[i][0] - inputorder[0]},
-                name=f"{inputorders[i][0]*parallelism + inputorders[i][1]}",
+                name=f"{inputorders[i][0] * parallelism + inputorders[i][1]}",
             )
             for i, inputorder in enumerate(inputorders)
         },
diff --git a/b_asic/resources.py b/b_asic/resources.py
index 53a5ef25d934b8209d676c361ac0aaa1f308ff97..36e2cec9f0eb1142b22e5b20553ec8e385f55c88 100644
--- a/b_asic/resources.py
+++ b/b_asic/resources.py
@@ -32,7 +32,7 @@ _WARNING_COLOR = tuple(c / 255 for c in WARNING_COLOR)
 #
 # Typing '_T' to help Pyright propagate type-information
 #
-_T = TypeVar('_T')
+_T = TypeVar("_T")
 
 
 def _sorted_nicely(to_be_sorted: Iterable[_T]) -> list[_T]:
@@ -42,7 +42,7 @@ def _sorted_nicely(to_be_sorted: Iterable[_T]) -> list[_T]:
         return int(text) if text.isdigit() else text
 
     def alphanum_key(key):
-        return [convert(c) for c in re.split('([0-9]+)', str(key))]
+        return [convert(c) for c in re.split("([0-9]+)", str(key))]
 
     return sorted(to_be_sorted, key=alphanum_key)
 
@@ -85,11 +85,11 @@ def _sanitize_port_option(
         write_ports = total_ports if write_ports is None else write_ports
     if total_ports < read_ports:
         raise ValueError(
-            f'Total ports ({total_ports}) less then read ports ({read_ports})'
+            f"Total ports ({total_ports}) less then read ports ({read_ports})"
         )
     if total_ports < write_ports:
         raise ValueError(
-            f'Total ports ({total_ports}) less then write ports ({write_ports})'
+            f"Total ports ({total_ports}) less then write ports ({write_ports})"
         )
     return read_ports, write_ports, total_ports
 
@@ -142,23 +142,23 @@ def draw_exclusion_graph_coloring(
     None
     """
     COLOR_LIST = [
-        '#aa0000',
-        '#00aa00',
-        '#0000ff',
-        '#ff00aa',
-        '#ffaa00',
-        '#ffffff',
-        '#00ffaa',
-        '#aaff00',
-        '#aa00ff',
-        '#00aaff',
-        '#ff0000',
-        '#00ff00',
-        '#0000aa',
-        '#aaaa00',
-        '#aa00aa',
-        '#00aaaa',
-        '#666666',
+        "#aa0000",
+        "#00aa00",
+        "#0000ff",
+        "#ff00aa",
+        "#ffaa00",
+        "#ffffff",
+        "#00ffaa",
+        "#aaff00",
+        "#aa00ff",
+        "#00aaff",
+        "#ff0000",
+        "#00ff00",
+        "#0000aa",
+        "#aaaa00",
+        "#aa00aa",
+        "#00aaaa",
+        "#666666",
     ]
     if color_list is None:
         node_color_dict = {k: COLOR_LIST[v] for k, v in color_dict.items()}
@@ -216,7 +216,7 @@ class _ForwardBackwardEntry:
 
 
 class _ForwardBackwardTable:
-    def __init__(self, collection: 'ProcessCollection'):
+    def __init__(self, collection: "ProcessCollection"):
         """
         Forward-Backward allocation table for ProcessCollections.
 
@@ -299,9 +299,9 @@ class _ForwardBackwardTable:
                             if self.table[next_row].regs[next_col] not in (None, reg):
                                 cell = self.table[next_row].regs[next_col]
                                 raise ValueError(
-                                    f'Can\'t forward allocate {reg} in row={time},'
-                                    f' col={reg_idx} to next_row={next_row},'
-                                    f' next_col={next_col} (cell contains: {cell})'
+                                    f"Can't forward allocate {reg} in row={time},"
+                                    f" col={reg_idx} to next_row={next_row},"
+                                    f" next_col={next_col} (cell contains: {cell})"
                                 )
                             else:
                                 self.table[(time + 1) % rows].regs[reg_idx + 1] = reg
@@ -380,27 +380,27 @@ class _ForwardBackwardTable:
         reg_col_w = max(4, reg_col_w + 2)
 
         # Header row of the string
-        res = f' T |{"In":^{input_col_w}}|'
+        res = f" T |{'In':^{input_col_w}}|"
         for i in range(max(self._live_variables)):
-            reg = f'R{i}'
-            res += f'{reg:^{reg_col_w}}|'
-        res += f'{"Out":^{output_col_w}}|'
-        res += '\n'
+            reg = f"R{i}"
+            res += f"{reg:^{reg_col_w}}|"
+        res += f"{'Out':^{output_col_w}}|"
+        res += "\n"
         res += (
             6 + input_col_w + (reg_col_w + 1) * max(self._live_variables) + output_col_w
-        ) * '-' + '\n'
+        ) * "-" + "\n"
 
         for time, entry in enumerate(self.table):
             # Time
-            res += f'{time:^3}| '
+            res += f"{time:^3}| "
 
             # Input column
-            inputs_str = ''
+            inputs_str = ""
             for input_ in entry.inputs:
-                inputs_str += input_.name + ','
+                inputs_str += input_.name + ","
             if inputs_str:
                 inputs_str = inputs_str[:-1]
-            res += f'{inputs_str:^{input_col_w-1}}|'
+            res += f"{inputs_str:^{input_col_w - 1}}|"
 
             # Register columns
             for reg_idx, reg in enumerate(entry.regs):
@@ -408,27 +408,27 @@ class _ForwardBackwardTable:
                     res += " " * reg_col_w + "|"
                 else:
                     if reg_idx in entry.back_edge_to:
-                        res += f'{GREEN_BACKGROUND_ANSI}'
-                        res += f'{reg.name:^{reg_col_w}}'
-                        res += f'{RESET_BACKGROUND_ANSI}|'
+                        res += f"{GREEN_BACKGROUND_ANSI}"
+                        res += f"{reg.name:^{reg_col_w}}"
+                        res += f"{RESET_BACKGROUND_ANSI}|"
                     elif reg_idx in entry.back_edge_from:
-                        res += f'{BROWN_BACKGROUND_ANSI}'
-                        res += f'{reg.name:^{reg_col_w}}'
-                        res += f'{RESET_BACKGROUND_ANSI}|'
+                        res += f"{BROWN_BACKGROUND_ANSI}"
+                        res += f"{reg.name:^{reg_col_w}}"
+                        res += f"{RESET_BACKGROUND_ANSI}|"
                     else:
-                        res += f'{reg.name:^{reg_col_w}}' + "|"
+                        res += f"{reg.name:^{reg_col_w}}" + "|"
 
             # Output column
-            outputs_str = ''
+            outputs_str = ""
             for output in entry.outputs:
-                outputs_str += output.name + ','
+                outputs_str += output.name + ","
             if outputs_str:
                 outputs_str = outputs_str[:-1]
             if entry.outputs_from is not None:
                 outputs_str += f"({entry.outputs_from})"
-            res += f'{outputs_str:^{output_col_w}}|'
+            res += f"{outputs_str:^{output_col_w}}|"
 
-            res += '\n'
+            res += "\n"
         return res
 
 
@@ -591,8 +591,8 @@ class ProcessCollection:
             # Schedule time needs to be greater than or equal to the maximum process
             # lifetime
             raise ValueError(
-                f'Schedule time: {self._schedule_time} < Max execution'
-                f' time: {max_execution_time}'
+                f"Schedule time: {self._schedule_time} < Max execution"
+                f" time: {max_execution_time}"
             )
 
         # Generate the life-time chart
@@ -673,12 +673,8 @@ class ProcessCollection:
                 )
         _ax.grid(True)  # type: ignore
 
-        _ax.xaxis.set_major_locator(
-            MaxNLocator(integer=True, min_n_ticks=1)
-        )  # type: ignore
-        _ax.yaxis.set_major_locator(
-            MaxNLocator(integer=True, min_n_ticks=1)
-        )  # type: ignore
+        _ax.xaxis.set_major_locator(MaxNLocator(integer=True, min_n_ticks=1))  # type: ignore
+        _ax.yaxis.set_major_locator(MaxNLocator(integer=True, min_n_ticks=1))  # type: ignore
         _ax.set_xlim(0, self._schedule_time)  # type: ignore
         if row is None:
             _ax.set_ylim(0.25, len(self._collection) + 0.75)  # type: ignore
@@ -1260,7 +1256,7 @@ class ProcessCollection:
         filename: str,
         entity_name: str,
         word_length: int,
-        assignment: list['ProcessCollection'],
+        assignment: list["ProcessCollection"],
         read_ports: int = 1,
         write_ports: int = 1,
         total_ports: int = 2,
@@ -1312,7 +1308,7 @@ class ProcessCollection:
         """
         # Check that entity name is a valid VHDL identifier
         if not is_valid_vhdl_identifier(entity_name):
-            raise KeyError(f'{entity_name} is not a valid identifier')
+            raise KeyError(f"{entity_name} is not a valid identifier")
 
         # Check that this is a ProcessCollection of (Plain)MemoryVariables
         is_memory_variable = all(
@@ -1337,51 +1333,51 @@ class ProcessCollection:
         for collection in assignment:
             for mv in collection:
                 if mv not in self:
-                    raise ValueError(f'{mv!r} is not part of {self!r}.')
+                    raise ValueError(f"{mv!r} is not part of {self!r}.")
 
         # Make sure that concurrent reads/writes do not surpass the port setting
         needed_write_ports = self.read_ports_bound()
         needed_read_ports = self.write_ports_bound()
         if needed_write_ports > write_ports + 1:
             raise ValueError(
-                f'More than {write_ports} write ports needed ({needed_write_ports})'
-                ' to generate HDL for this ProcessCollection'
+                f"More than {write_ports} write ports needed ({needed_write_ports})"
+                " to generate HDL for this ProcessCollection"
             )
         if needed_read_ports > read_ports + 1:
             raise ValueError(
-                f'More than {read_ports} read ports needed ({needed_read_ports}) to'
-                ' generate HDL for this ProcessCollection'
+                f"More than {read_ports} read ports needed ({needed_read_ports}) to"
+                " generate HDL for this ProcessCollection"
             )
 
         # Sanitize the address logic pipeline settings
         if adr_mux_size is not None and adr_pipe_depth is not None:
             if adr_mux_size < 1:
                 raise ValueError(
-                    f'adr_mux_size={adr_mux_size} need to be greater than zero'
+                    f"adr_mux_size={adr_mux_size} need to be greater than zero"
                 )
             if adr_pipe_depth < 0:
                 raise ValueError(
-                    f'adr_pipe_depth={adr_pipe_depth} needs to be non-negative'
+                    f"adr_pipe_depth={adr_pipe_depth} needs to be non-negative"
                 )
             if not input_sync:
-                raise ValueError('input_sync needs to be set to use address pipelining')
+                raise ValueError("input_sync needs to be set to use address pipelining")
             if not log2(adr_mux_size).is_integer():
                 raise ValueError(
-                    f'adr_mux_size={adr_mux_size} needs to be integer power of two'
+                    f"adr_mux_size={adr_mux_size} needs to be integer power of two"
                 )
             if adr_mux_size**adr_pipe_depth > assignment[0].schedule_time:
                 raise ValueError(
-                    f'adr_mux_size={adr_mux_size}, adr_pipe_depth={adr_pipe_depth} => '
-                    'more multiplexer inputs than schedule_time='
-                    f'{assignment[0].schedule_time}'
+                    f"adr_mux_size={adr_mux_size}, adr_pipe_depth={adr_pipe_depth} => "
+                    "more multiplexer inputs than schedule_time="
+                    f"{assignment[0].schedule_time}"
                 )
         else:
             if adr_mux_size is not None or adr_pipe_depth is not None:
                 raise ValueError(
-                    'both or none of adr_mux_size and adr_pipe_depth needs to be set'
+                    "both or none of adr_mux_size and adr_pipe_depth needs to be set"
                 )
 
-        with open(filename, 'w') as f:
+        with open(filename, "w") as f:
             from b_asic.codegen.vhdl import architecture, common, entity
 
             common.b_asic_preamble(f)
@@ -1483,7 +1479,7 @@ class ProcessCollection:
         """
         # Check that entity name is a valid VHDL identifier
         if not is_valid_vhdl_identifier(entity_name):
-            raise KeyError(f'{entity_name} is not a valid identifier')
+            raise KeyError(f"{entity_name} is not a valid identifier")
 
         # Check that this is a ProcessCollection of (Plain)MemoryVariables
         is_memory_variable = all(
@@ -1506,7 +1502,7 @@ class ProcessCollection:
         # Create the forward-backward table
         forward_backward_table = _ForwardBackwardTable(self)
 
-        with open(filename, 'w') as f:
+        with open(filename, "w") as f:
             from b_asic.codegen.vhdl import architecture, common, entity
 
             common.b_asic_preamble(f)
@@ -1666,4 +1662,4 @@ class ProcessCollection:
         if name in name_to_proc:
             return name_to_proc[name]
         else:
-            raise KeyError(f'{name} not in {self}')
+            raise KeyError(f"{name} not in {self}")
diff --git a/b_asic/schedule.py b/b_asic/schedule.py
index 33a629b365f1405bcacf76183ea57dcd23743ea6..1a70a84ab5bf8b93aeddb463600242784b1c240d 100644
--- a/b_asic/schedule.py
+++ b/b_asic/schedule.py
@@ -1199,7 +1199,7 @@ class Schedule:
                 )
                 path_patch = PathPatch(
                     path,
-                    fc='none',
+                    fc="none",
                     ec=_SIGNAL_COLOR,
                     lw=SIGNAL_LINEWIDTH,
                     zorder=10,
diff --git a/b_asic/scheduler_gui/__init__.py b/b_asic/scheduler_gui/__init__.py
index 65a54cad1b64720f0fdc55740e91a90c1593dc30..b1a11a86448fceabbb0a8a3775393743664654e8 100644
--- a/b_asic/scheduler_gui/__init__.py
+++ b/b_asic/scheduler_gui/__init__.py
@@ -6,4 +6,4 @@ Graphical user interface for B-ASIC scheduler.
 
 from b_asic.scheduler_gui.main_window import start_scheduler
 
-__all__ = ['start_scheduler']
+__all__ = ["start_scheduler"]
diff --git a/b_asic/scheduler_gui/_preferences.py b/b_asic/scheduler_gui/_preferences.py
index 90da43a7151ef168fb797bcb897d5dc3e0cda057..abe72305134495b565f8a8ad3443d9721f06db77 100644
--- a/b_asic/scheduler_gui/_preferences.py
+++ b/b_asic/scheduler_gui/_preferences.py
@@ -29,7 +29,7 @@ class ColorDataType:
         DEFAULT: QColor,
         current_color: QColor = SIGNAL_INACTIVE,
         changed: bool = False,
-        name: str = '',
+        name: str = "",
     ):
         self.current_color = current_color
         self.DEFAULT = DEFAULT
@@ -40,21 +40,21 @@ class ColorDataType:
 LATENCY_COLOR_TYPE = ColorDataType(
     current_color=OPERATION_LATENCY_INACTIVE,
     DEFAULT=OPERATION_LATENCY_INACTIVE,
-    name='Latency color',
+    name="Latency color",
 )
 EXECUTION_TIME_COLOR_TYPE = ColorDataType(
     current_color=OPERATION_EXECUTION_TIME_ACTIVE,
     DEFAULT=OPERATION_EXECUTION_TIME_ACTIVE,
-    name='Execution time color',
+    name="Execution time color",
 )
 SIGNAL_WARNING_COLOR_TYPE = ColorDataType(
-    current_color=SIGNAL_WARNING, DEFAULT=SIGNAL_WARNING, name='Warning color'
+    current_color=SIGNAL_WARNING, DEFAULT=SIGNAL_WARNING, name="Warning color"
 )
 SIGNAL_COLOR_TYPE = ColorDataType(
-    current_color=SIGNAL_INACTIVE, DEFAULT=SIGNAL_INACTIVE, name='Signal color'
+    current_color=SIGNAL_INACTIVE, DEFAULT=SIGNAL_INACTIVE, name="Signal color"
 )
 ACTIVE_COLOR_TYPE = ColorDataType(
-    current_color=SIGNAL_ACTIVE, DEFAULT=SIGNAL_ACTIVE, name='Active color'
+    current_color=SIGNAL_ACTIVE, DEFAULT=SIGNAL_ACTIVE, name="Active color"
 )
 
 
diff --git a/b_asic/scheduler_gui/axes_item.py b/b_asic/scheduler_gui/axes_item.py
index f65b11c042181481d5167a0d66f15fbd2aa2d0e9..52e143f1d83a4955dcd3c53891b4a9ae5c590778 100644
--- a/b_asic/scheduler_gui/axes_item.py
+++ b/b_asic/scheduler_gui/axes_item.py
@@ -5,6 +5,7 @@ B-ASIC Scheduler-gui Axes Item Module.
 Contains the scheduler-gui AxesItem class for drawing and maintaining the
 axes in a graph.
 """
+
 from math import pi, sin
 
 # QGraphics and QPainter imports
diff --git a/b_asic/scheduler_gui/main_window.py b/b_asic/scheduler_gui/main_window.py
index b5ba1a02ed3838c37c46abb1f1be2da914be1bfd..b295026828a329e8eea2bf07485280b07254fa8f 100644
--- a/b_asic/scheduler_gui/main_window.py
+++ b/b_asic/scheduler_gui/main_window.py
@@ -6,6 +6,7 @@ Contains the scheduler_gui MainWindow class for scheduling operations in an SFG.
 
 Start main-window with ``start_gui()``.
 """
+
 import inspect
 import os
 import pickle
@@ -31,28 +32,19 @@ from qtpy.QtCore import (
     Qt,
     Slot,
 )
-from qtpy.QtGui import QCloseEvent, QColor, QFont, QIcon, QIntValidator, QPalette
+from qtpy.QtGui import QCloseEvent, QColor, QPalette
 from qtpy.QtWidgets import (
     QAbstractButton,
     QAction,
     QApplication,
     QCheckBox,
-    QColorDialog,
-    QDialog,
-    QDialogButtonBox,
     QFileDialog,
-    QFontDialog,
     QGraphicsItemGroup,
     QGraphicsScene,
-    QGroupBox,
-    QHBoxLayout,
     QInputDialog,
-    QLabel,
-    QLineEdit,
     QMainWindow,
     QMessageBox,
     QTableWidgetItem,
-    QVBoxLayout,
 )
 
 # B-ASIC
@@ -60,24 +52,18 @@ import b_asic.logger as logger
 from b_asic._version import __version__
 from b_asic.graph_component import GraphComponent, GraphID
 from b_asic.gui_utils.about_window import AboutWindow
-from b_asic.gui_utils.color_button import ColorButton
 from b_asic.gui_utils.icons import get_icon
 from b_asic.gui_utils.mpl_window import MPLWindow
 from b_asic.schedule import Schedule
 from b_asic.scheduler_gui._preferences import (
-    ACTIVE_COLOR_TYPE,
-    EXECUTION_TIME_COLOR_TYPE,
     FONT,
     LATENCY_COLOR_TYPE,
-    SIGNAL_COLOR_TYPE,
-    SIGNAL_WARNING_COLOR_TYPE,
-    ColorDataType,
     read_from_settings,
-    reset_color_settings,
     write_to_settings,
 )
 from b_asic.scheduler_gui.axes_item import AxesItem
 from b_asic.scheduler_gui.operation_item import OperationItem
+from b_asic.scheduler_gui.preferences_dialog import PreferencesDialog
 from b_asic.scheduler_gui.scheduler_item import SchedulerItem
 from b_asic.scheduler_gui.ui_main_window import Ui_MainWindow
 
@@ -166,31 +152,31 @@ class ScheduleMainWindow(QMainWindow, Ui_MainWindow):
 
         # Connect signals to slots
         self.menu_load_from_file.triggered.connect(self._load_schedule_from_pyfile)
-        self.menu_load_from_file.setIcon(get_icon('import'))
-        self.menu_open.setIcon(get_icon('open'))
+        self.menu_load_from_file.setIcon(get_icon("import"))
+        self.menu_open.setIcon(get_icon("open"))
         self.menu_open.triggered.connect(self.open_schedule)
         self.menu_close_schedule.triggered.connect(self.close_schedule)
-        self.menu_close_schedule.setIcon(get_icon('close'))
+        self.menu_close_schedule.setIcon(get_icon("close"))
         self.menu_save.triggered.connect(self.save)
-        self.menu_save.setIcon(get_icon('save'))
+        self.menu_save.setIcon(get_icon("save"))
         self.menu_save_as.triggered.connect(self.save_as)
-        self.menu_save_as.setIcon(get_icon('save-as'))
+        self.menu_save_as.setIcon(get_icon("save-as"))
         self.actionPreferences.triggered.connect(self.open_preferences_dialog)
         self.menu_quit.triggered.connect(self.close)
-        self.menu_quit.setIcon(get_icon('quit'))
+        self.menu_quit.setIcon(get_icon("quit"))
         self.menu_node_info.triggered.connect(self.show_info_table)
-        self.menu_node_info.setIcon(get_icon('info'))
+        self.menu_node_info.setIcon(get_icon("info"))
         self.menu_exit_dialog.triggered.connect(self.hide_exit_dialog)
         self.actionReorder.triggered.connect(self._action_reorder)
-        self.actionReorder.setIcon(get_icon('reorder'))
+        self.actionReorder.setIcon(get_icon("reorder"))
         self.actionStatus_bar.triggered.connect(self._toggle_statusbar)
-        self.action_incorrect_execution_time.setIcon(get_icon('warning'))
+        self.action_incorrect_execution_time.setIcon(get_icon("warning"))
         self.action_incorrect_execution_time.triggered.connect(
             self._toggle_execution_time_warning
         )
-        self.action_show_port_numbers.setIcon(get_icon('port-numbers'))
+        self.action_show_port_numbers.setIcon(get_icon("port-numbers"))
         self.action_show_port_numbers.triggered.connect(self._toggle_port_number)
-        self.actionPlot_schedule.setIcon(get_icon('plot-schedule'))
+        self.actionPlot_schedule.setIcon(get_icon("plot-schedule"))
         self.actionPlot_schedule.triggered.connect(self._plot_schedule)
         self.action_view_variables.triggered.connect(
             self._show_execution_times_for_variables
@@ -198,25 +184,25 @@ class ScheduleMainWindow(QMainWindow, Ui_MainWindow):
         self.action_view_port_accesses.triggered.connect(
             self._show_ports_accesses_for_storage
         )
-        self.actionZoom_to_fit.setIcon(get_icon('zoom-to-fit'))
+        self.actionZoom_to_fit.setIcon(get_icon("zoom-to-fit"))
         self.actionZoom_to_fit.triggered.connect(self._zoom_to_fit)
-        self.actionToggle_full_screen.setIcon(get_icon('full-screen'))
+        self.actionToggle_full_screen.setIcon(get_icon("full-screen"))
         self.actionToggle_full_screen.triggered.connect(self._toggle_fullscreen)
-        self.actionUndo.setIcon(get_icon('undo'))
-        self.actionRedo.setIcon(get_icon('redo'))
+        self.actionUndo.setIcon(get_icon("undo"))
+        self.actionRedo.setIcon(get_icon("redo"))
         self.splitter.splitterMoved.connect(self._splitter_moved)
         self.actionDocumentation.triggered.connect(self._open_documentation)
-        self.actionDocumentation.setIcon(get_icon('docs'))
+        self.actionDocumentation.setIcon(get_icon("docs"))
         self.actionAbout.triggered.connect(self._open_about_window)
-        self.actionAbout.setIcon(get_icon('about'))
+        self.actionAbout.setIcon(get_icon("about"))
         self.actionDecrease_time_resolution.triggered.connect(
             self._decrease_time_resolution
         )
-        self.actionDecrease_time_resolution.setIcon(get_icon('decrease-timeresolution'))
+        self.actionDecrease_time_resolution.setIcon(get_icon("decrease-timeresolution"))
         self.actionIncrease_time_resolution.triggered.connect(
             self._increase_time_resolution
         )
-        self.actionIncrease_time_resolution.setIcon(get_icon('increase-timeresolution'))
+        self.actionIncrease_time_resolution.setIcon(get_icon("increase-timeresolution"))
         # Setup event member functions
         self.closeEvent = self._close_event
 
@@ -468,7 +454,7 @@ class ScheduleMainWindow(QMainWindow, Ui_MainWindow):
             self.save_as()
             return
         self._schedule._sfg._graph_id_generator = None
-        with open(self._file_name, 'wb') as f:
+        with open(self._file_name, "wb") as f:
             pickle.dump(self._schedule, f)
         self._add_recent_file(self._file_name)
         self.update_statusbar(self.tr("Schedule saved successfully"))
@@ -482,15 +468,15 @@ class ScheduleMainWindow(QMainWindow, Ui_MainWindow):
         """
         # TODO: Implement
         filename, extension = QFileDialog.getSaveFileName(
-            self, 'Save File', '.', filter=self.tr("B-ASIC schedule (*.bsc)")
+            self, "Save File", ".", filter=self.tr("B-ASIC schedule (*.bsc)")
         )
         if not filename:
             return
-        if not filename.endswith('.bsc'):
-            filename += '.bsc'
+        if not filename.endswith(".bsc"):
+            filename += ".bsc"
         self._file_name = filename
         self._schedule._sfg._graph_id_generator = None
-        with open(self._file_name, 'wb') as f:
+        with open(self._file_name, "wb") as f:
             pickle.dump(self._schedule, f)
         self._add_recent_file(self._file_name)
         self.update_statusbar(self.tr("Schedule saved successfully"))
@@ -521,7 +507,7 @@ class ScheduleMainWindow(QMainWindow, Ui_MainWindow):
         self._file_name = abs_path_filename
         self._add_recent_file(abs_path_filename)
 
-        with open(self._file_name, 'rb') as f:
+        with open(self._file_name, "rb") as f:
             schedule = pickle.load(f)
         self.open(schedule)
         settings = QSettings()
@@ -908,250 +894,69 @@ class ScheduleMainWindow(QMainWindow, Ui_MainWindow):
     @Slot()
     def open_preferences_dialog(self):
         """Open the preferences dialog to customize fonts, colors, and settings"""
-        dialog = QDialog()
-        dialog.setWindowTitle("Preferences")
-        layout = QVBoxLayout()
-        layout.setSpacing(15)
-
-        # Add label for the dialog
-        label = QLabel("Customize fonts and colors")
-        layout.addWidget(label)
-
-        groupbox = QGroupBox()
-        hlayout = QHBoxLayout()
-        label = QLabel("Color settings:")
-        layout.addWidget(label)
-        hlayout.setSpacing(20)
-
-        hlayout.addWidget(self.create_color_button(EXECUTION_TIME_COLOR_TYPE))
-        hlayout.addWidget(self.create_color_button(LATENCY_COLOR_TYPE))
-        hlayout.addWidget(
-            self.create_color_button(
-                ColorDataType(
-                    current_color=LATENCY_COLOR_TYPE.DEFAULT,
-                    DEFAULT=QColor('skyblue'),
-                    name="Latency color per type",
-                )
-            )
-        )
-
-        groupbox.setLayout(hlayout)
-        layout.addWidget(groupbox)
-
-        label = QLabel("Signal colors:")
-        layout.addWidget(label)
-        groupbox = QGroupBox()
-        hlayout = QHBoxLayout()
-        hlayout.setSpacing(20)
-
-        signal_color_button = self.create_color_button(SIGNAL_COLOR_TYPE)
-        signal_color_button.setStyleSheet(
-            f"color: {QColor(255,255,255,0).name()}; background-color: {SIGNAL_COLOR_TYPE.DEFAULT.name()}"
-        )
-
-        hlayout.addWidget(signal_color_button)
-        hlayout.addWidget(self.create_color_button(SIGNAL_WARNING_COLOR_TYPE))
-        hlayout.addWidget(self.create_color_button(ACTIVE_COLOR_TYPE))
-
-        groupbox.setLayout(hlayout)
-        layout.addWidget(groupbox)
-
-        reset_color_button = ColorButton(QColor('silver'))
-        reset_color_button.setText('Reset All Color settings')
-        reset_color_button.pressed.connect(self.reset_color_clicked)
-        layout.addWidget(reset_color_button)
-
-        label = QLabel("Font Settings:")
-        layout.addWidget(label)
-
-        groupbox = QGroupBox()
-        hlayout = QHBoxLayout()
-        hlayout.setSpacing(10)
-
-        font_button = ColorButton(QColor('moccasin'))
-        font_button.setText('Font Settings')
-        hlayout.addWidget(font_button)
-
-        font_color_button = ColorButton(QColor('moccasin'))
-        font_color_button.setText('Font Color')
-        font_color_button.pressed.connect(self.font_color_clicked)
-        hlayout.addWidget(font_color_button)
-
-        groupbox2 = QGroupBox()
-        hlayout2 = QHBoxLayout()
-
-        icon = QIcon.fromTheme("format-text-italic")
-        italic_button = (
-            ColorButton(QColor('silver'))
-            if FONT.italic
-            else ColorButton(QColor('snow'))
-        )
-        italic_button.setIcon(icon)
-        italic_button.pressed.connect(lambda: self.italic_font_clicked(italic_button))
-        hlayout2.addWidget(italic_button)
-
-        icon = QIcon.fromTheme("format-text-bold")
-        bold_button = (
-            ColorButton(QColor('silver')) if FONT.bold else ColorButton(QColor('snow'))
-        )
-        bold_button.setIcon(icon)
-        bold_button.pressed.connect(lambda: self.bold_font_clicked(bold_button))
-        hlayout2.addWidget(bold_button)
-
-        groupbox2.setLayout(hlayout2)
-        hlayout.addWidget(groupbox2)
-
-        groupbox2 = QGroupBox()
-        hlayout2 = QHBoxLayout()
-        font_size_input = QLineEdit()
-        font_button.pressed.connect(
-            lambda: self.font_clicked(font_size_input, italic_button, bold_button)
-        )
-
-        icon = QIcon.fromTheme("list-add")
-        increase_font_size_button = ColorButton(QColor('smoke'))
-        increase_font_size_button.setIcon(icon)
-        increase_font_size_button.pressed.connect(
-            lambda: self.increase_font_size_clicked(font_size_input)
-        )
-        increase_font_size_button.setShortcut(
-            QCoreApplication.translate("MainWindow", "Ctrl++")
-        )
-        hlayout2.addWidget(increase_font_size_button)
-
-        font_size_input.setPlaceholderText('Font Size')
-        font_size_input.setText(f'Font Size: {FONT.size}')
-        font_size_input.setValidator(QIntValidator(0, 99))
-        font_size_input.setAlignment(Qt.AlignCenter)
-        font_size_input.textChanged.connect(
-            lambda: self.set_font_size_clicked(font_size_input.text())
-        )
-        font_size_input.textChanged.connect(
-            lambda: self.set_font_size_clicked(font_size_input.text())
-        )
-        hlayout2.addWidget(font_size_input)
+        self._preferences_dialog = PreferencesDialog(self)
+        self._preferences_dialog.show()
 
-        icon = QIcon.fromTheme("list-remove")
-        decrease_font_size_button = ColorButton(QColor('smoke'))
-        decrease_font_size_button.setIcon(icon)
-        decrease_font_size_button.pressed.connect(
-            lambda: self.decrease_font_size_clicked(font_size_input)
+    def load_preferences(self):
+        "Load the last saved preferences from settings"
+        settings = QSettings()
+        LATENCY_COLOR_TYPE.current_color = QColor(
+            settings.value(
+                f"scheduler/preferences/{LATENCY_COLOR_TYPE.name}",
+                defaultValue=LATENCY_COLOR_TYPE.DEFAULT,
+                type=str,
+            )
         )
-        decrease_font_size_button.setShortcut(
-            QCoreApplication.translate("MainWindow", "Ctrl+-")
+        LATENCY_COLOR_TYPE.changed = settings.value(
+            f"scheduler/preferences/{LATENCY_COLOR_TYPE.name}_changed", False, bool
         )
-
-        hlayout2.addWidget(decrease_font_size_button)
-
-        groupbox2.setLayout(hlayout2)
-        hlayout.addWidget(groupbox2)
-
-        groupbox.setLayout(hlayout)
-        layout.addWidget(groupbox)
-
-        reset_font_button = ColorButton(QColor('silver'))
-        reset_font_button.setText('Reset All Font Settings')
-        reset_font_button.pressed.connect(
-            lambda: self.reset_font_clicked(font_size_input, italic_button, bold_button)
+        self._converted_color_per_type = settings.value(
+            f"scheduler/preferences/{LATENCY_COLOR_TYPE.name}/per_type",
+            self._converted_color_per_type,
         )
-        layout.addWidget(reset_font_button)
-
-        label = QLabel("")
-        layout.addWidget(label)
-
-        reset_all_button = ColorButton(QColor('salmon'))
-        reset_all_button.setText('Reset all settings')
-        reset_all_button.pressed.connect(
-            lambda: self.reset_all_clicked(font_size_input, italic_button, bold_button)
+        self._color_changed_per_type = settings.value(
+            f"scheduler/preferences/{LATENCY_COLOR_TYPE.name}/per_type_changed",
+            False,
+            bool,
         )
-        layout.addWidget(reset_all_button)
-
-        dialog.setLayout(layout)
-        button_box = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Close)
-        button_box.ButtonLayout(QDialogButtonBox.MacLayout)
-        button_box.accepted.connect(dialog.accept)
-        button_box.rejected.connect(dialog.close)
-        layout.addWidget(button_box)
-
-        dialog.exec_()
-
-    def create_color_button(self, color: ColorDataType) -> ColorButton:
-        """Create a colored button to be used to modify a certain color
+        settings.sync()
 
-        Parameters
-        ----------
-        color : ColorDataType
-            The ColorDataType assigned to the butten to be created.
-        """
-        button = ColorButton(color.DEFAULT)
-        button.setText(color.name)
-        if color.name == "Latency color":
-            button.pressed.connect(
-                lambda: self.set_latency_color_by_type_name(all=True)
-            )
-        elif color.name == "Latency color per type":
-            button.pressed.connect(
-                lambda: self.set_latency_color_by_type_name(all=False)
+        for key, color_str in self._converted_color_per_type.items():
+            color = QColor(color_str)
+            self._color_per_type[key] = color
+            Match = (
+                (color == LATENCY_COLOR_TYPE.current_color)
+                if LATENCY_COLOR_TYPE.changed
+                else (color == LATENCY_COLOR_TYPE.DEFAULT)
             )
-        else:
-            button.pressed.connect(lambda: self.color_button_clicked(color))
-        return button
-
-    def set_latency_color_by_type_name(self, all: bool) -> None:
-        """
-        Set latency color based on operation type names.
-
-        Parameters
-        ----------
-        all : bool
-            Indicates if the color of all type names to be modified.
-        """
-        if LATENCY_COLOR_TYPE.changed:
-            current_color = LATENCY_COLOR_TYPE.current_color
-        else:
-            current_color = LATENCY_COLOR_TYPE.DEFAULT
+            if self._color_changed_per_type and not Match:
+                self._changed_operation_colors[key] = color
+        self.update_color_preferences()
 
-        # Prompt user to select operation type if not setting color for all types
-        if not all:
-            used_types = self._schedule.get_used_type_names()
-            operation_type, ok = QInputDialog.getItem(
-                self, "Select operation type", "Type", used_types, editable=False
-            )
+        if FONT.changed:
+            FONT.current_font.setPointSizeF(FONT.size)
+            FONT.current_font.setItalic(FONT.italic)
+            FONT.current_font.setBold(FONT.bold)
+            self._graph._font_change(FONT.current_font)
+            self._graph._font_color_change(FONT.color)
         else:
-            operation_type = "all operations"
-            ok = False
-
-        # Open a color dialog to get the selected color
-        if all or ok:
-            color = QColorDialog.getColor(
-                current_color, self, f"Select the color of {operation_type}"
-            )
+            self._graph._font_change(FONT.DEFAULT)
+            self._graph._font_color_change(FONT.DEFAULT_COLOR)
 
-            # If a valid color is selected, update color settings and graph
-            if color.isValid():
-                if all:
-                    LATENCY_COLOR_TYPE.changed = True
-                    self._color_changed_per_type = False
-                    self._changed_operation_colors.clear()
-                    LATENCY_COLOR_TYPE.current_color = color
-                # Save color settings for each operation type
-                else:
-                    self._color_changed_per_type = True
-                    self._changed_operation_colors[operation_type] = color
-                self.update_color_preferences()
-                self.update_statusbar("Preferences updated")
+        self.update_statusbar("Saved Preferences Loaded")
 
     def update_color_preferences(self) -> None:
         """Update preferences of Latency color per type"""
+        used_type_names = self._schedule.get_used_type_names()
         match (LATENCY_COLOR_TYPE.changed, self._color_changed_per_type):
             case (True, False):
-                for type_name in self._schedule.get_used_type_names():
+                for type_name in used_type_names:
                     self._color_per_type[type_name] = LATENCY_COLOR_TYPE.current_color
             case (False, False):
-                for type_name in self._schedule.get_used_type_names():
+                for type_name in used_type_names:
                     self._color_per_type[type_name] = LATENCY_COLOR_TYPE.DEFAULT
             case (False, True):
-                for type_name in self._schedule.get_used_type_names():
+                for type_name in used_type_names:
                     if type_name in self._changed_operation_colors:
                         self._color_per_type[type_name] = (
                             self._changed_operation_colors[type_name]
@@ -1159,7 +964,7 @@ class ScheduleMainWindow(QMainWindow, Ui_MainWindow):
                     else:
                         self._color_per_type[type_name] = LATENCY_COLOR_TYPE.DEFAULT
             case (True, True):
-                for type_name in self._schedule.get_used_type_names():
+                for type_name in used_type_names:
                     if type_name in self._changed_operation_colors:
                         self._color_per_type[type_name] = (
                             self._changed_operation_colors[type_name]
@@ -1174,7 +979,8 @@ class ScheduleMainWindow(QMainWindow, Ui_MainWindow):
         """Save preferences of Latency color per type in settings"""
         settings = QSettings()
         for key, color in self._color_per_type.items():
-            self._graph._color_change(color, key)
+            if self._graph:
+                self._graph._color_change(color, key)
             self._converted_color_per_type[key] = color.name()
         settings.setValue(
             f"scheduler/preferences/{LATENCY_COLOR_TYPE.name}",
@@ -1193,274 +999,6 @@ class ScheduleMainWindow(QMainWindow, Ui_MainWindow):
             self._color_changed_per_type,
         )
 
-    def color_button_clicked(self, color_type: ColorDataType) -> None:
-        """
-        Open a color dialog to select a color based on the specified color type
-
-        Parameters
-        ----------
-        color_type : ColorDataType
-            The ColorDataType to be changed.
-        """
-        settings = QSettings()
-        if color_type.changed:
-            current_color = color_type.current_color
-        else:
-            current_color = color_type.DEFAULT
-
-        color = QColorDialog.getColor(current_color, self, f"Select {color_type.name}")
-        # If a valid color is selected, update the current color and settings
-        if color.isValid():
-            color_type.current_color = color
-            color_type.changed = color_type.current_color != color_type.DEFAULT
-            settings.setValue(f"scheduler/preferences/{color_type.name}", color.name())
-            settings.sync()
-
-        self._graph._signals.reopen.emit()
-        self.update_statusbar("Preferences Updated")
-
-    def font_clicked(
-        self, line: QLineEdit, italicbutton: ColorButton, boldbutton: ColorButton
-    ) -> None:
-        """
-        Open a font dialog to select a font and update the current font.
-
-        Parameters
-        ----------
-        line : QLineEdit
-            The line displaying the text size to be matched with the chosen font.
-        italicbutton : ColorButton
-            The button displaying the italic state to be matched with the chosen font.
-        boldbutton : ColorButton
-            The button displaying the bold state to be matched with the chosen font.
-        """
-        current_font = FONT.current_font if FONT.changed else FONT.DEFAULT
-
-        (font, ok) = QFontDialog.getFont(current_font, self)
-        if ok:
-            FONT.current_font = font
-            FONT.size = int(font.pointSizeF())
-            FONT.bold = font.bold()
-            FONT.italic = font.italic()
-            self.update_font()
-            self.match_dialog_font(line, italicbutton, boldbutton)
-            self.update_statusbar("Preferences Updated")
-
-    def update_font(self):
-        """Update font preferences based on current Font settings"""
-        settings = QSettings()
-        FONT.changed = not (
-            FONT.current_font == FONT.DEFAULT
-            and FONT.size == int(FONT.DEFAULT.pointSizeF())
-            and FONT.italic == FONT.DEFAULT.italic()
-            and FONT.bold == FONT.DEFAULT.bold()
-        )
-        settings.setValue("scheduler/preferences/font", FONT.current_font.toString())
-        settings.setValue("scheduler/preferences/font_size", FONT.size)
-        settings.setValue("scheduler/preferences/font_bold", FONT.bold)
-        settings.setValue("scheduler/preferences/font_italic", FONT.italic)
-        settings.sync()
-        self.load_preferences()
-
-    def load_preferences(self):
-        "Load the last saved preferences from settings"
-        settings = QSettings()
-        LATENCY_COLOR_TYPE.current_color = QColor(
-            settings.value(
-                f"scheduler/preferences/{LATENCY_COLOR_TYPE.name}",
-                defaultValue=LATENCY_COLOR_TYPE.DEFAULT,
-                type=str,
-            )
-        )
-        LATENCY_COLOR_TYPE.changed = settings.value(
-            f"scheduler/preferences/{LATENCY_COLOR_TYPE.name}_changed", False, bool
-        )
-        self._converted_color_per_type = settings.value(
-            f"scheduler/preferences/{LATENCY_COLOR_TYPE.name}/per_type",
-            self._converted_color_per_type,
-        )
-        self._color_changed_per_type = settings.value(
-            f"scheduler/preferences/{LATENCY_COLOR_TYPE.name}/per_type_changed",
-            False,
-            bool,
-        )
-        settings.sync()
-
-        for key, color_str in self._converted_color_per_type.items():
-            color = QColor(color_str)
-            self._color_per_type[key] = color
-            Match = (
-                (color == LATENCY_COLOR_TYPE.current_color)
-                if LATENCY_COLOR_TYPE.changed
-                else (color == LATENCY_COLOR_TYPE.DEFAULT)
-            )
-            if self._color_changed_per_type and not Match:
-                self._changed_operation_colors[key] = color
-        self.update_color_preferences()
-
-        if FONT.changed:
-            FONT.current_font.setPointSizeF(FONT.size)
-            FONT.current_font.setItalic(FONT.italic)
-            FONT.current_font.setBold(FONT.bold)
-            self._graph._font_change(FONT.current_font)
-            self._graph._font_color_change(FONT.color)
-        else:
-            self._graph._font_change(FONT.DEFAULT)
-            self._graph._font_color_change(FONT.DEFAULT_COLOR)
-
-        self.update_statusbar("Saved Preferences Loaded")
-
-    def font_color_clicked(self):
-        """Select a font color and update preferences"""
-        settings = QSettings()
-        color = QColorDialog.getColor(FONT.color, self, "Select font color")
-        if color.isValid():
-            FONT.color = color
-            FONT.changed = True
-        settings.setValue("scheduler/preferences/font_color", FONT.color.name())
-        settings.sync()
-        self._graph._font_color_change(FONT.color)
-
-    def set_font_size_clicked(self, size):
-        """Set the font size to the specified size and update the font
-        size
-            The font size to be set.
-        """
-        FONT.size = int(size) if size != "" else 6
-        FONT.current_font.setPointSizeF(FONT.size)
-        self.update_font()
-
-    def italic_font_clicked(self, button: ColorButton):
-        """Toggle the font style to italic if not already italic, otherwise remove italic
-        button: ColorButton
-            The clicked button. Used to indicate state on/off.
-        """
-        FONT.italic = not FONT.italic
-        FONT.current_font.setItalic(FONT.italic)
-        (
-            button.set_color(QColor('silver'))
-            if FONT.italic
-            else button.set_color(QColor('snow'))
-        )
-        self.update_font()
-
-    def bold_font_clicked(self, button: ColorButton):
-        """
-        Toggle the font style to bold if not already bold, otherwise unbold.
-
-        Parameters
-        ----------
-        button : ColorButton
-            The clicked button. Used to indicate state on/off.
-        """
-        FONT.bold = not FONT.bold
-        FONT.current_font.setBold(FONT.bold)
-        FONT.current_font.setWeight(50)
-        (
-            button.set_color(QColor('silver'))
-            if FONT.bold
-            else button.set_color(QColor('snow'))
-        )
-        self.update_font()
-
-    def increase_font_size_clicked(self, line: QLineEdit) -> None:
-        """
-        Increase the font size by 1.
-
-        Parameters
-        ----------
-        line : QLineEdit
-            The line displaying the text size to be matched.
-        """
-        if FONT.size <= 71:
-            line.setText(str(FONT.size + 1))
-        else:
-            line.setText(str(FONT.size))
-
-    def decrease_font_size_clicked(self, line: QLineEdit) -> None:
-        """
-        Decrease the font size by 1.
-
-        Parameters
-        ----------
-        line : QLineEdit
-            The line displaying the text size to be matched.
-        """
-        if FONT.size >= 7:
-            line.setText(str(FONT.size - 1))
-        else:
-            line.setText(str(FONT.size))
-
-    def reset_color_clicked(self):
-        """Reset the color settings"""
-        settings = QSettings()
-        reset_color_settings(settings)
-        self._color_changed_per_type = False
-        self.update_color_preferences()
-
-        self._graph._color_change(LATENCY_COLOR_TYPE.DEFAULT, "all operations")
-        self._graph._signals.reopen.emit()
-        self.load_preferences()
-
-    def reset_font_clicked(
-        self, line: QLineEdit, italicbutton: ColorButton, boldbutton: ColorButton
-    ):
-        """
-        Reset the font settings.
-
-        Parameters
-        ----------
-        line : QLineEdit
-            The line displaying the text size to be matched with the chosen font.
-        italicbutton : ColorButton
-            The button displaying the italic state to be matched with the chosen font.
-        boldbutton : ColorButton
-            The button displaying the bold state to be matched with the chosen font.
-        """
-        FONT.current_font = QFont("Times", 12)
-        FONT.changed = False
-        FONT.color = FONT.DEFAULT_COLOR
-        FONT.size = int(FONT.DEFAULT.pointSizeF())
-        FONT.bold = FONT.DEFAULT.bold()
-        FONT.italic = FONT.DEFAULT.italic()
-        self.update_font()
-        self.load_preferences()
-        self.match_dialog_font(line, italicbutton, boldbutton)
-
-    def reset_all_clicked(
-        self, line: QLineEdit, italicbutton: ColorButton, boldbutton: ColorButton
-    ):
-        """Reset both the color and the font settings."""
-        self.reset_color_clicked()
-        self.reset_font_clicked(line, italicbutton, boldbutton)
-
-    def match_dialog_font(
-        self, line: QLineEdit, italicbutton: ColorButton, boldbutton: ColorButton
-    ) -> None:
-        """
-        Update the widgets on the preference dialog to match the current font.
-
-        Parameters
-        ----------
-        line : QLineEdit
-            The line displaying the text size to be matched with the current font.
-        italicbutton : ColorButton
-            The button displaying the italic state to be matched with the current font.
-        boldbutton : ColorButton
-            The button displaying the bold state to be matched with the current font.
-        """
-        line.setText(str(FONT.size))
-
-        if FONT.italic:
-            italicbutton.set_color(QColor('silver'))
-        else:
-            italicbutton.set_color(QColor('snow'))
-
-        if FONT.bold:
-            boldbutton.set_color(QColor('silver'))
-        else:
-            boldbutton.set_color(QColor('snow'))
-
     @Slot(str)
     def _show_execution_times_for_type(self, type_name):
         self._execution_time_plot(type_name)
@@ -1557,7 +1095,7 @@ class ScheduleMainWindow(QMainWindow, Ui_MainWindow):
                     self._recent_files_actions[i].setVisible(False)
 
     def _open_recent_file(self, action):
-        if action.data().filePath().endswith('.bsc'):
+        if action.data().filePath().endswith(".bsc"):
             self._open_schedule_file(action.data().filePath())
         else:
             self._load_from_file(action.data().filePath())
@@ -1602,10 +1140,10 @@ class ScheduleMainWindow(QMainWindow, Ui_MainWindow):
         """Callback for toggling full screen mode."""
         if self.isFullScreen():
             self.showNormal()
-            self.actionToggle_full_screen.setIcon(get_icon('full-screen'))
+            self.actionToggle_full_screen.setIcon(get_icon("full-screen"))
         else:
             self.showFullScreen()
-            self.actionToggle_full_screen.setIcon(get_icon('full-screen-exit'))
+            self.actionToggle_full_screen.setIcon(get_icon("full-screen-exit"))
 
 
 @overload
diff --git a/b_asic/scheduler_gui/operation_item.py b/b_asic/scheduler_gui/operation_item.py
index 347ea9eeb8c1259068cdf3dbff8a5b94ac18311d..63778af3ade092fe27fffc814df08ff368498b9a 100644
--- a/b_asic/scheduler_gui/operation_item.py
+++ b/b_asic/scheduler_gui/operation_item.py
@@ -5,6 +5,7 @@ B-ASIC Scheduler-GUI Operation Item Module.
 Contains the scheduler_gui OperationItem class for drawing and maintain an operation
 in the schedule.
 """
+
 from typing import TYPE_CHECKING, cast
 
 # QGraphics and QPainter imports
@@ -347,16 +348,16 @@ class OperationItem(QGraphicsItemGroup):
 
     def _open_context_menu(self):
         menu = QMenu()
-        swap = QAction(get_icon('swap'), "Swap")
+        swap = QAction(get_icon("swap"), "Swap")
         menu.addAction(swap)
         swap.setEnabled(self._operation.is_swappable)
         swap.triggered.connect(self._swap_io)
         slacks = self._parent.schedule.slacks(self._operation.graph_id)
-        asap = QAction(get_icon('asap'), "Move as soon as possible")
+        asap = QAction(get_icon("asap"), "Move as soon as possible")
         asap.triggered.connect(self._move_asap)
         asap.setEnabled(slacks[0] > 0)
         menu.addAction(asap)
-        alap = QAction(get_icon('alap'), "Move as late as possible")
+        alap = QAction(get_icon("alap"), "Move as late as possible")
         alap.triggered.connect(self._move_alap)
         alap.setEnabled(slacks[1] > 0)
         menu.addAction(alap)
diff --git a/b_asic/scheduler_gui/preferences_dialog.py b/b_asic/scheduler_gui/preferences_dialog.py
new file mode 100644
index 0000000000000000000000000000000000000000..6ca990ca5d8d986b13fd31bce9a703db9efeef54
--- /dev/null
+++ b/b_asic/scheduler_gui/preferences_dialog.py
@@ -0,0 +1,422 @@
+# QGraphics and QPainter imports
+from qtpy.QtCore import (
+    QCoreApplication,
+    QSettings,
+    Qt,
+)
+from qtpy.QtGui import QColor, QFont, QIcon, QIntValidator
+from qtpy.QtWidgets import (
+    QColorDialog,
+    QDialogButtonBox,
+    QFontDialog,
+    QGroupBox,
+    QHBoxLayout,
+    QInputDialog,
+    QLabel,
+    QLineEdit,
+    QVBoxLayout,
+    QWidget,
+)
+
+from b_asic.gui_utils.color_button import ColorButton
+from b_asic.scheduler_gui._preferences import (
+    ACTIVE_COLOR_TYPE,
+    EXECUTION_TIME_COLOR_TYPE,
+    FONT,
+    LATENCY_COLOR_TYPE,
+    SIGNAL_COLOR_TYPE,
+    SIGNAL_WARNING_COLOR_TYPE,
+    ColorDataType,
+    reset_color_settings,
+)
+
+
+class PreferencesDialog(QWidget):
+    def __init__(self, parent):
+        super().__init__()
+        self._parent = parent
+        self.setWindowTitle("Preferences")
+        layout = QVBoxLayout()
+        layout.setSpacing(15)
+
+        # Add label for the dialog
+        label = QLabel("Customize fonts and colors")
+        layout.addWidget(label)
+
+        groupbox = QGroupBox()
+        hlayout = QHBoxLayout()
+        label = QLabel("Color settings:")
+        layout.addWidget(label)
+        hlayout.setSpacing(20)
+
+        hlayout.addWidget(self.create_color_button(EXECUTION_TIME_COLOR_TYPE))
+        hlayout.addWidget(self.create_color_button(LATENCY_COLOR_TYPE))
+        hlayout.addWidget(
+            self.create_color_button(
+                ColorDataType(
+                    current_color=LATENCY_COLOR_TYPE.DEFAULT,
+                    DEFAULT=QColor("skyblue"),
+                    name="Latency color per type",
+                )
+            )
+        )
+
+        groupbox.setLayout(hlayout)
+        layout.addWidget(groupbox)
+
+        label = QLabel("Signal colors:")
+        layout.addWidget(label)
+        groupbox = QGroupBox()
+        hlayout = QHBoxLayout()
+        hlayout.setSpacing(20)
+
+        signal_color_button = self.create_color_button(SIGNAL_COLOR_TYPE)
+        signal_color_button.setStyleSheet(
+            f"color: {QColor(255, 255, 255, 0).name()}; background-color: {SIGNAL_COLOR_TYPE.DEFAULT.name()}"
+        )
+
+        hlayout.addWidget(signal_color_button)
+        hlayout.addWidget(self.create_color_button(SIGNAL_WARNING_COLOR_TYPE))
+        hlayout.addWidget(self.create_color_button(ACTIVE_COLOR_TYPE))
+
+        groupbox.setLayout(hlayout)
+        layout.addWidget(groupbox)
+
+        reset_color_button = ColorButton(QColor("silver"))
+        reset_color_button.setText("Reset all color settings")
+        reset_color_button.pressed.connect(self.reset_color_clicked)
+        layout.addWidget(reset_color_button)
+
+        label = QLabel("Font settings:")
+        layout.addWidget(label)
+
+        groupbox = QGroupBox()
+        hlayout = QHBoxLayout()
+        hlayout.setSpacing(10)
+
+        font_button = ColorButton(QColor("moccasin"))
+        font_button.setText("Font settings")
+        hlayout.addWidget(font_button)
+
+        font_color_button = ColorButton(QColor("moccasin"))
+        font_color_button.setText("Font color")
+        font_color_button.pressed.connect(self.font_color_clicked)
+        hlayout.addWidget(font_color_button)
+
+        groupbox2 = QGroupBox()
+        hlayout2 = QHBoxLayout()
+
+        icon = QIcon.fromTheme("format-text-italic")
+        self._italic_button = (
+            ColorButton(QColor("silver"))
+            if FONT.italic
+            else ColorButton(QColor("snow"))
+        )
+        self._italic_button.setIcon(icon)
+        self._italic_button.pressed.connect(lambda: self.italic_font_clicked())
+        hlayout2.addWidget(self._italic_button)
+
+        icon = QIcon.fromTheme("format-text-bold")
+        self._bold_button = ColorButton(
+            QColor("silver") if FONT.bold else QColor("snow")
+        )
+        self._bold_button.setIcon(icon)
+        self._bold_button.pressed.connect(lambda: self.bold_font_clicked())
+        hlayout2.addWidget(self._bold_button)
+
+        groupbox2.setLayout(hlayout2)
+        hlayout.addWidget(groupbox2)
+
+        groupbox2 = QGroupBox()
+        hlayout2 = QHBoxLayout()
+        self._font_size_input = QLineEdit()
+        font_button.pressed.connect(lambda: self.font_clicked())
+
+        icon = QIcon.fromTheme("list-add")
+        increase_font_size_button = ColorButton(QColor("smoke"))
+        increase_font_size_button.setIcon(icon)
+        increase_font_size_button.pressed.connect(
+            lambda: self.increase_font_size_clicked()
+        )
+        increase_font_size_button.setShortcut(
+            QCoreApplication.translate("MainWindow", "Ctrl++")
+        )
+        hlayout2.addWidget(increase_font_size_button)
+
+        self._font_size_input.setPlaceholderText("Font Size")
+        self._font_size_input.setText(f"Font Size: {FONT.size}")
+        self._font_size_input.setValidator(QIntValidator(0, 99))
+        self._font_size_input.setAlignment(Qt.AlignCenter)
+        self._font_size_input.textChanged.connect(lambda: self.set_font_size_clicked())
+        hlayout2.addWidget(self._font_size_input)
+
+        icon = QIcon.fromTheme("list-remove")
+        decrease_font_size_button = ColorButton(QColor("smoke"))
+        decrease_font_size_button.setIcon(icon)
+        decrease_font_size_button.pressed.connect(
+            lambda: self.decrease_font_size_clicked()
+        )
+        decrease_font_size_button.setShortcut(
+            QCoreApplication.translate("MainWindow", "Ctrl+-")
+        )
+
+        hlayout2.addWidget(decrease_font_size_button)
+
+        groupbox2.setLayout(hlayout2)
+        hlayout.addWidget(groupbox2)
+
+        groupbox.setLayout(hlayout)
+        layout.addWidget(groupbox)
+
+        reset_font_button = ColorButton(QColor("silver"))
+        reset_font_button.setText("Reset All Font Settings")
+        reset_font_button.pressed.connect(lambda: self.reset_font_clicked())
+        layout.addWidget(reset_font_button)
+
+        label = QLabel("")
+        layout.addWidget(label)
+
+        reset_all_button = ColorButton(QColor("salmon"))
+        reset_all_button.setText("Reset all settings")
+        reset_all_button.pressed.connect(lambda: self.reset_all_clicked())
+        layout.addWidget(reset_all_button)
+
+        self.setLayout(layout)
+        button_box = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Close)
+        button_box.ButtonLayout(QDialogButtonBox.MacLayout)
+        button_box.accepted.connect(self.close)
+        button_box.rejected.connect(self.close)
+        layout.addWidget(button_box)
+
+    def increase_font_size_clicked(self) -> None:
+        """
+        Increase the font size by 1.
+        """
+        if FONT.size <= 71:
+            self._font_size_input.setText(str(FONT.size + 1))
+        else:
+            self._font_size_input.setText(str(FONT.size))
+
+    def decrease_font_size_clicked(self) -> None:
+        """
+        Decrease the font size by 1.
+        """
+        if FONT.size >= 7:
+            self._font_size_input.setText(str(FONT.size - 1))
+        else:
+            self._font_size_input.setText(str(FONT.size))
+
+    def set_font_size_clicked(self):
+        """
+        Set the font size to the specified size and update the font.
+        """
+        size = self._font_size_input.text()
+        FONT.size = int(size) if size != "" else 6
+        FONT.current_font.setPointSizeF(FONT.size)
+        self.update_font()
+
+    def create_color_button(self, color: ColorDataType) -> ColorButton:
+        """Create a colored button to be used to modify a certain color
+
+        Parameters
+        ----------
+        color : ColorDataType
+            The ColorDataType assigned to the butten to be created.
+        """
+        button = ColorButton(color.DEFAULT)
+        button.setText(color.name)
+        if color.name == "Latency color":
+            button.pressed.connect(
+                lambda: self.set_latency_color_by_type_name(all=True)
+            )
+        elif color.name == "Latency color per type":
+            button.pressed.connect(
+                lambda: self.set_latency_color_by_type_name(all=False)
+            )
+        else:
+            button.pressed.connect(lambda: self.color_button_clicked(color))
+        return button
+
+    def italic_font_clicked(self):
+        """
+        Toggle the font style to italic if not already italic, otherwise remove italic.
+        """
+        FONT.italic = not FONT.italic
+        FONT.current_font.setItalic(FONT.italic)
+        if FONT.italic:
+            self._italic_button.set_color(QColor("silver"))
+        else:
+            self._italic_button.set_color(QColor("snow"))
+        self.update_font()
+
+    def bold_font_clicked(self):
+        """
+        Toggle the font style to bold if not already bold, otherwise unbold.
+        """
+        FONT.bold = not FONT.bold
+        FONT.current_font.setBold(FONT.bold)
+        FONT.current_font.setWeight(50)
+        if FONT.bold:
+            self._bold_button.set_color(QColor("silver"))
+        else:
+            self._bold_button.set_color(QColor("snow"))
+        self.update_font()
+
+    def set_latency_color_by_type_name(self, all: bool) -> None:
+        """
+        Set latency color based on operation type names.
+
+        Parameters
+        ----------
+        all : bool
+            Indicates if the color of all type names to be modified.
+        """
+        if LATENCY_COLOR_TYPE.changed:
+            current_color = LATENCY_COLOR_TYPE.current_color
+        else:
+            current_color = LATENCY_COLOR_TYPE.DEFAULT
+
+        # Prompt user to select operation type if not setting color for all types
+        if not all:
+            used_types = self._parent._schedule.get_used_type_names()
+            operation_type, ok = QInputDialog.getItem(
+                self, "Select operation type", "Type", used_types, editable=False
+            )
+        else:
+            operation_type = "all operations"
+            ok = False
+
+        # Open a color dialog to get the selected color
+        if all or ok:
+            color = QColorDialog.getColor(
+                current_color, self, f"Select the color of {operation_type}"
+            )
+
+            # If a valid color is selected, update color settings and graph
+            if color.isValid():
+                if all:
+                    LATENCY_COLOR_TYPE.changed = True
+                    self._parent._color_changed_per_type = False
+                    self._parent._changed_operation_colors.clear()
+                    LATENCY_COLOR_TYPE.current_color = color
+                # Save color settings for each operation type
+                else:
+                    self._parent._color_changed_per_type = True
+                    self._parent._changed_operation_colors[operation_type] = color
+                self._parent.update_color_preferences()
+                self._parent.update_statusbar("Preferences updated")
+
+    def color_button_clicked(self, color_type: ColorDataType) -> None:
+        """
+        Open a color dialog to select a color based on the specified color type
+
+        Parameters
+        ----------
+        color_type : ColorDataType
+            The ColorDataType to be changed.
+        """
+        settings = QSettings()
+        if color_type.changed:
+            current_color = color_type.current_color
+        else:
+            current_color = color_type.DEFAULT
+
+        color = QColorDialog.getColor(current_color, self, f"Select {color_type.name}")
+        # If a valid color is selected, update the current color and settings
+        if color.isValid():
+            color_type.current_color = color
+            color_type.changed = color_type.current_color != color_type.DEFAULT
+            settings.setValue(f"scheduler/preferences/{color_type.name}", color.name())
+            settings.sync()
+
+        self._parent._graph._signals.reopen.emit()
+        self._parent.update_statusbar("Preferences Updated")
+
+    def font_clicked(self) -> None:
+        """
+        Open a font dialog to select a font and update the current font.
+        """
+        current_font = FONT.current_font if FONT.changed else FONT.DEFAULT
+
+        (font, ok) = QFontDialog.getFont(current_font, self)
+        if ok:
+            FONT.current_font = font
+            FONT.size = int(font.pointSizeF())
+            FONT.bold = font.bold()
+            FONT.italic = font.italic()
+            self.update_font()
+            self.match_dialog_font()
+            self._parent.update_statusbar("Preferences Updated")
+
+    def reset_font_clicked(self):
+        """
+        Reset the font settings.
+        """
+        FONT.current_font = QFont("Times", 12)
+        FONT.changed = False
+        FONT.color = FONT.DEFAULT_COLOR
+        FONT.size = int(FONT.DEFAULT.pointSizeF())
+        FONT.bold = FONT.DEFAULT.bold()
+        FONT.italic = FONT.DEFAULT.italic()
+        self.update_font()
+        self._parent.load_preferences()
+        self.match_dialog_font()
+
+    def match_dialog_font(self) -> None:
+        """
+        Update the widgets on the preference dialog to match the current font.
+        """
+        self._font_size_input.setText(str(FONT.size))
+
+        if FONT.italic:
+            self._italicbutton.set_color(QColor("silver"))
+        else:
+            self._italicbutton.set_color(QColor("snow"))
+
+        if FONT.bold:
+            self._boldbutton.set_color(QColor("silver"))
+        else:
+            self._boldbutton.set_color(QColor("snow"))
+
+    def update_font(self):
+        """Update font preferences based on current Font settings"""
+        settings = QSettings()
+        FONT.changed = not (
+            FONT.current_font == FONT.DEFAULT
+            and FONT.size == int(FONT.DEFAULT.pointSizeF())
+            and FONT.italic == FONT.DEFAULT.italic()
+            and FONT.bold == FONT.DEFAULT.bold()
+        )
+        settings.setValue("scheduler/preferences/font", FONT.current_font.toString())
+        settings.setValue("scheduler/preferences/font_size", FONT.size)
+        settings.setValue("scheduler/preferences/font_bold", FONT.bold)
+        settings.setValue("scheduler/preferences/font_italic", FONT.italic)
+        settings.sync()
+        self._parent.load_preferences()
+
+    def font_color_clicked(self):
+        """Select a font color and update preferences"""
+        settings = QSettings()
+        color = QColorDialog.getColor(FONT.color, self, "Select font color")
+        if color.isValid():
+            FONT.color = color
+            FONT.changed = True
+        settings.setValue("scheduler/preferences/font_color", FONT.color.name())
+        settings.sync()
+        self._parent._graph._font_color_change(FONT.color)
+
+    def reset_color_clicked(self):
+        """Reset the color settings"""
+        settings = QSettings()
+        reset_color_settings(settings)
+        self._parent._color_changed_per_type = False
+        self._parent.update_color_preferences()
+
+        self._parent._graph._color_change(LATENCY_COLOR_TYPE.DEFAULT, "all operations")
+        self._parent._graph._signals.reopen.emit()
+        self._parent.load_preferences()
+
+    def reset_all_clicked(self):
+        """Reset both the color and the font settings."""
+        self.reset_color_clicked()
+        self.reset_font_clicked()
diff --git a/b_asic/scheduler_gui/scheduler_event.py b/b_asic/scheduler_gui/scheduler_event.py
index b191fa50696f8de1b71e0dc82bcd965e0f6fcfd5..0524d1764577bab0b4ee6718c1cbe3d948ce553c 100644
--- a/b_asic/scheduler_gui/scheduler_event.py
+++ b/b_asic/scheduler_gui/scheduler_event.py
@@ -5,6 +5,7 @@ B-ASIC Scheduler-GUI Graphics Scheduler Event Module.
 Contains the scheduler_ui SchedulerEvent class containing event filters and
 handlers for SchedulerItem objects.
 """
+
 import math
 from typing import overload
 
diff --git a/b_asic/scheduler_gui/scheduler_item.py b/b_asic/scheduler_gui/scheduler_item.py
index 72f9cf8282cd4c0ee9cf71bb9772219016740e25..4309154597d0959033549d127bfae1ffc6ed30a6 100644
--- a/b_asic/scheduler_gui/scheduler_item.py
+++ b/b_asic/scheduler_gui/scheduler_item.py
@@ -5,6 +5,7 @@ B-ASIC Scheduler-GUI Scheduler Item Module.
 Contains the scheduler_gui SchedulerItem class for drawing and
 maintaining a schedule.
 """
+
 from collections import defaultdict
 from math import floor
 from pprint import pprint
diff --git a/b_asic/scheduler_gui/timeline_item.py b/b_asic/scheduler_gui/timeline_item.py
index 5fd10d075caa1e091fda997b401c47ee8b442461..fc29669f6287d86a4208d67f7201177f7cbf82a3 100644
--- a/b_asic/scheduler_gui/timeline_item.py
+++ b/b_asic/scheduler_gui/timeline_item.py
@@ -5,6 +5,7 @@ B-ASIC Scheduler-GUI Timeline Item Module.
 Contains the scheduler_gui TimelineItem class for drawing and
 maintain the timeline in a schedule.
 """
+
 from typing import overload
 
 # QGraphics and QPainter imports
diff --git a/b_asic/signal_flow_graph.py b/b_asic/signal_flow_graph.py
index 72c4a316251cffd0b09d2da317f9cd532366823c..de2a9db8754ec57973d28a8017b430fbabd13aa8 100644
--- a/b_asic/signal_flow_graph.py
+++ b/b_asic/signal_flow_graph.py
@@ -671,12 +671,12 @@ class SFG(AbstractOperation):
                 signal.remove_source()
                 signal.set_source(component.output(index_out))
 
-        if component_copy.type_name() == 'out':
+        if component_copy.type_name() == "out":
             sfg_copy._output_operations.remove(component_copy)
             warnings.warn(
                 f"Output port {component_copy.graph_id} has been removed", stacklevel=2
             )
-        if component.type_name() == 'out':
+        if component.type_name() == "out":
             sfg_copy._output_operations.append(component)
 
         return sfg_copy()  # Copy again to update IDs.
@@ -1019,14 +1019,14 @@ class SFG(AbstractOperation):
                     if port.operation.output_count > 1:
                         sub.node(
                             port_string,
-                            shape='rectangle',
+                            shape="rectangle",
                             height="0.1",
                             width="0.1",
                         )
                     else:
                         sub.node(
                             port_string,
-                            shape='rectangle',
+                            shape="rectangle",
                             label=port.operation.graph_id,
                             height="0.1",
                             width="0.1",
@@ -1688,7 +1688,7 @@ class SFG(AbstractOperation):
                     and source_name not in branch_nodes
                 ):
                     branch_nodes.add(source_name)
-                    dg.node(source_name, shape='point')
+                    dg.node(source_name, shape="point")
                     taillabel = (
                         str(source.index)
                         if source.operation.output_count > 1 and port_numbering
@@ -1697,7 +1697,7 @@ class SFG(AbstractOperation):
                     dg.edge(
                         source.operation.graph_id,
                         source_name,
-                        arrowhead='none',
+                        arrowhead="none",
                         taillabel=taillabel,
                     )
             else:
@@ -1857,7 +1857,7 @@ class SFG(AbstractOperation):
             time_of_loop = 0
             number_of_t_in_loop = 0
             for element in loop:
-                if ''.join([i for i in element if not i.isdigit()]) == 't':
+                if "".join([i for i in element if not i.isdigit()]) == "t":
                     number_of_t_in_loop += 1
                 for key, item in op_and_latency.items():
                     if key in element:
@@ -1881,7 +1881,7 @@ class SFG(AbstractOperation):
         """
         inputs_used = []
         for used_input in self._used_ids:
-            if 'in' in str(used_input):
+            if "in" in str(used_input):
                 used_input = used_input.replace("in", "")
                 inputs_used.append(int(used_input))
         if inputs_used == []:
@@ -1937,7 +1937,7 @@ class SFG(AbstractOperation):
         """
         delay_element_used = []
         for delay_element in self._used_ids:
-            if ''.join([i for i in delay_element if not i.isdigit()]) == 't':
+            if "".join([i for i in delay_element if not i.isdigit()]) == "t":
                 delay_element_used.append(delay_element)
         delay_element_used.sort()
         input_index_used = []
@@ -1945,10 +1945,10 @@ class SFG(AbstractOperation):
         output_index_used = []
         outputs_used = []
         for used_inout in self._used_ids:
-            if 'in' in str(used_inout):
+            if "in" in str(used_inout):
                 inputs_used.append(used_inout)
                 input_index_used.append(int(used_inout.replace("in", "")))
-            elif 'out' in str(used_inout):
+            elif "out" in str(used_inout):
                 outputs_used.append(used_inout)
                 output_index_used.append(int(used_inout.replace("out", "")))
         if input_index_used == []:
@@ -1995,12 +1995,12 @@ class SFG(AbstractOperation):
             raise ValueError("Empty SFG")
         addition_with_constant = {}
         for key, item in dict_of_sfg.items():
-            if ''.join([i for i in key if not i.isdigit()]) == 'c':
+            if "".join([i for i in key if not i.isdigit()]) == "c":
                 addition_with_constant[item[0]] = self.find_by_id(key).value
         cycles = [
             [node] + path
             for node in dict_of_sfg
-            if node[0] == 't'
+            if node[0] == "t"
             for path in self._dfs(dict_of_sfg, node, node)
         ]
         delay_loop_list = []
@@ -2009,7 +2009,7 @@ class SFG(AbstractOperation):
                 temp_list = []
                 for element in lista:
                     temp_list.append(element)
-                    if element[0] == 't' and len(temp_list) >= 2:
+                    if element[0] == "t" and len(temp_list) >= 2:
                         delay_loop_list.append(temp_list)
                         temp_list = [element]
         state_space_lista = []
@@ -2024,34 +2024,34 @@ class SFG(AbstractOperation):
         matrix_in = [0] * mat_col
         matrix_answer = [0] * mat_row
         for in_signal in inputs_used:
-            matrix_in[len(delay_element_used) + int(in_signal.replace('in', ''))] = (
-                in_signal.replace('in', 'x')
+            matrix_in[len(delay_element_used) + int(in_signal.replace("in", ""))] = (
+                in_signal.replace("in", "x")
             )
             for delay_element in delay_element_used:
                 matrix_answer[delay_element_used.index(delay_element)] = (
-                    delay_element.replace('t', 'v')
+                    delay_element.replace("t", "v")
                 )
                 matrix_in[delay_element_used.index(delay_element)] = (
-                    delay_element.replace('t', 'v')
+                    delay_element.replace("t", "v")
                 )
                 paths = self.find_all_paths(dict_of_sfg, in_signal, delay_element)
                 for lista in paths:
                     temp_list = []
                     for element in lista:
                         temp_list.append(element)
-                        if element[0] == 't':
+                        if element[0] == "t":
                             state_space_lista.append(temp_list)
                             temp_list = [element]
             for out_signal in outputs_used:
                 paths = self.find_all_paths(dict_of_sfg, in_signal, out_signal)
                 matrix_answer[
-                    len(delay_element_used) + int(out_signal.replace('out', ''))
-                ] = out_signal.replace('out', 'y')
+                    len(delay_element_used) + int(out_signal.replace("out", ""))
+                ] = out_signal.replace("out", "y")
                 for lista in paths:
                     temp_list1 = []
                     for element in lista:
                         temp_list1.append(element)
-                        if element[0] == 't':
+                        if element[0] == "t":
                             state_space_lista.append(temp_list1)
                             temp_list1 = [element]
                         if "out" in element:
@@ -2064,7 +2064,7 @@ class SFG(AbstractOperation):
             if x not in state_space_list_no_dup
         ]
         for lista in state_space_list_no_dup:
-            if "in" in lista[0] and lista[-1][0] == 't':
+            if "in" in lista[0] and lista[-1][0] == "t":
                 row = int(lista[-1].replace("t", ""))
                 column = len(delay_element_used) + int(lista[0].replace("in", ""))
                 temp_value = 1
@@ -2086,7 +2086,7 @@ class SFG(AbstractOperation):
                         if key == element:
                             temp_value += int(value)
                 mat_content[row, column] += temp_value
-            elif lista[0][0] == 't' and lista[-1][0] == 't':
+            elif lista[0][0] == "t" and lista[-1][0] == "t":
                 row = int(lista[-1].replace("t", ""))
                 column = int(lista[0].replace("t", ""))
                 temp_value = 1
@@ -2097,7 +2097,7 @@ class SFG(AbstractOperation):
                         if key == element:
                             temp_value += int(value)
                 mat_content[row, column] += temp_value
-            elif lista[0][0] == 't' and "out" in lista[-1]:
+            elif lista[0][0] == "t" and "out" in lista[-1]:
                 row = len(delay_element_used) + int(lista[-1].replace("out", ""))
                 column = int(lista[0].replace("t", ""))
                 temp_value = 1
@@ -2206,9 +2206,9 @@ class SFG(AbstractOperation):
         # Add suffixes to all graphIDs and names in order to keep them separated
         for i in range(factor):
             for operation in sfgs[i].operations:
-                suffix = f'_{i}'
+                suffix = f"_{i}"
                 operation.graph_id = operation.graph_id + suffix
-                if operation.name[:7] not in ['', 'input_t', 'output_']:
+                if operation.name[:7] not in ["", "input_t", "output_"]:
                     operation.name = operation.name + suffix
 
         input_name_to_idx = {}  # save the input port indices for future reference
@@ -2248,7 +2248,7 @@ class SFG(AbstractOperation):
                     input_port.connect(port)
                     delay_placements[port] = [i, number_of_delays_between]
             sfgs[i].graph_id = (
-                f'sfg{i}'  # deterministically set the graphID of the sfgs
+                f"sfg{i}"  # deterministically set the graphID of the sfgs
             )
 
         sfg = SFG(new_inputs, new_outputs)  # create a new SFG to remove floating nodes
@@ -2257,11 +2257,11 @@ class SFG(AbstractOperation):
         for port, val in delay_placements.items():
             i, no_of_delays = val
             for _ in range(no_of_delays):
-                sfg = sfg.insert_operation_after(f'sfg{i}.{port.index}', Delay())
+                sfg = sfg.insert_operation_after(f"sfg{i}.{port.index}", Delay())
 
         # Flatten all the copies of the original SFG
         for i in range(factor):
-            sfg.find_by_id(f'sfg{i}').connect_external_signals_to_components()
+            sfg.find_by_id(f"sfg{i}").connect_external_signals_to_components()
             sfg = sfg()
 
         return sfg
diff --git a/docs_sphinx/conf.py b/docs_sphinx/conf.py
index 32ba20282f013e59b0d0bf5be04fe24687efddf9..1822a3ecd41abbddc6a8b84e5c7b5a4740dbc475 100644
--- a/docs_sphinx/conf.py
+++ b/docs_sphinx/conf.py
@@ -8,40 +8,40 @@
 
 import shutil
 
-project = 'B-ASIC'
-copyright = '2020-2025, Oscar Gustafsson et al'
-author = 'Oscar Gustafsson et al'
+project = "B-ASIC"
+copyright = "2020-2025, Oscar Gustafsson et al"
+author = "Oscar Gustafsson et al"
 html_logo = "../logos/logo_tiny.png"
 
-pygments_style = 'sphinx'
+pygments_style = "sphinx"
 
 # -- General configuration ---------------------------------------------------
 # https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration
 
 extensions = [
-    'sphinx.ext.autodoc',
-    'sphinx.ext.autosummary',
-    'sphinx.ext.inheritance_diagram',
-    'sphinx.ext.intersphinx',
-    'sphinx_gallery.gen_gallery',
-    'numpydoc',  # Needs to be loaded *after* autodoc.
-    'sphinx_copybutton',
+    "sphinx.ext.autodoc",
+    "sphinx.ext.autosummary",
+    "sphinx.ext.inheritance_diagram",
+    "sphinx.ext.intersphinx",
+    "sphinx_gallery.gen_gallery",
+    "numpydoc",  # Needs to be loaded *after* autodoc.
+    "sphinx_copybutton",
 ]
 
-templates_path = ['_templates']
-exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
+templates_path = ["_templates"]
+exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"]
 
 autodoc_docstring_signature = True
 
 # nitpicky = True
 
 intersphinx_mapping = {
-    'python': ('https://docs.python.org/3/', None),
-    'graphviz': ('https://graphviz.readthedocs.io/en/stable/', None),
-    'matplotlib': ('https://matplotlib.org/stable/', None),
-    'numpy': ('https://numpy.org/doc/stable/', None),
-    'networkx': ('https://networkx.org/documentation/stable', None),
-    'mplsignal': ('https://mplsignal.readthedocs.io/en/stable/', None),
+    "python": ("https://docs.python.org/3/", None),
+    "graphviz": ("https://graphviz.readthedocs.io/en/stable/", None),
+    "matplotlib": ("https://matplotlib.org/stable/", None),
+    "numpy": ("https://numpy.org/doc/stable/", None),
+    "networkx": ("https://networkx.org/documentation/stable", None),
+    "mplsignal": ("https://mplsignal.readthedocs.io/en/stable/", None),
 }
 
 numpydoc_show_class_members = False
@@ -58,30 +58,30 @@ numpydoc_validation_checks = {
 
 inheritance_node_attrs = dict(fontsize=16)
 
-graphviz_dot = shutil.which('dot')
+graphviz_dot = shutil.which("dot")
 
-html_favicon = '_static/icon_logo.png'
+html_favicon = "_static/icon_logo.png"
 
 # -- Options for HTML output -------------------------------------------------
 # https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output
 
-html_theme = 'furo'
-html_static_path = ['_static']
+html_theme = "furo"
+html_static_path = ["_static"]
 
 # -- Options for sphinx-gallery --
 sphinx_gallery_conf = {
-    'examples_dirs': '../examples',  # path to your example scripts
-    'gallery_dirs': 'examples',  # path to where to save gallery generated output
-    'plot_gallery': 'True',  # sphinx-gallery/913
-    'filename_pattern': '.',
-    'doc_module': ('b_asic',),
-    'reference_url': {'b_asic': None},
-    'image_scrapers': (
+    "examples_dirs": "../examples",  # path to your example scripts
+    "gallery_dirs": "examples",  # path to where to save gallery generated output
+    "plot_gallery": "True",  # sphinx-gallery/913
+    "filename_pattern": ".",
+    "doc_module": ("b_asic",),
+    "reference_url": {"b_asic": None},
+    "image_scrapers": (
         #    qtgallery.qtscraper,
-        'matplotlib',
+        "matplotlib",
     ),
-    'reset_modules': (
+    "reset_modules": (
         #    qtgallery.reset_qapp,
-        'matplotlib',
+        "matplotlib",
     ),
 }
diff --git a/docs_sphinx/scheduler_gui.rst b/docs_sphinx/scheduler_gui.rst
index 288bf0a58a8f5ddc592454ffc7853ca5e7c4d59e..03ead85cac09f1a72c70f0e61777791fe4933bf2 100644
--- a/docs_sphinx/scheduler_gui.rst
+++ b/docs_sphinx/scheduler_gui.rst
@@ -37,6 +37,14 @@ scheduler\_gui.operation\_item module
    :undoc-members:
    :show-inheritance:
 
+scheduler\_gui.preferences\_dialog module
+-------------------------------------
+
+.. automodule:: b_asic.scheduler_gui.preferences_dialog
+   :members:
+   :undoc-members:
+   :show-inheritance:
+
 scheduler\_gui.scheduler\_event module
 --------------------------------------
 
diff --git a/test/fixtures/schedule.py b/test/fixtures/schedule.py
index e844ed92a3eeabcd3088692e89b1913e18957cbe..5d654e198e8e9bd2d54b6e083b39d52af420eab1 100644
--- a/test/fixtures/schedule.py
+++ b/test/fixtures/schedule.py
@@ -47,14 +47,14 @@ def schedule_direct_form_iir_lp_filter(sfg_direct_form_iir_lp_filter: SFG):
     schedule = Schedule(
         sfg_direct_form_iir_lp_filter, scheduler=ASAPScheduler(), cyclic=True
     )
-    schedule.move_operation('cmul3', -1)
-    schedule.move_operation('cmul2', -1)
-    schedule.move_operation('cmul3', -10)
-    schedule.move_operation('cmul3', 1)
-    schedule.move_operation('cmul2', -8)
-    schedule.move_operation('add3', 1)
-    schedule.move_operation('add3', 1)
-    schedule.move_operation('cmul1', 1)
-    schedule.move_operation('cmul1', 1)
-    schedule.move_operation('cmul3', 2)
+    schedule.move_operation("cmul3", -1)
+    schedule.move_operation("cmul2", -1)
+    schedule.move_operation("cmul3", -10)
+    schedule.move_operation("cmul3", 1)
+    schedule.move_operation("cmul2", -8)
+    schedule.move_operation("add3", 1)
+    schedule.move_operation("add3", 1)
+    schedule.move_operation("cmul1", 1)
+    schedule.move_operation("cmul1", 1)
+    schedule.move_operation("cmul3", 2)
     return schedule
diff --git a/test/fixtures/signal_flow_graph.py b/test/fixtures/signal_flow_graph.py
index 7eaccbe7c01809ffe7b8842d6e57d1db502948e3..df3e50b02cf193da1344d02a99d832d6e39cc46b 100644
--- a/test/fixtures/signal_flow_graph.py
+++ b/test/fixtures/signal_flow_graph.py
@@ -288,13 +288,13 @@ def sfg_two_tap_fir():
     # Operations:
     t1 = Delay(initial_value=0, name="t1")
     cmul1 = ConstantMultiplication(
-        value=0.5, name="cmul1", latency_offsets={'in0': None, 'out0': None}
+        value=0.5, name="cmul1", latency_offsets={"in0": None, "out0": None}
     )
     add1 = Addition(
-        name="add1", latency_offsets={'in0': None, 'in1': None, 'out0': None}
+        name="add1", latency_offsets={"in0": None, "in1": None, "out0": None}
     )
     cmul2 = ConstantMultiplication(
-        value=0.5, name="cmul2", latency_offsets={'in0': None, 'out0': None}
+        value=0.5, name="cmul2", latency_offsets={"in0": None, "out0": None}
     )
 
     # Signals:
@@ -305,7 +305,7 @@ def sfg_two_tap_fir():
     Signal(source=cmul1.output(0), destination=add1.input(0))
     Signal(source=add1.output(0), destination=out1.input(0))
     Signal(source=cmul2.output(0), destination=add1.input(1))
-    return SFG(inputs=[in1], outputs=[out1], name='twotapfir')
+    return SFG(inputs=[in1], outputs=[out1], name="twotapfir")
 
 
 @pytest.fixture
@@ -331,7 +331,7 @@ def sfg_direct_form_iir_lp_filter():
     d0.input(0).connect(top_node)
     d1.input(0).connect(d0)
     y <<= a1 * d0 + a2 * d1 + a0 * top_node
-    return SFG(inputs=[x], outputs=[y], name='Direct Form 2 IIR Lowpass filter')
+    return SFG(inputs=[x], outputs=[y], name="Direct Form 2 IIR Lowpass filter")
 
 
 @pytest.fixture
diff --git a/test/integration/test_sfg_to_architecture.py b/test/integration/test_sfg_to_architecture.py
index 6eebe152479638fc7c918a016906d767b822670d..be645aed50a22f0dc9500e1f9d7079933981665f 100644
--- a/test/integration/test_sfg_to_architecture.py
+++ b/test/integration/test_sfg_to_architecture.py
@@ -120,8 +120,8 @@ def test_pe_and_memory_constrained_chedule():
     bf_pe = ProcessingElement(bfs, entity_name="bf")
     mul_pe = ProcessingElement(const_muls, entity_name="mul")
 
-    pe_in = ProcessingElement(inputs, entity_name='input')
-    pe_out = ProcessingElement(outputs, entity_name='output')
+    pe_in = ProcessingElement(inputs, entity_name="input")
+    pe_out = ProcessingElement(outputs, entity_name="output")
 
     mem_vars = schedule.get_memory_variables()
     direct, mem_vars = mem_vars.split_on_length()
diff --git a/test/unit/test_architecture.py b/test/unit/test_architecture.py
index b07214198ebb7b9584dd3d8590576dc5f2dc2a6f..6ceabe631a215578926048dc5b722a8addadfacc 100644
--- a/test/unit/test_architecture.py
+++ b/test/unit/test_architecture.py
@@ -96,8 +96,8 @@ def test_architecture(schedule_direct_form_iir_lp_filter: Schedule):
         output_pe,
     ]
     s = (
-        'digraph {\n\tnode [shape=box]\n\t'
-        + 'adder'
+        "digraph {\n\tnode [shape=box]\n\t"
+        + "adder"
         + ' [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0" CELLPADDING="4">'
         + '<TR><TD COLSPAN="1" PORT="in0">in0</TD>'
         + '<TD COLSPAN="1" PORT="in1">in1</TD></TR>'
@@ -105,7 +105,7 @@ def test_architecture(schedule_direct_form_iir_lp_filter: Schedule):
         + '<TR><TD COLSPAN="2" PORT="out0">out0</TD></TR>'
         + '</TABLE>> fillcolor="#00B9E7" fontname="Times New Roman" style=filled]\n}'
     )
-    assert adder._digraph().source in (s, s + '\n')
+    assert adder._digraph().source in (s, s + "\n")
 
     # Extract zero-length memory variables
     direct_conn, mvs = mvs.split_on_length()
@@ -119,16 +119,16 @@ 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=box]\n\tMEM0'
+            "digraph {\n\tnode [shape=box]\n\tMEM0"
             + ' [label=<<TABLE BORDER="0" CELLBORDER="1"'
             + ' CELLSPACING="0" CELLPADDING="4">'
             + '<TR><TD COLSPAN="1" PORT="in0">in0</TD></TR>'
             + '<TR><TD COLSPAN="1"><B>MEM0</B></TD></TR>'
             + '<TR><TD COLSPAN="1" PORT="out0">out0</TD></TR>'
             + '</TABLE>> fillcolor="#00CFB5" fontname="Times New Roman" '
-            + 'style=filled]\n}'
+            + "style=filled]\n}"
         )
-        assert memory._digraph().source in (s, s + '\n')
+        assert memory._digraph().source in (s, s + "\n")
         assert memory.schedule_time == 18
         # Smoke test
         memory.show_content()
@@ -141,7 +141,7 @@ def test_architecture(schedule_direct_form_iir_lp_filter: Schedule):
         memory.show_content()
 
     # Set invalid name
-    with pytest.raises(ValueError, match='32 is not a valid VHDL identifier'):
+    with pytest.raises(ValueError, match="32 is not a valid VHDL identifier"):
         adder.set_entity_name("32")
     assert adder.entity_name == "adder"
     assert repr(adder) == "adder"
@@ -158,22 +158,22 @@ def test_architecture(schedule_direct_form_iir_lp_filter: Schedule):
 
     # Graph representation
     # Parts are non-deterministic, but this first part seems OK
-    s = 'digraph {\n\tnode [shape=box]\n\tsplines=spline\n\tsubgraph cluster_memories'
+    s = "digraph {\n\tnode [shape=box]\n\tsplines=spline\n\tsubgraph cluster_memories"
     assert architecture._digraph().source.startswith(s)
-    s = 'digraph {\n\tnode [shape=box]\n\tsplines=spline\n\tMEM0'
+    s = "digraph {\n\tnode [shape=box]\n\tsplines=spline\n\tMEM0"
     assert architecture._digraph(cluster=False).source.startswith(s)
     assert architecture.schedule_time == 18
 
     for pe in processing_elements:
         assert pe.schedule_time == 18
 
-    assert architecture.resource_from_name('adder') == adder
+    assert architecture.resource_from_name("adder") == adder
 
-    assert architecture.get_interconnects_for_memory('MEM0') == (
+    assert architecture.get_interconnects_for_memory("MEM0") == (
         {adder: 2, multiplier: 2, input_pe: 1},
         {adder: 4, multiplier: 4},
     )
-    assert architecture.get_interconnects_for_pe('adder') == (
+    assert architecture.get_interconnects_for_pe("adder") == (
         [
             {(multiplier, 0): 2, (memory, 0): 1, (adder, 0): 1},
             {(memory, 0): 3, (multiplier, 0): 1},
@@ -199,13 +199,13 @@ def test_move_process(schedule_direct_form_iir_lp_filter: Schedule):
 
     # Create necessary processing elements
     processing_elements: List[ProcessingElement] = [
-        ProcessingElement(operation, entity_name=f'pe{i}')
+        ProcessingElement(operation, entity_name=f"pe{i}")
         for i, operation in enumerate(chain(adders1, adders2, const_mults))
     ]
     for i, pc in enumerate(inputs):
-        processing_elements.append(ProcessingElement(pc, entity_name=f'input{i}'))
+        processing_elements.append(ProcessingElement(pc, entity_name=f"input{i}"))
     for i, pc in enumerate(outputs):
-        processing_elements.append(ProcessingElement(pc, entity_name=f'output{i}'))
+        processing_elements.append(ProcessingElement(pc, entity_name=f"output{i}"))
 
     # Extract zero-length memory variables
     direct_conn, mvs = mvs.split_on_length()
@@ -219,31 +219,31 @@ def test_move_process(schedule_direct_form_iir_lp_filter: Schedule):
     )
 
     # Some movement that must work
-    assert memories[1].collection.from_name('cmul3.0')
-    architecture.move_process('cmul3.0', memories[1], memories[0])
-    assert memories[0].collection.from_name('cmul3.0')
+    assert memories[1].collection.from_name("cmul3.0")
+    architecture.move_process("cmul3.0", memories[1], memories[0])
+    assert memories[0].collection.from_name("cmul3.0")
 
-    assert memories[1].collection.from_name('in0.0')
-    architecture.move_process('in0.0', memories[1], memories[0])
-    assert memories[0].collection.from_name('in0.0')
+    assert memories[1].collection.from_name("in0.0")
+    architecture.move_process("in0.0", memories[1], memories[0])
+    assert memories[0].collection.from_name("in0.0")
 
-    assert processing_elements[0].collection.from_name('add0')
-    architecture.move_process('add0', processing_elements[0], processing_elements[1])
-    assert processing_elements[1].collection.from_name('add0')
+    assert processing_elements[0].collection.from_name("add0")
+    architecture.move_process("add0", processing_elements[0], processing_elements[1])
+    assert processing_elements[1].collection.from_name("add0")
 
     # Processes leave the resources they have moved from
     with pytest.raises(KeyError):
-        memories[1].collection.from_name('cmul3.0')
+        memories[1].collection.from_name("cmul3.0")
     with pytest.raises(KeyError):
-        memories[1].collection.from_name('in0.0')
+        memories[1].collection.from_name("in0.0")
     with pytest.raises(KeyError):
-        processing_elements[0].collection.from_name('add0')
+        processing_elements[0].collection.from_name("add0")
 
     # Processes can only be moved when the source and destination process-types match
     with pytest.raises(TypeError, match="cmul3.0 not of type"):
-        architecture.move_process('cmul3.0', memories[0], processing_elements[0])
+        architecture.move_process("cmul3.0", memories[0], processing_elements[0])
     with pytest.raises(KeyError, match="invalid_name not in"):
-        architecture.move_process('invalid_name', memories[0], processing_elements[1])
+        architecture.move_process("invalid_name", memories[0], processing_elements[1])
 
 
 def test_resource_errors(precedence_sfg_delays):
@@ -260,7 +260,7 @@ def test_resource_errors(precedence_sfg_delays):
     operations = schedule.get_operations()
     additions = operations.get_by_type_name(Addition.type_name())
     with pytest.raises(
-        ValueError, match='Cannot map ProcessCollection to single ProcessingElement'
+        ValueError, match="Cannot map ProcessCollection to single ProcessingElement"
     ):
         ProcessingElement(additions)
 
diff --git a/test/unit/test_gui.py b/test/unit/test_gui.py
index d910765ce3fa0db76a0ccd0d93e7950a2f0adbd1..39a318575be128d05d558de76c32c8fad2691498 100644
--- a/test/unit/test_gui.py
+++ b/test/unit/test_gui.py
@@ -21,10 +21,10 @@ def test_start(qtbot):
 def test_load(qtbot, datadir):
     widget = SFGMainWindow()
     qtbot.addWidget(widget)
-    widget._load_from_file(datadir.join('twotapfir.py'))
-    assert 'twotapfir' in widget._sfg_dict
+    widget._load_from_file(datadir.join("twotapfir.py"))
+    assert "twotapfir" in widget._sfg_dict
     widget._clear_workspace()
-    assert 'twotapfir' not in widget._sfg_dict
+    assert "twotapfir" not in widget._sfg_dict
     assert not widget._sfg_dict
 
     widget.exit_app()
@@ -33,8 +33,8 @@ def test_load(qtbot, datadir):
 def test_flip(qtbot, datadir):
     widget = SFGMainWindow()
     qtbot.addWidget(widget)
-    widget._load_from_file(datadir.join('twotapfir.py'))
-    sfg = widget._sfg_dict['twotapfir']
+    widget._load_from_file(datadir.join("twotapfir.py"))
+    sfg = widget._sfg_dict["twotapfir"]
     op = sfg.find_by_name("cmul2")
     dragbutton = widget._drag_buttons[op[0]]
     assert not dragbutton.is_flipped()
@@ -46,8 +46,8 @@ def test_flip(qtbot, datadir):
 def test_sfg_invalidated_by_remove_of_operation(qtbot, datadir):
     widget = SFGMainWindow()
     qtbot.addWidget(widget)
-    widget._load_from_file(datadir.join('twotapfir.py'))
-    sfg = widget._sfg_dict['twotapfir']
+    widget._load_from_file(datadir.join("twotapfir.py"))
+    sfg = widget._sfg_dict["twotapfir"]
     ops_before_remove = len(widget._drag_buttons)
     op = sfg.find_by_name("cmul2")
     dragbutton = widget._drag_buttons[op[0]]
@@ -61,8 +61,8 @@ def test_sfg_invalidated_by_remove_of_operation(qtbot, datadir):
 def test_sfg_invalidated_by_deleting_of_operation(qtbot, datadir):
     widget = SFGMainWindow()
     qtbot.addWidget(widget)
-    widget._load_from_file(datadir.join('twotapfir.py'))
-    sfg = widget._sfg_dict['twotapfir']
+    widget._load_from_file(datadir.join("twotapfir.py"))
+    sfg = widget._sfg_dict["twotapfir"]
     ops_before_remove = len(widget._drag_buttons)
     op = sfg.find_by_name("cmul2")
     dragbutton = widget._drag_buttons[op[0]]
@@ -78,8 +78,8 @@ def test_sfg_invalidated_by_deleting_of_operation(qtbot, datadir):
 def test_select_operation(qtbot, datadir):
     widget = SFGMainWindow()
     qtbot.addWidget(widget)
-    widget._load_from_file(datadir.join('twotapfir.py'))
-    sfg = widget._sfg_dict['twotapfir']
+    widget._load_from_file(datadir.join("twotapfir.py"))
+    sfg = widget._sfg_dict["twotapfir"]
     op = sfg.find_by_name("cmul2")[0]
     dragbutton = widget._drag_buttons[op]
     assert not dragbutton.pressed
@@ -170,8 +170,8 @@ def test_properties_window_smoke_test(qtbot, datadir):
     # Should really check that the contents are correct and changes works etc
     widget = SFGMainWindow()
     qtbot.addWidget(widget)
-    widget._load_from_file(datadir.join('twotapfir.py'))
-    sfg = widget._sfg_dict['twotapfir']
+    widget._load_from_file(datadir.join("twotapfir.py"))
+    sfg = widget._sfg_dict["twotapfir"]
     op = sfg.find_by_name("cmul2")[0]
     dragbutton = widget._drag_buttons[op]
     dragbutton.show_properties_window()
@@ -187,8 +187,8 @@ def test_properties_window_change_name(qtbot, datadir):
     # Should really check that the contents are correct and changes works etc
     widget = SFGMainWindow()
     qtbot.addWidget(widget)
-    widget._load_from_file(datadir.join('twotapfir.py'))
-    sfg = widget._sfg_dict['twotapfir']
+    widget._load_from_file(datadir.join("twotapfir.py"))
+    sfg = widget._sfg_dict["twotapfir"]
     op = sfg.find_by_name("cmul2")[0]
     dragbutton = widget._drag_buttons[op]
     assert dragbutton.name == "cmul2"
diff --git a/test/unit/test_gui/twotapfir.py b/test/unit/test_gui/twotapfir.py
index 44300bb885c4d8ca60c28822fdfd48012a38ff10..120675aac2ec921a70f80ec78754b4d08c7a0daf 100644
--- a/test/unit/test_gui/twotapfir.py
+++ b/test/unit/test_gui/twotapfir.py
@@ -15,11 +15,11 @@ out1 = Output(name="")
 # Operations:
 t1 = Delay(initial_value=0, name="")
 cmul1 = ConstantMultiplication(
-    value=-0.5, name="cmul1", latency_offsets={'in0': None, 'out0': None}
+    value=-0.5, name="cmul1", latency_offsets={"in0": None, "out0": None}
 )
-add1 = Addition(name="add1", latency_offsets={'in0': None, 'in1': None, 'out0': None})
+add1 = Addition(name="add1", latency_offsets={"in0": None, "in1": None, "out0": None})
 cmul2 = ConstantMultiplication(
-    value=0.5, name="cmul2", latency_offsets={'in0': None, 'out0': None}
+    value=0.5, name="cmul2", latency_offsets={"in0": None, "out0": None}
 )
 
 # Signals:
@@ -30,15 +30,15 @@ Signal(source=in1.output(0), destination=cmul2.input(0))
 Signal(source=cmul1.output(0), destination=add1.input(0))
 Signal(source=add1.output(0), destination=out1.input(0))
 Signal(source=cmul2.output(0), destination=add1.input(1))
-twotapfir = SFG(inputs=[in1], outputs=[out1], name='twotapfir')
+twotapfir = SFG(inputs=[in1], outputs=[out1], name="twotapfir")
 
 # SFG Properties:
-prop = {'name': twotapfir}
+prop = {"name": twotapfir}
 positions = {
-    't1': (-209, 19),
-    'cmul1': (-95, 76),
-    'add1': (0, 95),
-    'cmul2': (-209, 114),
-    'out1': (76, 95),
-    'in1': (-323, 19),
+    "t1": (-209, 19),
+    "cmul1": (-95, 76),
+    "add1": (0, 95),
+    "cmul2": (-209, 114),
+    "out1": (76, 95),
+    "in1": (-323, 19),
 }
diff --git a/test/unit/test_list_schedulers.py b/test/unit/test_list_schedulers.py
index 076c2d0550b285504e8ab3cc534a87d7eeba5451..52d29a130c9dad0dff2c6c3ec2ea6784502640ed 100644
--- a/test/unit/test_list_schedulers.py
+++ b/test/unit/test_list_schedulers.py
@@ -1921,8 +1921,8 @@ def _validate_recreated_sfg_filter(sfg: SFG, schedule: Schedule) -> None:
     sim2 = Simulation(schedule.sfg, [Impulse()])
     sim2.run_for(1024)
 
-    spectrum_1 = abs(np.fft.fft(sim1.results['0']))
-    spectrum_2 = abs(np.fft.fft(sim2.results['0']))
+    spectrum_1 = abs(np.fft.fft(sim1.results["0"]))
+    spectrum_2 = abs(np.fft.fft(sim2.results["0"]))
     assert np.allclose(spectrum_1, spectrum_2)
 
 
diff --git a/test/unit/test_process.py b/test/unit/test_process.py
index 92a4eed176a4c5e523ee22a10d76228ea9e85eae..6b11e5e593348d76589911cd4bd2df949b9d2d05 100644
--- a/test/unit/test_process.py
+++ b/test/unit/test_process.py
@@ -14,7 +14,7 @@ def test_PlainMemoryVariable():
     assert mem.read_ports == [4, 5]
     assert repr(mem) == "PlainMemoryVariable(3, 0, {4: 1, 5: 2}, 'Var. 0')"
 
-    mem2 = PlainMemoryVariable(2, 0, {4: 2, 5: 3}, 'foo')
+    mem2 = PlainMemoryVariable(2, 0, {4: 2, 5: 3}, "foo")
     assert repr(mem2) == "PlainMemoryVariable(2, 0, {4: 2, 5: 3}, 'foo')"
 
     assert mem2 < mem
@@ -30,7 +30,7 @@ def test_MemoryVariables(secondorder_iir_schedule):
         "MemoryVariable\\(3, <b_asic.port.OutputPort object at 0x[a-fA-F0-9]+>,"
         " {<b_asic.port.InputPort object at 0x[a-fA-F0-9]+>: 4}, 'cmul0.0'\\)"
     )
-    mem_var = [m for m in mem_vars if m.name == 'cmul0.0'][0]
+    mem_var = [m for m in mem_vars if m.name == "cmul0.0"][0]
     assert pattern.match(repr(mem_var))
     assert mem_var.execution_time == 4
     assert mem_var.start_time == 3
@@ -44,7 +44,7 @@ def test_OperatorProcess_error(secondorder_iir_schedule):
 def test_MultiReadProcess():
     mv = PlainMemoryVariable(3, 0, {0: 1, 1: 2, 2: 5}, name="MV")
 
-    with pytest.raises(KeyError, match=r'Process MV: 3 not in life_times: \[1, 2, 5\]'):
+    with pytest.raises(KeyError, match=r"Process MV: 3 not in life_times: \[1, 2, 5\]"):
         mv._remove_life_time(3)
 
     assert mv.life_times == [1, 2, 5]
diff --git a/test/unit/test_resources.py b/test/unit/test_resources.py
index a8aafc3aeb7f356ed9b823a3bc889528e9dbf3b5..43d84d84da3efec0a680a3fec3c484a6d187f201 100644
--- a/test/unit/test_resources.py
+++ b/test/unit/test_resources.py
@@ -15,7 +15,7 @@ from b_asic.resources import ProcessCollection, _ForwardBackwardTable
 
 class TestProcessCollectionPlainMemoryVariable:
     @matplotlib.testing.decorators.image_comparison(
-        ['test_draw_process_collection.png']
+        ["test_draw_process_collection.png"]
     )
     def test_draw_process_collection(self, simple_collection):
         fig, ax = plt.subplots()
@@ -23,7 +23,7 @@ class TestProcessCollectionPlainMemoryVariable:
         return fig
 
     @matplotlib.testing.decorators.image_comparison(
-        ['test_draw_matrix_transposer_4.png']
+        ["test_draw_matrix_transposer_4.png"]
     )
     def test_draw_matrix_transposer_4(self):
         fig, ax = plt.subplots()
@@ -72,7 +72,7 @@ class TestProcessCollectionPlainMemoryVariable:
         assert len(split) == 2
 
     @matplotlib.testing.decorators.image_comparison(
-        ['test_left_edge_cell_assignment.png']
+        ["test_left_edge_cell_assignment.png"]
     )
     def test_left_edge_cell_assignment(self, simple_collection: ProcessCollection):
         fig, ax = plt.subplots(1, 2)
@@ -86,7 +86,7 @@ class TestProcessCollectionPlainMemoryVariable:
         collection = generate_matrix_transposer(4, min_lifetime=5)
         assignment_left_edge = collection._left_edge_assignment()
         assignment_graph_color = collection.split_on_execution_time(
-            heuristic="graph_color", coloring_strategy='saturation_largest_first'
+            heuristic="graph_color", coloring_strategy="saturation_largest_first"
         )
         assert len(assignment_left_edge) == 18
         assert len(assignment_graph_color) == 16
@@ -111,10 +111,10 @@ class TestProcessCollectionPlainMemoryVariable:
             assignment = collection.split_on_execution_time(heuristic="graph_color")
             collection.generate_memory_based_storage_vhdl(
                 filename=(
-                    'b_asic/codegen/testbench/'
-                    f'streaming_matrix_transposition_memory_{rows}x{cols}.vhdl'
+                    "b_asic/codegen/testbench/"
+                    f"streaming_matrix_transposition_memory_{rows}x{cols}.vhdl"
                 ),
-                entity_name=f'streaming_matrix_transposition_memory_{rows}x{cols}',
+                entity_name=f"streaming_matrix_transposition_memory_{rows}x{cols}",
                 assignment=assignment,
                 word_length=16,
                 adr_mux_size=mux_size,
@@ -127,10 +127,10 @@ class TestProcessCollectionPlainMemoryVariable:
                 rows, min_lifetime=0
             ).generate_register_based_storage_vhdl(
                 filename=(
-                    'b_asic/codegen/testbench/streaming_matrix_transposition_'
-                    f'register_{rows}x{rows}.vhdl'
+                    "b_asic/codegen/testbench/streaming_matrix_transposition_"
+                    f"register_{rows}x{rows}.vhdl"
                 ),
-                entity_name=f'streaming_matrix_transposition_register_{rows}x{rows}',
+                entity_name=f"streaming_matrix_transposition_register_{rows}x{rows}",
                 word_length=16,
             )
 
@@ -138,10 +138,10 @@ class TestProcessCollectionPlainMemoryVariable:
         collection = generate_matrix_transposer(rows=4, cols=8, min_lifetime=2)
         collection.generate_register_based_storage_vhdl(
             filename=(
-                'b_asic/codegen/testbench/streaming_matrix_transposition_register_'
-                '4x8.vhdl'
+                "b_asic/codegen/testbench/streaming_matrix_transposition_register_"
+                "4x8.vhdl"
             ),
-            entity_name='streaming_matrix_transposition_register_4x8',
+            entity_name="streaming_matrix_transposition_register_4x8",
             word_length=16,
         )
 
@@ -159,14 +159,14 @@ class TestProcessCollectionPlainMemoryVariable:
             cyclic=True,
         )
         t = _ForwardBackwardTable(collection)
-        process_names = {match.group(0) for match in re.finditer(r'PC[0-9]+', str(t))}
-        register_names = {match.group(0) for match in re.finditer(r'R[0-9]+', str(t))}
+        process_names = {match.group(0) for match in re.finditer(r"PC[0-9]+", str(t))}
+        register_names = {match.group(0) for match in re.finditer(r"R[0-9]+", str(t))}
         assert len(process_names) == 6  # 6 process in the collection
         assert len(register_names) == 5  # 5 register required
         for i, process in enumerate(sorted(process_names)):
-            assert process == f'PC{i}'
+            assert process == f"PC{i}"
         for i, register in enumerate(sorted(register_names)):
-            assert register == f'R{i}'
+            assert register == f"R{i}"
 
     def test_generate_random_interleaver(self):
         return
@@ -206,7 +206,7 @@ class TestProcessCollectionPlainMemoryVariable:
         assert new_proc not in simple_collection
 
     @matplotlib.testing.decorators.image_comparison(
-        ['test_max_min_lifetime_bar_plot.png']
+        ["test_max_min_lifetime_bar_plot.png"]
     )
     def test_max_min_lifetime_bar_plot(self):
         fig, ax = plt.subplots()
@@ -229,10 +229,10 @@ class TestProcessCollectionPlainMemoryVariable:
 
     def test_multiple_reads_exclusion_greaph(self):
         # Initial collection
-        p0 = PlainMemoryVariable(0, 0, {0: 3}, 'P0')
-        p1 = PlainMemoryVariable(1, 0, {0: 2}, 'P1')
-        p2 = PlainMemoryVariable(2, 0, {0: 2}, 'P2')
-        p3 = PlainMemoryVariable(3, 0, {0: 3}, 'P3')
+        p0 = PlainMemoryVariable(0, 0, {0: 3}, "P0")
+        p1 = PlainMemoryVariable(1, 0, {0: 2}, "P1")
+        p2 = PlainMemoryVariable(2, 0, {0: 2}, "P2")
+        p3 = PlainMemoryVariable(3, 0, {0: 3}, "P3")
         collection = ProcessCollection({p0, p1, p2, p3}, 5, cyclic=True)
         exclusion_graph = collection.create_exclusion_graph_from_ports(
             read_ports=1,
@@ -247,7 +247,7 @@ class TestProcessCollectionPlainMemoryVariable:
         assert exclusion_graph.degree(p3) == 2
 
         # Add multi-read process
-        p4 = PlainMemoryVariable(0, 0, {0: 1, 1: 2, 2: 3, 3: 4}, 'P4')
+        p4 = PlainMemoryVariable(0, 0, {0: 1, 1: 2, 2: 3, 3: 4}, "P4")
         collection.add_process(p4)
         exclusion_graph = collection.create_exclusion_graph_from_ports(
             read_ports=1,
diff --git a/test/unit/test_schedule.py b/test/unit/test_schedule.py
index ac767ff938fa819c0f6b2e3a07ca4aaed98a617f..b23c76a0865deb3e802698d77963d0792ce1ac29 100644
--- a/test/unit/test_schedule.py
+++ b/test/unit/test_schedule.py
@@ -279,20 +279,20 @@ class TestInit:
             "out0": 6,
         }
         laps = {
-            's8': 1,
-            's10': 2,
-            's15': 1,
-            's17': 2,
-            's0': 0,
-            's3': 0,
-            's12': 0,
-            's11': 0,
-            's14': 0,
-            's13': 0,
-            's6': 0,
-            's4': 0,
-            's5': 0,
-            's2': 0,
+            "s8": 1,
+            "s10": 2,
+            "s15": 1,
+            "s17": 2,
+            "s0": 0,
+            "s3": 0,
+            "s12": 0,
+            "s11": 0,
+            "s14": 0,
+            "s13": 0,
+            "s6": 0,
+            "s4": 0,
+            "s5": 0,
+            "s2": 0,
         }
 
         schedule = Schedule(sfg, start_times=start_times, laps=laps)
@@ -526,13 +526,13 @@ class TestRescheduling:
         )
 
         schedule = Schedule(precedence_sfg_delays, scheduler=ASAPScheduler())
-        assert schedule.backward_slack('cmul5') == 16
-        assert schedule.forward_slack('cmul5') == 0
-        schedule.move_operation_asap('cmul5')
-        assert schedule.start_time_of_operation('in0') == 0
-        assert schedule.laps['cmul5'] == 0
-        assert schedule.backward_slack('cmul5') == 0
-        assert schedule.forward_slack('cmul5') == 16
+        assert schedule.backward_slack("cmul5") == 16
+        assert schedule.forward_slack("cmul5") == 0
+        schedule.move_operation_asap("cmul5")
+        assert schedule.start_time_of_operation("in0") == 0
+        assert schedule.laps["cmul5"] == 0
+        assert schedule.backward_slack("cmul5") == 0
+        assert schedule.forward_slack("cmul5") == 16
 
     def test_move_input_asap_does_not_mess_up_laps(self, precedence_sfg_delays):
         precedence_sfg_delays.set_latency_of_type_name(Addition.type_name(), 1)
@@ -541,10 +541,10 @@ class TestRescheduling:
         )
 
         schedule = Schedule(precedence_sfg_delays, scheduler=ASAPScheduler())
-        old_laps = schedule.laps['in0']
-        schedule.move_operation_asap('in0')
-        assert schedule.start_time_of_operation('in0') == 0
-        assert schedule.laps['in0'] == old_laps
+        old_laps = schedule.laps["in0"]
+        schedule.move_operation_asap("in0")
+        assert schedule.start_time_of_operation("in0") == 0
+        assert schedule.laps["in0"] == old_laps
 
     def test_move_operation_acc(self):
         in0 = Input()
@@ -625,8 +625,8 @@ class TestRescheduling:
 
         fir_sfg = direct_form_fir(
             list(range(1, 10)),
-            mult_properties={'latency': 2, 'execution_time': 1},
-            add_properties={'latency': 2, 'execution_time': 1},
+            mult_properties={"latency": 2, "execution_time": 1},
+            add_properties={"latency": 2, "execution_time": 1},
         )
         schedule = Schedule(fir_sfg, scheduler=ASAPScheduler())
         sfg = schedule.sfg
@@ -778,7 +778,7 @@ class TestProcesses:
 
 class TestFigureGeneration:
     @matplotlib.testing.decorators.image_comparison(
-        ['test__get_figure_no_execution_times.png'], remove_text=True
+        ["test__get_figure_no_execution_times.png"], remove_text=True
     )
     def test__get_figure_no_execution_times(self, secondorder_iir_schedule):
         return secondorder_iir_schedule._get_figure()
@@ -864,16 +864,16 @@ class TestErrors:
             ConstantMultiplication.type_name(), 2
         )
         with pytest.raises(ValueError, match="Must provide laps when using 'provided'"):
-            Schedule(sfg_simple_filter, start_times={'in0': 0})
+            Schedule(sfg_simple_filter, start_times={"in0": 0})
 
 
 class TestGetUsedTypeNames:
     def test_secondorder_iir_schedule(self, secondorder_iir_schedule):
         assert secondorder_iir_schedule.get_used_type_names() == [
-            'add',
-            'cmul',
-            'in',
-            'out',
+            "add",
+            "cmul",
+            "in",
+            "out",
         ]
 
 
diff --git a/test/unit/test_scheduler_gui.py b/test/unit/test_scheduler_gui.py
index 0df333f98dbd125876fd08c077e7b125cbca4970..9d9b716f092a346ee240adc7ff4b3626f99f4981 100644
--- a/test/unit/test_scheduler_gui.py
+++ b/test/unit/test_scheduler_gui.py
@@ -26,3 +26,11 @@ def test_load_schedule(qtbot, sfg_simple_filter):
     schedule = Schedule(sfg_simple_filter, ASAPScheduler())
     widget.open(schedule)
     assert widget.statusbar.currentMessage() == "Schedule loaded successfully"
+
+
+def test_open_preferences_dialog(qtbot):
+    widget = ScheduleMainWindow()
+    qtbot.addWidget(widget)
+    widget.open_preferences_dialog()
+    widget._preferences_dialog.close()
+    widget.exit_app()
diff --git a/test/unit/test_sfg.py b/test/unit/test_sfg.py
index 50f0fb9d4db05bae683cdaf864d24f0684ac9d71..7cd54fc40a7e469605b8a95ebcdc5d3db822ed50 100644
--- a/test/unit/test_sfg.py
+++ b/test/unit/test_sfg.py
@@ -824,8 +824,8 @@ class TestConnectExternalSignalsToComponentsSoloComp:
         port goes to multiple operations
         """
         sfg1 = wdf_allpass(0.5)
-        sfg2 = sfg1.replace_operation(sfg1.find_by_id('sym2p0').to_sfg(), 'sym2p0')
-        sfg2.find_by_id('sfg0').connect_external_signals_to_components()
+        sfg2 = sfg1.replace_operation(sfg1.find_by_id("sym2p0").to_sfg(), "sym2p0")
+        sfg2.find_by_id("sfg0").connect_external_signals_to_components()
         test_sfg = SFG(sfg2.input_operations, sfg2.output_operations)
         assert sfg1.evaluate(1) == -0.5
         assert test_sfg.evaluate(1) == -0.5
@@ -1218,7 +1218,7 @@ class TestPrecedenceGraph:
         res = (
             'digraph {\n\trankdir=LR\n\tsubgraph cluster_0 {\n\t\tlabel=N0\n\t\t"in0.0"'
             ' [label=in0 height=0.1 shape=rectangle width=0.1]\n\t\t"t0.0" [label=t0'
-            ' height=0.1 shape=rectangle width=0.1]\n\t}\n\tsubgraph cluster_1'
+            " height=0.1 shape=rectangle width=0.1]\n\t}\n\tsubgraph cluster_1"
             ' {\n\t\tlabel=N1\n\t\t"cmul0.0" [label=cmul0 height=0.1 shape=rectangle'
             ' width=0.1]\n\t}\n\tsubgraph cluster_2 {\n\t\tlabel=N2\n\t\t"add0.0"'
             ' [label=add0 height=0.1 shape=rectangle width=0.1]\n\t}\n\t"in0.0" ->'
@@ -1471,7 +1471,7 @@ class TestSFGErrors:
             ValueError,
             match="Different number of input and output ports of operation with",
         ):
-            sfg.remove_operation('add0')
+            sfg.remove_operation("add0")
 
     def test_inputs_required_for_output(self):
         in1 = Input()
@@ -1499,7 +1499,7 @@ class TestInputDuplicationBug:
 
         out1.inputs[0].connect(add1)
 
-        twotapfir = SFG(inputs=[in1], outputs=[out1], name='twotapfir')
+        twotapfir = SFG(inputs=[in1], outputs=[out1], name="twotapfir")
 
         assert len([op for op in twotapfir.operations if isinstance(op, Input)]) == 1
 
@@ -1651,7 +1651,7 @@ class TestSwapIOOfOperation:
             assert ref_values == swap_values
 
     def test_single_accumulator(self, sfg_simple_accumulator: SFG):
-        self.do_test(sfg_simple_accumulator, 'add1')
+        self.do_test(sfg_simple_accumulator, "add1")
 
 
 class TestInsertComponentAfter:
@@ -1696,14 +1696,14 @@ class TestInsertComponentAfter:
         with pytest.raises(
             TypeError, match="Only operations with one input and one output"
         ):
-            sfg.insert_operation_after('constant4', SymmetricTwoportAdaptor(0.5))
+            sfg.insert_operation_after("constant4", SymmetricTwoportAdaptor(0.5))
 
     def test_insert_component_after_unknown_component_error(
         self, large_operation_tree_names
     ):
         sfg = SFG(outputs=[Output(large_operation_tree_names)])
         with pytest.raises(ValueError, match="Unknown component:"):
-            sfg.insert_operation_after('foo', SquareRoot())
+            sfg.insert_operation_after("foo", SquareRoot())
 
 
 class TestInsertComponentBefore:
@@ -1748,31 +1748,30 @@ class TestInsertComponentBefore:
         with pytest.raises(
             TypeError, match="Only operations with one input and one output"
         ):
-            sfg.insert_operation_before('add0', SymmetricTwoportAdaptor(0.5), port=0)
+            sfg.insert_operation_before("add0", SymmetricTwoportAdaptor(0.5), port=0)
 
     def test_insert_component_before_unknown_component_error(
         self, large_operation_tree_names
     ):
         sfg = SFG(outputs=[Output(large_operation_tree_names)])
         with pytest.raises(ValueError, match="Unknown component:"):
-            sfg.insert_operation_before('foo', SquareRoot())
+            sfg.insert_operation_before("foo", SquareRoot())
 
 
 class TestGetUsedTypeNames:
     def test_single_accumulator(self, sfg_simple_accumulator: SFG):
-        assert sfg_simple_accumulator.get_used_type_names() == ['add', 'in', 'out', 't']
+        assert sfg_simple_accumulator.get_used_type_names() == ["add", "in", "out", "t"]
 
     def test_sfg_nested(self, sfg_nested: SFG):
-        assert sfg_nested.get_used_type_names() == ['in', 'out', 'sfg']
+        assert sfg_nested.get_used_type_names() == ["in", "out", "sfg"]
 
     def test_large_operation_tree(self, large_operation_tree):
         sfg = SFG(outputs=[Output(large_operation_tree)])
-        assert sfg.get_used_type_names() == ['add', 'c', 'out']
+        assert sfg.get_used_type_names() == ["add", "c", "out"]
 
 
 class Test_Keep_GraphIDs:
     def test_single_accumulator(self):
-
         i = Input()
         d = Delay()
         o = Output(d)
@@ -1781,23 +1780,23 @@ class Test_Keep_GraphIDs:
         d.input(0).connect(a)
 
         sfg = SFG([i], [o])
-        sfg = sfg.insert_operation_before('t0', ConstantMultiplication(8))
-        sfg = sfg.insert_operation_after('t0', ConstantMultiplication(8))
-        sfg = sfg.insert_operation(ConstantMultiplication(8), 't0')
+        sfg = sfg.insert_operation_before("t0", ConstantMultiplication(8))
+        sfg = sfg.insert_operation_after("t0", ConstantMultiplication(8))
+        sfg = sfg.insert_operation(ConstantMultiplication(8), "t0")
         assert sfg.get_used_graph_ids() == {
-            'add0',
-            'cmul0',
-            'cmul1',
-            'cmul2',
-            'cmul3',
-            'in0',
-            'out0',
-            't0',
+            "add0",
+            "cmul0",
+            "cmul1",
+            "cmul2",
+            "cmul3",
+            "in0",
+            "out0",
+            "t0",
         }
 
     def test_large_operation_tree(self, large_operation_tree):
         sfg = SFG(outputs=[Output(large_operation_tree)])
-        assert sfg.get_used_type_names() == ['add', 'c', 'out']
+        assert sfg.get_used_type_names() == ["add", "c", "out"]
 
 
 class TestInsertDelays:
@@ -1816,11 +1815,11 @@ class TestInsertDelays:
 
         assert len(sfg.find_by_type_name(d_type_name)) == 3
 
-        sfg.find_by_id('out1').input(0).delay(3)
+        sfg.find_by_id("out1").input(0).delay(3)
         sfg = sfg()
 
         assert len(sfg.find_by_type_name(d_type_name)) == 6
-        source1 = sfg.find_by_id('out1').input(0).signals[0].source.operation
+        source1 = sfg.find_by_id("out1").input(0).signals[0].source.operation
         source2 = source1.input(0).signals[0].source.operation
         source3 = source2.input(0).signals[0].source.operation
         source4 = source3.input(0).signals[0].source.operation
@@ -1859,7 +1858,7 @@ class TestResourceLowerBound:
             precedence_sfg_delays.resource_lower_bound("cmul", -1)
 
     def test_accumulator(self, sfg_simple_accumulator):
-        sfg_simple_accumulator.set_latency_of_type_name('add', 2)
+        sfg_simple_accumulator.set_latency_of_type_name("add", 2)
 
         with pytest.raises(
             ValueError,
@@ -1889,7 +1888,7 @@ class TestResourceLowerBound:
 
 class TestIterationPeriodBound:
     def test_accumulator(self, sfg_simple_accumulator):
-        sfg_simple_accumulator.set_latency_of_type_name('add', 2)
+        sfg_simple_accumulator.set_latency_of_type_name("add", 2)
         assert sfg_simple_accumulator.iteration_period_bound() == 2
 
     def test_no_latency(self, sfg_simple_accumulator):
@@ -1900,8 +1899,8 @@ class TestIterationPeriodBound:
             sfg_simple_accumulator.iteration_period_bound()
 
     def test_secondorder_iir(self, precedence_sfg_delays):
-        precedence_sfg_delays.set_latency_of_type_name('add', 2)
-        precedence_sfg_delays.set_latency_of_type_name('cmul', 3)
+        precedence_sfg_delays.set_latency_of_type_name("add", 2)
+        precedence_sfg_delays.set_latency_of_type_name("cmul", 3)
         assert precedence_sfg_delays.iteration_period_bound() == 10
 
     def test_fractional_value(self):
@@ -1956,25 +1955,25 @@ class TestLoops:
 class TestStateSpace:
     def test_accumulator(self, sfg_simple_accumulator):
         ss = sfg_simple_accumulator.state_space_representation()
-        assert ss[0] == ['v0', 'y0']
+        assert ss[0] == ["v0", "y0"]
         assert (ss[1] == np.array([[1.0, 1.0], [0.0, 1.0]])).all()
-        assert ss[2] == ['v0', 'x0']
+        assert ss[2] == ["v0", "x0"]
 
     def test_secondorder_iir(self, precedence_sfg_delays):
         ss = precedence_sfg_delays.state_space_representation()
-        assert ss[0] == ['v0', 'v1', 'y0']
+        assert ss[0] == ["v0", "v1", "y0"]
 
         mat = np.array([[3.0, 2.0, 5.0], [1.0, 0.0, 0.0], [4.0, 6.0, 35.0]])
         assert (ss[1] == mat).all()
-        assert ss[2] == ['v0', 'v1', 'x0']
+        assert ss[2] == ["v0", "v1", "x0"]
 
     # @pytest.mark.xfail()
     def test_sfg_two_inputs_two_outputs(self, sfg_two_inputs_two_outputs):
         ss = sfg_two_inputs_two_outputs.state_space_representation()
 
-        assert ss[0] == ['y0', 'y1']
+        assert ss[0] == ["y0", "y1"]
         assert (ss[1] == np.array([[1.0, 1.0], [1.0, 2.0]])).all()
-        assert ss[2] == ['x0', 'x1']
+        assert ss[2] == ["x0", "x1"]
 
     def test_sfg_two_inputs_two_outputs_independent(
         self, sfg_two_inputs_two_outputs_independent
@@ -1982,9 +1981,9 @@ class TestStateSpace:
         # assert sfg_two_inputs_two_outputs_independent.state_space_representation() == 1
         ss = sfg_two_inputs_two_outputs_independent.state_space_representation()
 
-        assert ss[0] == ['y0', 'y1']
+        assert ss[0] == ["y0", "y1"]
         assert (ss[1] == np.array([[1.0, 0.0], [0.0, 4.0]])).all()
-        assert ss[2] == ['x0', 'x1']
+        assert ss[2] == ["x0", "x1"]
 
     def test_sfg_two_inputs_two_outputs_independent_with_cmul(
         self, sfg_two_inputs_two_outputs_independent_with_cmul
@@ -1993,6 +1992,6 @@ class TestStateSpace:
             sfg_two_inputs_two_outputs_independent_with_cmul.state_space_representation()
         )
 
-        assert ss[0] == ['y0', 'y1']
+        assert ss[0] == ["y0", "y1"]
         assert (ss[1] == np.array([[20.0, 0.0], [0.0, 8.0]])).all()
-        assert ss[2] == ['x0', 'x1']
+        assert ss[2] == ["x0", "x1"]
diff --git a/test/unit/test_sfg_generators.py b/test/unit/test_sfg_generators.py
index 773979719254f910801a10767c9dbc4ca8c8cd84..a51224bd121887976bc3879b4316c757ee999036 100644
--- a/test/unit/test_sfg_generators.py
+++ b/test/unit/test_sfg_generators.py
@@ -124,20 +124,20 @@ def test_direct_form_fir():
     sim = Simulation(sfg, [Impulse()])
     sim.run_for(4)
     impulse_response.append(0.0)
-    assert np.allclose(sim.results['0'], impulse_response)
+    assert np.allclose(sim.results["0"], impulse_response)
 
     impulse_response = [0.3, 0.4, 0.5, 0.6, 0.3]
     sfg = direct_form_fir(
         (0.3, 0.4, 0.5, 0.6, 0.3),
-        mult_properties={'latency': 2, 'execution_time': 1},
-        add_properties={'latency': 1, 'execution_time': 1},
+        mult_properties={"latency": 2, "execution_time": 1},
+        add_properties={"latency": 1, "execution_time": 1},
     )
     assert sfg.critical_path_time() == 6
 
     sim = Simulation(sfg, [Impulse()])
     sim.run_for(6)
     impulse_response.append(0.0)
-    assert np.allclose(sim.results['0'], impulse_response)
+    assert np.allclose(sim.results["0"], impulse_response)
 
     impulse_response = [0.3]
     sfg = direct_form_fir(impulse_response)
@@ -189,20 +189,20 @@ def test_transposed_direct_form_fir():
     sim = Simulation(sfg, [Impulse()])
     sim.run_for(4)
     impulse_response.append(0.0)
-    assert np.allclose(sim.results['0'], impulse_response)
+    assert np.allclose(sim.results["0"], impulse_response)
 
     impulse_response = [0.3, 0.4, 0.5, 0.6, 0.3]
     sfg = transposed_direct_form_fir(
         (0.3, 0.4, 0.5, 0.6, 0.3),
-        mult_properties={'latency': 2, 'execution_time': 1},
-        add_properties={'latency': 1, 'execution_time': 1},
+        mult_properties={"latency": 2, "execution_time": 1},
+        add_properties={"latency": 1, "execution_time": 1},
     )
     assert sfg.critical_path_time() == 3
 
     sim = Simulation(sfg, [Impulse()])
     sim.run_for(6)
     impulse_response.append(0.0)
-    assert np.allclose(sim.results['0'], impulse_response)
+    assert np.allclose(sim.results["0"], impulse_response)
 
     impulse_response = [0.3]
     sfg = transposed_direct_form_fir(impulse_response)
@@ -318,7 +318,7 @@ class TestDirectFormIIRType1:
         sim = Simulation(sfg, [ZeroPad(input_signal)])
         sim.run_for(100)
 
-        assert np.allclose(sim.results['0'], reference_filter_output)
+        assert np.allclose(sim.results["0"], reference_filter_output)
 
     def test_random_input_compare_with_scipy_butterworth_filter(self):
         N = 10
@@ -334,13 +334,13 @@ class TestDirectFormIIRType1:
         sim = Simulation(sfg, [ZeroPad(input_signal)])
         sim.run_for(100)
 
-        assert np.allclose(sim.results['0'], reference_filter_output)
+        assert np.allclose(sim.results["0"], reference_filter_output)
 
     def test_random_input_compare_with_scipy_elliptic_filter(self):
         N = 2
         Wc = 0.3
 
-        b, a = signal.ellip(N, 0.1, 60, Wc, btype='low', analog=False)
+        b, a = signal.ellip(N, 0.1, 60, Wc, btype="low", analog=False)
         b, a = signal.butter(N, Wc, btype="lowpass", output="ba")
 
         input_signal = np.random.randn(100)
@@ -351,7 +351,7 @@ class TestDirectFormIIRType1:
         sim = Simulation(sfg, [ZeroPad(input_signal)])
         sim.run_for(100)
 
-        assert np.allclose(sim.results['0'], reference_filter_output)
+        assert np.allclose(sim.results["0"], reference_filter_output)
 
     def test_add_and_mult_properties(self):
         N = 17
@@ -438,7 +438,7 @@ class TestDirectFormIIRType2:
         sim = Simulation(sfg, [ZeroPad(input_signal)])
         sim.run_for(100)
 
-        assert np.allclose(sim.results['0'], reference_filter_output)
+        assert np.allclose(sim.results["0"], reference_filter_output)
 
     def test_random_input_compare_with_scipy_butterworth_filter(self):
         N = 10
@@ -454,13 +454,13 @@ class TestDirectFormIIRType2:
         sim = Simulation(sfg, [ZeroPad(input_signal)])
         sim.run_for(100)
 
-        assert np.allclose(sim.results['0'], reference_filter_output)
+        assert np.allclose(sim.results["0"], reference_filter_output)
 
     def test_random_input_compare_with_scipy_elliptic_filter(self):
         N = 2
         Wc = 0.3
 
-        b, a = signal.ellip(N, 0.1, 60, Wc, btype='low', analog=False)
+        b, a = signal.ellip(N, 0.1, 60, Wc, btype="low", analog=False)
         b, a = signal.butter(N, Wc, btype="lowpass", output="ba")
 
         input_signal = np.random.randn(100)
@@ -471,7 +471,7 @@ class TestDirectFormIIRType2:
         sim = Simulation(sfg, [ZeroPad(input_signal)])
         sim.run_for(100)
 
-        assert np.allclose(sim.results['0'], reference_filter_output)
+        assert np.allclose(sim.results["0"], reference_filter_output)
 
     def test_add_and_mult_properties(self):
         N = 17
diff --git a/test/unit/test_signal_generator.py b/test/unit/test_signal_generator.py
index 65266a25ae4ab9d7a989eeba2207dd877e5fcbf5..719bb714247d9c88b133e98fae0d2bb50e6c3506 100644
--- a/test/unit/test_signal_generator.py
+++ b/test/unit/test_signal_generator.py
@@ -275,17 +275,17 @@ def test_division():
 
 
 def test_fromfile(datadir):
-    g = FromFile(datadir.join('input.csv'))
+    g = FromFile(datadir.join("input.csv"))
     assert g(-1) == 0.0
     assert g(0) == 0
     assert g(1) == 1
     assert g(2) == 0
 
     with pytest.raises(FileNotFoundError, match="tset.py not found"):
-        g = FromFile(datadir.join('tset.py'))
+        g = FromFile(datadir.join("tset.py"))
 
     with pytest.raises(ValueError, match="could not convert string"):
-        g = FromFile(datadir.join('bad.csv'))
+        g = FromFile(datadir.join("bad.csv"))
 
 
 def test_upsample():
diff --git a/test/unit/test_simulation_gui.py b/test/unit/test_simulation_gui.py
index 177fb11fb15a09c3e4ed6da58416767881f8c817..4779ecf15906e5fc614d7666cbaf64101684a7a3 100644
--- a/test/unit/test_simulation_gui.py
+++ b/test/unit/test_simulation_gui.py
@@ -15,12 +15,12 @@ def test_start(qtbot):
 
 def test_start_with_data(qtbot):
     sim_res = {
-        '0': [0.5, 0.5, 0, 0],
-        'add1': [0.5, 0.5, 0, 0],
-        'cmul1': [0, 0.5, 0, 0],
-        'cmul2': [0.5, 0, 0, 0],
-        'in1': [1, 0, 0, 0],
-        't1': [0, 1, 0, 0],
+        "0": [0.5, 0.5, 0, 0],
+        "add1": [0.5, 0.5, 0, 0],
+        "cmul1": [0, 0.5, 0, 0],
+        "cmul2": [0.5, 0, 0, 0],
+        "in1": [1, 0, 0, 0],
+        "t1": [0, 1, 0, 0],
     }
     widget = PlotWindow(sim_res)
     qtbot.addWidget(widget)
@@ -32,12 +32,12 @@ def test_start_with_data(qtbot):
 @pytest.mark.filterwarnings("ignore:No artists with labels found to put in legend")
 def test_click_buttons(qtbot):
     sim_res = {
-        '0': [0.5, 0.5, 0, 0],
-        'add1': [0.5, 0.5, 0, 0],
-        'cmul1': [0, 0.5, 0, 0],
-        'cmul2': [0.5, 0, 0, 0],
-        'in1': [1, 0, 0, 0],
-        't1': [0, 1, 0, 0],
+        "0": [0.5, 0.5, 0, 0],
+        "add1": [0.5, 0.5, 0, 0],
+        "cmul1": [0, 0.5, 0, 0],
+        "cmul2": [0.5, 0, 0, 0],
+        "in1": [1, 0, 0, 0],
+        "t1": [0, 1, 0, 0],
     }
     widget = PlotWindow(sim_res)
     qtbot.addWidget(widget)