def connection_UR(x1, y1, x2, y2, elec_m, elec_s, e_e_gap, Rt): #right down D = Device() x1t = x1 + elec_m / 2 + elec_s / 2 + e_e_gap x1b = x1 - elec_m / 2 - elec_s / 2 - e_e_gap y2t = y2 - elec_m / 2 - elec_s / 2 - e_e_gap y2b = y2 + elec_m / 2 + elec_s / 2 + e_e_gap points = np.array([(x1, y1), (x1, y2), (x2, y2)]) points_t = np.array([(x1t, y1), (x1t, y2t), (x2, y2t)]) points_b = np.array([(x1b, y1), (x1b, y2b), (x2, y2b)]) M = pp.smooth( points=points, radius=Rt + elec_m / 2 + elec_s / 2 + e_e_gap, corner_fun=pp.arc, ) M.rotate(90, center=(x1, y1)) Mt = pp.smooth( points=points_t, radius=Rt, corner_fun=pp.arc, ) Mt.rotate(90, center=(x1t, y1)) Mb = pp.smooth( points=points_b, radius=Rt + 2 * (elec_m / 2 + elec_s / 2 + e_e_gap), corner_fun=pp.arc, ) Mb.rotate(90, center=(x1b, y1)) X = CrossSection() X.add(width=elec_m, offset=0, layer=70) Xt = CrossSection() Xt.add(width=elec_s, offset=0, layer=70) Xb = CrossSection() Xb.add(width=elec_s, offset=0, layer=70) L = M.extrude(X) #Left Trace Lt = Mt.extrude(Xt) #Left Trace Lb = Mb.extrude(Xb) #Left Trace D << L D << Lt D << Lb return D
def extend_port(port, width, length, layer): '''Create a rectangle extending perpendicularly from the port. Attributes: ---------- port : dl.Port width : float length : float layer : int, tuple or set Returns: ------- dl.Device. ''' p1 = Point(port.midpoint) dir = Point(port.normal[1]) - Point(port.normal[0]) p2 = p1 + dir * length p = path.smooth(points=[p1.coord, p2.coord]) return p.extrude(width=width, layer=layer)
def _make_paware_connection(self, s, d): Yovertravel = self._yovertravel(s) p0 = Point(s.midpoint) p1 = p0 - Point(0, Yovertravel) p2 = Point(d.midpoint[0], p1.y) p3 = Point(p2.x, d.midpoint[1]) list_points = _check_points_path(p0, p1, p2, p3, trace_width=s.width) try: return pp.smooth(points=list_points, radius=self._radius, num_pts=self._num_pts) except Exception: import pdb pdb.set_trace()
def connect(x2, y2, middle_e_width, chip_width, chip_height, pos, radius, length, e_e_gap, setpos): mm = 10**3 um = 1 M = Path() # Dimensions margin = 0.5 * mm to_pad_term = 0.1 * mm pad = 50 * um pitch = 100 * um side_e_width = middle_e_width * 2 rad_gap = e_e_gap + middle_e_width / 2 + side_e_width / 2 if pos == 't': Rt = radius + rad_gap * 2 elif pos == 'm': Rt = radius + rad_gap else: Rt = radius if setpos == 't': set_bias = 0.6 * mm elif setpos == 'm': set_bias = 0.3 * mm else: set_bias = 0 x1 = (chip_width - length) / 2 - Rt - set_bias y1 = margin + to_pad_term points = np.array([(x1, y1), (x1, y2), (x2, y2)]) points = rotate90(points) M = pp.smooth( points=points, radius=Rt, corner_fun=pp.arc, ) M.rotate(90) X = CrossSection() if pos == 'm': X.add(width=middle_e_width, offset=0, layer=3) else: X.add(width=side_e_width, offset=0, layer=3) L = M.extrude(X) #Left Trace if pos == 'm': # adding pads S = pg.rectangle(size=(pad, pad), layer=3) L.add_ref(S).move([x1 - pad / 2, margin]) L.add_ref(S).move([x1 - pad / 2 - pitch, margin]) L.add_ref(S).move([x1 - pad / 2 + pitch, margin]) xm1 = x1 - middle_e_width / 2 xm2 = x1 + middle_e_width / 2 xm3 = x1 + pad / 2 xm4 = x1 - pad / 2 xpts = (xm1, xm2, xm3, xm4) ypts = (y1, y1, margin + pad, margin + pad) L.add_polygon([xpts, ypts], layer=3) xt1 = xm1 + middle_e_width + e_e_gap xt2 = xt1 + side_e_width xt3 = xm3 + pitch xt4 = xm4 + pitch xpts = (xt1, xt2, xt3, xt4) ypts = (y1, y1, margin + pad, margin + pad) L.add_polygon([xpts, ypts], layer=3) xb1 = xm1 - side_e_width - e_e_gap xb2 = xm1 - e_e_gap xb3 = xm3 - pitch xb4 = xm4 - pitch xpts = (xb1, xb2, xb3, xb4) ypts = (y1, y1, margin + pad, margin + pad) L.add_polygon([xpts, ypts], layer=3) R = pg.copy(L) # Right Trace R.mirror((chip_width / 2, chip_height), (chip_width / 2, 0)) D = Device('trace') D << L D << R return D
def path(self): tol = 1e-3 bbox = pg.bbox(self.clearance) ll, lr, ul, ur = get_corners(bbox) source = self.source destination = self.destination if source.y > destination.y: source = self.destination destination = self.source if Point(source.midpoint).in_box(bbox.bbox): raise ValueError( f" Source of routing {source.midport} is in clearance area {bbox.bbox}" ) if Point(destination.midpoint).in_box(bbox.bbox): raise ValueError( f" Destination of routing{destination.midpoint} is in clearance area{bbox.bbox}" ) if destination.y <= ll.y + tol: # destination is below clearance if not(destination.orientation==source.orientation+180 or \ destination.orientation==source.orientation-180): raise Exception( "Routing error: non-hindered routing needs +90 -> -90 oriented ports" ) distance=Point(destination.midpoint)-\ Point(source.midpoint) p1 = Point(source.midpoint) p2 = p1 + Point(distance.x, distance.y * (3 / 4)) p3 = p2 + Point(0, distance.y / 4) list_points = _check_points_path(p1, p2, p3, trace_width=self.trace_width) try: p = pp.smooth(points=list_points, radius=self._radius, num_pts=self._num_pts) except Exception: raise ValueError("error for non-hindered path ") else: #destination is above clearance if not destination.orientation == 90: raise ValueError("Routing case not covered yet") elif source.orientation == 0: #right ground_pad_side source.name = 'source' destination.name = 'destination' p0 = Point(source.midpoint) p1 = Point(ur.x + self.trace_width, p0.y) p2 = Point(p1.x, ur.y + self.trace_width) p3 = Point(destination.x, p2.y) p4 = Point(destination.x, destination.y) list_points_rx = _check_points_path( p0, p1, p2, p3, p4, trace_width=self.trace_width) try: p = pp.smooth(points=list_points_rx, radius=self._radius, num_pts=self._num_pts) except Exception: raise ValueError("error in +0 source, rx path") if source.orientation == 90: if source.x + self.trace_width > ll.x and source.x - self.trace_width < lr.x: #source tucked inside clearance p0 = Point(source.midpoint) center_box = Point(bbox.center) #left path p1 = p0 - Point(0, source.width / 2) p2 = Point(ll.x - self.trace_width, p1.y) p3 = Point(p2.x, self.trace_width + destination.y) p4 = Point(destination.x, p3.y) p5 = Point(destination.x, destination.y) list_points_lx = _check_points_path( p0, p1, p2, p3, p4, p5, trace_width=self.trace_width) try: p_lx = pp.smooth(points=list_points_lx, radius=self._radius, num_pts=self._num_pts) except: raise ValueError( "error in +90 hindered tucked path, lx path") #right path p1 = p0 - Point(0, source.width / 2) p2 = Point(lr.x + self.trace_width, p1.y) p3 = Point(p2.x, self.trace_width + destination.y) p4 = Point(destination.x, p3.y) p5 = Point(destination.x, destination.y) list_points_rx = _check_points_path( p0, p1, p2, p3, p4, p5, trace_width=self.trace_width) try: p_rx = pp.smooth(points=list_points_rx, radius=self._radius, num_pts=self._num_pts) except: raise ValueError("error in +90 source, rx path") if self.side == 'auto': if p_lx.length() < p_rx.length(): p = p_lx else: p = p_rx elif self.side == 'left': p = p_lx elif self.side == 'right': p = p_rx else: raise ValueError("Invalid option for side :{}".format( self.side)) else: # source is not tucked under the clearance p0 = Point(source.midpoint) ll, lr, ul, ur = get_corners(bbox) center_box = Point(bbox.center) #left path p1 = Point(p0.x, destination.y + self.trace_width) p2 = Point(destination.x, p1.y) p3 = Point(destination.x, destination.y) list_points = _check_points_path( p0, p1, p2, p3, trace_width=self.trace_width) try: p = pp.smooth(points=list_points, radius=self._radius, num_pts=self._num_pts ) #source tucked inside clearance except Exception: raise ValueError( "error for non-tucked hindered p ,90 deg") elif source.orientation == 180: #left path p0 = Point(source.midpoint) p1 = Point(ll.x - self.trace_width, p0.y) p2 = Point(p1.x, ur.y + self.trace_width) p3 = Point(destination.x, p2.y) p4 = Point(destination.x, destination.y) list_points_lx = _check_points_path( p0, p1, p2, p3, p4, trace_width=self.trace_width) try: p = pp.smooth(points=list_points_lx, radius=self._radius, num_pts=self._num_pts) except Exception: import pdb pdb.set_trace() raise ValueError("error in +180 source, lx path") return p
import phidl.geometry as pg import phidl.device_layout as dl import phidl.path as pp from phidl import quickplot as qp from phidl import set_quickplot_options set_quickplot_options(blocking=True) p1 = (0, 0) p2 = (0, 40) p3 = (20, 1600) p4 = (20, 2000) path = pp.smooth(points=(p1, p2, p3, p4), radius=0.1, num_pts=1000) qp(path)