diff --git a/src/simudator/core/processor.py b/src/simudator/core/processor.py
index 0fd905e24236fe9ce6533d4a001b1839f30199b9..264ff98777b6e8fff486c5076246d4ba784309e1 100644
--- a/src/simudator/core/processor.py
+++ b/src/simudator/core/processor.py
@@ -116,34 +116,54 @@ class Processor:
 
         Each entry in the list is a tuple of a instruction with its column and
         row position for the pipeline diagram.
+
+        Returns
+        -------
+        list[tuple[str, int, int]]
+            A list of instructions represented as tuples. Each tuple contains
+            the instruction and its position in the pipeline.
         """
         raise NotImplementedError
 
     def get_pipeline_dimensions(self) -> tuple[int, int]:
-        """Return a tuple on the form (x, y) for the processors preferred
-        pipeline display size.
+        """Return the dimensions of the pipeline of the processor.
 
-        (x, y) represents the number of columns respective rows the pipeline
-        should have.
+        Returns
+        -------
+        width : int
+            The width of the pipeline (number of cycles to display at a time).
+        depth : int
+           Depth of the pipeline.
         """
         raise NotImplementedError
 
     def get_asm_instruction(self) -> str:
-        """
-        Return a string containing the 'code' for the current assembly
+        """Return a string containing the 'code' for the current assembly
         instruction.
 
         What 'code' refers to is up to each processor to define. It could be a
         memory address, an instruction label or something else.
+
+        Returns
+        -------
+        str
+            The current assembly instruction.
         """
         raise NotImplementedError
 
     def run_asm_instruction(self, num_instructions=1) -> None:
-        """
-        Runs assembler instructions on the processors 'num_instructions' times.
+        """Run a number of assembly instructions.
 
-        Default argument is one, but it is possible to specify any number of
-        instructions. This should be implemented per processor and thus we
+        Defaults to running 1 instruction unless some other number is provided.
+
+        Parameters
+        ----------
+        num_instructions : int
+            Number of assembly instructions to perform.
+
+        Notes
+        -----
+        This should be implemented per processor and thus we
         raise NotImplementedError.
         """
 
@@ -151,14 +171,15 @@ class Processor:
 
     def undo_asm_instruction(self, num_instructions=1) -> None:
         """
-        Undos 'num_instructions' numbers of assembler instructions on the CPU.
+        Undo a number of assembly instructions on the CPU.
 
         Default argument is one, but it is possible to specify any number of
-        instructions. Undo assembler instruction assumes the CPU is always at
-        the end of the list 'self.assembly_cycles'.
+        instructions.
 
-        Undos asm instructions by finding the corresponding clock cycle before
-        said number of asm instructions started and loading that clock cycle.
+        Parameters
+        ----------
+        num_instructions : int
+            Number of assembly instructions to undo.
         """
 
         current_clock_cycle = self.clock
@@ -196,7 +217,12 @@ class Processor:
 
     def should_halt(self) -> bool:
         """
-        Return True when the processor should halt, otherwise False.
+        Return whether the processor should halt this clock cycle or not.
+
+        Returns
+        -------
+        bool
+            ``True`` if the processor should halt, ``False`` otherwise.
 
         Notes
         ----
@@ -208,16 +234,13 @@ class Processor:
         return False
 
     def stop(self) -> None:
-        """
-        Signal to stop the execution of the processor until the processor is
+        """Signal to stop the execution of the processor until the processor is
         instructed to run continuously or do some ticks again.
         """
         self.is_stopped = True
 
     def unstop(self) -> None:
-        """
-        Reset the stop execution signal.
-        """
+        """Reset the stop execution signal."""
         self.is_stopped = False
 
     def is_new_instruction(self) -> bool:
@@ -267,45 +290,83 @@ class Processor:
             module.update_logic()
 
     def add_modules_to_update(self, module: Module) -> None:
-        """
-        Queues module to be updated at the end of clock cycle.
+        """Queue a module to be updated at the end of clock cycle.
+
+        Parameters
+        ----------
+        module : Module
+            Module to queue for update.
+
+        See Also
+        --------
+        Module.update_logic :
+            Method for updating a module.
         """
         if module not in self.update_queue:
             self.update_queue.append(module)
 
     def add_module(self, module: Module) -> None:
-        """
-        Add module into the processor.
+        """Add module to be simulated by the processor.
+
+        Parameters
+        ----------
+        module : Module
+            Module to add.
         """
         self.modules[module.name] = module
 
     def get_module(self, name: str) -> Module:
