mirror of https://github.com/VLSIDA/OpenRAM.git
Adjusted bitcell analytical delays for multiport cells.
This commit is contained in:
parent
25c034f85d
commit
a500d7ee3d
|
|
@ -2,6 +2,7 @@ import design
|
||||||
import debug
|
import debug
|
||||||
import utils
|
import utils
|
||||||
from tech import GDS,layer,parameter,drc
|
from tech import GDS,layer,parameter,drc
|
||||||
|
import logical_effort
|
||||||
|
|
||||||
class bitcell_1rw_1r(design.design):
|
class bitcell_1rw_1r(design.design):
|
||||||
"""
|
"""
|
||||||
|
|
@ -25,17 +26,11 @@ class bitcell_1rw_1r(design.design):
|
||||||
self.pin_map = bitcell_1rw_1r.pin_map
|
self.pin_map = bitcell_1rw_1r.pin_map
|
||||||
|
|
||||||
def analytical_delay(self, corner, slew, load=0, swing = 0.5):
|
def analytical_delay(self, corner, slew, load=0, swing = 0.5):
|
||||||
# delay of bit cell is not like a driver(from WL)
|
parasitic_delay = 1
|
||||||
# so the slew used should be 0
|
size = 0.5 #This accounts for bitline being drained thought the access TX and internal node
|
||||||
# it should not be slew dependent?
|
cin = 3 #Assumes always a minimum sizes inverter. Could be specified in the tech.py file.
|
||||||
# because the value is there
|
read_port_load = 0.5 #min size NMOS gate load
|
||||||
# the delay is only over half transsmission gate
|
return logical_effort.logical_effort('bitline', size, cin, load+read_port_load, parasitic_delay, False)
|
||||||
from tech import spice
|
|
||||||
r = spice["min_tx_r"]*3
|
|
||||||
c_para = spice["min_tx_drain_c"]
|
|
||||||
result = self.cal_delay_with_rc(corner, r = r, c = c_para+load, slew = slew, swing = swing)
|
|
||||||
return result
|
|
||||||
|
|
||||||
|
|
||||||
def list_bitcell_pins(self, col, row):
|
def list_bitcell_pins(self, col, row):
|
||||||
""" Creates a list of connections in the bitcell, indexed by column and row, for instance use in bitcell_array """
|
""" Creates a list of connections in the bitcell, indexed by column and row, for instance use in bitcell_array """
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ import design
|
||||||
import debug
|
import debug
|
||||||
import utils
|
import utils
|
||||||
from tech import GDS,layer,parameter,drc
|
from tech import GDS,layer,parameter,drc
|
||||||
|
import logical_effort
|
||||||
|
|
||||||
class bitcell_1w_1r(design.design):
|
class bitcell_1w_1r(design.design):
|
||||||
"""
|
"""
|
||||||
|
|
@ -25,17 +26,11 @@ class bitcell_1w_1r(design.design):
|
||||||
self.pin_map = bitcell_1w_1r.pin_map
|
self.pin_map = bitcell_1w_1r.pin_map
|
||||||
|
|
||||||
def analytical_delay(self, corner, slew, load=0, swing = 0.5):
|
def analytical_delay(self, corner, slew, load=0, swing = 0.5):
|
||||||
# delay of bit cell is not like a driver(from WL)
|
parasitic_delay = 1
|
||||||
# so the slew used should be 0
|
size = 0.5 #This accounts for bitline being drained thought the access TX and internal node
|
||||||
# it should not be slew dependent?
|
cin = 3 #Assumes always a minimum sizes inverter. Could be specified in the tech.py file.
|
||||||
# because the value is there
|
read_port_load = 0.5 #min size NMOS gate load
|
||||||
# the delay is only over half transsmission gate
|
return logical_effort.logical_effort('bitline', size, cin, load+read_port_load, parasitic_delay, False)
|
||||||
from tech import spice
|
|
||||||
r = spice["min_tx_r"]*3
|
|
||||||
c_para = spice["min_tx_drain_c"]
|
|
||||||
result = self.cal_delay_with_rc(corner, r = r, c = c_para+load, slew = slew, swing = swing)
|
|
||||||
return result
|
|
||||||
|
|
||||||
|
|
||||||
def list_bitcell_pins(self, col, row):
|
def list_bitcell_pins(self, col, row):
|
||||||
""" Creates a list of connections in the bitcell, indexed by column and row, for instance use in bitcell_array """
|
""" Creates a list of connections in the bitcell, indexed by column and row, for instance use in bitcell_array """
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ from tech import drc, parameter, spice
|
||||||
from vector import vector
|
from vector import vector
|
||||||
from ptx import ptx
|
from ptx import ptx
|
||||||
from globals import OPTS
|
from globals import OPTS
|
||||||
|
import logical_effort
|
||||||
|
|
||||||
class pbitcell(design.design):
|
class pbitcell(design.design):
|
||||||
"""
|
"""
|
||||||
|
|
@ -867,12 +868,16 @@ class pbitcell(design.design):
|
||||||
self.add_path("metal1", [Q_bar_pos, vdd_pos])
|
self.add_path("metal1", [Q_bar_pos, vdd_pos])
|
||||||
|
|
||||||
def analytical_delay(self, corner, slew, load=0, swing = 0.5):
|
def analytical_delay(self, corner, slew, load=0, swing = 0.5):
|
||||||
#FIXME: Delay copied exactly over from bitcell
|
parasitic_delay = 1
|
||||||
from tech import spice
|
size = 0.5 #This accounts for bitline being drained thought the access TX and internal node
|
||||||
r = spice["min_tx_r"]*3
|
cin = 3 #Assumes always a minimum sizes inverter. Could be specified in the tech.py file.
|
||||||
c_para = spice["min_tx_drain_c"]
|
|
||||||
result = self.cal_delay_with_rc(corner, r = r, c = c_para+load, slew = slew, swing = swing)
|
#Internal loads due to port configs are halved. This is to account for the size already being halved
|
||||||
return result
|
#for stacked TXs, but internal loads do not see this size estimation.
|
||||||
|
write_port_load = self.num_w_ports*logical_effort.convert_farad_to_relative_c(parameter['bitcell_drain_cap'])/2
|
||||||
|
read_port_load = self.num_r_ports/2 #min size NMOS gate load
|
||||||
|
total_load = load+read_port_load+write_port_load
|
||||||
|
return logical_effort.logical_effort('bitline', size, cin, load+read_port_load, parasitic_delay, False)
|
||||||
|
|
||||||
def analytical_power(self, corner, load):
|
def analytical_power(self, corner, load):
|
||||||
"""Bitcell power in nW. Only characterizes leakage."""
|
"""Bitcell power in nW. Only characterizes leakage."""
|
||||||
|
|
|
||||||
|
|
@ -1215,7 +1215,7 @@ class bank(design.design):
|
||||||
offset=control_pos,
|
offset=control_pos,
|
||||||
rotate=90)
|
rotate=90)
|
||||||
|
|
||||||
def analytical_delay(self, corner, slew, load):
|
def analytical_delay(self, corner, slew, load, port):
|
||||||
""" return analytical delay of the bank. This will track the clock to output path"""
|
""" return analytical delay of the bank. This will track the clock to output path"""
|
||||||
#FIXME: This delay is determined in the control logic. Should be moved here.
|
#FIXME: This delay is determined in the control logic. Should be moved here.
|
||||||
# word_driver_delay = self.wordline_driver.analytical_delay(corner,
|
# word_driver_delay = self.wordline_driver.analytical_delay(corner,
|
||||||
|
|
@ -1224,7 +1224,6 @@ class bank(design.design):
|
||||||
|
|
||||||
#FIXME: Array delay is the same for every port.
|
#FIXME: Array delay is the same for every port.
|
||||||
word_driver_slew = 0
|
word_driver_slew = 0
|
||||||
port = 0
|
|
||||||
if self.words_per_row > 1:
|
if self.words_per_row > 1:
|
||||||
bitline_ext_load = self.column_mux_array[port].get_drain_cin()
|
bitline_ext_load = self.column_mux_array[port].get_drain_cin()
|
||||||
else:
|
else:
|
||||||
|
|
|
||||||
|
|
@ -517,7 +517,7 @@ class sram_base(design, verilog, lef):
|
||||||
else:
|
else:
|
||||||
continue
|
continue
|
||||||
clk_to_wlen_delays = control_logic.analytical_delay(corner, slew, load)
|
clk_to_wlen_delays = control_logic.analytical_delay(corner, slew, load)
|
||||||
wlen_to_dout_delays = self.bank.analytical_delay(corner,slew,load) #port should probably be specified...
|
wlen_to_dout_delays = self.bank.analytical_delay(corner,slew,load,port) #port should probably be specified...
|
||||||
all_delays = clk_to_wlen_delays+wlen_to_dout_delays
|
all_delays = clk_to_wlen_delays+wlen_to_dout_delays
|
||||||
total_delay = logical_effort.calculate_absolute_delay(all_delays)
|
total_delay = logical_effort.calculate_absolute_delay(all_delays)
|
||||||
last_slew = .1*all_delays[-1].get_absolute_delay() #slew approximated as 10% of delay
|
last_slew = .1*all_delays[-1].get_absolute_delay() #slew approximated as 10% of delay
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue