mirror of https://github.com/VLSIDA/OpenRAM.git
Dynamically try and DRC decoder for height
This commit is contained in:
parent
4103745de2
commit
0c27942bb2
|
|
@ -11,6 +11,7 @@ import math
|
||||||
from sram_factory import factory
|
from sram_factory import factory
|
||||||
from vector import vector
|
from vector import vector
|
||||||
from globals import OPTS
|
from globals import OPTS
|
||||||
|
from errors import drc_error
|
||||||
|
|
||||||
|
|
||||||
class hierarchical_decoder(design.design):
|
class hierarchical_decoder(design.design):
|
||||||
|
|
@ -37,18 +38,28 @@ class hierarchical_decoder(design.design):
|
||||||
def find_decoder_height(self):
|
def find_decoder_height(self):
|
||||||
b = factory.create(module_type="bitcell")
|
b = factory.create(module_type="bitcell")
|
||||||
# Old behavior
|
# Old behavior
|
||||||
return (b.height, 1)
|
# return (b.height, 1)
|
||||||
|
|
||||||
# Search for the smallest multiple that works
|
# Search for the smallest multiple that works
|
||||||
cell_multiple = 1
|
cell_multiple = 1
|
||||||
while cell_multiple < 3:
|
while cell_multiple < 5:
|
||||||
cell_height = cell_multiple * b.height
|
cell_height = cell_multiple * b.height
|
||||||
and3 = factory.create(module_type="pand3",
|
# debug.info(2,"Trying mult = {0} height={1}".format(cell_multiple, cell_height))
|
||||||
height=cell_height)
|
try:
|
||||||
(drc_errors, lvs_errors) = and3.DRC_LVS(force_check=True)
|
and3 = factory.create(module_type="pand3",
|
||||||
if drc_errors + lvs_errors == 0:
|
height=cell_height)
|
||||||
return (cell_height, cell_multiple)
|
except drc_error:
|
||||||
|
# debug.info(1, "Incrementing decoder height by 1 bitcell height {}".format(b.height))
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
(drc_errors, lvs_errors) = and3.DRC_LVS(force_check=True)
|
||||||
|
total_errors = drc_errors + lvs_errors
|
||||||
|
if total_errors == 0:
|
||||||
|
debug.info(1, "Decoder height is multiple of {} bitcells.".format(cell_multiple))
|
||||||
|
return (cell_height, cell_multiple)
|
||||||
|
|
||||||
cell_multiple += 1
|
cell_multiple += 1
|
||||||
|
|
||||||
else:
|
else:
|
||||||
debug.error("Couldn't find a valid decoder height multiple.", -1)
|
debug.error("Couldn't find a valid decoder height multiple.", -1)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@ from globals import OPTS
|
||||||
from utils import round_to_grid
|
from utils import round_to_grid
|
||||||
import logical_effort
|
import logical_effort
|
||||||
from sram_factory import factory
|
from sram_factory import factory
|
||||||
|
from errors import drc_error
|
||||||
|
|
||||||
|
|
||||||
class pinv(pgate.pgate):
|
class pinv(pgate.pgate):
|
||||||
|
|
@ -105,11 +106,14 @@ class pinv(pgate.pgate):
|
||||||
# This is a poly-to-poly of a flipped cell
|
# This is a poly-to-poly of a flipped cell
|
||||||
self.top_bottom_space = max(0.5*self.m1_width + self.m1_space + extra_contact_space,
|
self.top_bottom_space = max(0.5*self.m1_width + self.m1_space + extra_contact_space,
|
||||||
self.poly_extend_active + self.poly_space)
|
self.poly_extend_active + self.poly_space)
|
||||||
total_height = tx_height + min_channel + 2 * self.top_bottom_space
|
|
||||||
|
|
||||||
debug.check(self.height > total_height,
|
total_height = tx_height + min_channel + 2 * self.top_bottom_space
|
||||||
"Cell height {0} too small for simple min height {1}.".format(self.height,
|
# debug.check(self.height > total_height,
|
||||||
total_height))
|
# "Cell height {0} too small for simple min height {1}.".format(self.height,
|
||||||
|
# total_height))
|
||||||
|
if total_height > self.height:
|
||||||
|
msg = "Cell height {0} too small for simple min height {1}.".format(self.height, total_height)
|
||||||
|
raise drc_error(msg)
|
||||||
|
|
||||||
# Determine the height left to the transistors to determine
|
# Determine the height left to the transistors to determine
|
||||||
# the number of fingers
|
# the number of fingers
|
||||||
|
|
@ -141,12 +145,16 @@ class pinv(pgate.pgate):
|
||||||
# with LVS property mismatch errors when fingers are not a grid
|
# with LVS property mismatch errors when fingers are not a grid
|
||||||
# length and get rounded in the offset geometry.
|
# length and get rounded in the offset geometry.
|
||||||
self.nmos_width = round_to_grid(self.nmos_width / self.tx_mults)
|
self.nmos_width = round_to_grid(self.nmos_width / self.tx_mults)
|
||||||
debug.check(self.nmos_width >= drc("minwidth_tx"),
|
# debug.check(self.nmos_width >= drc("minwidth_tx"),
|
||||||
"Cannot finger NMOS transistors to fit cell height.")
|
# "Cannot finger NMOS transistors to fit cell height.")
|
||||||
self.pmos_width = round_to_grid(self.pmos_width / self.tx_mults)
|
if self.nmos_width < drc("minwidth_tx"):
|
||||||
debug.check(self.pmos_width >= drc("minwidth_tx"),
|
raise drc_error("Cannot finger NMOS transistors to fit cell height.")
|
||||||
"Cannot finger PMOS transistors to fit cell height.")
|
|
||||||
|
|
||||||
|
self.pmos_width = round_to_grid(self.pmos_width / self.tx_mults)
|
||||||
|
#debug.check(self.pmos_width >= drc("minwidth_tx"),
|
||||||
|
# "Cannot finger PMOS transistors to fit cell height.")
|
||||||
|
if self.pmos_width < drc("minwidth_tx"):
|
||||||
|
raise drc_error("Cannot finger NMOS transistors to fit cell height.")
|
||||||
|
|
||||||
def add_ptx(self):
|
def add_ptx(self):
|
||||||
""" Create the PMOS and NMOS transistors. """
|
""" Create the PMOS and NMOS transistors. """
|
||||||
|
|
|
||||||
|
|
@ -223,7 +223,7 @@ class pnand3(pgate.pgate):
|
||||||
position="center")
|
position="center")
|
||||||
|
|
||||||
# FIXME: constant hack
|
# FIXME: constant hack
|
||||||
self.inputA_yoffset = self.inputB_yoffset + 1.12 * m1_pitch
|
self.inputA_yoffset = self.inputB_yoffset + 1.15 * m1_pitch
|
||||||
self.route_input_gate(self.pmos1_inst,
|
self.route_input_gate(self.pmos1_inst,
|
||||||
self.nmos1_inst,
|
self.nmos1_inst,
|
||||||
self.inputA_yoffset,
|
self.inputA_yoffset,
|
||||||
|
|
|
||||||
|
|
@ -108,7 +108,6 @@ class ptx(design.design):
|
||||||
area_sd = 2.5 * self.poly_width * self.tx_width
|
area_sd = 2.5 * self.poly_width * self.tx_width
|
||||||
perimeter_sd = 2 * self.poly_width + 2 * self.tx_width
|
perimeter_sd = 2 * self.poly_width + 2 * self.tx_width
|
||||||
if OPTS.tech_name == "s8":
|
if OPTS.tech_name == "s8":
|
||||||
print("here {0}".format(self.name))
|
|
||||||
# s8 technology is in microns
|
# s8 technology is in microns
|
||||||
main_str = "M{{0}} {{1}} {0} m={1} w={2} l={3} ".format(spice[self.tx_type],
|
main_str = "M{{0}} {{1}} {0} m={1} w={2} l={3} ".format(spice[self.tx_type],
|
||||||
self.mults,
|
self.mults,
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue