diff --git a/b_asic/operation.py b/b_asic/operation.py index 33c5b753b8feb3f4b7854e9b537f5afea2038e94..9e5aa204defe3293471301000d8af9a4dbc83f9f 100644 --- a/b_asic/operation.py +++ b/b_asic/operation.py @@ -1,4 +1,5 @@ -"""B-ASIC Operation Module. +""" +B-ASIC Operation Module. Contains the base for operations that are used by B-ASIC. """ @@ -201,12 +202,17 @@ class Operation(GraphComponent, SignalSourceProvider): bits_override: Optional[int] = None, truncate: bool = True, ) -> Number: - """Evaluate the output at the given index of this operation with the given input values. - The results parameter will be used to store any results (including intermediate results) for caching. - The delays parameter will be used to get the current value of any intermediate delays that are encountered, and be updated with their new values. + """ + Evaluate the output at the given index of this operation with the given input values. + The results parameter will be used to store any results (including intermediate results) + for caching. + The delays parameter will be used to get the current value of any intermediate delays + that are encountered, and be updated with their new values. The prefix parameter will be used as a prefix for the key string when storing results/delays. - The bits_override parameter specifies a word length override when truncating inputs which ignores the word length specified by the input signal. - The truncate parameter specifies whether input truncation should be enabled in the first place. If set to False, input values will be used driectly without any bit truncation. + The bits_override parameter specifies a word length override when truncating inputs + which ignores the word length specified by the input signal. + The truncate parameter specifies whether input truncation should be enabled in the first + place. If set to False, input values will be used driectly without any bit truncation. See also: evaluate_outputs, current_output, current_outputs. """ raise NotImplementedError diff --git a/b_asic/port.py b/b_asic/port.py index ab164d7547775370a2356c97e4ad2fca391c2c92..ea7930c292ecb654f6b7fc2d821f481309e71c1f 100644 --- a/b_asic/port.py +++ b/b_asic/port.py @@ -1,4 +1,5 @@ -"""B-ASIC Port Module. +""" +B-ASIC Port Module. Contains classes for managing the ports of operations. """ @@ -15,7 +16,8 @@ if TYPE_CHECKING: class Port(ABC): - """Port interface. + """ + Port interface. Ports serve as connection points for connecting signals between operations. They also store information about the latency of the corresponding @@ -65,14 +67,16 @@ class Port(ABC): @abstractmethod def add_signal(self, signal: Signal) -> None: - """Connect this port to the entered signal. If the entered signal isn't connected to + """ + Connect this port to the entered signal. If the entered signal isn't connected to this port then connect the entered signal to the port as well. """ raise NotImplementedError @abstractmethod def remove_signal(self, signal: Signal) -> None: - """Remove the signal that was entered from the Ports signals. + """ + Remove the signal that was entered from the Ports signals. If the entered signal still is connected to this port then disconnect the entered signal from the port as well. @@ -88,7 +92,8 @@ class Port(ABC): class AbstractPort(Port): - """Generic abstract port base class. + """ + Generic abstract port base class. Concrete ports should normally derive from this to get the default behavior. @@ -127,7 +132,8 @@ class AbstractPort(Port): class SignalSourceProvider(ABC): - """Signal source provider interface. + """ + Signal source provider interface. Signal source providers give access to a single output port that can be used to connect signals from. diff --git a/b_asic/save_load_structure.py b/b_asic/save_load_structure.py index f85bcfb473b8f07390c928afb3cf64da0567c7d8..b37c16929f80f1c7fe78b8bf6b43de0a33f4371d 100644 --- a/b_asic/save_load_structure.py +++ b/b_asic/save_load_structure.py @@ -1,4 +1,5 @@ -"""B-ASIC Save/Load Structure Module. +""" +B-ASIC Save/Load Structure Module. Contains functions for saving/loading SFGs to/from strings that can be stored as files. diff --git a/b_asic/schedule.py b/b_asic/schedule.py index 9af317154f7f44b264152e2101354d453afceea4..f82c67565a72b361e0fcccee48ef326b80d12eb5 100644 --- a/b_asic/schedule.py +++ b/b_asic/schedule.py @@ -73,7 +73,7 @@ class Schedule: return self._start_times[op_id] def get_max_end_time(self) -> int: - """Returnes the current maximum end time among all operations.""" + """Returns the current maximum end time among all operations.""" max_end_time = 0 for op_id, op_start_time in self._start_times.items(): op = self._sfg.find_by_id(op_id) @@ -151,7 +151,7 @@ class Schedule: assert ( op_id in self._start_times ), "No operation with the specified op_id in this schedule." - return (self.backward_slack(op_id), self.forward_slack(op_id)) + return self.backward_slack(op_id), self.forward_slack(op_id) def print_slacks(self) -> None: raise NotImplementedError @@ -355,40 +355,6 @@ class Schedule: self._remove_delays() def _plot_schedule(self, ax): - def _draw_arrow2(start, end): - if end[0] < start[0]: # Wrap around - ax.plot([start[0], self._schedule_time], [start[1], start[1]]) - ax.plot([0, end[0]], [end[1], end[1]]) - elif end[0] == start[0]: - ax.plot( - [ - start[0], - start[0] + 0.2, - start[0] + 0.2, - start[0] - 0.2, - start[0] - 0.2, - start[0], - ], - [ - start[1], - start[1], - (start[1] + end[1]) / 2, - (start[1] + end[1]) / 2, - end[1], - end[1], - ], - ) - else: - ax.plot( - [ - start[0], - (start[0] + end[0]) / 2, - (start[0] + end[0]) / 2, - end[0], - ], - [start[1], start[1], end[1], end[1]], - ) - def _draw_arrow(start, end, name="", laps=0): if end[0] < start[0] or laps > 0: # Wrap around ax.plot( diff --git a/b_asic/signal.py b/b_asic/signal.py index 90af747f7b16bd685c317c868dad11357cf8b708..7e42bb082c87921ca85f23cdc351224ba16da401 100644 --- a/b_asic/signal.py +++ b/b_asic/signal.py @@ -1,4 +1,5 @@ -"""B-ASIC Signal Module. +""" +B-ASIC Signal Module. Contains the class for representing the connections between operations. """ @@ -113,14 +114,20 @@ class Signal(AbstractGraphComponent): @property def bits(self) -> Optional[int]: - """Get the number of bits that this operations using this signal as an input should truncate received values to. - None = unlimited.""" + """ + Get the number of bits that this operation using this signal as an + input should truncate received values to. + None = unlimited. + """ return self.param("bits") @bits.setter def bits(self, bits: Optional[int]) -> None: - """Set the number of bits that operations using this signal as an input should truncate received values to. - None = unlimited.""" + """ + Set the number of bits that operations using this signal as an input + should truncate received values to. + None = unlimited. + """ assert bits is None or ( isinstance(bits, int) and bits >= 0 ), "Bits must be non-negative." diff --git a/b_asic/signal_flow_graph.py b/b_asic/signal_flow_graph.py index 1e5f1ccb99e6716b3d55c8a1f2cfe842042d5054..ddec697f908c491c53d50121869f535cb7d135d2 100644 --- a/b_asic/signal_flow_graph.py +++ b/b_asic/signal_flow_graph.py @@ -1,4 +1,5 @@ -"""B-ASIC Signal Flow Graph Module. +""" +B-ASIC Signal Flow Graph Module. Contains the signal flow graph operation. """ @@ -72,7 +73,8 @@ class GraphIDGenerator: class SFG(AbstractOperation): - """Signal flow graph. + """ + Signal flow graph. Contains a set of connected operations, forming a new operation. Used as a base for simulation, scheduling, etc. @@ -103,7 +105,8 @@ class SFG(AbstractOperation): Sequence[Optional[SignalSourceProvider]] ] = None, ): - """Construct an SFG given its inputs and outputs. + """ + Construct an SFG given its inputs and outputs. Inputs/outputs may be specified using either Input/Output operations directly with the inputs/outputs parameters, or using signals with the @@ -148,7 +151,7 @@ class SFG(AbstractOperation): for input_index, signal in enumerate(input_signals): assert ( signal not in self._original_components_to_new - ), "Duplicate input signals supplied to SFG construcctor." + ), "Duplicate input signals supplied to SFG constructor." new_input_op = self._add_component_unconnected_copy(Input()) new_signal = self._add_component_unconnected_copy(signal) new_signal.set_source(new_input_op.output(0)) @@ -165,7 +168,7 @@ class SFG(AbstractOperation): for signal in input_op.output(0).signals: assert signal not in self._original_components_to_new, ( "Duplicate input signals connected to input ports" - " supplied to SFG construcctor." + " supplied to SFG constructor." ) new_signal = self._add_component_unconnected_copy(signal) new_signal.set_source(new_input_op.output(0)) @@ -295,7 +298,9 @@ class SFG(AbstractOperation): def __call__( self, *src: Optional[SignalSourceProvider], name: Name = "" ) -> "SFG": - """Get a new independent SFG instance that is identical to this SFG except without any of its external connections. + """ + Get a new independent SFG instance that is identical to this SFG + except without any of its external connections. """ return SFG( inputs=self._input_operations, @@ -377,8 +382,11 @@ class SFG(AbstractOperation): return value def connect_external_signals_to_components(self) -> bool: - """Connects any external signals to this SFG's internal operations. This SFG becomes unconnected to the SFG - it is a component off, causing it to become invalid afterwards. Returns True if succesful, False otherwise. + """ + Connects any external signals to this SFG's internal operations. + This SFG becomes unconnected to the SFG it is a component off, + causing it to become invalid afterwards. Returns True if successful, + False otherwise. """ if len(self.inputs) != len(self.input_operations): raise IndexError( @@ -541,11 +549,12 @@ class SFG(AbstractOperation): def replace_component( self, component: Operation, graph_id: GraphID ) -> "SFG": - """Find and replace all components matching either on GraphID, Type or both. + """ + Find and replace all components matching either on GraphID, Type or both. Then return a new deepcopy of the sfg with the replaced component. Arguments: - component: The new component(s), e.g Multiplication + component: The new component(s), e.g. Multiplication graph_id: The GraphID to match the component to replace. """ @@ -582,7 +591,7 @@ class SFG(AbstractOperation): Then return a new deepcopy of the sfg with the inserted component. Arguments: - component: The new component, e.g Multiplication. + component: The new component, e.g. Multiplication. output_comp_id: The source operation GraphID to connect from. """ @@ -760,7 +769,7 @@ class SFG(AbstractOperation): def get_operations_topological_order(self) -> Iterable[Operation]: """Returns an Iterable of the Operations in the SFG in Topological Order. Feedback loops makes an absolutely correct Topological order impossible, so an - approximative Topological Order is returned in such cases in this implementation. + approximate Topological Order is returned in such cases in this implementation. """ if self._operations_topological_order: return self._operations_topological_order @@ -844,7 +853,7 @@ class SFG(AbstractOperation): ) ) - # Else fetch operation with lowest input count that is not zero + # Else fetch operation with the lowest input count that is not zero elif seen_but_not_visited_count > 0: for i in it.count(start=1): seen_inputs_queue = seen_with_inputs_dict[i] @@ -860,7 +869,7 @@ class SFG(AbstractOperation): seen_but_not_visited_count -= 1 break else: - raise RuntimeError("Unallowed structure in SFG detected") + raise RuntimeError("Disallowed structure in SFG detected") self._operations_topological_order = top_order return self._operations_topological_order @@ -1237,10 +1246,10 @@ class SFG(AbstractOperation): Parameters ---------- format : string, optional - File format of the generated graph. Output formats can be found at https://www.graphviz.org/doc/info/output.html + File format of the generated graph. Output formats can be found at + https://www.graphviz.org/doc/info/output.html Most common are "pdf", "eps", "png", and "svg". Default is None which leads to PDF. - show_id : Boolean, optional If True, the graph_id:s of signals are shown. The default is False.