diff --git a/docs/examples/07_full_flow_demo_electronic_photonic/07_full_flow_demo_electronic_photonic.py b/docs/examples/07_full_flow_demo_electronic_photonic/07_full_flow_demo_electronic_photonic.py index d0d1f027..94c8aca0 100644 --- a/docs/examples/07_full_flow_demo_electronic_photonic/07_full_flow_demo_electronic_photonic.py +++ b/docs/examples/07_full_flow_demo_electronic_photonic/07_full_flow_demo_electronic_photonic.py @@ -124,6 +124,8 @@ def create_switch_fabric(): chain_3_mode_lattice_circuit = create_switch_fabric() chain_3_mode_lattice_circuit +chain_3_mode_lattice_circuit + # ## 2. Extracting our optical-to-electronic control logic truth table @@ -249,6 +251,17 @@ def create_switch_fabric(): # | 1 | 001 | 00000 | 11111 | # | 2 | 010 | 11111 | 00000 | +transition_dataframe_latex = ( + piel.visual.table.electronic.compose_fock_state_truth_table_latex( + truth_table.dataframe + ) +) +piel.write_file( + directory_path=os.getenv("TAT"), + file_text=transition_dataframe_latex, + file_name="chain_3_truth_table.tex", +) + truth_table.input_ports truth_table.output_ports @@ -366,7 +379,7 @@ def create_switch_fabric(): # Now, we could technically also use this simulation to model our optical signal transmission too. -# + +# + active="" # # Current work in progress move this out of here. # simple_ideal_o4_mzi_2x2_plots = piel.experimental.plot_simple_multi_row( # files=mzi2x2_simple_simulation_data_lines, @@ -382,13 +395,13 @@ def create_switch_fabric(): # "../_static/img/examples/03a_sax_active_cosimulation/simple_ideal_o4_mzi_2x2_plots.PNG" # ) -# + +# + active="" # # Current work in progress move this out of here. # import pandas as pd # import sax # from typing import Callable - - +# +# # def compute_simulation_unitaries( # simulation_data: pd.DataFrame, # phase_mapping_function: Callable, @@ -399,7 +412,7 @@ def create_switch_fabric(): # ) -> List[Any]: # """ # Processes simulation files to generate a list of unitaries using a digital-to-phase model and a custom library. - +# # Args: # simulation_data (pd.DataFrame): DataFrame containing simulation files. # phase_mapping_function (Callable): Function to map files series to phase array. @@ -410,7 +423,7 @@ def create_switch_fabric(): # library_defaults (Dict[str, Any]): Default parameters for the custom model library. # s_parameters_function (Callable): Function to convert model output to S-parameters matrix. # input_ports_order (Tuple[str, str]): Order of input connection for the S-parameters function. - +# # Returns: # List[Any]: List of unitaries corresponding to the phase array. # """ @@ -418,46 +431,46 @@ def create_switch_fabric(): # data_series = simulation_data[data_series_key] # phase_array = phase_mapping_function(data_series=data_series, phase_map=phase_map) # simulation_data["phase"] = phase_array - +# # # Create the circuit model using the netlist and custom library # circuit_model, _ = sax.circuit(netlist=netlist, measurement=custom_library) - +# # # Generate unitaries for each phase in the phase array # unitaries = [] # for phase in phase_array: # # Compute the unitary for the current phase # unitary = s_parameters_function(circuit_model(sxt={"active_phase_rad": phase})) # unitaries.append(unitary) - +# # return unitaries - - +# +# # # def compute_simulation_unitaries(): # # Inputs # # digital-to-phase model # # simulation files file # # sax-circuit-model library # # output returns list of unitaries accordingly - +# # # basic_ideal_phase_array = ( # # piel.measurement.logic.electro_optic.return_phase_array_from_data_series( # # data_series=example_simple_simulation_data.x, phase_map=basic_ideal_phase_map # # ) # # ) - +# # # example_simple_simulation_data["phase"] = basic_ideal_phase_array # # example_simple_simulation_data - +# # # our_custom_library = piel.measurement.frequency.compose_custom_model_library_from_defaults( # # {"straight_heater_metal_undercut": straight_heater_metal_simple} # # ) # # our_custom_library - +# # # mzi2x2_model, mzi2x2_model_info = sax.circuit( # # netlist=mzi2x2_2x2_phase_shifter_netlist, measurement=our_custom_library # # ) # # piel.tools.sax.sax_to_s_parameters_standard_matrix(mzi2x2_model(), input_ports_order=("o2", "o1")) - +# # # mzi2x2_active_unitary_array = list() # # for phase_i in example_simple_simulation_data.phase: # # mzi2x2_active_unitary_i = piel.tools.sax.sax_to_s_parameters_standard_matrix( @@ -471,32 +484,32 @@ def create_switch_fabric(): # # mzi2x2_active_unitary_array.append(mzi2x2_active_unitary_i) -# + +# + active="" # Inputs # digital-to-phase model # simulation files file # sax-circuit-model library # output returns list of unitaries accordingly - +# # basic_ideal_phase_array = ( # piel.measurement.logic.electro_optic.return_phase_array_from_data_series( # data_series=example_simple_simulation_data.x, phase_map=basic_ideal_phase_map # ) # ) - +# # example_simple_simulation_data["phase"] = basic_ideal_phase_array # example_simple_simulation_data - +# # our_custom_library = piel.measurement.frequency.compose_custom_model_library_from_defaults( # {"straight_heater_metal_undercut": straight_heater_metal_simple} # ) # our_custom_library - +# # mzi2x2_model, mzi2x2_model_info = sax.circuit( # netlist=mzi2x2_2x2_phase_shifter_netlist, measurement=our_custom_library # ) # piel.tools.sax.sax_to_s_parameters_standard_matrix(mzi2x2_model(), input_ports_order=("o2", "o1")) - +# # mzi2x2_active_unitary_array = list() # for phase_i in example_simple_simulation_data.phase: # mzi2x2_active_unitary_i = piel.tools.sax.sax_to_s_parameters_standard_matrix( @@ -507,19 +520,19 @@ def create_switch_fabric(): # ), # ) # mzi2x2_active_unitary_array.append(mzi2x2_active_unitary_i) - +# # second function up to here - +# # third function starts here. - +# # optical_port_input = np.array([1, 0]) # optical_port_input - +# # example_optical_power_output = np.dot( # mzi2x2_simple_simulation_data.unitary.iloc[0][0], optical_port_input # ) # example_optical_power_output - +# # output_amplitude_array_0 = np.array([]) # output_amplitude_array_1 = np.array([]) # for unitary_i in mzi2x2_simple_simulation_data.unitary: @@ -531,17 +544,17 @@ def create_switch_fabric(): # output_amplitude_array_1, output_amplitude_i[1] # ) # output_amplitude_array_0 - +# # mzi2x2_simple_simulation_data["output_amplitude_array_0"] = output_amplitude_array_0 # mzi2x2_simple_simulation_data["output_amplitude_array_1"] = output_amplitude_array_1 # mzi2x2_simple_simulation_data - +# # mzi2x2_simple_simulation_data_lines = piel.experimental.points_to_lines_fixed_transient( # files=mzi2x2_simple_simulation_data, # time_index_name="t", # fixed_transient_time=1, # ) - +# # simple_ideal_o3_mzi_2x2_plots = piel.experimental.plot_simple_multi_row( # files=mzi2x2_simple_simulation_data_lines, # x_axis_column_name="t", @@ -559,6 +572,27 @@ def create_switch_fabric(): # ## 3b. Digital Chip Implementation +# Note that in order to run this you will need to have a PDK installed locally. This is not provided intentionally within the `piel-nix` environment. You can simply run the following command within the `piel-nix` environment: +# +# ``` +# openlane --volare-pdk +# ``` + +# + +# # !openlane --volare-pdk +# - + +# Now you can verify you have the right environment configuration by running the smoke test: + +# + +# # !openlane --smoke-test +# - + +# You should see: +# ``` +# [09:07:02] INFO Smoke test passed. ]8;id=893291;file:///nix/store/9jb8wsk32ny2yy5ghcaq3y7mbmmavi2c-python3.11-openlane/lib/python3.11/site-packages/openlane/__main__.py\__main__.py]8;;\:]8;id=568740;file:///nix/store/9jb8wsk32ny2yy5ghcaq3y7mbmmavi2c-python3.11-openlane/lib/python3.11/site-packages/openlane/__main__.py#267\267]8;;\ +# ``` + component = piel.flows.layout_truth_table( truth_table=truth_table, module=full_flow_demo, diff --git a/docs/examples/07_full_flow_demo_electronic_photonic/full_flow_demo/full_flow_demo/config.json b/docs/examples/07_full_flow_demo_electronic_photonic/full_flow_demo/full_flow_demo/config.json index ea5ce012..3018e99b 100644 --- a/docs/examples/07_full_flow_demo_electronic_photonic/full_flow_demo/full_flow_demo/config.json +++ b/docs/examples/07_full_flow_demo_electronic_photonic/full_flow_demo/full_flow_demo/config.json @@ -38,7 +38,6 @@ "FP_PDN_VOFFSET": 5, "FP_PDN_HOFFSET": 5, "FP_SIZING": "absolute", - "PDK": "sky130A", "pdk::sky130A": { "MAX_FANOUT_CONSTRAINT": 6, "FP_CORE_UTIL": 40, diff --git a/docs/examples/07_full_flow_demo_electronic_photonic/full_flow_demo/full_flow_demo/src/truth_table_module.v b/docs/examples/07_full_flow_demo_electronic_photonic/full_flow_demo/full_flow_demo/src/truth_table_module.v index 2cb2310c..84b9c565 100644 --- a/docs/examples/07_full_flow_demo_electronic_photonic/full_flow_demo/full_flow_demo/src/truth_table_module.v +++ b/docs/examples/07_full_flow_demo_electronic_photonic/full_flow_demo/full_flow_demo/src/truth_table_module.v @@ -1,52 +1,52 @@ -/* Generated by Amaranth Yosys 0.40 (PyPI ver 0.40.0.0.post100, git sha1 a1bb0255d) */ +/* Generated by Yosys 0.38 (git sha1 543faed9c8c, clang++ 17.0.6 -fPIC -Os) */ (* top = 1 *) (* generator = "Amaranth" *) module top(bit_phase_0, bit_phase_1, input_fock_state_str); - reg \$auto$verilog_backend.cc:2352:dump_module$1 = 0; - (* src = "/home/daquintero/phd/piel/piel/tools/amaranth/construct.py:86" *) + reg \$auto$verilog_backend.cc:2334:dump_module$1 = 0; + (* src = "/nix/store/c6rxsq40wg2715fm1zpzbld1x83y8r8j-python3.11-piel-0.1.0/lib/python3.11/site-packages/piel/tools/amaranth/construct.py:86" *) output [4:0] bit_phase_0; reg [4:0] bit_phase_0; - (* src = "/home/daquintero/phd/piel/piel/tools/amaranth/construct.py:86" *) + (* src = "/nix/store/c6rxsq40wg2715fm1zpzbld1x83y8r8j-python3.11-piel-0.1.0/lib/python3.11/site-packages/piel/tools/amaranth/construct.py:86" *) output [4:0] bit_phase_1; reg [4:0] bit_phase_1; - (* src = "/home/daquintero/phd/piel/piel/tools/amaranth/construct.py:82" *) + (* src = "/nix/store/c6rxsq40wg2715fm1zpzbld1x83y8r8j-python3.11-piel-0.1.0/lib/python3.11/site-packages/piel/tools/amaranth/construct.py:82" *) input [2:0] input_fock_state_str; wire [2:0] input_fock_state_str; always @* begin - if (\$auto$verilog_backend.cc:2352:dump_module$1 ) begin end + if (\$auto$verilog_backend.cc:2334:dump_module$1 ) begin end (* full_case = 32'd1 *) - (* src = "/home/daquintero/phd/piel/piel/tools/amaranth/construct.py:112" *) + (* src = "/nix/store/c6rxsq40wg2715fm1zpzbld1x83y8r8j-python3.11-piel-0.1.0/lib/python3.11/site-packages/piel/tools/amaranth/construct.py:112" *) casez (input_fock_state_str) - /* src = "/home/daquintero/phd/piel/piel/tools/amaranth/construct.py:115" */ + /* src = "/nix/store/c6rxsq40wg2715fm1zpzbld1x83y8r8j-python3.11-piel-0.1.0/lib/python3.11/site-packages/piel/tools/amaranth/construct.py:115" */ 3'h4: bit_phase_0 = 5'h00; - /* src = "/home/daquintero/phd/piel/piel/tools/amaranth/construct.py:115" */ + /* src = "/nix/store/c6rxsq40wg2715fm1zpzbld1x83y8r8j-python3.11-piel-0.1.0/lib/python3.11/site-packages/piel/tools/amaranth/construct.py:115" */ 3'h1: bit_phase_0 = 5'h00; - /* src = "/home/daquintero/phd/piel/piel/tools/amaranth/construct.py:115" */ + /* src = "/nix/store/c6rxsq40wg2715fm1zpzbld1x83y8r8j-python3.11-piel-0.1.0/lib/python3.11/site-packages/piel/tools/amaranth/construct.py:115" */ 3'h2: bit_phase_0 = 5'h1f; - /* src = "/home/daquintero/phd/piel/piel/tools/amaranth/construct.py:124" */ + /* src = "/nix/store/c6rxsq40wg2715fm1zpzbld1x83y8r8j-python3.11-piel-0.1.0/lib/python3.11/site-packages/piel/tools/amaranth/construct.py:124" */ default: bit_phase_0 = 5'h00; endcase end always @* begin - if (\$auto$verilog_backend.cc:2352:dump_module$1 ) begin end + if (\$auto$verilog_backend.cc:2334:dump_module$1 ) begin end (* full_case = 32'd1 *) - (* src = "/home/daquintero/phd/piel/piel/tools/amaranth/construct.py:112" *) + (* src = "/nix/store/c6rxsq40wg2715fm1zpzbld1x83y8r8j-python3.11-piel-0.1.0/lib/python3.11/site-packages/piel/tools/amaranth/construct.py:112" *) casez (input_fock_state_str) - /* src = "/home/daquintero/phd/piel/piel/tools/amaranth/construct.py:115" */ + /* src = "/nix/store/c6rxsq40wg2715fm1zpzbld1x83y8r8j-python3.11-piel-0.1.0/lib/python3.11/site-packages/piel/tools/amaranth/construct.py:115" */ 3'h4: bit_phase_1 = 5'h00; - /* src = "/home/daquintero/phd/piel/piel/tools/amaranth/construct.py:115" */ + /* src = "/nix/store/c6rxsq40wg2715fm1zpzbld1x83y8r8j-python3.11-piel-0.1.0/lib/python3.11/site-packages/piel/tools/amaranth/construct.py:115" */ 3'h1: bit_phase_1 = 5'h1f; - /* src = "/home/daquintero/phd/piel/piel/tools/amaranth/construct.py:115" */ + /* src = "/nix/store/c6rxsq40wg2715fm1zpzbld1x83y8r8j-python3.11-piel-0.1.0/lib/python3.11/site-packages/piel/tools/amaranth/construct.py:115" */ 3'h2: bit_phase_1 = 5'h00; - /* src = "/home/daquintero/phd/piel/piel/tools/amaranth/construct.py:124" */ + /* src = "/nix/store/c6rxsq40wg2715fm1zpzbld1x83y8r8j-python3.11-piel-0.1.0/lib/python3.11/site-packages/piel/tools/amaranth/construct.py:124" */ default: bit_phase_1 = 5'h00; endcase diff --git a/docs/examples/component.svg b/docs/examples/component.svg deleted file mode 100644 index 9e849125..00000000 --- a/docs/examples/component.svg +++ /dev/null @@ -1,196 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/piel/visual/table/electro_optic/transitions.py b/piel/visual/table/electro_optic/transitions.py index 726c4207..b3808425 100644 --- a/piel/visual/table/electro_optic/transitions.py +++ b/piel/visual/table/electro_optic/transitions.py @@ -4,11 +4,21 @@ # Combined function to convert DataFrame to Fock state formatted LaTeX table -def compose_optical_state_transition_dataframe_latex_table(df) -> str: +def compose_optical_state_transition_dataframe_latex_table( + df, + headers: list = None, +) -> str: latex_table = "\\begin{tabular}{|c|c|c|c|}\n\\hline\n" # Column headers - headers = ["Phase", "Fock Input", "Fock Output", "Target"] + if headers is None: + headers = [ + "$(\\phi_{N},...)$", + "$|\\psi_{IN}\\rangle$", + "$|\\psi_{OUT}\\rangle$", + "Target", + ] + latex_table += ( " & ".join([f"\\textbf{{{escape_latex(header)}}}" for header in headers]) + " \\\\\n\\hline\n" diff --git a/piel/visual/table/electronic/__init__.py b/piel/visual/table/electronic/__init__.py index b1808518..ddbe1c19 100644 --- a/piel/visual/table/electronic/__init__.py +++ b/piel/visual/table/electronic/__init__.py @@ -1 +1,2 @@ from .metrics import compose_amplifier_collection_performance_latex_table +from .truth_table import compose_fock_state_truth_table_latex diff --git a/piel/visual/table/electronic/truth_table.py b/piel/visual/table/electronic/truth_table.py new file mode 100644 index 00000000..95a9581d --- /dev/null +++ b/piel/visual/table/electronic/truth_table.py @@ -0,0 +1,40 @@ +from piel.conversion import convert_array_type +from piel.visual.table.latex import escape_latex + + +def compose_fock_state_truth_table_latex( + df, + headers: list = None, +) -> str: + latex_table = "\\begin{tabular}{|c|" + "c|" * (len(df.columns)) + "}\n\\hline\n" + + # Column headers + if headers is None: + headers = ["$|\\psi_{IN}\\rangle$"] + [ + f"Bit Phase {i}" for i in range(len(df.columns) - 1) + ] + + latex_table += ( + " & ".join([f"\\textbf{{{escape_latex(header)}}}" for header in headers]) + + " \\\\\n\\hline\n" + ) + + # Rows in Fock state notation + for _, row in df.iterrows(): + # Convert each bit phase to the desired LaTeX representation + bit_phases = [ + convert_array_type(row[f"bit_phase_{i}"], output_type="str") + for i in range(len(headers) - 1) + ] + + input_fock_state = row["input_fock_state_str"] + input_state = f"$|{input_fock_state}\\rangle$" + + # Each row formatted for LaTeX + latex_row = f"{input_state} & " + " & ".join(bit_phases) + " \\\\\n\\hline\n" + latex_table += latex_row + + # Closing LaTeX syntax + latex_table += "\\end{tabular}\n" + + return latex_table diff --git a/piel/visual/table/latex.py b/piel/visual/table/latex.py index 99c51a38..f185dde8 100644 --- a/piel/visual/table/latex.py +++ b/piel/visual/table/latex.py @@ -1,18 +1,18 @@ # Function to escape LaTeX special characters def escape_latex(s: str) -> str: replacements = { - "&": r"\&", - "%": r"\%", - "$": r"\$", - "#": r"\#", - "_": r"\_", - "{": r"\{", - "}": r"\}", + "&": r"&", + "%": r"%", + "$": r"$", + "#": r"#", + "_": r"_", + "{": r"{", + "}": r"}", "\\(": "", "\\)": "", - "~": r"\textasciitilde{}", - "^": r"\textasciicircum{}", - "\\": r"\textbackslash{}", + "~": r"~", + "^": r"^", + "\\": "\\", } for original, replacement in replacements.items(): s = s.replace(original, replacement)