mirror of https://github.com/VLSIDA/OpenRAM.git
Add per tool lvs directories
This commit is contained in:
parent
4fa084f272
commit
e460eff014
|
|
@ -17,6 +17,7 @@ from wire_spice_model import wire_spice_model
|
||||||
from power_data import power_data
|
from power_data import power_data
|
||||||
import logical_effort
|
import logical_effort
|
||||||
|
|
||||||
|
|
||||||
class spice():
|
class spice():
|
||||||
"""
|
"""
|
||||||
This provides a set of useful generic types for hierarchy
|
This provides a set of useful generic types for hierarchy
|
||||||
|
|
@ -36,14 +37,15 @@ class spice():
|
||||||
# If we have a separate lvs directory, then all the lvs files
|
# If we have a separate lvs directory, then all the lvs files
|
||||||
# should be in there (all or nothing!)
|
# should be in there (all or nothing!)
|
||||||
try:
|
try:
|
||||||
lvs_subdir = tech.lvs_lib
|
from tech import lvs_name
|
||||||
except AttributeError:
|
lvs_dir = OPTS.openram_tech + lvs_name + "_lvs_lib/"
|
||||||
lvs_subdir = "lvs_lib"
|
except ImportError:
|
||||||
lvs_dir = OPTS.openram_tech + lvs_subdir + "/"
|
lvs_dir = OPTS.openram_tech + "lvs_lib/"
|
||||||
|
if not os.path.exists(lvs_dir):
|
||||||
|
lvs_dir = OPTS.openram_tech + "lvs_lib/"
|
||||||
|
|
||||||
if os.path.exists(lvs_dir):
|
self.lvs_file = lvs_dir + cell_name + ".sp"
|
||||||
self.lvs_file = lvs_dir + cell_name + ".sp"
|
if not os.path.exists(self.lvs_file):
|
||||||
else:
|
|
||||||
self.lvs_file = self.sp_file
|
self.lvs_file = self.sp_file
|
||||||
|
|
||||||
self.valid_signal_types = ["INOUT", "INPUT", "OUTPUT", "BIAS", "POWER", "GROUND"]
|
self.valid_signal_types = ["INOUT", "INPUT", "OUTPUT", "BIAS", "POWER", "GROUND"]
|
||||||
|
|
@ -277,7 +279,10 @@ class spice():
|
||||||
# parses line into ports and remove subckt
|
# parses line into ports and remove subckt
|
||||||
lvs_pins = subckt_line.split(" ")[2:]
|
lvs_pins = subckt_line.split(" ")[2:]
|
||||||
debug.check(lvs_pins == self.pins,
|
debug.check(lvs_pins == self.pins,
|
||||||
"Spice netlists for LVS and simulation have port mismatches: {0} (LVS) vs {1} (sim)".format(lvs_pins, self.pins))
|
"Spice netlists for LVS and simulation have port mismatches:\n{0} (LVS {1})\nvs\n{2} (sim {3})".format(lvs_pins,
|
||||||
|
self.lvs_file,
|
||||||
|
self.pins,
|
||||||
|
self.sp_file))
|
||||||
|
|
||||||
def check_net_in_spice(self, net_name):
|
def check_net_in_spice(self, net_name):
|
||||||
"""Checks if a net name exists in the current. Intended to be check nets in hand-made cells."""
|
"""Checks if a net name exists in the current. Intended to be check nets in hand-made cells."""
|
||||||
|
|
@ -419,7 +424,7 @@ class spice():
|
||||||
self.cacti_params = cacti_params
|
self.cacti_params = cacti_params
|
||||||
# Get the r_on the the tx
|
# Get the r_on the the tx
|
||||||
rd = self.get_on_resistance()
|
rd = self.get_on_resistance()
|
||||||
# Calculate the intrinsic capacitance
|
# Calculate the intrinsic capacitance
|
||||||
c_intrinsic = self.get_intrinsic_capacitance()
|
c_intrinsic = self.get_intrinsic_capacitance()
|
||||||
# Get wire values
|
# Get wire values
|
||||||
c_wire = self.module_wire_c()
|
c_wire = self.module_wire_c()
|
||||||
|
|
@ -453,13 +458,13 @@ class spice():
|
||||||
|
|
||||||
def module_wire_c(self):
|
def module_wire_c(self):
|
||||||
"""All devices assumed to have ideal capacitance (0).
|
"""All devices assumed to have ideal capacitance (0).
|
||||||
Non-ideal cases should have this function re-defined.
|
Non-ideal cases should have this function re-defined.
|
||||||
"""
|
"""
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
def module_wire_r(self):
|
def module_wire_r(self):
|
||||||
"""All devices assumed to have ideal resistance (0).
|
"""All devices assumed to have ideal resistance (0).
|
||||||
Non-ideal cases should have this function re-defined.
|
Non-ideal cases should have this function re-defined.
|
||||||
"""
|
"""
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
|
|
@ -517,19 +522,19 @@ class spice():
|
||||||
self.cell_name))
|
self.cell_name))
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
def cacti_rc_delay(self,
|
def cacti_rc_delay(self,
|
||||||
inputramptime, # input rise time
|
inputramptime, # input rise time
|
||||||
tf, # time constant of gate
|
tf, # time constant of gate
|
||||||
vs1, # threshold voltage
|
vs1, # threshold voltage
|
||||||
vs2, # threshold voltage
|
vs2, # threshold voltage
|
||||||
rise, # whether input rises or fall
|
rise, # whether input rises or fall
|
||||||
extra_param_dict=None):
|
extra_param_dict=None):
|
||||||
"""By default, CACTI delay uses horowitz for gate delay.
|
"""By default, CACTI delay uses horowitz for gate delay.
|
||||||
Can be overriden in cases like bitline if equation is different.
|
Can be overriden in cases like bitline if equation is different.
|
||||||
"""
|
"""
|
||||||
return self.horowitz(inputramptime, tf, vs1, vs2, rise)
|
return self.horowitz(inputramptime, tf, vs1, vs2, rise)
|
||||||
|
|
||||||
def horowitz(self,
|
def horowitz(self,
|
||||||
inputramptime, # input rise time
|
inputramptime, # input rise time
|
||||||
tf, # time constant of gate
|
tf, # time constant of gate
|
||||||
vs1, # threshold voltage
|
vs1, # threshold voltage
|
||||||
|
|
@ -549,17 +554,17 @@ class spice():
|
||||||
td = tf * math.sqrt(math.log(1.0 - vs1)*math.log(1.0 - vs1) + 2*a*b*(vs1)) + tf*(math.log(1.0 - vs1) - math.log(1.0 - vs2))
|
td = tf * math.sqrt(math.log(1.0 - vs1)*math.log(1.0 - vs1) + 2*a*b*(vs1)) + tf*(math.log(1.0 - vs1) - math.log(1.0 - vs2))
|
||||||
|
|
||||||
return td
|
return td
|
||||||
|
|
||||||
def tr_r_on(self, width, is_nchannel, stack, _is_cell):
|
def tr_r_on(self, width, is_nchannel, stack, _is_cell):
|
||||||
|
|
||||||
restrans = self.cacti_params["r_nch_on"] if is_nchannel else self.cacti_params["r_pch_on"]
|
restrans = self.cacti_params["r_nch_on"] if is_nchannel else self.cacti_params["r_pch_on"]
|
||||||
return stack * restrans / width
|
return stack * restrans / width
|
||||||
|
|
||||||
def gate_c(self, width):
|
def gate_c(self, width):
|
||||||
|
|
||||||
return (tech.spice["c_g_ideal"] + tech.spice["c_overlap"] + 3*tech.spice["c_fringe"])*width +\
|
return (tech.spice["c_g_ideal"] + tech.spice["c_overlap"] + 3*tech.spice["c_fringe"])*width +\
|
||||||
tech.drc["minlength_channel"]*tech.spice["cpolywire"]
|
tech.drc["minlength_channel"]*tech.spice["cpolywire"]
|
||||||
|
|
||||||
def drain_c_(self,
|
def drain_c_(self,
|
||||||
width,
|
width,
|
||||||
stack,
|
stack,
|
||||||
|
|
@ -570,10 +575,10 @@ class spice():
|
||||||
c_fringe = 2*tech.spice["c_overlap"]
|
c_fringe = 2*tech.spice["c_overlap"]
|
||||||
c_overlap = 2*tech.spice["c_fringe"]
|
c_overlap = 2*tech.spice["c_fringe"]
|
||||||
drain_C_metal_connecting_folded_tr = 0
|
drain_C_metal_connecting_folded_tr = 0
|
||||||
|
|
||||||
w_folded_tr = width/folds
|
w_folded_tr = width/folds
|
||||||
num_folded_tr = folds
|
num_folded_tr = folds
|
||||||
|
|
||||||
# Re-created some logic contact to get minwidth as importing the contact
|
# Re-created some logic contact to get minwidth as importing the contact
|
||||||
# module causes a failure
|
# module causes a failure
|
||||||
if "minwidth_contact" in tech.drc:
|
if "minwidth_contact" in tech.drc:
|
||||||
|
|
@ -595,10 +600,10 @@ class spice():
|
||||||
|
|
||||||
if num_folded_tr%2 == 0:
|
if num_folded_tr%2 == 0:
|
||||||
drain_h_for_sidewall = 0
|
drain_h_for_sidewall = 0
|
||||||
|
|
||||||
total_drain_height_for_cap_wrt_gate *= num_folded_tr
|
total_drain_height_for_cap_wrt_gate *= num_folded_tr
|
||||||
drain_C_metal_connecting_folded_tr = tech.spice["wire_c_per_um"] * total_drain_w
|
drain_C_metal_connecting_folded_tr = tech.spice["wire_c_per_um"] * total_drain_w
|
||||||
|
|
||||||
|
|
||||||
drain_C_area = c_junc_area * total_drain_w * w_folded_tr
|
drain_C_area = c_junc_area * total_drain_w * w_folded_tr
|
||||||
drain_C_sidewall = c_junc_sidewall * (drain_h_for_sidewall + 2 * total_drain_w)
|
drain_C_sidewall = c_junc_sidewall * (drain_h_for_sidewall + 2 * total_drain_w)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue