diff --git a/b_asic/core_operations.py b/b_asic/core_operations.py index 090a80971fbe0fa7b6f339702f1251ca27c5bca3..bd3ae9de640028b1fa345f23fd8e60cee7e96a76 100644 --- a/b_asic/core_operations.py +++ b/b_asic/core_operations.py @@ -307,16 +307,16 @@ class Multiplication(AbstractOperation): latency : int, optional Operation latency (delay from input to output in time units). latency_offsets : dict[str, int], optional - Used if inputs have different arrival times, e.g., - ``{"in0": 0, "in1": 1}`` which corresponds to *src1* arriving one - time unit later than *src0*. If not provided and *latency* is - provided, set to zero if not explicitly provided. So the previous - example can be written as ``{"in1": 1}`` only. + Used if inputs have different arrival times or if the inputs should arrive + after the operator has stared. For example, ``{"in0": 0, "in1": 1}`` which + corresponds to *src1* arriving one time unit later than *src0* and one time + unit later than the operator starts. If not provided and *latency* is provided, + set to zero. Hence, the previous example can be written as ``{"in1": 1}`` + only. execution_time : int, optional - Operation execution time (time units before operator can be - reused). + Operation execution time (time units before operator can be reused). - See also + See Also ======== ConstantMultiplication @@ -365,7 +365,26 @@ class Division(AbstractOperation): .. math:: y = \frac{x_0}{x_1} - See also + Parameters + ========== + + src0, src1 : SignalSourceProvider, optional + The two signals to divide. + name : Name, optional + Operation name. + latency : int, optional + Operation latency (delay from input to output in time units). + latency_offsets : dict[str, int], optional + Used if inputs have different arrival times or if the inputs should arrive + after the operator has stared. For example, ``{"in0": 0, "in1": 1}`` which + corresponds to *src1* arriving one time unit later than *src0* and one time + unit later than the operator starts. If not provided and *latency* is provided, + set to zero. Hence, the previous example can be written as ``{"in1": 1}`` + only. + execution_time : int, optional + Operation execution time (time units before operator can be reused). + + See Also ======== Reciprocal """ @@ -412,7 +431,26 @@ class Min(AbstractOperation): .. note:: Only real-valued numbers are supported. - See also + Parameters + ========== + + src0, src1 : SignalSourceProvider, optional + The two signals to determine the min of. + name : Name, optional + Operation name. + latency : int, optional + Operation latency (delay from input to output in time units). + latency_offsets : dict[str, int], optional + Used if inputs have different arrival times or if the inputs should arrive + after the operator has stared. For example, ``{"in0": 0, "in1": 1}`` which + corresponds to *src1* arriving one time unit later than *src0* and one time + unit later than the operator starts. If not provided and *latency* is provided, + set to zero. Hence, the previous example can be written as ``{"in1": 1}`` + only. + execution_time : int, optional + Operation execution time (time units before operator can be reused). + + See Also ======== Max """ @@ -458,7 +496,26 @@ class Max(AbstractOperation): .. note:: Only real-valued numbers are supported. - See also + Parameters + ========== + + src0, src1 : SignalSourceProvider, optional + The two signals to determine the min of. + name : Name, optional + Operation name. + latency : int, optional + Operation latency (delay from input to output in time units). + latency_offsets : dict[str, int], optional + Used if inputs have different arrival times or if the inputs should arrive + after the operator has stared. For example, ``{"in0": 0, "in1": 1}`` which + corresponds to *src1* arriving one time unit later than *src0* and one time + unit later than the operator starts. If not provided and *latency* is provided, + set to zero. Hence, the previous example can be written as ``{"in1": 1}`` + only. + execution_time : int, optional + Operation execution time (time units before operator can be reused). + + See Also ======== Min """ @@ -501,6 +558,22 @@ class SquareRoot(AbstractOperation): Gives the square root of its input. .. math:: y = \sqrt{x} + + Parameters + ---------- + src0 : :class:`~b_asic.port.SignalSourceProvider`, optional + The signal to compute the square root of. + name : Name, optional + Operation name. + latency : int, optional + Operation latency (delay from input to output in time units). + latency_offsets : dict[str, int], optional + Used if input arrives later than when the operator starts, e.g., + ``{"in0": 0`` which corresponds to *src0* arriving one time unit after the + operator starts. If not provided and *latency* is provided, set to zero. + execution_time : int, optional + Operation execution time (time units before operator can be reused). + """ def __init__( @@ -537,6 +610,22 @@ class ComplexConjugate(AbstractOperation): Gives the complex conjugate of its input. .. math:: y = x^* + + Parameters + ---------- + src0 : :class:`~b_asic.port.SignalSourceProvider`, optional + The signal to compute the complex conjugate of. + name : Name, optional + Operation name. + latency : int, optional + Operation latency (delay from input to output in time units). + latency_offsets : dict[str, int], optional + Used if input arrives later than when the operator starts, e.g., + ``{"in0": 0`` which corresponds to *src0* arriving one time unit after the + operator starts. If not provided and *latency* is provided, set to zero. + execution_time : int, optional + Operation execution time (time units before operator can be reused). + """ def __init__( @@ -573,6 +662,22 @@ class Absolute(AbstractOperation): Gives the absolute value of its input. .. math:: y = |x| + + Parameters + ---------- + src0 : :class:`~b_asic.port.SignalSourceProvider`, optional + The signal to compute the absolute value of. + name : Name, optional + Operation name. + latency : int, optional + Operation latency (delay from input to output in time units). + latency_offsets : dict[str, int], optional + Used if input arrives later than when the operator starts, e.g., + ``{"in0": 0`` which corresponds to *src0* arriving one time unit after the + operator starts. If not provided and *latency* is provided, set to zero. + execution_time : int, optional + Operation execution time (time units before operator can be reused). + """ def __init__( @@ -609,6 +714,27 @@ class ConstantMultiplication(AbstractOperation): Gives the result of multiplying its input by a specified value. .. math:: y = x_0 \times \text{value} + + Parameters + ---------- + value : int + Value to multiply with. + src0 : :class:`~b_asic.port.SignalSourceProvider`, optional + The signal to multiply. + name : Name, optional + Operation name. + latency : int, optional + Operation latency (delay from input to output in time units). + latency_offsets : dict[str, int], optional + Used if input arrives later than when the operator starts, e.g., + ``{"in0": 0`` which corresponds to *src0* arriving one time unit after the + operator starts. If not provided and *latency* is provided, set to zero. + execution_time : int, optional + Operation execution time (time units before operator can be reused). + + See Also + -------- + Multiplication """ is_linear = True @@ -653,16 +779,35 @@ class ConstantMultiplication(AbstractOperation): class Butterfly(AbstractOperation): r""" - Radix-2 Butterfly operation. + Radix-2 Butterfly operation for FFTs. - Gives the result of adding its two inputs, as well as the result of - subtracting the second input from the first one. + Gives the result of adding its two inputs, as well as the result of subtracting the + second input from the first one. This corresponds to a 2-point DFT. .. math:: \begin{eqnarray} y_0 & = & x_0 + x_1\\ y_1 & = & x_0 - x_1 \end{eqnarray} + + Parameters + ========== + + src0, src1 : SignalSourceProvider, optional + The two signals to compute the 2-point DFT of. + name : Name, optional + Operation name. + latency : int, optional + Operation latency (delay from input to output in time units). + latency_offsets : dict[str, int], optional + Used if inputs have different arrival times or if the inputs should arrive + after the operator has stared. For example, ``{"in0": 0, "in1": 1}`` which + corresponds to *src1* arriving one time unit later than *src0* and one time + unit later than the operator starts. If not provided and *latency* is provided, + set to zero. Hence, the previous example can be written as ``{"in1": 1}`` + only. + execution_time : int, optional + Operation execution time (time units before operator can be reused). """ is_linear = True @@ -702,6 +847,28 @@ class MAD(AbstractOperation): then adding the third input. .. math:: y = x_0 \times x_1 + x_2 + + Parameters + ========== + + src0, src1, src2 : SignalSourceProvider, optional + The three signals to determine the multiply-add operation of. + name : Name, optional + Operation name. + latency : int, optional + Operation latency (delay from input to output in time units). + latency_offsets : dict[str, int], optional + Used if inputs have different arrival times or if the inputs should arrive + after the operator has stared. For example, ``{"in0": 0, "in1": 0, "in2": 2}`` + which corresponds to *src2*, i.e., the term to be added, arriving two time + units later than *src0* and *src1*. If not provided and *latency* is provided, + set to zero. Hence, the previous example can be written as ``{"in1": 1}`` + only. + execution_time : int, optional + Operation execution time (time units before operator can be reused). + + See Also + """ is_swappable = True @@ -752,7 +919,7 @@ class MAD(AbstractOperation): class SymmetricTwoportAdaptor(AbstractOperation): r""" - Symmetric twoport-adaptor operation. + Wave digital filter symmetric twoport-adaptor operation. .. math:: \begin{eqnarray} @@ -825,6 +992,21 @@ class Reciprocal(AbstractOperation): .. math:: y = \frac{1}{x} + Parameters + ---------- + src0 : :class:`~b_asic.port.SignalSourceProvider`, optional + The signal to compute the reciprocal of. + name : Name, optional + Operation name. + latency : int, optional + Operation latency (delay from input to output in time units). + latency_offsets : dict[str, int], optional + Used if input arrives later than when the operator starts, e.g., + ``{"in0": 0`` which corresponds to *src0* arriving one time unit after the + operator starts. If not provided and *latency* is provided, set to zero. + execution_time : int, optional + Operation execution time (time units before operator can be reused). + See also ======== Division diff --git a/b_asic/operation.py b/b_asic/operation.py index 982a2b318fa75fc5a36efa329f8eea8c8a09d58a..b93482332c437e429668e3dbd096203696b4bb19 100644 --- a/b_asic/operation.py +++ b/b_asic/operation.py @@ -336,8 +336,10 @@ class Operation(GraphComponent, SignalSourceProvider): @abstractmethod def latency(self) -> int: """ - Get the latency of the operation, which is the longest time it takes from one of - the operations inputport to one of the operations outputport. + Get the latency of the operation. + + This is the longest time it takes from one of the input ports to one of the + output ports. """ raise NotImplementedError @@ -368,7 +370,7 @@ class Operation(GraphComponent, SignalSourceProvider): latency_offsets dictionary. The latency offsets dictionary should be {'in0': 2, 'out1': 4} if you want to - set the latency offset for the inport port with index 0 to 2, and the latency + set the latency offset for the input port with index 0 to 2, and the latency offset of the output port with index 1 to 4. """ raise NotImplementedError diff --git a/b_asic/process.py b/b_asic/process.py index bf0c2ef3c9c3df50919bdf989e8990d5ba4c2c7a..95f3695c85c05fa9280bdf81a31c5a2c0f06ccb9 100644 --- a/b_asic/process.py +++ b/b_asic/process.py @@ -109,7 +109,7 @@ class MemoryProcess(Process): """ Intermediate class (abstract) for memory processes. - Different from regular :class:`Processe` objects, :class:`MemoryProcess` objects + Different from regular :class:`Process` objects, :class:`MemoryProcess` objects can contain multiple read accesses and can be split into two new :class:`MemoryProcess` objects based on these read times. diff --git a/b_asic/resources.py b/b_asic/resources.py index 03ed8f22e8145a9b11f0e0fdc7b4f80029947f46..212be2c291f0b3d35d38ebe34d38ca445dead1bb 100644 --- a/b_asic/resources.py +++ b/b_asic/resources.py @@ -520,7 +520,7 @@ class ProcessCollection: If the ``ax`` parameter is not specified, a new Matplotlib figure is created. Raises :class:`KeyError` if any :class:`~b_asic.process.Process` lifetime - exceedes this :class:`~b_asic.resources.ProcessCollection` schedule time, + exceeds this :class:`~b_asic.resources.ProcessCollection` schedule time, unless ``allow_excessive_lifetimes`` is specified. In that case, :class:`~b_asic.process.Process` objects whose lifetime exceed the schedule time are drawn using the B-ASIC warning color. @@ -698,7 +698,7 @@ class ProcessCollection: show_markers : bool, default True Show markers at read and write times. allow_excessive_lifetimes : bool, default False - If set to True, the plot method allows ploting collections of variables with + If True, the plot method allows plotting collections of variables with a greater lifetime than the schedule time. title : str, optional Title of plot. @@ -897,7 +897,7 @@ class ProcessCollection: """ Split this process storage based on concurrent read/write times according. - Different heurstic methods can be used. + Different heuristic methods can be used. Parameters ---------- @@ -1075,7 +1075,7 @@ class ProcessCollection: algorithm. Two or more processes can share a single resource if, and only if, they have no - overlaping execution time. + overlapping execution time. Raises :class:`ValueError` if any process in this collection has an execution time which is greater than the collection schedule time. @@ -1461,7 +1461,7 @@ class ProcessCollection: Get a :class:`~b_asic.process.Process` from this collection from its name. Raises :class:`KeyError` if no processes with ``name`` is found in this - colleciton. + collection. Parameters ---------- diff --git a/b_asic/sfg_generators.py b/b_asic/sfg_generators.py index 875387044353dc31eff2d14792028319fe73a9b2..0b750a7e35364f0b784e0815420648510c4dd758 100644 --- a/b_asic/sfg_generators.py +++ b/b_asic/sfg_generators.py @@ -174,8 +174,8 @@ def direct_form_fir( prev_delay = input_op prev_add = None - for i, coeff in enumerate(np_coefficients): - tmp_mul = ConstantMultiplication(coeff, prev_delay, **mult_properties) + for i, coefficient in enumerate(np_coefficients): + tmp_mul = ConstantMultiplication(coefficient, prev_delay, **mult_properties) prev_add = ( tmp_mul if prev_add is None @@ -241,8 +241,8 @@ def transposed_direct_form_fir( output = Output() prev_delay = None - for i, coeff in enumerate(reversed(np_coefficients)): - tmp_mul = ConstantMultiplication(coeff, input_op, **mult_properties) + for i, coefficient in enumerate(reversed(np_coefficients)): + tmp_mul = ConstantMultiplication(coefficient, input_op, **mult_properties) tmp_add = ( tmp_mul if prev_delay is None diff --git a/b_asic/signal_flow_graph.py b/b_asic/signal_flow_graph.py index 464513bbc2f6b67f1cf2ccdbfe4511518a395095..74d3f1a2c54200d6702ae0de1eba9113470554bc 100644 --- a/b_asic/signal_flow_graph.py +++ b/b_asic/signal_flow_graph.py @@ -400,7 +400,8 @@ class SFG(AbstractOperation): def connect_external_signals_to_components(self) -> bool: """ - Connects any external signals to this SFG's internal operations. + Connects any external signals to the internal operations of SFG. + This SFG becomes unconnected to the SFG it is a component off, causing it to become invalid afterwards. Returns True if successful, False otherwise. @@ -836,11 +837,12 @@ class SFG(AbstractOperation): """ Display the output of :func:`precedence_graph` in the system viewer. """ - self.precedence_graph().view() + self.precedence_graph.view() + @property def precedence_graph(self) -> Digraph: """ - Return the SFG in prededence form in Graphviz format. + The SFG in precedence form in Graphviz format. This can be rendered in enriched shells. @@ -906,7 +908,8 @@ class SFG(AbstractOperation): def print_precedence_graph(self) -> None: """ - Print a representation of the SFG's precedence list to the standard out. + Print a representation of the SFG precedence list to the standard out. + If the precedence list already has been calculated then it uses the cached version, otherwise it calculates the precedence list and then prints it. @@ -1655,7 +1658,7 @@ class SFG(AbstractOperation): new_destination = new_dest_op.inputs[sink_op_output_index] new_destination.connect(new_source_port) else: - # Other opreations need to be re-targeted to the corresponding + # Other operations need to be re-targeted to the corresponding # output in the current layer, as long as that output is not a # delay, as that has been solved above. # To avoid double connections, we'll only re-connect inputs diff --git a/b_asic/special_operations.py b/b_asic/special_operations.py index c1bc4deb4aee1e420f7b420a12a14e8b80f6b410..e523f3429861552075d62065a6817887aae34731 100644 --- a/b_asic/special_operations.py +++ b/b_asic/special_operations.py @@ -146,10 +146,6 @@ class Output(AbstractOperation): def latency(self) -> int: return self.latency_offsets["in0"] - @property - def is_linear(self) -> bool: - return True - class Delay(AbstractOperation): """ diff --git a/examples/firstorderiirfilter.py b/examples/firstorderiirfilter.py index 9f02c0910d71d85af677006e00c7543a2ae4c115..d34cd5de2089adcf0d7bf7317e8ce92b864dfe2b 100644 --- a/examples/firstorderiirfilter.py +++ b/examples/firstorderiirfilter.py @@ -74,7 +74,7 @@ firstorderiir firstorderiir.print_precedence_graph() # %% -# Executing ``firstorderiir.precedence_graph()`` will show something like +# Executing ``firstorderiir.precedence_graph`` will show something like # # .. graphviz:: # diff --git a/test/test_sfg.py b/test/test_sfg.py index f6a42e7aaa39014b7dd2cb155c989ca11eafc572..2f8c0455963ad0d8d47196ac554c1834aa49a977 100644 --- a/test/test_sfg.py +++ b/test/test_sfg.py @@ -1239,7 +1239,7 @@ class TestPrecedenceGraph: ' shape=square]\n\tadd1 -> "add1.0"\n\tadd1 [label=add1 shape=ellipse]\n}' ) - assert sfg_simple_filter.precedence_graph().source in (res, res + "\n") + assert sfg_simple_filter.precedence_graph.source in (res, res + "\n") class TestSFGGraph: