From ce58bd0eb72e307f80cc5cecd1f8829a3218b24b Mon Sep 17 00:00:00 2001
From: Oscar Gustafsson <oscar.gustafsson@gmail.com>
Date: Fri, 25 Aug 2023 17:27:48 +0200
Subject: [PATCH] Documentation fixes

---
 b_asic/GUI/arrow.py                   | 19 ++++++++++++--
 b_asic/GUI/precedence_graph_window.py |  2 ++
 b_asic/GUI/simulate_sfg_window.py     |  2 ++
 b_asic/codegen/vhdl/architecture.py   |  9 ++++---
 b_asic/codegen/vhdl/common.py         | 38 +++++++++++++++------------
 b_asic/graph_component.py             | 11 +++++---
 b_asic/operation.py                   |  3 +--
 b_asic/quantization.py                | 24 +++++------------
 b_asic/resources.py                   | 16 ++++++-----
 b_asic/schedule.py                    | 14 +++++-----
 b_asic/signal_flow_graph.py           | 37 +++++++++++++-------------
 11 files changed, 97 insertions(+), 78 deletions(-)

diff --git a/b_asic/GUI/arrow.py b/b_asic/GUI/arrow.py
index 2fa24b15..8cb05fec 100644
--- a/b_asic/GUI/arrow.py
+++ b/b_asic/GUI/arrow.py
@@ -106,11 +106,26 @@ class Arrow(QGraphicsPathItem):
         return cast("InputPort", self._destination_port_button.port)
 
     def set_source_operation(self, source: "Operation"):
-        """Set operation of the source DragButton."""
+        """
+        Set operation of the source DragButton.
+
+        Parameters
+        ----------
+        source : :class:`~b_asic.operation.Operation`
+            The operation to use as source.
+        """
         self._source_port_button._operation_button.operation = source
 
     def set_destination_operation(self, destination: "Operation"):
-        """Set operation of the destination DragButton."""
+        """
+        Set operation of the destination DragButton.
+
+        Parameters
+        ----------
+        destination : :class:`~b_asic.operation.Operation`
+            The operation to use as destination.
+
+        """
         self._destination_port_button._operation_button.operation = destination
 
     def remove(self):
