piel.flows
==========

.. py:module:: piel.flows


Submodules
----------

.. toctree::
   :maxdepth: 1

   /autoapi/piel/flows/analog_photonic/index
   /autoapi/piel/flows/digital_electro_optic/index
   /autoapi/piel/flows/digital_logic/index
   /autoapi/piel/flows/electro_optic/index


Functions
---------

.. autoapisummary::

   piel.flows.extract_component_spice_from_netlist
   piel.flows.generate_verilog_and_verification_from_truth_table
   piel.flows.get_latest_digital_run_component
   piel.flows.read_simulation_data_to_truth_table
   piel.flows.run_verification_simulation_for_design
   piel.flows.layout_truth_table
   piel.flows.add_truth_table_phase_to_bit_data
   piel.flows.convert_phase_to_bit_iterable
   piel.flows.find_nearest_bit_for_phase
   piel.flows.find_nearest_phase_for_bit
   piel.flows.extract_phase_from_fock_state_transitions
   piel.flows.format_electro_optic_fock_transition
   piel.flows.generate_s_parameter_circuit_from_photonic_circuit
   piel.flows.get_state_phase_transitions
   piel.flows.get_state_to_phase_map


Package Contents
----------------

.. py:function:: extract_component_spice_from_netlist(component: piel.types.CircuitComponent, output_path: piel.types.PathTypes = sys.stdout, fmt: str = 'spice')

.. py:function:: generate_verilog_and_verification_from_truth_table(module: piel.types.PathTypes, truth_table: piel.types.TruthTable, target_file_name: str = 'truth_table_module')

   Processes a truth table to generate an Amaranth module, converts it to Verilog,
   and creates a testbench for verification.

   Parameters:
   - truth_table (dict): The truth table defining the logic. It should be a dictionary where keys are
                         port names and values are lists of binary strings representing the truth table entries.
                         Example: {"detector_in": ["00", "01", "10", "11"], "phase_map_out": ["00", "10", "11", "11"]}
   - input_ports (list of str): A list of input port names that correspond to keys in the truth table.
                                Example: ["detector_in"]
   - output_ports (list of str): A list of output port names that correspond to keys in the truth table.
                                 Example: ["phase_map_out"]
   - module (str): The name or path of the module within the design hierarchy where the generated files
                   will be placed. This is used to determine the file structure and directory paths.
                   Example: "full_flow_demo"
   - target_file_name (str): The verilog and vcd file name.

   Returns:
   - None

   Steps:
   1. Combines the input and output connection into a single list.
   2. Constructs an Amaranth module from the provided truth table.
   3. Determines the appropriate directory and source folder for the design.
   4. Generates a Verilog file from the Amaranth module.
   5. Creates a testbench to verify the generated module logic and produces a VCD file.


.. py:function:: get_latest_digital_run_component(module: piel.types.PathTypes, *args, **kwargs) -> piel.types.CircuitComponent

.. py:function:: read_simulation_data_to_truth_table(file_path: piel.types.PathTypes, input_ports: piel.types.LogicSignalsList, output_ports: piel.types.LogicSignalsList, *args, **kwargs) -> piel.types.TruthTable

   The goal of this function is to read an existing simulation files output from cocotb and convert it into a valid Dataframe with proper type validation of bit signals into the corresponding byte formats.

   Args:
   - file_path (PathTypes): The path to the simulation files file.
   - input_ports (LogicSignalsList): The list of input port names.
   - output_ports (LogicSignalsList): The list of output port names.

   Returns:
   - truth_table (TruthTable): The truth table object containing the input and output port files.

   Examples:
   >>> read_simulation_data_to_truth_table("simulation_data.csv", ["input_port"], ["output_port"])
   TruthTable(input_ports=["input_port"], output_ports=["output_port"], ...)


.. py:function:: run_verification_simulation_for_design(module: piel.types.PathTypes, top_level_verilog_module: str, test_python_module: str, simulator: piel.types.HDLSimulator = 'icarus')

   Configures and runs a Cocotb simulation for a given design module and retrieves the simulation files.
   TODO possibly in the future swap the methodology of running the simulation here.

   Parameters:
   - module (str): The name or path of the module within the design hierarchy where the generated files
                   will be placed. This is used to determine the file structure and directory paths.
                   Example: "full_flow_demo"
   - top_level_verilog_module (str): The name of the top-level Verilog module in the design.
                                       Example: "full_flow_demo_module"
   - test_python_module (str): The name of the Python test module for the design.
                               Example: "test_full_flow_demo"
   - simulator (HDLSimulator): The simulator to use for the Cocotb simulation. Default is "icarus".

   Returns:
   - example_simulation_data: The simulation files read from the output files.


