mirror of
https://github.com/VLSIDA/OpenRAM.git
synced 2026-09-03 08:27:11 +02:00
Merge branch 'tech_migration' into dev
This commit is contained in:
+19
-12
@@ -55,7 +55,7 @@ class contact(hierarchy_design.hierarchy_design):
|
||||
# Module does not have pins, but has empty pin list.
|
||||
self.pins = []
|
||||
self.create_layout()
|
||||
|
||||
|
||||
def create_layout(self):
|
||||
|
||||
self.setup_layers()
|
||||
@@ -65,8 +65,10 @@ class contact(hierarchy_design.hierarchy_design):
|
||||
self.create_second_layer_enclosure()
|
||||
self.create_nitride_cut_enclosure()
|
||||
|
||||
self.height = max(obj.offset.y + obj.height for obj in self.objs)
|
||||
self.width = max(obj.offset.x + obj.width for obj in self.objs)
|
||||
self.height = max(self.first_layer_position.y + self.first_layer_height,
|
||||
self.second_layer_position.y + self.second_layer_height)
|
||||
self.width = max(self.first_layer_position.x + self.first_layer_width,
|
||||
self.second_layer_position.x + self.second_layer_width)
|
||||
|
||||
# Do not include the select layer in the height/width
|
||||
if self.implant_type and self.well_type:
|
||||
@@ -83,7 +85,7 @@ class contact(hierarchy_design.hierarchy_design):
|
||||
self.second_layer_name = second_layer
|
||||
|
||||
# Contacts will have unique per first layer
|
||||
if via_layer in tech.layer.keys():
|
||||
if via_layer in tech.layer:
|
||||
self.via_layer_name = via_layer
|
||||
elif via_layer == "contact":
|
||||
if first_layer in ("active", "poly"):
|
||||
@@ -171,7 +173,7 @@ class contact(hierarchy_design.hierarchy_design):
|
||||
def create_nitride_cut_enclosure(self):
|
||||
""" Special layer that encloses poly contacts in some processes """
|
||||
# Check if there is a special poly nitride cut layer
|
||||
if "npc" not in tech.layer.keys():
|
||||
if "npc" not in tech.layer:
|
||||
return
|
||||
|
||||
# Only add for poly layers
|
||||
@@ -224,13 +226,18 @@ class contact(hierarchy_design.hierarchy_design):
|
||||
offset=implant_position,
|
||||
width=implant_width,
|
||||
height=implant_height)
|
||||
well_position = self.first_layer_position - [drc("well_enclose_active")] * 2
|
||||
well_width = self.first_layer_width + 2 * drc("well_enclose_active")
|
||||
well_height = self.first_layer_height + 2 * drc("well_enclose_active")
|
||||
self.add_rect(layer="{}well".format(self.well_type),
|
||||
offset=well_position,
|
||||
width=well_width,
|
||||
height=well_height)
|
||||
|
||||
# Optionally implant well if layer exists
|
||||
well_layer = "{}well".format(self.well_type)
|
||||
if well_layer in tech.layer:
|
||||
well_enclose_active = drc(well_layer + "_enclose_active")
|
||||
well_position = self.first_layer_position - [well_enclose_active] * 2
|
||||
well_width = self.first_layer_width + 2 * well_enclose_active
|
||||
well_height = self.first_layer_height + 2 * well_enclose_active
|
||||
self.add_rect(layer=well_layer,
|
||||
offset=well_position,
|
||||
width=well_width,
|
||||
height=well_height)
|
||||
|
||||
def analytical_power(self, corner, load):
|
||||
""" Get total power of a module """
|
||||
|
||||
@@ -63,8 +63,8 @@ class design(hierarchy_design):
|
||||
|
||||
contact1 = getattr(contact, layer1 + layer2)
|
||||
max_contact = max(contact1.width, contact1.height)
|
||||
layer1_space = getattr(self, layer1+"_space")
|
||||
layer2_space = getattr(self, layer2+"_space")
|
||||
layer1_space = getattr(self, layer1 + "_space")
|
||||
layer2_space = getattr(self, layer2 + "_space")
|
||||
pitch = max_contact + max(layer1_space, layer2_space)
|
||||
|
||||
return pitch
|
||||
@@ -83,7 +83,7 @@ class design(hierarchy_design):
|
||||
if match.group(1) == "active_contact":
|
||||
setattr(self, "contact_width", drc(match.group(0)))
|
||||
else:
|
||||
setattr(self, match.group(1)+"_width", drc(match.group(0)))
|
||||
setattr(self, match.group(1) + "_width", drc(match.group(0)))
|
||||
|
||||
# Single layer area rules
|
||||
match = re.search(r"minarea_(.*)", rule)
|
||||
@@ -93,10 +93,10 @@ class design(hierarchy_design):
|
||||
# Single layer spacing rules
|
||||
match = re.search(r"(.*)_to_(.*)", rule)
|
||||
if match and match.group(1) == match.group(2):
|
||||
setattr(self, match.group(1)+"_space", drc(match.group(0)))
|
||||
setattr(self, match.group(1) + "_space", drc(match.group(0)))
|
||||
elif match and match.group(1) != match.group(2):
|
||||
if match.group(2) == "poly_active":
|
||||
setattr(self, match.group(1)+"_to_contact",
|
||||
setattr(self, match.group(1) + "_to_contact",
|
||||
drc(match.group(0)))
|
||||
else:
|
||||
setattr(self, match.group(0), drc(match.group(0)))
|
||||
|
||||
@@ -69,7 +69,9 @@ class geometry:
|
||||
""" Transform with offset, mirror and rotation to get the absolute pin location.
|
||||
We must then re-find the ll and ur. The master is the cell instance. """
|
||||
if OPTS.netlist_only:
|
||||
self.boundary = [vector(0,0), vector(0,0)]
|
||||
return
|
||||
|
||||
(ll, ur) = [vector(0, 0), vector(self.width, self.height)]
|
||||
|
||||
if mirror == "MX":
|
||||
|
||||
+437
-322
File diff suppressed because it is too large
Load Diff
@@ -128,7 +128,14 @@ class pin_layout:
|
||||
max_y = max(max_y, pin.ur().y)
|
||||
|
||||
self.rect = [vector(min_x, min_y), vector(max_x, max_y)]
|
||||
|
||||
|
||||
def fix_minarea(self):
|
||||
"""
|
||||
Try to fix minimum area rule.
|
||||
"""
|
||||
min_area = drc("{}_minarea".format(self.layer))
|
||||
pass
|
||||
|
||||
def inflate(self, spacing=None):
|
||||
"""
|
||||
Inflate the rectangle by the spacing (or other rule)
|
||||
|
||||
@@ -50,7 +50,7 @@ class vector():
|
||||
else:
|
||||
self.x=float(value[0])
|
||||
self.y=float(value[1])
|
||||
|
||||
|
||||
def __getitem__(self, index):
|
||||
"""
|
||||
override getitem function
|
||||
|
||||
Reference in New Issue
Block a user