piel.integration#
Submodules#
- piel.integration.amaranth_cocotb
- piel.integration.amaranth_openlane
- piel.integration.cocotb_sax
- piel.integration.gdsfactory_hdl21
- piel.integration.gdsfactory_openlane
- piel.integration.hdl21_gdsfactory
- piel.integration.sax_qutip
- piel.integration.sax_thewalrus
- piel.integration.signal
- piel.integration.thewalrus_qutip
Attributes#
Functions#
Creates a cocotb test script for verifying logic defined by the truth table. |
|
|
Implements an Amaranth truth table module through the OpenLane flow. |
|
Translates a truth table to an OpenLane flow implementation. |
|
Not for the hdl21 design flow, but useful for other SPICE level conversions. |
This function converts a GDSFactory electrical netlist into a standard SPICE netlist. It follows the same |
|
|
This function allows us to map the |
|
This function returns a list of tuples that match the names of the connections. |
|
|
|
This function converts a gdsfactory-spice converted netlist using the component measurement into a SPICE circuit. |
|
Convert from: |
|
Filter the port name to match spice declaration to gds port name, specifically focused on the SKY130nm technology. |
|
|
|
Constructs a SchematicEditor instance from a hdl21 module object. |
|
Generate a raw netlist yaml from a hdl21 module object which could be manually edited for specific instances |
Generate a raw netlist dictionary from a hdl21 module object. |
|
|
The permanent of a unitary is used to determine the state probability of combinatorial Gaussian boson samping systems. |
A |
|
|
|
|
|
This function returns the transition probability amplitude between two Fock states when propagating in between |
|
This function takes in any supported FrequencyTransmissionModel and provides translation between the different |
Package Contents#
- create_cocotb_truth_table_verification_python_script(module: piel.types.PathTypes, truth_table: piel.types.digital.TruthTable, test_python_module_name: str = 'top_test')[source]#
Creates a cocotb test script for verifying logic defined by the truth table.
- Parameters:
module (PathTypes) – The path to the module where the test script will be placed.
truth_table (TruthTable) – A dictionary representing the truth table.
test_python_module_name (str, optional) – The name of the test python module. Defaults to “top_test”.
Example
- truth_table = {
“A”: [0, 0, 1, 1], “B”: [0, 1, 0, 1], “X”: [0, 1, 1, 0] # Expected output (for XOR logic, as an example)
} create_cocotb_truth_table_verification_python_script(truth_table)
- layout_amaranth_truth_table_through_openlane(amaranth_module: piel.types.DigitalLogicModule, truth_table: piel.types.TruthTable, parent_directory: piel.types.PathTypes, target_directory_name: str | None = None, openlane_version: Literal['v1', 'v2'] = 'v2', openlane_configuration: dict | None = None, **kwargs)[source]#
Implements an Amaranth truth table module through the OpenLane flow.
This function implements an amaranth truth-table module through the openlane flow. There are several ways to implement a module. Fundamentally, this requires the verilog files to be generated from the openlane-module in a particular directory. For the particular directory provided, this function will generate the verilog files in the corresponding directory. It can also generate the
openlaneconfiguration files for this particular location.This function does a few things:
Starts off from a
amaranthmodule class.Determines the output directory in which to generate the files, and creates one accordingly if it does not exist.
Generates the verilog files from the
amaranthmodule class.Generates the
openlaneconfiguration files for this particular location.Implements the
openlaneflow for this particular location to generate a chip.
- Parameters:
amaranth_module (am.Module) – The Amaranth module representing the truth table logic.
truth_table (TruthTable) – The truth table files structure containing the logic for the module.
parent_directory (PathTypes) – The directory where the project will be created or found.
target_directory_name (Optional[str]) – The name for the target directory. Defaults to the name of the Amaranth module’s class.
openlane_version (Literal["v1", "v2"]) – The version of OpenLane to use. Defaults to “v2”.
**kwargs – Additional keyword arguments for OpenLane configuration.
- Returns:
None
- layout_truth_table_through_openlane(truth_table: piel.types.TruthTable, parent_directory: piel.types.PathTypes, target_directory_name: str | None = None, openlane_version: Literal['v1', 'v2'] = 'v2', **kwargs)[source]#
Translates a truth table to an OpenLane flow implementation.
This function takes a truth table and converts it into an OpenLane flow, using the specified OpenLane version. It first constructs an Amaranth module from the truth table, and then passes this module to the layout_amaranth_truth_table_through_openlane function for further processing.
- Parameters:
truth_table (TruthTable) – The truth table to be converted. It includes input connection, output connection, and the table logic.
parent_directory (PathTypes) – The directory where the OpenLane project will be created.
target_directory_name (Optional[str]) – Name of the target directory. If not specified, a default name will be used.
openlane_version (Literal["v1", "v2"]) – Specifies the OpenLane version to use. Defaults to “v2”.
**kwargs – Additional keyword arguments passed to the Amaranth module construction.
- Returns:
None
- create_gdsfactory_component_from_openlane(design_name_v1: str | None = None, design_directory: piel.types.PathTypes | None = None, run_name: str | None = None, v1: bool = False) piel.types.PhotonicCircuitComponent[source]#
- gdsfactory_netlist_to_spice_string_connectivity_netlist(gdsfactory_netlist: dict, models=None)[source]#
Not for the hdl21 design flow, but useful for other SPICE level conversions.
This function maps the connections of a netlist to a node that can be used in a SPICE netlist. SPICE netlists are in the form of:
RXXXXXXX N1 N2 <VALUE> <MNAME> <L=LENGTH> <W=WIDTH> <TEMP=T>
This means that every instance, is an electrical type, and we define the two particular nodes in which it is connected. This means we need to convert the gdsfactory dictionary netlist into a form that allows us to map the connectivity for every instance. Then we can define that as a line of the SPICE netlist with a particular electrical model. For passives this works fine when it’s a two port network such as sources, or electrical elements. However, non-passive elements like transistors have three connection or more which are provided in an ordered form.
This means that the order of translations is as follows:
1. Extract all instances and required measurement from the netlist, and assign the corresponding parameters on instantiation. 2. Verify that the measurement have been provided. Each model describes the type of component this is, how many connection it requires and so on. 3. Map the connections to each instance port as part of the instance dictionary.
We should get as an output a dictionary in the structure:
{ instance_1: { ... "connections": [('straight_1,e1', 'taper_1,e2'), ('straight_1,e2', 'taper_2,e2')], 'spice_nets': {'e1': 'straight_1__e1___taper_1__e2', 'e2': 'straight_1__e2___taper_2__e2'}, 'spice_model': <function piel.measurement.physical.electronic.spice.resistor.basic_resistor()>}, } ... }
- gdsfactory_netlist_to_spice_netlist(gdsfactory_netlist: dict, generators: dict, **kwargs) piel.types.AnalogueModule[source]#
This function converts a GDSFactory electrical netlist into a standard SPICE netlist. It follows the same principle as the sax circuit composition.
Each GDSFactory netlist has a set of instances, each with a corresponding model, and each instance with a given set of geometrical settings that can be applied to each particular model. We know the type of SPICE model from the instance model we provides.
We know that the gdsfactory has a set of instances, and we can map unique measurement via sax through our own composition circuit. Write the SPICE component based on the model into a total circuit representation in string from the reshaped gdsfactory dictionary into our own structure.
- Parameters:
gdsfactory_netlist – GDSFactory netlist
generators – Dictionary of Generators
- Returns:
hdl21 module or raw SPICE string
- gdsfactory_netlist_with_hdl21_generators(gdsfactory_netlist: dict, generators=None)[source]#
This function allows us to map the
hdl21measurement dictionary in a sax-like implementation to theGDSFactorynetlist. This allows us to iterate over each instance in the netlist and construct a circuit after this function.]Example usage:
>>> import gdsfactory as gf >>> from piel.integration.gdsfactory_hdl21.conversion import gdsfactory_netlist_with_hdl21_generators >>> from piel.measurement.physical.electronic import get_default_models >>> gdsfactory_netlist_with_hdl21_generators(gdsfactory_netlist=gf.components.mzi2x2_2x2_phase_shifter().get_netlist(exclude_port_types="optical"),generators=get_default_models())
- Parameters:
gdsfactory_netlist – The netlist from
GDSFactoryto map to thehdl21measurement dictionary.generators – The
hdl21measurement dictionary to map to theGDSFactorynetlist.
- Returns:
The
GDSFactorynetlist with thehdl21measurement dictionary.
- get_matching_connections(names: list, connections: dict)[source]#
This function returns a list of tuples that match the names of the connections.
- Parameters:
names – List of names to match
connections – Dictionary of connections to match
- Returns:
List of tuples that match the names of the connections
- construct_hdl21_module(spice_netlist: dict, **kwargs) piel.types.AnalogueModule[source]#
This function converts a gdsfactory-spice converted netlist using the component measurement into a SPICE circuit.
Part of the complexity of this function is the multiport nature of some components and measurement, and assigning the parameters accordingly into the SPICE function. This is because not every SPICE component will be bi-port, and many will have multi-connection and parameters accordingly. Each model can implement the composition into a SPICE circuit, but they depend on a set of parameters that must be set from the instance. Another aspect is that we may want to assign the component ID according to the type of component. However, we can also assign the ID based on the individual instance in the circuit, which is also a reasonable approximation. However, it could be said, that the ideal implementation would be for each component model provided to return the SPICE instance including connectivity except for the ID.
# TODO implement validators
- convert_connections_to_tuples(connections: dict)[source]#
Convert from:
{ 'straight_1,e1': 'taper_1,e2', 'straight_1,e2': 'taper_2,e2', 'taper_1,e1': 'via_stack_1,e3', 'taper_2,e1': 'via_stack_2,e1' }
to:
[(('straight_1', 'e1'), ('taper_1', 'e2')), (('straight_1', 'e2'), ('taper_2', 'e2')), (('taper_1', 'e1'), ('via_stack_1', 'e3')), (('taper_2', 'e1'), ('via_stack_2', 'e1'))]
- filter_port(port)[source]#
Filter the port name to match spice declaration to gds port name, specifically focused on the SKY130nm technology.
- hdl21_module_to_schematic_editor(module: piel.types.AnalogueModule, yaml_schematic_file_name: str, spice_gds_mapping_method: Callable | None = find_most_relevant_gds, port_filter_method: Callable = filter_port)[source]#
Constructs a SchematicEditor instance from a hdl21 module object.
- Parameters:
module (h.module) – The hdl21 module object.
yaml_schematic_file_name (str) – The yaml schematic file name.
spice_gds_mapping_method (Callable) – The method to map the spice instance name to the component name.
port_filter_method (Callable) – The method to filter the port name.
- generate_raw_yaml_from_module(module: piel.types.AnalogueModule)[source]#
Generate a raw netlist yaml from a hdl21 module object which could be manually edited for specific instances related to the corresponding SPICE.
- generate_raw_netlist_dict_from_module(module: piel.types.AnalogueModule)[source]#
Generate a raw netlist dictionary from a hdl21 module object. This just gives us a raw structure of the hdl21 modules, we cannot use this json equivalently to a gdsfactory netlist.
- ParsedProtoVLSIR#
- sax_circuit_permanent(sax_input: Any) tuple[source]#
The permanent of a unitary is used to determine the state probability of combinatorial Gaussian boson samping systems.
thewalrusRyser’s algorithm permananet implementation is described here: https://the-walrus.readthedocs.io/en/latest/gallery/permanent_tutorial.html# TODO maybe implement subroutine if computation is taking forever.
- Parameters:
sax_input (sax.SType) – The sax S-parameter dictionary.
- Returns:
The circuit permanent and the time it took to compute it.
- Return type:
tuple
- sax_to_s_parameters_standard_matrix(sax_input: Any, input_ports_order: tuple[str] | None = None, round_int: bool | None = None, *args, **kwargs) piel.types.SParameterMatrixTuple[source]#
A
saxS-parameter SDict is provided as a dictionary of tuples with (port0, port1) as the key. This determines the direction of the scattering relationship. It means that the number of terms in an S-parameter matrix is the number of connection squared.In order to generalise, this function returns both the S-parameter matrices and the indexing connection based on the amount provided. In terms of computational speed, we definitely would like this function to be algorithmically very fast. For now, I will write a simple python implementation and optimise in the future.
It is possible to see the sax SDense notation equivalence here: https://flaport.github.io/sax/nbs/08_backends.html
import jax.numpy as jnp from sax.core import SDense # Directional coupler SDense representation dc_sdense: SDense = ( jnp.array([[0, 0, τ, κ], [0, 0, κ, τ], [τ, κ, 0, 0], [κ, τ, 0, 0]]), {"in0": 0, "in1": 1, "out0": 2, "out1": 3}, ) # Directional coupler SDict representation # Taken from https://flaport.github.io/sax/nbs/05_models.html def coupler(*, coupling: float = 0.5) -> SDict: kappa = coupling**0.5 tau = (1 - coupling) ** 0.5 sdict = reciprocal( { ("in0", "out0"): tau, ("in0", "out1"): 1j * kappa, ("in1", "out0"): 1j * kappa, ("in1", "out1"): tau, } ) return sdict
If we were to relate the mapping accordingly based on the connection indexes, a S-Parameter matrix in the form of \(S_{(output,i),(input,i)}\) would be:
\[\begin{split}S = \begin{bmatrix} S_{00} & S_{10} \\ S_{01} & S_{11} \\ \end{bmatrix} = \begin{bmatrix} \tau & j \kappa \\ j \kappa & \tau \\ \end{bmatrix}\end{split}\]Note that the standard S-parameter and hence unitary representation is in the form of:
\[\begin{split}S = \begin{bmatrix} S_{00} & S_{01} \\ S_{10} & S_{11} \\ \end{bmatrix}\end{split}\]\[\begin{split}\begin{bmatrix} b_{1} \\ \vdots \\ b_{n} \end{bmatrix} = \begin{bmatrix} S_{11} & \dots & S_{1n} \\ \vdots & \ddots & \vdots \\ S_{n1} & \dots & S_{nn} \end{bmatrix} \begin{bmatrix} a_{1} \\ \vdots \\ a_{n} \end{bmatrix}\end{split}\]TODO check with Floris, does this mean we need to transpose the matrix? TODO document round_int
- Parameters:
sax_input (sax.SType) – The sax S-parameter dictionary.
input_ports_order (tuple) – The connection order tuple containing the names and order of the input connection.
round_int (bool) – Whether to round the complex numbers to integers.
- Returns:
The S-parameter matrix and the input connection index tuple in the standard S-parameter notation.
- Return type:
tuple
- sax_to_ideal_qutip_unitary(sax_input: piel.types.OpticalTransmissionCircuit, input_ports_order: tuple | None = None)[source]#
- verify_sax_model_is_unitary(model: piel.types.OpticalTransmissionCircuit, input_ports_order: tuple | None = None) bool[source]#
- fock_transition_probability_amplitude(initial_fock_state: Any, final_fock_state: Any, unitary_matrix: jax.numpy.ndarray)[source]#
This function returns the transition probability amplitude between two Fock states when propagating in between the unitary_matrix which represents a quantum state circuit.
Note that based on (TODO cite Jeremy), the initial Fock state corresponds to the columns of the unitary and the final Fock states corresponds to the rows of the unitary.
\[\]ewcommand{ket}[1]{left|{#1} ight angle}
The subunitary \(U_{f_1}^{f_2}\) is composed from the larger unitary by selecting the rows from the output state Fock state occupation of \(\ket{f_2}\), and columns from the input \(\ket{f_1}\). In our case, we need to select the columns indexes \((0,3)\) and rows indexes \((1,2)\).
If we consider a photon number of more than one for the transition Fock states, then the Permanent needs to be normalised. The probability amplitude for the transition is described as:
\[a(\ket{f_1} o \ket{f_2}) =\]rac{ ext{per}(U_{f_1}^{f_2})}{sqrt{(j_1! j_2! … j_N!)(j_1^{‘}! j_2^{‘}! … j_N^{‘}!)}}
- Args:
initial_fock_state (qutip.Qobj | jnp.ndarray): The initial Fock state. final_fock_state (qutip.Qobj | jnp.ndarray): The final Fock state. unitary_matrix (jnp.ndarray): The unitary matrix that represents the quantum state circuit.
- Returns:
float: The transition probability amplitude between the initial and final Fock states.
- convert_to_network_transmission(network: piel.types.FrequencyTransmissionModel) piel.types.NetworkTransmission[source]#
This function takes in any supported FrequencyTransmissionModel and provides translation between the different domain representations and returns a standard NetworkTransmission class.