.. py:function:: layout_truth_table(truth_table: piel.types.TruthTable, module: piel.types.PathTypes) -> piel.types.ElectronicCircuitComponent

   Layout a truth table through the OpenLane flow and create a GDSFactory component.

   Parameters:
   - truth_table (TruthTable): The truth table object containing the input and output port files.
   - module (str): The name or path of the module within the design hierarchy where the generated files
                   will be placed. This is used to determine the file structure and directory paths.
                   Example: "full_flow_demo"

   Returns:
   - digital_component (gf.Component): The GDSFactory component representing the layout of the truth table as implemented by OpenLane


.. py:function:: add_truth_table_phase_to_bit_data(truth_table: piel.types.TruthTable, bit_phase_map: piel.types.BitPhaseMap, phase_column_name: str = None, rounding_function: Optional[Callable] = None) -> piel.types.TruthTable

   This function converts the phase column of a dataframe into a bit tuple using the phase_bit_dataframe. The
   phase_bit_dataframe is a dataframe that maps the phase to the bit. The phase_series_name is the name of the
   phase series in the phase_bit_dataframe. The bit_series_name is the name of the bit series in the
   phase_bit_dataframe. The phase_column_name is the name of the phase column in the dataframe. The function returns
   a tuple of bits that correspond to the phase column of the dataframe.

   :param truth_table: The dataframe that contains the phase column.
   :type truth_table: pd.DataFrame
   :param bit_phase_map: The dataframe that maps the phase to the bit.
   :type bit_phase_map: BitPhaseMap
   :param rounding_function: The rounding function that is used to round the phase to the nearest
                             phase in the phase_bit_dataframe.
   :type rounding_function: Optional[Callable]

   :returns: A tuple of bits that correspond to the phase column of the dataframe.
   :rtype: tuple


.. py:function:: convert_phase_to_bit_iterable(phase: piel.types.PhaseMapType, bit_phase_map: piel.types.BitPhaseMap, rounding_function: Optional[Callable] = None) -> tuple

   This function converts a phase array or tuple iterable, into the corresponding mapping of their bitstring
   required within a particular bit-phase mapping. A ``phase_array`` iterable is provided, and each phase is mapped
   to a particular bitstring based on the ``phase_bit_dataframe``. A tuple is composed of strings that represent the
   bitstrings of the phases provided.

   :param phase: Iterable of phases to map to bitstrings.
   :type phase: Iterable
   :param bit_phase_map: Dataframe containing the phase-bits mapping.
   :type bit_phase_map: BitPhaseMap
   :param rounding_function: Rounding function to apply to the target phase.
   :type rounding_function: Callable

   :returns: Tuple of bitstrings corresponding to the phases.
   :rtype: bit_array(tuple)


.. py:function:: find_nearest_bit_for_phase(target_phase: float, bit_phase_map: piel.types.BitPhaseMap, rounding_function: Optional[Callable] = None) -> tuple

   This is a mapping function between a provided target phase that might be more analogous, with the closest
   bit-value in a `bit-phase` ideal relationship. The error between the target phase and the applied phase is
   limited to the discretisation error of the phase mapping.

   :param target_phase: Target phase to map to.
   :type target_phase: float
   :param bit_phase_map: Dataframe containing the phase-bits mapping.
   :type bit_phase_map: pd.DataFrame
   :param rounding_function: Rounding function to apply to the target phase.
   :type rounding_function: Callable

   :returns: Bitstring corresponding to the nearest phase.
   :rtype: bitstring(str)


.. py:function:: find_nearest_phase_for_bit(bits: piel.types.BitsType, phase_map: piel.types.BitPhaseMap) -> piel.types.PhaseMapType

   Maps a bitstring to the nearest phase(s) in a phase-bit mapping dataframe.

   :param bits: Bitstring to map to a phase.
   :type bits: AbstractBitsType
   :param phase_map: Dataframe containing the phase-bits mapping.
   :type phase_map: BitPhaseMap

   :returns: Tuple of phases or an empty tuple if no match is found.
   :rtype: Tuple[str, ...]


.. py:function:: extract_phase_from_fock_state_transitions(optical_state_transitions: piel.types.OpticalStateTransitionCollection, transition_type: piel.types.PhaseTransitionTypes = 'cross')

   Extracts the phase corresponding to the specified transition type.

   Parameters:
   optical_state_transitions (OpticalStateTransitionCollection): Optical state transitions.
       transition_type (str): Type of transition to extract phase for ('cross' or 'bar').

   :returns: Phase corresponding to the specified transition type.
   :rtype: float


