Skip to content

Commit

Permalink
Method to create via fence on both sides of the trace (#3759)
Browse files Browse the repository at this point in the history
* fix

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Update primitives_data.py

---------

Co-authored-by: ring630 <@gmail.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: svandenb-dev <[email protected]>
  • Loading branch information
3 people authored Oct 18, 2023
1 parent 6782324 commit 5def190
Show file tree
Hide file tree
Showing 2 changed files with 112 additions and 0 deletions.
5 changes: 5 additions & 0 deletions _unittest/test_00_EDB.py
Original file line number Diff line number Diff line change
Expand Up @@ -2480,6 +2480,11 @@ def test_130_create_padstack_instance(self):
assert pad_instance3.dcir_equipotential_region
pad_instance3.dcir_equipotential_region = False
assert not pad_instance3.dcir_equipotential_region

trace = edb.modeler.create_trace([[0, 0], [0, 10e-3]], "1_Top", "0.1mm", "trace_with_via_fence")
edb.padstacks.create_padstack("via_0")
trace.create_via_fence("1mm", "1mm", "via_0")

edb.close()

def test_131_assign_hfss_extent_non_multiple_with_simconfig(self):
Expand Down
107 changes: 107 additions & 0 deletions pyaedt/edb_core/edb_data/primitives_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -835,6 +835,113 @@ def create_edge_port(
else:
return self._app.hfss.create_edge_port_vertical(self.id, pos, name, 50, reference_layer)

pyaedt_function_handler()

def create_via_fence(self, distance, gap, padstack_name):
"""Create via fences on both sides of the trace.
Parameters
----------
distance: str, float
Distance between via fence and trace center line.
gap: str, float
Gap between vias.
padstack_name: str
Name of the via padstack.
Returns
-------
"""

def getAngle(v1, v2): # pragma: no cover
v1_mag = math.sqrt(v1[0] ** 2 + v1[1] ** 2)
v2_mag = math.sqrt(v2[0] ** 2 + v2[1] ** 2)
dotsum = v1[0] * v2[0] + v1[1] * v2[1]
if v1[0] * v2[1] - v1[1] * v2[0] > 0:
scale = 1
else:
scale = -1
dtheta = scale * math.acos(dotsum / (v1_mag * v2_mag))

return dtheta

def getLocations(line, gap): # pragma: no cover
location = [line[0]]
residual = 0

for n in range(len(line) - 1):
x0, y0 = line[n]
x1, y1 = line[n + 1]
length = math.sqrt((x1 - x0) ** 2 + (y1 - y0) ** 2)
dx, dy = (x1 - x0) / length, (y1 - y0) / length
x = x0 - dx * residual
y = y0 - dy * residual
length = length + residual
while length >= gap:
x += gap * dx
y += gap * dy
location.append((x, y))
length -= gap

residual = length
return location

def getParalletLines(pts, distance): # pragma: no cover
leftline = []
rightline = []

x0, y0 = pts[0]
x1, y1 = pts[1]
vector = (x1 - x0, y1 - y0)
orientation1 = getAngle((1, 0), vector)

leftturn = orientation1 + math.pi / 2
righrturn = orientation1 - math.pi / 2
leftPt = (x0 + distance * math.cos(leftturn), y0 + distance * math.sin(leftturn))
leftline.append(leftPt)
rightPt = (x0 + distance * math.cos(righrturn), y0 + distance * math.sin(righrturn))
rightline.append(rightPt)

for n in range(1, len(pts) - 1):
x0, y0 = pts[n - 1]
x1, y1 = pts[n]
x2, y2 = pts[n + 1]

v1 = (x1 - x0, y1 - y0)
v2 = (x2 - x1, y2 - y1)
dtheta = getAngle(v1, v2)
orientation1 = getAngle((1, 0), v1)

leftturn = orientation1 + dtheta / 2 + math.pi / 2
righrturn = orientation1 + dtheta / 2 - math.pi / 2

distance2 = distance / math.sin((math.pi - dtheta) / 2)
leftPt = (x1 + distance2 * math.cos(leftturn), y1 + distance2 * math.sin(leftturn))
leftline.append(leftPt)
rightPt = (x1 + distance2 * math.cos(righrturn), y1 + distance2 * math.sin(righrturn))
rightline.append(rightPt)

x0, y0 = pts[-2]
x1, y1 = pts[-1]

vector = (x1 - x0, y1 - y0)
orientation1 = getAngle((1, 0), vector)
leftturn = orientation1 + math.pi / 2
righrturn = orientation1 - math.pi / 2
leftPt = (x1 + distance * math.cos(leftturn), y1 + distance * math.sin(leftturn))
leftline.append(leftPt)
rightPt = (x1 + distance * math.cos(righrturn), y1 + distance * math.sin(righrturn))
rightline.append(rightPt)
return leftline, rightline

distance = self._pedb.edb_value(distance).ToDouble()
gap = self._pedb.edb_value(gap).ToDouble()
center_line = self.get_center_line()
leftline, rightline = getParalletLines(center_line, distance)
for x, y in getLocations(rightline, gap) + getLocations(leftline, gap):
self._pedb.padstacks.place([x, y], padstack_name)


class EdbRectangle(EDBPrimitives, RectangleDotNet):
def __init__(self, raw_primitive, core_app):
Expand Down

0 comments on commit 5def190

Please sign in to comment.