diff --git a/b_asic/GUI/precedence_graph_window.py b/b_asic/GUI/precedence_graph_window.py
index 82f5ca5a..090ca3d1 100644
--- a/b_asic/GUI/precedence_graph_window.py
+++ b/b_asic/GUI/precedence_graph_window.py
@@ -13,6 +13,8 @@ from qtpy.QtWidgets import (
 
 
 class PrecedenceGraphWindow(QDialog):
+    """Precedence graph window."""
+
     pc = Signal()
 
     def __init__(self, window):
diff --git a/b_asic/GUI/simulate_sfg_window.py b/b_asic/GUI/simulate_sfg_window.py
index 671e9fe6..2e27170e 100644
--- a/b_asic/GUI/simulate_sfg_window.py
+++ b/b_asic/GUI/simulate_sfg_window.py
@@ -25,6 +25,8 @@ if TYPE_CHECKING:
 
 
 class SimulateSFGWindow(QDialog):
+    """Simulation window."""
+
     simulate = Signal()
 
     def __init__(self, window):
diff --git a/b_asic/codegen/vhdl/architecture.py b/b_asic/codegen/vhdl/architecture.py
index bc8d8227..67a0d042 100644
--- a/b_asic/codegen/vhdl/architecture.py
+++ b/b_asic/codegen/vhdl/architecture.py
@@ -33,6 +33,8 @@ def memory_based_storage(
         corresponds to the cell to assign all MemoryVariables in corresponding process
         collection.
         If unset, each MemoryVariable will be assigned to a unique cell.
+    entity_name : str
+        The entity name for the resulting HDL.
     word_length : int
         Word length of the memory variable objects.
     read_ports : int
@@ -220,12 +222,13 @@ def memory_based_storage(
             mv = cast(PlainMemoryVariable, mv)
             write(f, 4, f'-- {mv!r}')
             for read_time in mv.reads.values():
+                val = (
+                    mv.start_time + read_time - int(not (input_sync))
+                ) % schedule_time
                 write(
                     f,
                     4,
-                    'when'
-                    f' {(mv.start_time+read_time-int(not(input_sync))) % schedule_time}'
-                    ' =>',
+                    f'when {val} =>',
                 )
                 write_lines(
                     f,
diff --git a/b_asic/codegen/vhdl/common.py b/b_asic/codegen/vhdl/common.py
index abd7f1e3..cae5c4f2 100644
--- a/b_asic/codegen/vhdl/common.py
+++ b/b_asic/codegen/vhdl/common.py
@@ -51,8 +51,9 @@ def ieee_header(
     numeric_std: bool = True,
 ):
     """
-    Write the standard IEEE VHDL use header with includes of std_logic_1164 and
-    numeric_std.
+    Write the standard IEEE VHDL use header.
+
+    This includes std_logic_1164 and numeric_std.
 
     Parameters
     ----------
@@ -81,7 +82,9 @@ def signal_declaration(
     quartus_ram_style: Optional[str] = None,
 ):
     """
-    Create a VHDL signal declaration: ::
+    Create a VHDL signal declaration.
+
+    The declaration looks like::
 
         signal {name} : {type} [:= {default_value}];
 
@@ -136,7 +139,6 @@ def constant_declaration(
     signal_type: str,
     value: Any,
     name_pad: Optional[int] = None,
-    type_pad: Optional[int] = None,
 ):
     """
     Write a VHDL constant declaration with a name, a type and a value.
@@ -197,7 +199,7 @@ def process_prologue(
         Content of the process sensitivity list.
     indent : int, default: 1
         Indentation level to use for this process.
-    name : Optional[str]
+    name : str, optional
         An optional name for the process.
     """
     if name is not None:
@@ -214,17 +216,19 @@ def process_epilogue(
     name: Optional[str] = None,
 ):
     """
+    Write the epilogue of a regular VHDL process.
+
     Parameters
     ----------
     f : TextIO
         The TextIO object to write the type declaration to.
-    sensitivity_list : str
+    sensitivity_list : str, optional
         Content of the process sensitivity list. Not needed when writing the epilogue.
     indent : int, default: 1
         Indentation level to use for this process.
     indent : int, default: 1
         Indentation level to use for this process.
-    name : Optional[str]
+    name : str, optional
         An optional name of the ending process.
     """
     _ = sensitivity_list
@@ -256,7 +260,7 @@ def synchronous_process_prologue(
         Name of the clock.
     indent : int, default: 1
         Indentation level to use for this process.
-    name : Optional[str]
+    name : str, optional
         An optional name for the process.
     """
     process_prologue(f, sensitivity_list=clk, indent=indent, name=name)
@@ -265,12 +269,12 @@ def synchronous_process_prologue(
 
 def synchronous_process_epilogue(
     f: TextIO,
-    clk: Optional[str],
+    clk: Optional[str] = None,
     indent: int = 1,
     name: Optional[str] = None,
 ):
     """
-    Write only the epilogue of a regular VHDL synchronous process with a single clock.
+    Write the epilogue of a regular VHDL synchronous process with a single clock.
 
     The clock is the only item in the sensitivity list and is triggering a rising edge
     block by some body of VHDL code.
@@ -279,12 +283,12 @@ def synchronous_process_epilogue(
     ----------
     f : TextIO
         The TextIO to write the VHDL code onto.
-    clk : str
+    clk : str, optional
         Name of the clock.
     indent : int, default: 1
         Indentation level to use for this process.
-    name : Optional[str]
-        An optional name for the process
+    name : str, optional
+        An optional name for the process.
     """
     _ = clk
     write(f, indent + 1, 'end if;')
@@ -314,8 +318,8 @@ def synchronous_process(
         Body of the `if rising_edge(clk) then` block.
     indent : int, default: 1
         Indentation level to use for this process.
-    name : Optional[str]
-        An optional name for the process
+    name : str, optional
+        An optional name for the process.
     """
     synchronous_process_prologue(f, clk, indent, name)
     for line in body.split('\n'):
@@ -344,7 +348,7 @@ def synchronous_memory(
         A set of strings used as identifiers for the read ports of the memory.
     write_ports : Set[Tuple[str,str,str]]
         A set of strings used as identifiers for the write ports of the memory.
-    name : Optional[str]
+    name : str, optional
         An optional name for the memory process.
     """
     assert len(read_ports) >= 1
@@ -391,7 +395,7 @@ def asynchronous_read_memory(
         A set of strings used as identifiers for the read ports of the memory.
     write_ports : Set[Tuple[str,str,str]]
         A set of strings used as identifiers for the write ports of the memory.
-    name : Optional[str]
+    name : str, optional
         An optional name for the memory process.
     """
     assert len(read_ports) >= 1
diff --git a/b_asic/graph_component.py b/b_asic/graph_component.py
index a91b84f9..1b3ac9a7 100644
--- a/b_asic/graph_component.py
+++ b/b_asic/graph_component.py
@@ -70,6 +70,7 @@ class GraphComponent(ABC):
     def param(self, name: str) -> Any:
         """
         Get the value of a parameter.
+
         Returns None if the parameter is not defined.
         """
         raise NotImplementedError
@@ -78,6 +79,7 @@ class GraphComponent(ABC):
     def set_param(self, name: str, value: Any) -> None:
         """
         Set the value of a parameter.
+
         Adds the parameter if it is not already defined.
         """
         raise NotImplementedError
@@ -85,8 +87,9 @@ class GraphComponent(ABC):
     @abstractmethod
     def copy(self, *args, **kwargs) -> "GraphComponent":
         """
-        Get a new instance of this graph component type with the same name, id and
-        parameters.
+        Get a new instance of this graph component type.
+
+        The new instance will have the same name, id, and parameters.
         """
         raise NotImplementedError
 
@@ -99,7 +102,9 @@ class GraphComponent(ABC):
     @abstractmethod
     def traverse(self) -> Generator["GraphComponent", None, None]:
         """
-        Get a generator that recursively iterates through all components that
+        Get a generator for traversing the all connected components.
+
+        The generator recursively iterates through all components that
         are connected to this operation,
         as well as the ones that they are connected to.
         """
diff --git a/b_asic/operation.py b/b_asic/operation.py
index 1c31f788..28502c08 100644
--- a/b_asic/operation.py
+++ b/b_asic/operation.py
@@ -154,8 +154,7 @@ class Operation(GraphComponent, SignalSourceProvider):
         quantize: bool = True,
     ) -> Num:
         """
-        Evaluate the output at the given index of this operation with the given input
-        values.
+        Evaluate the output at the given index with the given input values.
 
         Parameters
         ----------
diff --git a/b_asic/quantization.py b/b_asic/quantization.py
index c1cc3596..26cc2c70 100644
--- a/b_asic/quantization.py
+++ b/b_asic/quantization.py
@@ -10,34 +10,22 @@ class Quantization(Enum):
     """Quantization types."""
 
     ROUNDING = 1
-    """
-    Standard two's complement rounding, i.e, tie rounds towards infinity.
-    """
+    """Standard two's complement rounding, i.e, tie rounds towards infinity."""
 
     TRUNCATION = 2
-    """
-    Two's complement truncation, i.e., round towards negative infinity.
-    """
+    """Two's complement truncation, i.e., round towards negative infinity."""
 
     MAGNITUDE_TRUNCATION = 3
-    """
-    Magnitude truncation, i.e., round towards zero.
-    """
+    """Magnitude truncation, i.e., round towards zero."""
 
     JAMMING = 4
-    """
-    Jamming/von Neumann rounding, i.e., set the LSB to one.
-    """
+    """Jamming/von Neumann rounding, i.e., set the LSB to one."""
 
     UNBIASED_ROUNDING = 5
-    """
-    Unbiased rounding, i.e., tie rounds towards even.
-    """
+    """Unbiased rounding, i.e., tie rounds towards even."""
 
     UNBIASED_JAMMING = 6
-    """
-    Unbiased jamming/von Neumann rounding.
-    """
+    """Unbiased jamming/von Neumann rounding."""
 
 
 class Overflow(Enum):
diff --git a/b_asic/resources.py b/b_asic/resources.py
index 08668aec..25cc9f07 100644
--- a/b_asic/resources.py
+++ b/b_asic/resources.py
@@ -553,7 +553,7 @@ class ProcessCollection:
         Returns
         -------
         ax : :class:`matplotlib.axes.Axes`
-            Associated Matplotlib Axes (or array of Axes) object
+            Associated Matplotlib Axes (or array of Axes) object.
         """
 
         # Set up the Axes object
@@ -1302,10 +1302,7 @@ class ProcessCollection:
         """
         Generate VHDL code for register based storage.
 
-        This is based on Forward-Backward Register Allocation [1].
-
-        [1]: K. Parhi: VLSI Digital Signal Processing Systems: Design and
-        Implementation, Ch. 6.3.2
+        This is based on Forward-Backward Register Allocation.
 
         Parameters
         ----------
@@ -1326,6 +1323,12 @@ class ProcessCollection:
         total_ports : int, default: 2
             The total number of ports used when splitting process collection based on
             memory variable access.
+
+        References
+        ----------
+        - K. Parhi: VLSI Digital Signal Processing Systems: Design and
+          Implementation, Ch. 6.3.2
+
         """
         # Check that entity name is a valid VHDL identifier
         if not is_valid_vhdl_identifier(entity_name):
@@ -1372,8 +1375,7 @@ class ProcessCollection:
 
     def get_by_type_name(self, type_name: TypeName) -> "ProcessCollection":
         """
-        Return a new :class:`~b_asic.resources.ProcessCollection` with only a given
-        type of operation.
+        Return a new ProcessCollection with only a given type of operation.
 
         Parameters
         ----------
diff --git a/b_asic/schedule.py b/b_asic/schedule.py
index 99ed184c..b342c022 100644
--- a/b_asic/schedule.py
+++ b/b_asic/schedule.py
@@ -765,10 +765,10 @@ class Schedule:
         """
         new_sfg = self._sfg()
         destination_laps = []
-        for signal_id,lap in self._laps.items():
+        for signal_id, lap in self._laps.items():
             port = new_sfg.find_by_id(signal_id).destination
             destination_laps.append((port.operation.graph_id, port.index, lap))
-        for op,port,lap in destination_laps:
+        for op, port, lap in destination_laps:
             for delays in range(lap):
                 new_sfg = new_sfg.insert_operation_before(op, Delay(), port)
         return new_sfg()
@@ -904,12 +904,11 @@ class Schedule:
 
     def get_memory_variables(self) -> ProcessCollection:
         """
-        Return a :class:`~b_asic.resources.ProcessCollection` containing all
-        memory variables.
+        Return a ProcessCollection containing all memory variables.
 
         Returns
         -------
-        ProcessCollection
+        :class:`~b_asic.resources.ProcessCollection`
         """
         return ProcessCollection(
             set(self._get_memory_variables_list()), self.schedule_time
@@ -917,12 +916,11 @@ class Schedule:
 
     def get_operations(self) -> ProcessCollection:
         """
-        Return a :class:`~b_asic.resources.ProcessCollection` containing all
-        operations.
+        Return a ProcessCollection containing all operations.
 
         Returns
         -------
-        ProcessCollection
+        :class:`~b_asic.resources.ProcessCollection`
         """
         return ProcessCollection(
             {
diff --git a/b_asic/signal_flow_graph.py b/b_asic/signal_flow_graph.py
index 7d4610ae..f33f36bd 100644
--- a/b_asic/signal_flow_graph.py
+++ b/b_asic/signal_flow_graph.py
@@ -741,7 +741,7 @@ class SFG(AbstractOperation):
         self,
         input_comp_id: GraphID,
         new_operation: Operation,
-        port: Optional[int] = None
+        port: Optional[int] = None,
     ) -> Optional["SFG"]:
         """
         Insert an operation in the SFG before a given source operation.
@@ -761,7 +761,8 @@ class SFG(AbstractOperation):
         new_operation : Operation
             The new operation, e.g. Multiplication.
         port : Optional[int]
-            The number of the InputPort before which the new operation shall be inserted
+            The number of the InputPort before which the new operation shall be
+            inserted.
         """
 
         # Preserve the original SFG by creating a copy.
@@ -1696,7 +1697,7 @@ class SFG(AbstractOperation):
         if factor == 0:
             raise ValueError("Unfolding 0 times removes the SFG")
 
-        sfg = self() # copy the sfg
+        sfg = self()  # copy the sfg
 
         inputs = sfg.input_operations
         outputs = sfg.output_operations
@@ -1706,9 +1707,8 @@ class SFG(AbstractOperation):
         for delay in sfg.find_by_type_name(Delay.type_name()):
             i = Input(name="input_" + delay.graph_id)
             o = Output(
-                    src0=delay.input(0).signals[0].source,
-                    name="output_" + delay.graph_id
-                )
+                src0=delay.input(0).signals[0].source, name="output_" + delay.graph_id
+            )
 
             inputs.append(i)
             outputs.append(o)
@@ -1724,9 +1724,9 @@ class SFG(AbstractOperation):
             delay.input(0).signals[0].remove_source()
             delay.input(0).clear()
 
-        new_sfg = SFG(inputs, outputs) # The new sfg without the delays
+        new_sfg = SFG(inputs, outputs)  # The new sfg without the delays
 
-        sfgs = [new_sfg() for _ in range(factor)] # Copy the SFG factor times
+        sfgs = [new_sfg() for _ in range(factor)]  # Copy the SFG factor times
 
         # Add suffixes to all graphIDs and names in order to keep them separated
         for i in range(factor):
@@ -1736,12 +1736,12 @@ class SFG(AbstractOperation):
                 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
+        input_name_to_idx = {}  # save the input port indices for future reference
         new_inputs = []
         # For each copy of the SFG, create new input operations for every "original"
         # input operation and connect them to begin creating the unfolded SFG
         for i in range(factor):
-            for port,operation in zip(sfgs[i].inputs, sfgs[i].input_operations):
+            for port, operation in zip(sfgs[i].inputs, sfgs[i].input_operations):
                 if not operation.name.startswith("input_t"):
                     i = Input()
                     new_inputs.append(i)
@@ -1758,22 +1758,24 @@ class SFG(AbstractOperation):
         new_outputs = []
         delay_placements = {}
         for i in range(factor):
-            for port,operation in zip(sfgs[i].outputs, sfgs[i].output_operations):
+            for port, operation in zip(sfgs[i].outputs, sfgs[i].output_operations):
                 if not operation.name.startswith("output_t"):
                     new_outputs.append(Output(port))
                 else:
-                    index = operation.name[8:] # Remove the "output_t" prefix
+                    index = operation.name[8:]  # Remove the "output_t" prefix
                     j = (i + 1) % factor
-                    number_of_delays_between = (i + 1)//factor
+                    number_of_delays_between = (i + 1) // factor
                     input_port = sfgs[j].input(input_name_to_idx["input_t" + index])
                     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
+                    delay_placements[port] = [i, number_of_delays_between]
+            sfgs[i].graph_id = (
+                f'sfg{i}'  # deterministically set the graphID of the sfgs
+            )
 
-        sfg = SFG(new_inputs, new_outputs) # create a new SFG to remove floating nodes
+        sfg = SFG(new_inputs, new_outputs)  # create a new SFG to remove floating nodes
 
         # Insert the interconnect delays according to what is saved in delay_placements
-        for port,val in delay_placements.items():
+        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())
@@ -1785,7 +1787,6 @@ class SFG(AbstractOperation):
 
         return sfg
 
-
     @property
     def is_linear(self) -> bool:
         return all(op.is_linear for op in self.split())
-- 
GitLab