Merge pull request #2 from ucb-art/primitives_pr
Fix the BAG3 primitives setup to match the technology design parameters.
* Updated BAG routing grid
* Updated metal width/space and via specs in `tech_params.yaml`
* Changed transistor gate and implant implementation in primitives
diff --git a/src/templates_skywater130/data/tech_params.yaml b/src/templates_skywater130/data/tech_params.yaml
index 8bbfd51..b610fed 100644
--- a/src/templates_skywater130/data/tech_params.yaml
+++ b/src/templates_skywater130/data/tech_params.yaml
@@ -85,8 +85,8 @@
- [[60, .inf]]
- [[60, 2001]]
5:
- - [[320, .inf]]
- - [[320, .inf]]
+ - [[284, .inf]]
+ - [[284, .inf]]
# mapping from tuple of via layers to via ID.
via_id:
@@ -227,7 +227,7 @@
bot_layer: 0
# wire_w, is_horiz, v_w, v_h, v_sp, v_bot_enc, v_top_enc
info_list:
- - [34, True, 34, 34, 34, 16, 16]
+ - [34, True, 34, 34, 34, 10, 10]
- [52, False, 34, 34, 38, 8, 12]
# minimum horizontal space between OD, in resolution units
@@ -238,8 +238,8 @@
od_spy_gr: 4000
# maximum vertical space between OD, in resolution units
od_spy_max: 4000
- # set by via enclosure
- od_po_extx: 56
+ # set by via enclosure, licon.5
+ od_po_extx: 96
# poly.2
po_spy: 42
@@ -269,7 +269,8 @@
grid_info:
- [1, 52, 1]
- - [3, 66, 2]
+ - [3, 66, 1]
+ - [5, 284, 1]
fill: {}
@@ -863,3 +864,4 @@
- [22, 4294967295]
- [27902976, 4294967295]
- [6, 4294967295]
+
diff --git a/src/templates_skywater130/mos/tech.py b/src/templates_skywater130/mos/tech.py
index 837dded..437893c 100644
--- a/src/templates_skywater130/mos/tech.py
+++ b/src/templates_skywater130/mos/tech.py
@@ -21,15 +21,15 @@
#
# SPDX-License-Identifier: BSD-3-Clause OR Apache 2.0
-
-from typing import Tuple, FrozenSet, List
-
+from typing import Tuple, Optional, FrozenSet, List, Mapping, Any
from dataclasses import dataclass
+from itertools import chain
from pybag.enum import Orient2D
-from pybag.core import BBox
+from pybag.core import COORD_MAX, BBox
+from bag.util.immutable import ImmutableSortedDict, ImmutableList, Param
from bag.layout.tech import TechInfo
from bag.layout.routing.grid import TrackSpec
from bag.util.immutable import ImmutableSortedDict, ImmutableList, Param
@@ -42,9 +42,10 @@
MOSRowSpecs, MOSRowInfo, BlkExtInfo, MOSEdgeInfo, MOSLayInfo, ExtWidthInfo, LayoutInfo,
ExtEndLayInfo, RowExtInfo
)
-
from ..util import add_base, get_arr_edge_dim
+MConnInfoType = Tuple[int, int, Orient2D, int, Tuple[str, str]]
+
@dataclass(eq=True, frozen=True)
class ConnInfo:
@@ -95,8 +96,8 @@
class MOSTechSkywater130(MOSTech):
ignore_vm_sp_le_layers: FrozenSet[str] = frozenset(('m1',))
- def __init__(self, tech_info: TechInfo, lch: int, mos_entry_name: str = 'mos') -> None:
- MOSTech.__init__(self, tech_info, lch, mos_entry_name)
+ def __init__(self, tech_info: TechInfo, lch: int, arr_options: Mapping[str, Any]) -> None:
+ MOSTech.__init__(self, tech_info, lch, arr_options)
@property
def blk_h_pitch(self) -> int:
@@ -353,7 +354,7 @@
od_y = self._add_mos_active(builder, row_info, 0, fg, w)
# draw gate connection
- self._draw_g_conn(builder, sep_g, g_xc, po_y_gate, num_g, g_pitch)
+ self._draw_g_conn(builder, sep_g, g_xc, po_y_gate, fg, g_pitch, g_on_s)
# draw drain/source connections
d0_info = self.get_conn_info(0, False)
@@ -375,9 +376,7 @@
else:
m_info = None
- # draw base
bbox = BBox(0, 0, fg * sd_pitch, height)
- add_base(builder, row_type, threshold, imp_y, bbox)
edge_info = MOSEdgeInfo(mos_type=row_type, imp_y=imp_y, has_od=True)
be = BlkExtInfo(row_type, row_info.threshold, False, ImmutableList([(fg, row_type)]),
@@ -388,7 +387,7 @@
shorted_ports=ImmutableList([MOSPortType.G]))
def _draw_g_conn(self, builder: LayoutInfoBuilder, sep_g: bool, g_xc: int,
- po_y_gate: Tuple[int, int], num_g: int, conn_pitch: int) -> None:
+ po_y_gate: Tuple[int, int], fg: int, conn_pitch: int, g_on_s: bool) -> None:
lch = self.lch
sd_pitch = self.sd_pitch
@@ -404,8 +403,29 @@
po_lp = ('poly', 'drawing')
po_conn_w = sd_pitch + lch
po_xl_gate = g_xc - po_conn_w // 2
- builder.add_rect_arr(po_lp, BBox(po_xl_gate, po_y_gate[0], po_xl_gate + po_conn_w,
- po_y_gate[1]), nx=num_g, spx=conn_pitch)
+
+ if g_on_s:
+ g_xc = 0
+ num_g = fg // 2 + 1
+ po_xl_even = g_xc
+ po_xh_even = g_xc + sd_pitch // 2 + lch // 2
+ po_xl_odd = sd_pitch + sd_pitch // 2 - lch // 2
+ po_xh_odd = 2 * sd_pitch
+ else:
+ g_xc = sd_pitch
+ num_g = (fg + 1) // 2
+ po_xl_even = sd_pitch // 2 - lch // 2
+ po_xh_even = sd_pitch
+ po_xl_odd = sd_pitch
+ po_xh_odd = sd_pitch + sd_pitch // 2 + lch // 2
+
+ # builder.add_rect_arr(po_lp, BBox(po_xl_gate, po_y_gate[0], po_xl_gate + po_conn_w,
+ # po_y_gate[1]), nx=num_g, spx=conn_pitch)
+ builder.add_rect_arr(po_lp, BBox(po_xl_even, po_y_gate[0], po_xh_even, po_y_gate[1]),
+ nx=(fg - (fg // 2)), spx=conn_pitch)
+ builder.add_rect_arr(po_lp, BBox(po_xl_odd, po_y_gate[0], po_xh_odd, po_y_gate[1]),
+ nx=(fg // 2), spx=conn_pitch)
+
po_yc_gate = (po_y_gate[0] + po_y_gate[1]) // 2
po_h_gate = po_y_gate[1] - po_y_gate[0]
builder.add_via(g0_info.get_via_info('PYL1_C', g_xc, po_yc_gate, po_h_gate,
@@ -737,6 +757,11 @@
od_xh = stop * sd_pitch + od_sd_dx
builder.add_rect_arr(od_lp, BBox(od_xl, od_yl, od_xh, od_yh))
+ # draw base
+ imp_od_encx: int = self.mos_config['imp_od_encx']
+ bbox = BBox(od_xl-imp_od_encx, 0, od_xh+imp_od_encx, row_info.height)
+ add_base(builder, row_info.row_type, row_info.threshold, row_info['imp_y'], bbox)
+
return od_yl, od_yh
def _add_po_array(self, builder: LayoutInfoBuilder, po_y: Tuple[int, int], start: int,
@@ -806,3 +831,4 @@
xcur = xh
return xcur
+