.. py:function:: format_electro_optic_fock_transition(switch_state_array: piel.types.ArrayTypes, input_fock_state_array: piel.types.ArrayTypes, raw_output_state: piel.types.ArrayTypes, **kwargs) -> piel.types.FockStatePhaseTransition

   Formats the electro-optic state into a standard FockStatePhaseTransition format. This is useful for the
   electro-optic model to ensure that the output state is in the correct format. The output state is a dictionary
   that contains the phase, input fock state, and output fock state. The idea is that this will allow us to
   standardise and compare the output states of the electro-optic model across multiple formats.

   :param switch_state_array: Array of switch states.
   :type switch_state_array: array_types
   :param input_fock_state_array: Array of valid input fock states.
   :type input_fock_state_array: array_types
   :param raw_output_state: Array of raw output state.
   :type raw_output_state: array_types
   :param \*\*kwargs: Additional keyword arguments.

   :returns: Electro-optic state.
   :rtype: electro_optic_state(FockStatePhaseTransition)


.. py:function:: generate_s_parameter_circuit_from_photonic_circuit(circuit: piel.types.PhotonicCircuitComponent, models: Any = None, netlist_function: Optional[Callable] = None) -> tuple[any, any]

   Generates the S-parameters and related information for a given circuit using SAX and custom measurement.

   :param circuit: The circuit for which the S-parameters are to be generated.
   :type circuit: gf.Component
   :param models: The measurement to be used for the S-parameter generation. Defaults to None.
   :type models: sax.ModelFactory, optional
   :param netlist_function: The function to generate the netlist. Defaults to None.
   :type netlist_function: Callable, optional

   :returns: The S-parameters circuit and related information.
   :rtype: tuple[any, any]


.. py:function:: get_state_phase_transitions(circuit_component: piel.types.PhotonicCircuitComponent, models: dict = None, mode_amount: int = None, input_fock_states: list[piel.types.ArrayTypes] | None = None, switch_states: list[piel.types.NumericalTypes] | None = None, determine_ideal_mode_function: Optional[Callable] = None, netlist_function: Optional[Callable] = None, target_mode_index: Optional[int] = None, **kwargs) -> piel.types.OpticalStateTransitionCollection

   The goal of this function is to extract the corresponding phase required to implement a state transition.

   Let's consider a simple MZI 2x2 logic with two transmission states. We want to verify that the electronic function
   switch, effectively switches the optical output between the cross and bar states of the optical transmission function.

   For the corresponding switch model:

   Let's assume a switch model unitary. For a given 2x2 input optical switch "X". In bar state, in dual rail, transforms an optical input:
   ```
   .. raw::

       [[1] ----> [[1]
       [0]]        [0]]

   In cross state, in dual rail, transforms an optical input:

   .. raw::

       [[1] ----> [[0]
       [0]]        [1]]

   However, sometimes it is easier to describe a photonic logic transformation based on these states, rather than inherently
   the numerical phase that is applied. This may be the case, for example, in asymmetric Mach-Zehnder modulators measurement, etc.

   As such, this function will help us extract the corresponding phase for a particular switch transition.

   When the switch function is larger than a single switch, it is necessary to extract the location of the corresponding switches as function parameters.


.. py:function:: get_state_to_phase_map(switch_function: piel.types.OpticalTransmissionCircuit, switch_states: list[piel.types.NumericalTypes] | None = None, input_fock_states: list[piel.types.ArrayTypes] | None = None, target_transition_list: list[dict] | None = None, mode_amount: int | None = None, **kwargs) -> tuple[piel.types.ArrayTypes]

   The goal of this function is to extract the corresponding phase required to implement a state transition.

   Let's consider a simple MZI 2x2 logic with two transmission states. We want to verify that the electronic function
   switch, effectively switches the optical output between the cross and bar states of the optical transmission function.

   For the corresponding switch model:

   Let's assume a switch model unitary. For a given 2x2 input optical switch "X". In bar state, in dual rail, transforms an optical input:
   ```
   .. raw::

       [[1] ----> [[1]
       [0]]        [0]]

   In cross state, in dual rail, transforms an optical input:

   .. raw::

       [[1] ----> [[0]
       [0]]        [1]]

   However, sometimes it is easier to describe a photonic logic transformation based on these states, rather than inherently
   the numerical phase that is applied. This may be the case, for example, in asymmetric Mach-Zehnder modulators measurement, etc.

   As such, this function will help us extract the corresponding phase for a particular switch transition.