-        """
-        Get module with specific name.
+        """Get module with specific name.
+
+        Parameters
+        ----------
+        name : str
+            Name of the module to get.
+
+        Returns
+        -------
+        Module
+            The module with the specified name.
         """
         return self.modules[name]
 
     def get_modules(self) -> list[Module]:
-        """
-        Get list of all modules.
+        """Get list of all modules.
+
+        Returns
+        -------
+        list[Module]
+            List of all modules in the processor.
         """
         return list(self.modules.values())
 
     def add_signals(self, signals: list[Signal]) -> None:
-        """
-        Add signals into the processor.
+        """Add signals to the processor.
+
+        Parameters
+        ----------
+        list[Signal]
+            List of signals to add for simulation.
         """
         self.signals += signals
 
     def get_clock(self) -> int:
-        """
-        Get current clockcycle.
+        """Get the current clockcycle number.
+
+        Returns
+        -------
+        int
+            Current clock cycle number of the processor.
         """
         return self.clock
 
     def set_clock(self, value: int) -> None:
-        """
-        Set current clockcycle.
+        """Set current clockcycle number.
+
+        Parameters
+        ----------
+        value : int
+            Cycle number to set the clock to.
         """
         self.clock = value
 
@@ -327,10 +388,15 @@ class Processor:
         self.module_history.append(module_states)
 
     def load_cycle(self, cycle: int) -> None:
-        """
-        Load the state of all modules as they were at the specified clock cycle.
+        """Load the state of all modules as they were at the specified clock
+        cycle.
 
         This does not erase the history of states for the later cycles.
+
+        Parameters
+        ----------
+        cycle : int
+            Number of the cycle to load.
         """
 
         cycle_index = cycle - self.removed_cycles
@@ -355,13 +421,13 @@ class Processor:
             module = self.update_queue.pop(0)
             module.update_logic()
 
-    def load_state_from_file(self, file_path) -> None:
-        """
-        Loads states for modules from a file.
+    def load_state_from_file(self, file_path: str) -> None:
+        """Load states for modules from a file.
 
-        Appends the lines from the loaded file to a long string. This string
-        is given to each module in the function 'load_from_str'. Each module
-        will thus load itself.
+        Parameters
+        ----------
+        file_path : str
+            Path to the file containing the processor state to load.
         """
         self.reset()
 
@@ -374,6 +440,9 @@ class Processor:
         else:
             raise ValueError  # Else raise error
 
+        # Appends the lines from the loaded file to a long string. This string
+        # is given to each module in the function 'load_from_str'. Each module
+        # will thus load itself.
         module_name = None
         module_str = ""
 
@@ -405,10 +474,14 @@ class Processor:
             module.load_from_str(module_str)
 
     def save_state_to_file(self, file_path: str) -> None:
-        """
-        Saves the current state of the cpu to a given file.
+        """Save the current state of the cpu to file.
 
         Will overwrite the given file.
+
+        Parameters
+        ----------
+        file_path : str
+            Path to the file to write to.
         """
         file = open(file_path, "w")
         file.write("")
@@ -419,13 +492,21 @@ class Processor:
             module.save_state_to_file(file_path)
 
     def pretty_print(self) -> None:
+        """Print the processor state in a readable and compact format."""
         self.pretty_print_verbose(self.ignore_keys)
 
     def pretty_print_verbose(self, ignore_keys=None) -> None:
         """
-        Prints the most relevant information about each module
-        compact and pretty. Fields of modules can be ignored with the
-        optional argument 'ignore_keys'.
+        Print the most relevant information about each module in a compact and
+        readable format.
+
+        State variables of modules can be ignored with the optional argument.
+
+        Parameters
+        ----------
+        ignore_keys : list[str]
+            List of names of state variables of modules to exclude when
+            printing module states.
         """
         # TODO: ignore keys per module and not for all modules
         memory_modules = []
@@ -455,7 +536,8 @@ class Processor:
         module_to_line_length = {}
         # get the longest line length for all other_modules
         for module in other_modules:
-            line_len = module.get_longest_line_len(ignore_keys) + 3  # +3 for padding
+            # +3 for padding
+            line_len = module.get_longest_line_len(ignore_keys) + 3
 
             # TODO: what to do if two or more modules has the same name
             module_to_line_length[module] = line_len
@@ -464,7 +546,7 @@ class Processor:
 
         print(Processor.LINE_SEPARATOR * Processor.MAX_LINE_LEN)
 
-        # print each group seperate
+        # print each group separate
         for group in groups:
             self.pretty_print_names(group)
 
@@ -493,8 +575,7 @@ class Processor:
                             real_keys[row] + ": " + str(module_state[real_keys[row]])
                         )
 
-                    # padd the string so each string has the same
-                    # length
+                    # pad the string so each string has the same length
                     total_padding += module_to_line_length[module]
                     string = string.ljust(total_padding)
                     # replace last to chars with a separator and padding
@@ -506,7 +587,14 @@ class Processor:
         for memory_module in memory_modules:
             self.pretty_print_memory(memory_module)
 
-    def pretty_print_memory(self, module: Module) -> None:
+    def pretty_print_memory(self, module: Memory) -> None:
+        """Print a memory module in a compact and readable format.
+
+        Parameters
+        ----------
+        module : Memory
+            Memory module to print the state of.
+        """
         print(module.name)
         print(Processor.LINE_SEPARATOR * Processor.MAX_LINE_LEN)
 
@@ -515,11 +603,11 @@ class Processor:
         string = ""
         last_mem_len = module.get_largest_mem_adr()
 
-        for i, value in enumerate(module.memory):
+        for i, value in enumerate(module.get_state()["memory"]):
 
-            # create a new string containg the adress and the value
-            # of the memory adress formattet to fit with the largest
-            # adress and largest memory value
+            # create a new string containing the address and the value
+            # of the memory address formatted to fit with the largest
+            # address and largest memory value
             new_row = (str(i).ljust(last_mem_len) + ": " + str(value)).ljust(
                 longest_line_len + last_mem_len + 3
             ) + "|"
@@ -542,11 +630,16 @@ class Processor:
 
     def pretty_print_names(self, module_to_line_length: dict[Module, int]) -> None:
         """
-        Prints the name of the modules in one row, but pretty.
+        Print the name of the modules in one row with formatting.
 
+        Adds spacing between the names so that the longest state variable of
+        each module has space to be printed below the name.
 
-        Adds spacing between the names so that the modules
-        longest field will have space to be printed below.
+        Parameters
+        ----------
+        module_to_line_length : dict[Module, int]
+            Mapping from module to length of the longest state variable of
+            the module.
         """
         name_string = ""
         total_len = 0
@@ -561,9 +654,20 @@ class Processor:
     def group_pp_modules(
         self, module_to_line_length: dict[Module, int]
     ) -> list[dict[Module, int]]:
-        """
-        Groups the modules to be pretty printed into groups with a
+        """Group the modules to be pretty printed into groups with a
         total line length lower than 'Processor.MAX_LINE_LEN'.
+
+        Parameters
+        ----------
+        module_to_line_length : dict[Module, int]
+            Mapping from module to length of the longest state variable of
+            the module (takes as the line length).
+
+        Returns
+        -------
+        list[dict[Module, int]]
+            List of mappings from module to line length, each mapping
+            representing a group of modules for printing.
         """
 
         groups = [{}]
@@ -586,8 +690,21 @@ class Processor:
 
     def fields_to_list(self, module: Module, ignore_keys=[]) -> list[str]:
         """
-        Return a list containing all the keys for a module except the name.
-        Optinal argument to ignore specific keys.
+        Return a list containing all state variable names, excluding module
+        name, for a module.
+        Optional argument to ignore specific state variables.
+
+        Parameters
+        ----------
+        module : Module
+            Module to get state variable names from.
+        ignore_keys : list[str]
+            List of state variable names to exclude.
+
+        Returns
+        -------
+        list[str]
+            List of state variable names, excluding module name, of a module.
         """
         return [
             key
@@ -595,11 +712,24 @@ class Processor:
             if key != "name" and key not in ignore_keys
         ]
 
-    def get_most_fields(self, modules: dict[Module,int], ignore_keys=[]) -> int:
-        """
-        Return the most number of a fields a module has.
+    def get_most_fields(self, modules: dict[Module, int], ignore_keys=[]) -> int:
+        """Get the maximum number of state variables among all modules.
 
         Can optionally ignore keys.
+
+        Parameters
+        ----------
+        modules : dict[Module, int]
+            Mapping from module to length of the longest state variable of
+            the module. Used as a list of modules to take the maximum over.
+        ignore_keys : list[str]
+            State variables to exclude.
+
+        Returns
+        -------
+        int
+            The maximum of the number of module state variables among all
+            modules of the processor.
         """
         fields = 0
         for module in modules:
@@ -612,6 +742,24 @@ class Processor:
     def add_state_breakpoint(
         self, module_name: str, state_name: str, value: Any
     ) -> None:
+        """Add a module state breakpoint to the processor.
+
+        Parameters
+        ----------
+            module_name : str
+                Name of the module for which a breakpoint will be added.
+            state_name : str
+                Name of the state variable of the module to put a breakpoint
+                on.
+            value : Any
+                Value of the state variable that triggers the breakpoint.
+
+        Raises
+        ------
+        ValueError
+            If the module does not exist or if the state variable does not
+            exist in the module.
+        """
 
         if module_name not in self.modules:
             raise ValueError(f"No module named {module_name}")
@@ -626,19 +774,43 @@ class Processor:
         self.breakpoint_id_counter += 1
 
     def remove_breakpoint(self, id: int) -> bool:
+        """Remove a specific breakpoint.
+
+        Parameters
+        ----------
+        id : int
+            ID of the breakpoint to be removed.
+        """
         if id in self.breakpoints:
             del self.breakpoints[id]
             return True
         return False
 
     def print_breakpoints(self) -> None:
+        """Print all breakpoints of the processor."""
         if not self.breakpoints:
             print("There are no breakpoints.")
         else:
             for bp_id, bp in self.breakpoints.items():
                 print(f"BP {bp_id}: {bp}")
 
-    def add_memory_breakpoint(self, module_name: str, adress: int, value: Any) -> None:
+    def add_memory_breakpoint(self, module_name: str, address: int, value: Any) -> None:
+        """Add a breakpoint for a memory module.
+
+        Parameters
+        ----------
+        module_name : str
+            Name of the memory module for which a breakpoint will be added.
+        address : int
+            Address of the memory module to break at.
+        value : Any
+            Value of the address that triggers the breakpoint.
+
+        Raises
+        ------
+        ValueError
+            If the module does not exist or is not a memory.
+        """
 
         if module_name not in self.modules:
             raise ValueError(f"No module named {module_name}")
@@ -647,14 +819,42 @@ class Processor:
         if "memory" not in module.get_state():
             raise ValueError(f"Module {module_name} is not a memory.")
 
-        bp = MemoryBreakpoint(module, adress, value)
+        bp = MemoryBreakpoint(module, address, value)
         self.breakpoints[self.breakpoint_id_counter] = bp
         self.breakpoint_id_counter += 1
 
     def get_breakpoint_lambdas(self) -> list[str]:
+        """Get all functions available for lambda breakpoints.
+
+        Returns
+        -------
+        list[str]
+            List of names of all functions of the processor that are available
+            for adding lambda breakpoints.
+        """
+
         return list(self.lambdas.keys())
 
     def add_lambda_breakpoint(self, lambda_name: str, **kwargs) -> None:
+        """Add a lambda breakpoint to the processor.
+
+        Module names used in the keyword arguments are substituted by the
+        actual modules before being passed on to the lambda breakpoint
+        function.
+
+        Parameters
+        ----------
+        lambda_name : str
+            Name of the lambda breakpoint function to be used by the
+            breakpoint.
+        **kwargs
+            Arguments to pass to the breakpoint function.
+
+        Raises
+        ------
+        ValueError
+            If the  lambda breakpoint function does not exist.
+        """
         # Substitute any module names for the module instances
         # This is to be able to externally create general lambda breakpoints
         # that can take any values as arguments while also having a way to take
@@ -673,4 +873,13 @@ class Processor:
         self.breakpoint_id_counter += 1
 
     def set_enabled_breakpoint(self, bp_id: int, is_enabled: bool) -> None:
+        """Toggle a breakpoint to enabled or disabled.
+
+        Parameters
+        ----------
+        bp_id : int
+            ID of the breakpoint to toggle.
+        is_enabled : bool
+            ``True`` to enable, ``False`` to disable the breakpoint.
+        """
         self.breakpoints[bp_id].set_enabled(is_enabled)