@@ -4012,3 +4012,199 @@ def get_point_terminal(self, name, net_name, location, layer):
4012
4012
4013
4013
point_terminal = PointTerminal (self )
4014
4014
return point_terminal .create (name , net_name , location , layer )
4015
+
4016
+ @pyedb_function_handler
4017
+ def auto_parametrize_design (
4018
+ self ,
4019
+ layers = True ,
4020
+ materials = True ,
4021
+ via_holes = True ,
4022
+ pads = True ,
4023
+ antipads = True ,
4024
+ traces = True ,
4025
+ layer_filter = None ,
4026
+ material_filter = None ,
4027
+ padstack_definition_filter = None ,
4028
+ trace_net_filter = None ,
4029
+ ):
4030
+ """Assign automatically design and project variables with current values.
4031
+ Parameters
4032
+ ----------
4033
+ layers : bool, optional
4034
+ ``True`` enable layer thickness parametrization. Default value is ``True``.
4035
+ materials : bool, optional
4036
+ ``True`` enable material parametrization. Default value is ``True``.
4037
+ via_holes : bool, optional
4038
+ ``True`` enable via diameter parametrization. Default value is ``True``.
4039
+ pads : bool, optional
4040
+ ``True`` enable pads size parametrization. Default value is ``True``.
4041
+ antipads : bool, optional
4042
+ ``True`` enable anti pads size parametrization. Default value is ``True``.
4043
+ traces : bool, optional
4044
+ ``True`` enable trace width parametrization. Default value is ``True``.
4045
+ layer_filter : str, List(str), optional
4046
+ Enable layer filter. Default value is ``None``, all layers are parametrized.
4047
+ material_filter : str, List(str), optional
4048
+ Enable material filter. Default value is ``None``, all material are parametrized.
4049
+ padstack_definition_filter : str, List(str), optional
4050
+ Enable padstack definition filter. Default value is ``None``, all padsatcks are parametrized.
4051
+ trace_net_filter : str, List(str), optional
4052
+ Enable nets filter for trace width parametrization. Default value is ``None``, all layers are
4053
+ parametrized.
4054
+ Returns
4055
+ -------
4056
+ List(str)
4057
+ List of all parameters name created.
4058
+ """
4059
+ parameters = []
4060
+ if layers :
4061
+ if not layer_filter :
4062
+ _layers = self .stackup .stackup_layers
4063
+ else :
4064
+ if isinstance (layer_filter , str ):
4065
+ layer_filter = [layer_filter ]
4066
+ _layers = {k : v for k , v in self .stackup .stackup_layers .items () if k in layer_filter }
4067
+ for layer_name , layer in _layers .items ():
4068
+ thickness_variable = "${}_thick" .format (layer_name )
4069
+ self ._clean_string_for_variable_name (thickness_variable )
4070
+ if thickness_variable not in self .variables :
4071
+ self .add_design_variable (thickness_variable , layer .thickness )
4072
+ layer .thickness = thickness_variable
4073
+ parameters .append (thickness_variable )
4074
+ if materials :
4075
+ if not material_filter :
4076
+ _materials = self .materials .materials
4077
+ else :
4078
+ _materials = {k : v for k , v in self .materials .materials .items () if k in material_filter }
4079
+ for mat_name , material in _materials .items ():
4080
+ if material .conductivity < 1e4 :
4081
+ epsr_variable = "$epsr_{}" .format (mat_name )
4082
+ self ._clean_string_for_variable_name (epsr_variable )
4083
+ if epsr_variable not in self .variables :
4084
+ self .add_design_variable (epsr_variable , material .permittivity )
4085
+ material .permittivity = epsr_variable
4086
+ parameters .append (epsr_variable )
4087
+ loss_tg_variable = "$loss_tangent_{}" .format (mat_name )
4088
+ self ._clean_string_for_variable_name (loss_tg_variable )
4089
+ if not loss_tg_variable in self .variables :
4090
+ self .add_design_variable (loss_tg_variable , material .loss_tangent )
4091
+ material .loss_tangent = loss_tg_variable
4092
+ parameters .append (loss_tg_variable )
4093
+ else :
4094
+ sigma_variable = "$sigma_{}" .format (mat_name )
4095
+ self ._clean_string_for_variable_name (sigma_variable )
4096
+ if not sigma_variable in self .variables :
4097
+ self .add_design_variable (sigma_variable , material .conductivity )
4098
+ material .conductivity = sigma_variable
4099
+ parameters .append (sigma_variable )
4100
+ if traces :
4101
+ if not trace_net_filter :
4102
+ paths = self .modeler .paths
4103
+ else :
4104
+ paths = [path for path in self .modeler .paths if path .net_name in trace_net_filter ]
4105
+ for path in paths :
4106
+ trace_width_variable = "trace_w_{}_{}" .format (path .net_name , path .id )
4107
+ self ._clean_string_for_variable_name (trace_width_variable )
4108
+ if trace_width_variable not in self .variables :
4109
+ self .add_design_variable (trace_width_variable , path .width )
4110
+ path .width = trace_width_variable
4111
+ parameters .append (trace_width_variable )
4112
+ if not padstack_definition_filter :
4113
+ used_padsatck_defs = list (
4114
+ set ([padstack_inst .padstack_definition for padstack_inst in list (self .padstacks .instances .values ())])
4115
+ )
4116
+ padstack_defs = {k : v for k , v in self .padstacks .definitions .items () if k in used_padsatck_defs }
4117
+ else :
4118
+ padstack_defs = {k : v for k , v in self .padstacks .definitions .items () if k in padstack_definition_filter }
4119
+ for def_name , padstack_def in padstack_defs .items ():
4120
+ if not padstack_def .via_start_layer == padstack_def .via_stop_layer :
4121
+ if via_holes : # pragma no cover
4122
+ hole_variable = self ._clean_string_for_variable_name ("$hole_diam_{}" .format (def_name ))
4123
+ if hole_variable not in self .variables :
4124
+ self .add_design_variable (hole_variable , padstack_def .hole_properties [0 ])
4125
+ padstack_def .hole_properties = hole_variable
4126
+ parameters .append (hole_variable )
4127
+ if pads :
4128
+ for layer , pad in padstack_def .pad_by_layer .items ():
4129
+ if pad .geometry_type == 1 :
4130
+ pad_diameter_variable = self ._clean_string_for_variable_name (
4131
+ "$pad_diam_{}_{}" .format (def_name , layer )
4132
+ )
4133
+ if pad_diameter_variable not in self .variables :
4134
+ self .add_design_variable (pad_diameter_variable , pad .parameters_values [0 ])
4135
+ pad .parameters = {"Diameter" : pad_diameter_variable }
4136
+ parameters .append (pad_diameter_variable )
4137
+ if pad .geometry_type == 2 : # pragma no cover
4138
+ pad_size_variable = self ._clean_string_for_variable_name (
4139
+ "$pad_size_{}_{}" .format (def_name , layer )
4140
+ )
4141
+ if pad_size_variable not in self .variables :
4142
+ self .add_design_variable (pad_size_variable , pad .parameters_values [0 ])
4143
+ pad .parameters = {"Size" : pad_size_variable }
4144
+ parameters .append (pad_size_variable )
4145
+ elif pad .geometry_type == 3 : # pragma no cover
4146
+ pad_size_variable_x = self ._clean_string_for_variable_name (
4147
+ "$pad_size_x_{}_{}" .format (def_name , layer )
4148
+ )
4149
+ pad_size_variable_y = self ._clean_string_for_variable_name (
4150
+ "$pad_size_y_{}_{}" .format (def_name , layer )
4151
+ )
4152
+ if pad_size_variable_x not in self .variables and pad_size_variable_y not in self .variables :
4153
+ self .add_design_variable (pad_size_variable_x , pad .parameters_values [0 ])
4154
+ self .add_design_variable (pad_size_variable_y , pad .parameters_values [1 ])
4155
+ pad .parameters = {"XSize" : pad_size_variable_x , "YSize" : pad_size_variable_y }
4156
+ parameters .append (pad_size_variable_x )
4157
+ parameters .append (pad_size_variable_y )
4158
+ if antipads :
4159
+ for layer , antipad in padstack_def .antipad_by_layer .items ():
4160
+ if antipad .geometry_type == 1 : # pragma no cover
4161
+ antipad_diameter_variable = self ._clean_string_for_variable_name (
4162
+ "$antipad_diam_{}_{}" .format (def_name , layer )
4163
+ )
4164
+ if antipad_diameter_variable not in self .variables : # pragma no cover
4165
+ self .add_design_variable (antipad_diameter_variable , antipad .parameters_values [0 ])
4166
+ antipad .parameters = {"Diameter" : antipad_diameter_variable }
4167
+ parameters .append (antipad_diameter_variable )
4168
+ if antipad .geometry_type == 2 : # pragma no cover
4169
+ antipad_size_variable = self ._clean_string_for_variable_name (
4170
+ "$antipad_size_{}_{}" .format (def_name , layer )
4171
+ )
4172
+ if antipad_size_variable not in self .variables : # pragma no cover
4173
+ self .add_design_variable (antipad_size_variable , antipad .parameters_values [0 ])
4174
+ antipad .parameters = {"Size" : antipad_size_variable }
4175
+ parameters .append (antipad_size_variable )
4176
+ elif antipad .geometry_type == 3 : # pragma no cover
4177
+ antipad_size_variable_x = self ._clean_string_for_variable_name (
4178
+ "$antipad_size_x_{}_{}" .format (def_name , layer )
4179
+ )
4180
+ antipad_size_variable_y = self ._clean_string_for_variable_name (
4181
+ "$antipad_size_y_{}_{}" .format (def_name , layer )
4182
+ )
4183
+ if (
4184
+ antipad_size_variable_x not in self .variables
4185
+ and antipad_size_variable_y not in self .variables
4186
+ ): # pragma no cover
4187
+ self .add_design_variable (antipad_size_variable_x , antipad .parameters_values [0 ])
4188
+ self .add_design_variable (antipad_size_variable_y , antipad .parameters_values [1 ])
4189
+ antipad .parameters = {"XSize" : antipad_size_variable_x , "YSize" : antipad_size_variable_y }
4190
+ parameters .append (antipad_size_variable_x )
4191
+ parameters .append (antipad_size_variable_y )
4192
+ return parameters
4193
+
4194
+ @pyedb_function_handler
4195
+ def _clean_string_for_variable_name (self , variable_name ):
4196
+ """Remove forbidden character for variable name.
4197
+ Parameter
4198
+ ----------
4199
+ variable_name : str
4200
+ Variable name.
4201
+ Returns
4202
+ -------
4203
+ str
4204
+ Edited name.
4205
+ """
4206
+ if "-" in variable_name :
4207
+ variable_name = variable_name .replace ("-" , "_" )
4208
+ if "+" in variable_name :
4209
+ variable_name = variable_name .replace ("+" , "p" )
4210
+ return variable_name
0 commit comments