Skip to content

Commit 845b821

Browse files
FEAT: split via, convert via hole to conical shape (#1096)
* padstacks_data.py * test_edb_padstacks.py * MISC: Auto fixes from pre-commit.com hooks For more information, see https://pre-commit.ci --------- Co-authored-by: ring630 <@gmail.com> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
1 parent 6965ccf commit 845b821

File tree

2 files changed

+83
-3
lines changed

2 files changed

+83
-3
lines changed

src/pyedb/dotnet/database/edb_data/padstacks_data.py

Lines changed: 80 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -510,7 +510,7 @@ def via_layers(self):
510510
list
511511
List of layers.
512512
"""
513-
return self._padstack_def_data.GetLayerNames()
513+
return list(self._padstack_def_data.GetLayerNames())
514514

515515
@property
516516
def via_start_layer(self):
@@ -521,7 +521,7 @@ def via_start_layer(self):
521521
str
522522
Name of the starting layer.
523523
"""
524-
return list(self.via_layers)[0]
524+
return self.via_layers[0]
525525

526526
@property
527527
def via_stop_layer(self):
@@ -532,7 +532,7 @@ def via_stop_layer(self):
532532
str
533533
Name of the stopping layer.
534534
"""
535-
return list(self.via_layers)[-1]
535+
return self.via_layers[-1]
536536

537537
@property
538538
def hole_params(self):
@@ -2141,3 +2141,80 @@ def get_reference_pins(self, reference_net="GND", search_radius=5e-3, max_limit=
21412141
max_limit=max_limit,
21422142
component_only=component_only,
21432143
)
2144+
2145+
def split(self):
2146+
"""Split padstack instance into multiple instances. The new instances only connect adjacent layers."""
2147+
pdef_name = self.padstack_definition
2148+
position = self.position
2149+
net_name = self.net_name
2150+
name = self.name
2151+
stackup_layer_range = list(self._pedb.stackup.signal_layers.keys())
2152+
start_idx = stackup_layer_range.index(self.start_layer)
2153+
stop_idx = stackup_layer_range.index(self.stop_layer)
2154+
for idx, (l1, l2) in enumerate(
2155+
list(zip(stackup_layer_range[start_idx:stop_idx], stackup_layer_range[start_idx + 1 : stop_idx + 1]))
2156+
):
2157+
self._pedb.padstacks.place(position, pdef_name, net_name, f"{name}_{idx}", fromlayer=l1, tolayer=l2)
2158+
self.delete()
2159+
2160+
def convert_hole_to_conical_shape(self, angle=75):
2161+
"""Convert actual padstack instance to microvias 3D Objects with a given aspect ratio.
2162+
2163+
Parameters
2164+
----------
2165+
angle : float, optional
2166+
Angle of laser penetration in degrees. The angle defines the lowest hole diameter with this formula:
2167+
HoleDiameter -2*tan(laser_angle* Hole depth). Hole depth is the height of the via (dielectric thickness).
2168+
The default is ``75``.
2169+
The lowest hole is ``0.75*HoleDepth/HoleDiam``.
2170+
2171+
Returns
2172+
-------
2173+
"""
2174+
pos = self.position
2175+
stackup_layers = self._pedb.stackup.stackup_layers
2176+
signal_layers = self._pedb.stackup.signal_layers
2177+
layer_idx = list(signal_layers.keys()).index(self.start_layer)
2178+
2179+
_layer_idx = list(stackup_layers.keys()).index(self.start_layer)
2180+
diel_layer_idx = list(stackup_layers.keys())[_layer_idx + 1]
2181+
diel_thickness = stackup_layers[diel_layer_idx].thickness
2182+
2183+
rad_large = self.definition.hole_diameter / 2
2184+
rad_small = rad_large - diel_thickness * 1 / math.tan(math.radians(angle))
2185+
2186+
if layer_idx + 1 < len(signal_layers) / 2: # upper half of stack
2187+
rad_u = rad_large
2188+
rad_l = rad_small
2189+
else:
2190+
rad_u = rad_small
2191+
rad_l = rad_large
2192+
2193+
layout = self._pedb.active_layout
2194+
cloned_circle = self._edb.cell.primitive.circle.create(
2195+
layout,
2196+
self.start_layer,
2197+
self._edb_padstackinstance.GetNet(),
2198+
self._pedb.edb_value(pos[0]),
2199+
self._pedb.edb_value(pos[1]),
2200+
self._pedb.edb_value(rad_u),
2201+
)
2202+
cloned_circle2 = self._edb.cell.primitive.circle.create(
2203+
layout,
2204+
self.stop_layer,
2205+
self._edb_padstackinstance.GetNet(),
2206+
self._pedb.edb_value(pos[0]),
2207+
self._pedb.edb_value(pos[1]),
2208+
self._pedb.edb_value(rad_l),
2209+
)
2210+
s3d = self._pedb._edb.Cell.Hierarchy.Structure3D.Create(
2211+
layout, generate_unique_name("via3d_" + self.aedt_name.replace("via_", ""), n=3)
2212+
)
2213+
s3d.AddMember(cloned_circle.prim_obj)
2214+
s3d.AddMember(cloned_circle2.prim_obj)
2215+
s3d.SetMaterial(self.definition.material)
2216+
s3d.SetMeshClosureProp(self._pedb._edb.Cell.Hierarchy.Structure3D.TClosure.EndsClosed)
2217+
2218+
hole_override_enabled = True
2219+
hole_override_diam = 0
2220+
self._edb_object.SetHoleOverride(hole_override_enabled, self._pedb.edb_value(hole_override_diam))

tests/legacy/system/test_edb_padstacks.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,9 @@ def test_microvias(self):
241241
def test_split_microvias(self):
242242
"""Convert padstack definition to multiple microvias definitions."""
243243
edbapp = Edb(self.target_path4, edbversion=desktop_version)
244+
edbapp.padstacks.instances_by_name["via219"].split()
245+
assert "via219_2" in [i.name for i in edbapp.padstacks.definitions["BALL_VIA_1"].instances]
246+
edbapp.padstacks.instances_by_name["via218"].convert_hole_to_conical_shape()
244247
assert len(edbapp.padstacks.definitions["C4_POWER_1"].split_to_microvias()) > 0
245248
edbapp.close()
246249

0 commit comments

Comments
 (0)