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)
|
||||
if "pwell" in layer:
|
||||
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
|
||||
if False:
|
||||
|
|
|
|||
|
|
@ -149,13 +149,9 @@ class precharge(design.design):
|
|||
# Compute the other pmos2 location,
|
||||
# but determining offset to overlap the source and drain pins
|
||||
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
|
||||
bl_xoffset = self.bitcell_bl_pin.lx()
|
||||
self.lower_pmos_position = vector(max(bl_xoffset - contact_xdiff,
|
||||
self.nwell_enclose_active),
|
||||
self.lower_pmos_position = vector(self.well_enclose_active + 0.5 * self.m1_width,
|
||||
self.initial_yoffset)
|
||||
self.lower_pmos_inst.place(self.lower_pmos_position)
|
||||
|
||||
|
|
@ -218,7 +214,7 @@ class precharge(design.design):
|
|||
|
||||
# adds the contact from active to metal1
|
||||
offset_height = self.upper_pmos1_inst.uy() + \
|
||||
0.5 * contact.active_contact.height + \
|
||||
contact.active_contact.height + \
|
||||
self.nwell_extend_active
|
||||
self.well_contact_pos = self.upper_pmos1_inst.get_pin("D").center().scale(1, 0) + \
|
||||
vector(0, offset_height)
|
||||
|
|
|
|||
|
|
@ -205,29 +205,15 @@ class ptx(design.design):
|
|||
# Poly height must include poly extension over active
|
||||
self.poly_height = self.tx_width + 2 * self.poly_extend_active
|
||||
|
||||
# The active offset is due to the well extension
|
||||
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)
|
||||
self.active_offset = vector([self.well_enclose_active] * 2)
|
||||
|
||||
# Well enclosure of active, ensure minwidth as well
|
||||
well_name = "{}well".format(self.well_type)
|
||||
if well_name in layer:
|
||||
well_width_rule = drc("minwidth_" + well_name)
|
||||
well_enclose_active = drc(well_name + "_enclose_active")
|
||||
self.well_width = max(self.active_width + 2 * well_enclose_active,
|
||||
self.well_width = max(self.active_width + 2 * self.well_enclose_active,
|
||||
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)
|
||||
# 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
|
||||
|
|
|
|||
|
|
@ -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