Added analyical model test which compares measured delay to model delay.

This commit is contained in:
Hunter Nichols
2019-04-03 16:26:20 -07:00
parent f6eefc1728
commit cc5b347f42
11 changed files with 71 additions and 170 deletions
+12 -36
View File
@@ -1215,37 +1215,6 @@ class bank(design.design):
offset=control_pos,
rotate=90)
# def analytical_delay(self, corner, slew, load):
# """ return analytical delay of the bank"""
# results = []
# decoder_delay = self.row_decoder.analytical_delay(corner, slew, self.wordline_driver.input_load())
# word_driver_delay = self.wordline_driver.analytical_delay(corner,
# decoder_delay.slew,
# self.bitcell_array.input_load())
# #FIXME: Array delay is the same for every port.
# bitcell_array_delay = self.bitcell_array.analytical_delay(corner, word_driver_delay.slew)
# #This also essentially creates the same delay for each port. Good structure, no substance
# for port in self.all_ports:
# if self.words_per_row > 1:
# column_mux_delay = self.column_mux_array[port].analytical_delay(corner,
# bitcell_array_delay.slew,
# self.sense_amp_array.input_load())
# else:
# column_mux_delay = self.return_delay(delay = 0.0, slew=word_driver_delay.slew)
# bl_t_data_out_delay = self.sense_amp_array.analytical_delay(corner,
# column_mux_delay.slew,
# self.bitcell_array.output_load())
# # output load of bitcell_array is set to be only small part of bl for sense amp.
# results.append(decoder_delay + word_driver_delay + bitcell_array_delay + column_mux_delay + bl_t_data_out_delay)
# return results
def analytical_delay(self, corner, slew, load):
""" 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.
@@ -1255,20 +1224,27 @@ class bank(design.design):
#FIXME: Array delay is the same for every port.
word_driver_slew = 0
bitcell_array_delay = self.bitcell_array.analytical_delay(corner, word_driver_slew)
if self.words_per_row > 1:
bitline_ext_load = self.column_mux_array[port].get_drain_cin()
else:
bitline_ext_load = self.sense_amp_array.get_drain_cin()
bitcell_array_delay = self.bitcell_array.analytical_delay(corner, word_driver_slew, bitline_ext_load)
bitcell_array_slew = 0
#This also essentially creates the same delay for each port. Good structure, no substance
if self.words_per_row > 1:
sa_load = self.sense_amp_array.get_drain_load()
column_mux_delay = self.column_mux_array[port].analytical_delay(corner,
bitcell_array_delay.slew,
self.sense_amp_array.input_load())
bitcell_array_slew,
sa_load)
else:
column_mux_delay = []
column_mux_slew = 0
sense_amp_delay = self.sense_amp_array.analytical_delay(corner,
column_mux_slew,
self.bitcell_array.output_load())
column_mux_slew,
load)
# output load of bitcell_array is set to be only small part of bl for sense amp.
return bitcell_array_delay + column_mux_delay + sense_amp_delay
+2 -20
View File
@@ -128,27 +128,9 @@ class bitcell_array(design.design):
inst = self.cell_inst[row,col]
for pin_name in ["vdd", "gnd"]:
for pin in inst.get_pins(pin_name):
self.add_power_pin(pin_name, pin.center(), 0, pin.layer)
# def analytical_delay(self, corner, slew, load=0):
# from tech import drc
# wl_wire = self.gen_wl_wire()
# wl_wire.return_delay_over_wire(slew)
# wl_to_cell_delay = wl_wire.return_delay_over_wire(slew)
# # hypothetical delay from cell to bl end without sense amp
# bl_wire = self.gen_bl_wire()
# cell_load = 2 * bl_wire.return_input_cap() # we ingore the wire r
# # hence just use the whole c
# bl_swing = 0.1
# cell_delay = self.cell.analytical_delay(corner, wl_to_cell_delay.slew, cell_load, swing = bl_swing)
# #we do not consider the delay over the wire for now
# return self.return_delay(cell_delay.delay+wl_to_cell_delay.delay,
# wl_to_cell_delay.slew)
self.add_power_pin(pin_name, pin.center(), 0, pin.layer)
def analytical_delay(self, corner, slew, load=0):
def analytical_delay(self, corner, slew, load):
"""Returns relative delay of the bitline in the bitcell array"""
#The load being driven/drained is mostly the bitline but could include the sense amp or the column mux.
#The load from the bitlines is due to the drain capacitances from all the other bitlines and wire parasitics.
+7
View File
@@ -4,6 +4,7 @@ from vector import vector
from sram_factory import factory
import debug
from globals import OPTS
import logical_effort
class sense_amp_array(design.design):
"""
@@ -143,3 +144,9 @@ class sense_amp_array(design.design):
"""Get the relative capacitance of all the sense amp enable connections in the array"""
sense_amp_en_cin = self.amp.get_en_cin()
return sense_amp_en_cin * self.word_size
def get_drain_cin(self):
"""Get the relative capacitance of the drain of the PMOS isolation TX"""
#Estimated as half a parasitic delay.
drain_parasitics = .5
return drain_parasitics * logical_effort.logical_effort.pinv
@@ -7,6 +7,7 @@ import math
from vector import vector
from sram_factory import factory
from globals import OPTS
import logical_effort
class single_level_column_mux_array(design.design):
"""
@@ -232,5 +233,11 @@ class single_level_column_mux_array(design.design):
"""Returns relative delay that the column mux adds"""
#Single level column mux will add parasitic loads from other mux pass transistors and the sense amp.
drain_parasitics = .5 #Assumed parasitics from unused TXs
array_load = drain_parasitics*self.words_per_row*logical_effort.pinv
return [self.mux.analytical_delay(corner, slew, load+array_load)]
array_load = drain_parasitics*self.words_per_row*logical_effort.logical_effort.pinv
return [self.mux.analytical_delay(corner, slew, load+array_load)]
def get_drain_cin(self):
"""Get the relative capacitance of the drain of the NMOS pass TX"""
#Estimated as half a parasitic delay.
drain_parasitics = .5
return drain_parasitics * logical_effort.logical_effort.pinv