mirror of https://github.com/VLSIDA/OpenRAM.git
Fix precharge offset. Move well rules to design class.
This commit is contained in:
parent
148521c458
commit
a28e747a02
|
|
@ -172,6 +172,20 @@ class design(hierarchy_design):
|
||||||
self.well_extend_active = max(self.well_extend_active, self.nwell_extend_active)
|
self.well_extend_active = max(self.well_extend_active, self.nwell_extend_active)
|
||||||
if "pwell" in layer:
|
if "pwell" in layer:
|
||||||
self.well_extend_active = max(self.well_extend_active, self.pwell_extend_active)
|
self.well_extend_active = max(self.well_extend_active, self.pwell_extend_active)
|
||||||
|
|
||||||
|
# The active offset is due to the well extension
|
||||||
|
if "pwell" in layer:
|
||||||
|
self.pwell_enclose_active = drc("pwell_enclose_active")
|
||||||
|
else:
|
||||||
|
self.pwell_enclose_active = 0
|
||||||
|
if "nwell" in layer:
|
||||||
|
self.nwell_enclose_active = drc("nwell_enclose_active")
|
||||||
|
else:
|
||||||
|
self.nwell_enclose_active = 0
|
||||||
|
# Use the max of either so that the poly gates will align properly
|
||||||
|
self.well_enclose_active = max(self.pwell_enclose_active,
|
||||||
|
self.nwell_enclose_active,
|
||||||
|
self.active_space)
|
||||||
|
|
||||||
# These are for debugging previous manual rules
|
# These are for debugging previous manual rules
|
||||||
if False:
|
if False:
|
||||||
|
|
|
||||||
|
|
@ -149,13 +149,9 @@ class precharge(design.design):
|
||||||
# Compute the other pmos2 location,
|
# Compute the other pmos2 location,
|
||||||
# but determining offset to overlap the source and drain pins
|
# but determining offset to overlap the source and drain pins
|
||||||
overlap_offset = self.pmos.get_pin("D").ll() - self.pmos.get_pin("S").ll()
|
overlap_offset = self.pmos.get_pin("D").ll() - self.pmos.get_pin("S").ll()
|
||||||
# This is how much the contact is placed inside the ptx active
|
|
||||||
contact_xdiff = self.pmos.get_pin("S").lx()
|
|
||||||
|
|
||||||
# adds the lower pmos to layout
|
# adds the lower pmos to layout
|
||||||
bl_xoffset = self.bitcell_bl_pin.lx()
|
self.lower_pmos_position = vector(self.well_enclose_active + 0.5 * self.m1_width,
|
||||||
self.lower_pmos_position = vector(max(bl_xoffset - contact_xdiff,
|
|
||||||
self.nwell_enclose_active),
|
|
||||||
self.initial_yoffset)
|
self.initial_yoffset)
|
||||||
self.lower_pmos_inst.place(self.lower_pmos_position)
|
self.lower_pmos_inst.place(self.lower_pmos_position)
|
||||||
|
|
||||||
|
|
@ -218,7 +214,7 @@ class precharge(design.design):
|
||||||
|
|
||||||
# adds the contact from active to metal1
|
# adds the contact from active to metal1
|
||||||
offset_height = self.upper_pmos1_inst.uy() + \
|
offset_height = self.upper_pmos1_inst.uy() + \
|
||||||
0.5 * contact.active_contact.height + \
|
contact.active_contact.height + \
|
||||||
self.nwell_extend_active
|
self.nwell_extend_active
|
||||||
self.well_contact_pos = self.upper_pmos1_inst.get_pin("D").center().scale(1, 0) + \
|
self.well_contact_pos = self.upper_pmos1_inst.get_pin("D").center().scale(1, 0) + \
|
||||||
vector(0, offset_height)
|
vector(0, offset_height)
|
||||||
|
|
|
||||||
|
|
@ -205,29 +205,15 @@ class ptx(design.design):
|
||||||
# Poly height must include poly extension over active
|
# Poly height must include poly extension over active
|
||||||
self.poly_height = self.tx_width + 2 * self.poly_extend_active
|
self.poly_height = self.tx_width + 2 * self.poly_extend_active
|
||||||
|
|
||||||
# The active offset is due to the well extension
|
self.active_offset = vector([self.well_enclose_active] * 2)
|
||||||
if "pwell" in layer:
|
|
||||||
pwell_enclose_active = drc("pwell_enclose_active")
|
|
||||||
else:
|
|
||||||
pwell_enclose_active = 0
|
|
||||||
if "nwell" in layer:
|
|
||||||
nwell_enclose_active = drc("nwell_enclose_active")
|
|
||||||
else:
|
|
||||||
nwell_enclose_active = 0
|
|
||||||
# Use the max of either so that the poly gates will align properly
|
|
||||||
well_enclose_active = max(pwell_enclose_active,
|
|
||||||
nwell_enclose_active,
|
|
||||||
self.active_space)
|
|
||||||
self.active_offset = vector([well_enclose_active] * 2)
|
|
||||||
|
|
||||||
# Well enclosure of active, ensure minwidth as well
|
# Well enclosure of active, ensure minwidth as well
|
||||||
well_name = "{}well".format(self.well_type)
|
well_name = "{}well".format(self.well_type)
|
||||||
if well_name in layer:
|
if well_name in layer:
|
||||||
well_width_rule = drc("minwidth_" + well_name)
|
well_width_rule = drc("minwidth_" + well_name)
|
||||||
well_enclose_active = drc(well_name + "_enclose_active")
|
self.well_width = max(self.active_width + 2 * self.well_enclose_active,
|
||||||
self.well_width = max(self.active_width + 2 * well_enclose_active,
|
|
||||||
well_width_rule)
|
well_width_rule)
|
||||||
self.well_height = max(self.active_height + 2 * well_enclose_active,
|
self.well_height = max(self.active_height + 2 * self.well_enclose_active,
|
||||||
well_width_rule)
|
well_width_rule)
|
||||||
# We are going to shift the 0,0, so include that in the width and height
|
# We are going to shift the 0,0, so include that in the width and height
|
||||||
self.height = self.well_height - self.active_offset.y
|
self.height = self.well_height - self.active_offset.y
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,47 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
# See LICENSE for licensing information.
|
||||||
|
#
|
||||||
|
# Copyright (c) 2016-2019 Regents of the University of California and The Board
|
||||||
|
# of Regents for the Oklahoma Agricultural and Mechanical College
|
||||||
|
# (acting for and on behalf of Oklahoma State University)
|
||||||
|
# All rights reserved.
|
||||||
|
#
|
||||||
|
import unittest
|
||||||
|
from testutils import *
|
||||||
|
import sys,os
|
||||||
|
sys.path.append(os.getenv("OPENRAM_HOME"))
|
||||||
|
import globals
|
||||||
|
from globals import OPTS
|
||||||
|
from sram_factory import factory
|
||||||
|
import debug
|
||||||
|
|
||||||
|
|
||||||
|
class precharge_test(openram_test):
|
||||||
|
|
||||||
|
def runTest(self):
|
||||||
|
config_file = "{}/tests/configs/config".format(os.getenv("OPENRAM_HOME"))
|
||||||
|
globals.init_openram(config_file)
|
||||||
|
|
||||||
|
# check precharge array in multi-port
|
||||||
|
OPTS.num_rw_ports = 1
|
||||||
|
OPTS.num_r_ports = 1
|
||||||
|
OPTS.num_w_ports = 0
|
||||||
|
globals.setup_bitcell()
|
||||||
|
|
||||||
|
debug.info(2, "Checking precharge for 1rw1r port 0")
|
||||||
|
tx = factory.create(module_type="precharge", size=1, bitcell_bl="bl0", bitcell_br="br0")
|
||||||
|
self.local_check(tx)
|
||||||
|
|
||||||
|
factory.reset()
|
||||||
|
debug.info(2, "Checking precharge for 1rw1r port 1")
|
||||||
|
tx = factory.create(module_type="precharge", size=1, bitcell_bl="bl1", bitcell_br="br1")
|
||||||
|
self.local_check(tx)
|
||||||
|
|
||||||
|
globals.end_openram()
|
||||||
|
|
||||||
|
# run the test from the command line
|
||||||
|
if __name__ == "__main__":
|
||||||
|
(OPTS, args) = globals.parse_args()
|
||||||
|
del sys.argv[1:]
|
||||||
|
header(__file__, OPTS.tech_name)
|
||||||
|
unittest.main(testRunner=debugTestRunner())
|
||||||
Loading…
Reference in New Issue