mirror of https://github.com/VLSIDA/OpenRAM.git
Removed dead code related to older characterization scheme
This commit is contained in:
parent
42f2ff679e
commit
73b2277daa
|
|
@ -55,12 +55,6 @@ class dff(design.design):
|
||||||
transition_prob = 0.5
|
transition_prob = 0.5
|
||||||
return transition_prob*(c_load + c_para)
|
return transition_prob*(c_load + c_para)
|
||||||
|
|
||||||
def get_clk_cin(self):
|
|
||||||
"""Return the total capacitance (in relative units) that the clock is loaded by in the dff"""
|
|
||||||
#This is a handmade cell so the value must be entered in the tech.py file or estimated.
|
|
||||||
#Calculated in the tech file by summing the widths of all the gates and dividing by the minimum width.
|
|
||||||
return parameter["dff_clk_cin"]
|
|
||||||
|
|
||||||
def build_graph(self, graph, inst_name, port_nets):
|
def build_graph(self, graph, inst_name, port_nets):
|
||||||
"""Adds edges based on inputs/outputs. Overrides base class function."""
|
"""Adds edges based on inputs/outputs. Overrides base class function."""
|
||||||
self.add_graph_edges(graph, port_nets)
|
self.add_graph_edges(graph, port_nets)
|
||||||
|
|
|
||||||
|
|
@ -1039,42 +1039,6 @@ class bank(design.design):
|
||||||
self.add_via_center(layers=self.m1_stack,
|
self.add_via_center(layers=self.m1_stack,
|
||||||
offset=control_pos)
|
offset=control_pos)
|
||||||
|
|
||||||
def determine_wordline_stage_efforts(self, external_cout, inp_is_rise=True):
|
|
||||||
"""Get the all the stage efforts for each stage in the path within the bank clk_buf to a wordline"""
|
|
||||||
# Decoder is assumed to have settled before the negative edge of the clock.
|
|
||||||
# Delay model relies on this assumption
|
|
||||||
stage_effort_list = []
|
|
||||||
wordline_cout = self.bitcell_array.get_wordline_cin() + external_cout
|
|
||||||
stage_effort_list += self.port_address.wordline_driver.determine_wordline_stage_efforts(wordline_cout,
|
|
||||||
inp_is_rise)
|
|
||||||
|
|
||||||
return stage_effort_list
|
|
||||||
|
|
||||||
def get_wl_en_cin(self):
|
|
||||||
"""Get the relative capacitance of all the clk connections in the bank"""
|
|
||||||
# wl_en only used in the wordline driver.
|
|
||||||
return self.port_address.wordline_driver.get_wl_en_cin()
|
|
||||||
|
|
||||||
def get_w_en_cin(self):
|
|
||||||
"""Get the relative capacitance of all the clk connections in the bank"""
|
|
||||||
# wl_en only used in the wordline driver.
|
|
||||||
port = self.write_ports[0]
|
|
||||||
return self.port_data[port].write_driver.get_w_en_cin()
|
|
||||||
|
|
||||||
def get_clk_bar_cin(self):
|
|
||||||
"""Get the relative capacitance of all the clk_bar connections in the bank"""
|
|
||||||
# Current bank only uses clock bar (clk_buf_bar) as an enable for the precharge array.
|
|
||||||
|
|
||||||
# Precharges are the all the same in Mulitport, one is picked
|
|
||||||
port = self.read_ports[0]
|
|
||||||
return self.port_data[port].precharge_array.get_en_cin()
|
|
||||||
|
|
||||||
def get_sen_cin(self):
|
|
||||||
"""Get the relative capacitance of all the sense amp enable connections in the bank"""
|
|
||||||
# Current bank only uses sen as an enable for the sense amps.
|
|
||||||
port = self.read_ports[0]
|
|
||||||
return self.port_data[port].sense_amp_array.get_en_cin()
|
|
||||||
|
|
||||||
def graph_exclude_precharge(self):
|
def graph_exclude_precharge(self):
|
||||||
"""Precharge adds a loop between bitlines, can be excluded to reduce complexity"""
|
"""Precharge adds a loop between bitlines, can be excluded to reduce complexity"""
|
||||||
for port in self.read_ports:
|
for port in self.read_ports:
|
||||||
|
|
|
||||||
|
|
@ -97,13 +97,6 @@ class bitcell_array(bitcell_base_array):
|
||||||
bl_wire.wire_c =spice["min_tx_drain_c"] + bl_wire.wire_c
|
bl_wire.wire_c =spice["min_tx_drain_c"] + bl_wire.wire_c
|
||||||
return bl_wire
|
return bl_wire
|
||||||
|
|
||||||
def get_wordline_cin(self):
|
|
||||||
"""Get the relative input capacitance from the wordline connections in all the bitcell"""
|
|
||||||
# A single wordline is connected to all the bitcells in a single row meaning the capacitance depends on the # of columns
|
|
||||||
bitcell_wl_cin = self.cell.get_wl_cin()
|
|
||||||
total_cin = bitcell_wl_cin * self.column_size
|
|
||||||
return total_cin
|
|
||||||
|
|
||||||
def graph_exclude_bits(self, targ_row, targ_col):
|
def graph_exclude_bits(self, targ_row, targ_col):
|
||||||
"""Excludes bits in column from being added to graph except target"""
|
"""Excludes bits in column from being added to graph except target"""
|
||||||
# Function is not robust with column mux configurations
|
# Function is not robust with column mux configurations
|
||||||
|
|
|
||||||
|
|
@ -156,96 +156,12 @@ class control_logic(design.design):
|
||||||
self.nand2 = factory.create(module_type="pnand2",
|
self.nand2 = factory.create(module_type="pnand2",
|
||||||
height=dff_height)
|
height=dff_height)
|
||||||
self.add_mod(self.nand2)
|
self.add_mod(self.nand2)
|
||||||
|
|
||||||
# if (self.port_type == "rw") or (self.port_type == "r"):
|
|
||||||
# from importlib import reload
|
|
||||||
# self.delay_chain_resized = False
|
|
||||||
# c = reload(__import__(OPTS.replica_bitline))
|
|
||||||
# replica_bitline = getattr(c, OPTS.replica_bitline)
|
|
||||||
# bitcell_loads = int(math.ceil(self.num_rows * OPTS.rbl_delay_percentage))
|
|
||||||
# #Use a model to determine the delays with that heuristic
|
|
||||||
# if OPTS.use_tech_delay_chain_size: #Use tech parameters if set.
|
|
||||||
# fanout_list = OPTS.delay_chain_stages*[OPTS.delay_chain_fanout_per_stage]
|
|
||||||
# debug.info(1, "Using tech parameters to size delay chain: fanout_list={}".format(fanout_list))
|
|
||||||
# self.replica_bitline = factory.create(module_type="replica_bitline",
|
|
||||||
# delay_fanout_list=fanout_list,
|
|
||||||
# bitcell_loads=bitcell_loads)
|
|
||||||
# if self.sram != None: #Calculate model value even for specified sizes
|
|
||||||
# self.set_sen_wl_delays()
|
|
||||||
|
|
||||||
# else: #Otherwise, use a heuristic and/or model based sizing.
|
|
||||||
# #First use a heuristic
|
|
||||||
# delay_stages_heuristic, delay_fanout_heuristic = self.get_heuristic_delay_chain_size()
|
|
||||||
# self.replica_bitline = factory.create(module_type="replica_bitline",
|
|
||||||
# delay_fanout_list=[delay_fanout_heuristic]*delay_stages_heuristic,
|
|
||||||
# bitcell_loads=bitcell_loads)
|
|
||||||
# #Resize if necessary, condition depends on resizing method
|
|
||||||
# if self.sram != None and self.enable_delay_chain_resizing and not self.does_sen_rise_fall_timing_match():
|
|
||||||
# #This resizes to match fall and rise delays, can make the delay chain weird sizes.
|
|
||||||
# stage_list = self.get_dynamic_delay_fanout_list(delay_stages_heuristic, delay_fanout_heuristic)
|
|
||||||
# self.replica_bitline = factory.create(module_type="replica_bitline",
|
|
||||||
# delay_fanout_list=stage_list,
|
|
||||||
# bitcell_loads=bitcell_loads)
|
|
||||||
|
|
||||||
# #This resizes based on total delay.
|
|
||||||
# # delay_stages, delay_fanout = self.get_dynamic_delay_chain_size(delay_stages_heuristic, delay_fanout_heuristic)
|
|
||||||
# # self.replica_bitline = factory.create(module_type="replica_bitline",
|
|
||||||
# # delay_fanout_list=[delay_fanout]*delay_stages,
|
|
||||||
# # bitcell_loads=bitcell_loads)
|
|
||||||
|
|
||||||
# self.sen_delay_rise,self.sen_delay_fall = self.get_delays_to_sen() #get the new timing
|
|
||||||
# self.delay_chain_resized = True
|
|
||||||
|
|
||||||
debug.check(OPTS.delay_chain_stages % 2,
|
debug.check(OPTS.delay_chain_stages % 2,
|
||||||
"Must use odd number of delay chain stages for inverting delay chain.")
|
"Must use odd number of delay chain stages for inverting delay chain.")
|
||||||
self.delay_chain=factory.create(module_type="delay_chain",
|
self.delay_chain=factory.create(module_type="delay_chain",
|
||||||
fanout_list = OPTS.delay_chain_stages * [ OPTS.delay_chain_fanout_per_stage ])
|
fanout_list = OPTS.delay_chain_stages * [ OPTS.delay_chain_fanout_per_stage ])
|
||||||
self.add_mod(self.delay_chain)
|
self.add_mod(self.delay_chain)
|
||||||
|
|
||||||
def get_heuristic_delay_chain_size(self):
|
|
||||||
"""Use a basic heuristic to determine the size of the delay chain used for the Sense Amp Enable """
|
|
||||||
# FIXME: The minimum was 2 fanout, now it will not pass DRC unless it is 3. Why?
|
|
||||||
delay_fanout = 3 # This can be anything >=3
|
|
||||||
# Model poorly captures delay of the column mux. Be pessismistic for column mux
|
|
||||||
if self.words_per_row >= 2:
|
|
||||||
delay_stages = 8
|
|
||||||
else:
|
|
||||||
delay_stages = 2
|
|
||||||
|
|
||||||
# Read ports have a shorter s_en delay. The model is not accurate enough to catch this difference
|
|
||||||
# on certain sram configs.
|
|
||||||
if self.port_type == "r":
|
|
||||||
delay_stages+=2
|
|
||||||
|
|
||||||
return (delay_stages, delay_fanout)
|
|
||||||
|
|
||||||
def set_sen_wl_delays(self):
|
|
||||||
"""Set delays for wordline and sense amp enable"""
|
|
||||||
self.wl_delay_rise, self.wl_delay_fall = self.get_delays_to_wl()
|
|
||||||
self.sen_delay_rise, self.sen_delay_fall = self.get_delays_to_sen()
|
|
||||||
self.wl_delay = self.wl_delay_rise + self.wl_delay_fall
|
|
||||||
self.sen_delay = self.sen_delay_rise + self.sen_delay_fall
|
|
||||||
|
|
||||||
def does_sen_rise_fall_timing_match(self):
|
|
||||||
"""Compare the relative rise/fall delays of the sense amp enable and wordline"""
|
|
||||||
self.set_sen_wl_delays()
|
|
||||||
# This is not necessarily more reliable than total delay in some cases.
|
|
||||||
if (self.wl_delay_rise * self.wl_timing_tolerance >= self.sen_delay_rise or
|
|
||||||
self.wl_delay_fall * self.wl_timing_tolerance >= self.sen_delay_fall):
|
|
||||||
return False
|
|
||||||
else:
|
|
||||||
return True
|
|
||||||
|
|
||||||
def does_sen_total_timing_match(self):
|
|
||||||
"""Compare the total delays of the sense amp enable and wordline"""
|
|
||||||
self.set_sen_wl_delays()
|
|
||||||
# The sen delay must always be bigger than than the wl
|
|
||||||
# delay. This decides how much larger the sen delay must be
|
|
||||||
# before a re-size is warranted.
|
|
||||||
if self.wl_delay * self.wl_timing_tolerance >= self.sen_delay:
|
|
||||||
return False
|
|
||||||
else:
|
|
||||||
return True
|
|
||||||
|
|
||||||
def get_dynamic_delay_chain_size(self, previous_stages, previous_fanout):
|
def get_dynamic_delay_chain_size(self, previous_stages, previous_fanout):
|
||||||
"""Determine the size of the delay chain used for the Sense Amp Enable using path delays"""
|
"""Determine the size of the delay chain used for the Sense Amp Enable using path delays"""
|
||||||
|
|
@ -333,17 +249,6 @@ class control_logic(design.design):
|
||||||
delay_per_stage = fanout + 1 + self.inv_parasitic_delay
|
delay_per_stage = fanout + 1 + self.inv_parasitic_delay
|
||||||
delay_stages = ceil(required_delay / delay_per_stage)
|
delay_stages = ceil(required_delay / delay_per_stage)
|
||||||
return delay_stages
|
return delay_stages
|
||||||
|
|
||||||
def calculate_stage_list(self, total_stages, fanout_rise, fanout_fall):
|
|
||||||
"""
|
|
||||||
Produces a list of fanouts which determine the size of the delay chain.
|
|
||||||
List length is the number of stages.
|
|
||||||
Assumes the first stage is falling.
|
|
||||||
"""
|
|
||||||
stage_list = []
|
|
||||||
for i in range(total_stages):
|
|
||||||
if i % 2 == 0:
|
|
||||||
stage_list.append()
|
|
||||||
|
|
||||||
def setup_signal_busses(self):
|
def setup_signal_busses(self):
|
||||||
""" Setup bus names, determine the size of the busses etc """
|
""" Setup bus names, determine the size of the busses etc """
|
||||||
|
|
@ -869,137 +774,6 @@ class control_logic(design.design):
|
||||||
offset=pin.ll(),
|
offset=pin.ll(),
|
||||||
height=pin.height(),
|
height=pin.height(),
|
||||||
width=pin.width())
|
width=pin.width())
|
||||||
def get_delays_to_wl(self):
|
|
||||||
"""Get the delay (in delay units) of the clk to a wordline in the bitcell array"""
|
|
||||||
debug.check(self.sram.all_mods_except_control_done, "Cannot calculate sense amp enable delay unless all module have been added.")
|
|
||||||
self.wl_stage_efforts = self.get_wordline_stage_efforts()
|
|
||||||
clk_to_wl_rise, clk_to_wl_fall = logical_effort.calculate_relative_rise_fall_delays(self.wl_stage_efforts)
|
|
||||||
total_delay = clk_to_wl_rise + clk_to_wl_fall
|
|
||||||
debug.info(1,
|
|
||||||
"Clock to wl delay is rise={:.3f}, fall={:.3f}, total={:.3f} in delay units".format(clk_to_wl_rise,
|
|
||||||
clk_to_wl_fall,
|
|
||||||
total_delay))
|
|
||||||
return clk_to_wl_rise, clk_to_wl_fall
|
|
||||||
|
|
||||||
def get_wordline_stage_efforts(self):
|
|
||||||
"""Follows the gated_clk_bar -> wl_en -> wordline signal for the total path efforts"""
|
|
||||||
stage_effort_list = []
|
|
||||||
|
|
||||||
# Initial direction of gated_clk_bar signal for this path
|
|
||||||
is_clk_bar_rise = True
|
|
||||||
|
|
||||||
# Calculate the load on wl_en within the module and add it to external load
|
|
||||||
external_cout = self.sram.get_wl_en_cin()
|
|
||||||
# First stage is the clock buffer
|
|
||||||
stage_effort_list += self.clk_buf_driver.get_stage_efforts(external_cout, is_clk_bar_rise)
|
|
||||||
last_stage_is_rise = stage_effort_list[-1].is_rise
|
|
||||||
|
|
||||||
# Then ask the sram for the other path delays (from the bank)
|
|
||||||
stage_effort_list += self.sram.get_wordline_stage_efforts(last_stage_is_rise)
|
|
||||||
|
|
||||||
return stage_effort_list
|
|
||||||
|
|
||||||
def get_delays_to_sen(self):
|
|
||||||
"""
|
|
||||||
Get the delay (in delay units) of the clk to a sense amp enable.
|
|
||||||
This does not incorporate the delay of the replica bitline.
|
|
||||||
"""
|
|
||||||
debug.check(self.sram.all_mods_except_control_done, "Cannot calculate sense amp enable delay unless all module have been added.")
|
|
||||||
self.sen_stage_efforts = self.get_sa_enable_stage_efforts()
|
|
||||||
clk_to_sen_rise, clk_to_sen_fall = logical_effort.calculate_relative_rise_fall_delays(self.sen_stage_efforts)
|
|
||||||
total_delay = clk_to_sen_rise + clk_to_sen_fall
|
|
||||||
debug.info(1,
|
|
||||||
"Clock to s_en delay is rise={:.3f}, fall={:.3f}, total={:.3f} in delay units".format(clk_to_sen_rise,
|
|
||||||
clk_to_sen_fall,
|
|
||||||
total_delay))
|
|
||||||
return clk_to_sen_rise, clk_to_sen_fall
|
|
||||||
|
|
||||||
def get_sa_enable_stage_efforts(self):
|
|
||||||
"""Follows the gated_clk_bar signal to the sense amp enable signal adding each stages stage effort to a list"""
|
|
||||||
stage_effort_list = []
|
|
||||||
|
|
||||||
# Initial direction of clock signal for this path
|
|
||||||
last_stage_rise = True
|
|
||||||
|
|
||||||
# First stage, gated_clk_bar -(and2)-> rbl_in. Only for RW ports.
|
|
||||||
if self.port_type == "rw":
|
|
||||||
stage1_cout = self.replica_bitline.get_en_cin()
|
|
||||||
stage_effort_list += self.and2.get_stage_efforts(stage1_cout, last_stage_rise)
|
|
||||||
last_stage_rise = stage_effort_list[-1].is_rise
|
|
||||||
|
|
||||||
# Replica bitline stage, rbl_in -(rbl)-> pre_s_en
|
|
||||||
stage2_cout = self.sen_and2.get_cin()
|
|
||||||
stage_effort_list += self.replica_bitline.determine_sen_stage_efforts(stage2_cout, last_stage_rise)
|
|
||||||
last_stage_rise = stage_effort_list[-1].is_rise
|
|
||||||
|
|
||||||
# buffer stage, pre_s_en -(buffer)-> s_en
|
|
||||||
stage3_cout = self.sram.get_sen_cin()
|
|
||||||
stage_effort_list += self.s_en_driver.get_stage_efforts(stage3_cout, last_stage_rise)
|
|
||||||
last_stage_rise = stage_effort_list[-1].is_rise
|
|
||||||
|
|
||||||
return stage_effort_list
|
|
||||||
|
|
||||||
def get_wl_sen_delays(self):
|
|
||||||
""" Gets a list of the stages and delays in order of their path. """
|
|
||||||
|
|
||||||
if self.sen_stage_efforts == None or self.wl_stage_efforts == None:
|
|
||||||
debug.error("Model delays not calculated for SRAM.", 1)
|
|
||||||
wl_delays = logical_effort.calculate_delays(self.wl_stage_efforts)
|
|
||||||
sen_delays = logical_effort.calculate_delays(self.sen_stage_efforts)
|
|
||||||
return wl_delays, sen_delays
|
|
||||||
|
|
||||||
def analytical_delay(self, corner, slew, load):
|
|
||||||
""" Gets the analytical delay from clk input to wl_en output """
|
|
||||||
|
|
||||||
stage_effort_list = []
|
|
||||||
# Calculate the load on clk_buf_bar
|
|
||||||
# ext_clk_buf_cout = self.sram.get_clk_bar_cin()
|
|
||||||
|
|
||||||
# Operations logic starts on negative edge
|
|
||||||
last_stage_rise = False
|
|
||||||
|
|
||||||
# First stage(s), clk -(pdriver)-> clk_buf.
|
|
||||||
# clk_buf_cout = self.replica_bitline.get_en_cin()
|
|
||||||
clk_buf_cout = 0
|
|
||||||
stage_effort_list += self.clk_buf_driver.get_stage_efforts(clk_buf_cout, last_stage_rise)
|
|
||||||
last_stage_rise = stage_effort_list[-1].is_rise
|
|
||||||
|
|
||||||
# Second stage, clk_buf -(inv)-> clk_bar
|
|
||||||
clk_bar_cout = self.and2.get_cin()
|
|
||||||
stage_effort_list += self.and2.get_stage_efforts(clk_bar_cout, last_stage_rise)
|
|
||||||
last_stage_rise = stage_effort_list[-1].is_rise
|
|
||||||
|
|
||||||
# Third stage clk_bar -(and)-> gated_clk_bar
|
|
||||||
gated_clk_bar_cin = self.get_gated_clk_bar_cin()
|
|
||||||
stage_effort_list.append(self.inv.get_stage_effort(gated_clk_bar_cin, last_stage_rise))
|
|
||||||
last_stage_rise = stage_effort_list[-1].is_rise
|
|
||||||
|
|
||||||
# Stages from gated_clk_bar -------> wordline
|
|
||||||
stage_effort_list += self.get_wordline_stage_efforts()
|
|
||||||
return stage_effort_list
|
|
||||||
|
|
||||||
def get_clk_buf_cin(self):
|
|
||||||
"""
|
|
||||||
Get the loads that are connected to the buffered clock.
|
|
||||||
Includes all the DFFs and some logic.
|
|
||||||
"""
|
|
||||||
|
|
||||||
# Control logic internal load
|
|
||||||
int_clk_buf_cap = self.inv.get_cin() + self.ctrl_dff_array.get_clk_cin() + self.and2.get_cin()
|
|
||||||
|
|
||||||
# Control logic external load (in the other parts of the SRAM)
|
|
||||||
ext_clk_buf_cap = self.sram.get_clk_bar_cin()
|
|
||||||
|
|
||||||
return int_clk_buf_cap + ext_clk_buf_cap
|
|
||||||
|
|
||||||
def get_gated_clk_bar_cin(self):
|
|
||||||
"""Get intermediates net gated_clk_bar's capacitance"""
|
|
||||||
|
|
||||||
total_cin = 0
|
|
||||||
total_cin += self.wl_en_driver.get_cin()
|
|
||||||
if self.port_type == 'rw':
|
|
||||||
total_cin += self.and2.get_cin()
|
|
||||||
return total_cin
|
|
||||||
|
|
||||||
def graph_exclude_dffs(self):
|
def graph_exclude_dffs(self):
|
||||||
"""Exclude dffs from graph as they do not represent critical path"""
|
"""Exclude dffs from graph as they do not represent critical path"""
|
||||||
|
|
|
||||||
|
|
@ -210,25 +210,3 @@ class delay_chain(design.design):
|
||||||
layer="m2",
|
layer="m2",
|
||||||
start=mid_point,
|
start=mid_point,
|
||||||
end=mid_point.scale(1, 0))
|
end=mid_point.scale(1, 0))
|
||||||
|
|
||||||
def get_cin(self):
|
|
||||||
"""Get the enable input ralative capacitance"""
|
|
||||||
# Only 1 input to the delay chain which is connected to an inverter.
|
|
||||||
dc_cin = self.inv.get_cin()
|
|
||||||
return dc_cin
|
|
||||||
|
|
||||||
def determine_delayed_en_stage_efforts(self, ext_delayed_en_cout, inp_is_rise=True):
|
|
||||||
"""Get the stage efforts from the en to s_en. Does not compute the delay for the bitline load."""
|
|
||||||
stage_effort_list = []
|
|
||||||
# Add a stage to the list for every stage in delay chain.
|
|
||||||
# Stages only differ in fanout except the last which has an external cout.
|
|
||||||
last_stage_is_rise = inp_is_rise
|
|
||||||
for stage_fanout in self.fanout_list:
|
|
||||||
stage_cout = self.inv.get_cin() * (stage_fanout + 1)
|
|
||||||
if len(stage_effort_list) == len(self.fanout_list) - 1:
|
|
||||||
stage_cout+=ext_delayed_en_cout
|
|
||||||
stage = self.inv.get_stage_effort(stage_cout, last_stage_is_rise)
|
|
||||||
stage_effort_list.append(stage)
|
|
||||||
last_stage_is_rise = stage.is_rise
|
|
||||||
|
|
||||||
return stage_effort_list
|
|
||||||
|
|
|
||||||
|
|
@ -155,9 +155,3 @@ class dff_array(design.design):
|
||||||
self.add_via_stack_center(from_layer=clk_pin.layer,
|
self.add_via_stack_center(from_layer=clk_pin.layer,
|
||||||
to_layer="m3",
|
to_layer="m3",
|
||||||
offset=vector(clk_pin.cx(), clk_ypos))
|
offset=vector(clk_pin.cx(), clk_ypos))
|
||||||
|
|
||||||
def get_clk_cin(self):
|
|
||||||
"""Return the total capacitance (in relative units) that the clock is loaded by in the dff array"""
|
|
||||||
dff_clk_cin = self.dff.get_clk_cin()
|
|
||||||
total_cin = dff_clk_cin * self.rows * self.columns
|
|
||||||
return total_cin
|
|
||||||
|
|
|
||||||
|
|
@ -196,10 +196,3 @@ class dff_buf(design.design):
|
||||||
self.add_via_stack_center(from_layer=a2_pin.layer,
|
self.add_via_stack_center(from_layer=a2_pin.layer,
|
||||||
to_layer="m2",
|
to_layer="m2",
|
||||||
offset=qb_pos)
|
offset=qb_pos)
|
||||||
|
|
||||||
def get_clk_cin(self):
|
|
||||||
"""Return the total capacitance (in relative units) that the clock is loaded by in the dff"""
|
|
||||||
# This is a handmade cell so the value must be entered in the tech.py file or estimated.
|
|
||||||
# Calculated in the tech file by summing the widths of all the gates and dividing by the minimum width.
|
|
||||||
# FIXME: Dff changed in a past commit. The parameter need to be updated.
|
|
||||||
return parameter["dff_clk_cin"]
|
|
||||||
|
|
|
||||||
|
|
@ -227,9 +227,3 @@ class dff_buf_array(design.design):
|
||||||
# Drop a via to the M3 pin
|
# Drop a via to the M3 pin
|
||||||
self.add_via_center(layers=self.m2_stack,
|
self.add_via_center(layers=self.m2_stack,
|
||||||
offset=vector(clk_pin.cx(), clk_ypos))
|
offset=vector(clk_pin.cx(), clk_ypos))
|
||||||
|
|
||||||
def get_clk_cin(self):
|
|
||||||
"""Return the total capacitance (in relative units) that the clock is loaded by in the dff array"""
|
|
||||||
dff_clk_cin = self.dff.get_clk_cin()
|
|
||||||
total_cin = dff_clk_cin * self.rows * self.columns
|
|
||||||
return total_cin
|
|
||||||
|
|
|
||||||
|
|
@ -150,7 +150,3 @@ class dff_inv(design.design):
|
||||||
offset=dout_pin.center())
|
offset=dout_pin.center())
|
||||||
self.add_via_center(layers=self.m1_stack,
|
self.add_via_center(layers=self.m1_stack,
|
||||||
offset=dout_pin.center())
|
offset=dout_pin.center())
|
||||||
|
|
||||||
def get_clk_cin(self):
|
|
||||||
"""Return the total capacitance (in relative units) that the clock is loaded by in the dff"""
|
|
||||||
return self.dff.get_clk_cin()
|
|
||||||
|
|
|
||||||
|
|
@ -188,10 +188,4 @@ class dff_inv_array(design.design):
|
||||||
height=self.height)
|
height=self.height)
|
||||||
# Drop a via to the M3 pin
|
# Drop a via to the M3 pin
|
||||||
self.add_via_center(layers=self.m2_stack,
|
self.add_via_center(layers=self.m2_stack,
|
||||||
offset=vector(clk_pin.cx(),clk_ypos))
|
offset=vector(clk_pin.cx(),clk_ypos))
|
||||||
|
|
||||||
def get_clk_cin(self):
|
|
||||||
"""Return the total capacitance (in relative units) that the clock is loaded by in the dff array"""
|
|
||||||
dff_clk_cin = self.dff.get_clk_cin()
|
|
||||||
total_cin = dff_clk_cin * self.rows * self.columns
|
|
||||||
return total_cin
|
|
||||||
|
|
|
||||||
|
|
@ -54,12 +54,7 @@ class dummy_array(bitcell_base_array):
|
||||||
self.connect_inst(self.get_bitcell_pins(row, col))
|
self.connect_inst(self.get_bitcell_pins(row, col))
|
||||||
|
|
||||||
def input_load(self):
|
def input_load(self):
|
||||||
|
# FIXME: This appears to be old code from previous characterization. Needs to be updated.
|
||||||
wl_wire = self.gen_wl_wire()
|
wl_wire = self.gen_wl_wire()
|
||||||
return wl_wire.return_input_cap()
|
return wl_wire.return_input_cap()
|
||||||
|
|
||||||
def get_wordline_cin(self):
|
|
||||||
"""Get the relative input capacitance from the wordline connections in all the bitcell"""
|
|
||||||
# A single wordline is connected to all the bitcells in a single row meaning the capacitance depends on the # of columns
|
|
||||||
bitcell_wl_cin = self.cell.get_wl_cin()
|
|
||||||
total_cin = bitcell_wl_cin * self.column_size
|
|
||||||
return total_cin
|
|
||||||
|
|
@ -606,11 +606,3 @@ class hierarchical_decoder(design.design):
|
||||||
to_layer=self.output_layer,
|
to_layer=self.output_layer,
|
||||||
offset=rail_pos,
|
offset=rail_pos,
|
||||||
directions=self.bus_directions)
|
directions=self.bus_directions)
|
||||||
|
|
||||||
def input_load(self):
|
|
||||||
if self.determine_predecodes(self.num_inputs)[1]==0:
|
|
||||||
pre = self.pre2_4
|
|
||||||
else:
|
|
||||||
pre = self.pre3_8
|
|
||||||
return pre.input_load()
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -125,13 +125,3 @@ class precharge_array(design.design):
|
||||||
offset = vector(tempx, 0)
|
offset = vector(tempx, 0)
|
||||||
self.local_insts[i].place(offset=offset, mirror=mirror)
|
self.local_insts[i].place(offset=offset, mirror=mirror)
|
||||||
xoffset = xoffset + self.pc_cell.width
|
xoffset = xoffset + self.pc_cell.width
|
||||||
|
|
||||||
def get_en_cin(self):
|
|
||||||
"""
|
|
||||||
Get the relative capacitance of all the clk connections
|
|
||||||
in the precharge array
|
|
||||||
"""
|
|
||||||
# Assume single port
|
|
||||||
precharge_en_cin = self.pc_cell.get_en_cin()
|
|
||||||
return precharge_en_cin * self.columns
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -552,13 +552,6 @@ class replica_bitcell_array(bitcell_base_array.bitcell_base_array):
|
||||||
bl_wire.wire_c =spice["min_tx_drain_c"] + bl_wire.wire_c # 1 access tx d/s per cell
|
bl_wire.wire_c =spice["min_tx_drain_c"] + bl_wire.wire_c # 1 access tx d/s per cell
|
||||||
return bl_wire
|
return bl_wire
|
||||||
|
|
||||||
def get_wordline_cin(self):
|
|
||||||
"""Get the relative input capacitance from the wordline connections in all the bitcell"""
|
|
||||||
# A single wordline is connected to all the bitcells in a single row meaning the capacitance depends on the # of columns
|
|
||||||
bitcell_wl_cin = self.cell.get_wl_cin()
|
|
||||||
total_cin = bitcell_wl_cin * self.column_size
|
|
||||||
return total_cin
|
|
||||||
|
|
||||||
def graph_exclude_bits(self, targ_row, targ_col):
|
def graph_exclude_bits(self, targ_row, targ_col):
|
||||||
"""Excludes bits in column from being added to graph except target"""
|
"""Excludes bits in column from being added to graph except target"""
|
||||||
self.bitcell_array.graph_exclude_bits(targ_row, targ_col)
|
self.bitcell_array.graph_exclude_bits(targ_row, targ_col)
|
||||||
|
|
|
||||||
|
|
@ -82,13 +82,6 @@ class sense_amp(design.design):
|
||||||
# Power in this module currently not defined. Returns 0 nW (leakage and dynamic).
|
# Power in this module currently not defined. Returns 0 nW (leakage and dynamic).
|
||||||
total_power = self.return_power()
|
total_power = self.return_power()
|
||||||
return total_power
|
return total_power
|
||||||
|
|
||||||
def get_en_cin(self):
|
|
||||||
"""Get the relative capacitance of sense amp enable gate cin"""
|
|
||||||
pmos_cin = parameter["sa_en_pmos_size"] / drc("minwidth_tx")
|
|
||||||
nmos_cin = parameter["sa_en_nmos_size"] / drc("minwidth_tx")
|
|
||||||
# sen is connected to 2 pmos isolation TX and 1 nmos per sense amp.
|
|
||||||
return 2 * pmos_cin + nmos_cin
|
|
||||||
|
|
||||||
def get_enable_name(self):
|
def get_enable_name(self):
|
||||||
"""Returns name used for enable net"""
|
"""Returns name used for enable net"""
|
||||||
|
|
|
||||||
|
|
@ -190,18 +190,3 @@ class sense_amp_array(design.design):
|
||||||
self.add_via_stack_center(from_layer=en_pin.layer,
|
self.add_via_stack_center(from_layer=en_pin.layer,
|
||||||
to_layer=self.en_layer,
|
to_layer=self.en_layer,
|
||||||
offset=inst.get_pin(self.amp.en_name).center())
|
offset=inst.get_pin(self.amp.en_name).center())
|
||||||
|
|
||||||
def input_load(self):
|
|
||||||
return self.amp.input_load()
|
|
||||||
|
|
||||||
def get_en_cin(self):
|
|
||||||
"""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"""
|
|
||||||
from tech import parameter
|
|
||||||
# Bitcell drain load being used to estimate PMOS drain load
|
|
||||||
drain_load = logical_effort.convert_farad_to_relative_c(parameter['bitcell_drain_cap'])
|
|
||||||
return drain_load
|
|
||||||
|
|
|
||||||
|
|
@ -230,10 +230,3 @@ class single_level_column_mux_array(design.design):
|
||||||
to_layer=self.sel_layer,
|
to_layer=self.sel_layer,
|
||||||
offset=br_out_offset_begin,
|
offset=br_out_offset_begin,
|
||||||
directions=self.via_directions)
|
directions=self.via_directions)
|
||||||
|
|
||||||
def get_drain_cin(self):
|
|
||||||
"""Get the relative capacitance of the drain of the NMOS pass TX"""
|
|
||||||
from tech import parameter
|
|
||||||
# Bitcell drain load being used to estimate mux NMOS drain load
|
|
||||||
drain_load = logical_effort.convert_farad_to_relative_c(parameter['bitcell_drain_cap'])
|
|
||||||
return drain_load
|
|
||||||
|
|
|
||||||
|
|
@ -159,24 +159,3 @@ class wordline_driver_array(design.design):
|
||||||
layer=self.route_layer,
|
layer=self.route_layer,
|
||||||
start=wl_offset,
|
start=wl_offset,
|
||||||
end=wl_offset - vector(self.m1_width, 0))
|
end=wl_offset - vector(self.m1_width, 0))
|
||||||
|
|
||||||
def determine_wordline_stage_efforts(self, external_cout, inp_is_rise=True):
|
|
||||||
"""
|
|
||||||
Follows the clk_buf to a wordline signal adding
|
|
||||||
each stages stage effort to a list.
|
|
||||||
"""
|
|
||||||
stage_effort_list = []
|
|
||||||
|
|
||||||
stage1 = self.wl_driver.get_stage_effort(external_cout, inp_is_rise)
|
|
||||||
stage_effort_list.append(stage1)
|
|
||||||
|
|
||||||
return stage_effort_list
|
|
||||||
|
|
||||||
def get_wl_en_cin(self):
|
|
||||||
"""
|
|
||||||
Get the relative capacitance of all
|
|
||||||
the enable connections in the bank
|
|
||||||
"""
|
|
||||||
# The enable is connected to a and2 for every row.
|
|
||||||
total_cin = self.wl_driver.get_cin() * self.rows
|
|
||||||
return total_cin
|
|
||||||
|
|
|
||||||
|
|
@ -265,7 +265,3 @@ class write_driver_array(design.design):
|
||||||
offset=inst.get_pin(inst.mod.en_name).ll().scale(0, 1),
|
offset=inst.get_pin(inst.mod.en_name).ll().scale(0, 1),
|
||||||
width=self.width)
|
width=self.width)
|
||||||
|
|
||||||
def get_w_en_cin(self):
|
|
||||||
"""Get the relative capacitance of all the enable connections in the bank"""
|
|
||||||
# The enable is connected to a nand2 for every row.
|
|
||||||
return self.driver.get_w_en_cin() * len(self.driver_insts)
|
|
||||||
|
|
|
||||||
|
|
@ -140,8 +140,3 @@ class write_mask_and_array(design.design):
|
||||||
supply_pin_left = self.and2_insts[0].get_pin(supply)
|
supply_pin_left = self.and2_insts[0].get_pin(supply)
|
||||||
supply_pin_right = self.and2_insts[self.num_wmasks - 1].get_pin(supply)
|
supply_pin_right = self.and2_insts[self.num_wmasks - 1].get_pin(supply)
|
||||||
self.add_path(supply_pin_left.layer, [supply_pin_left.lc(), supply_pin_right.rc()])
|
self.add_path(supply_pin_left.layer, [supply_pin_left.lc(), supply_pin_right.rc()])
|
||||||
|
|
||||||
def get_cin(self):
|
|
||||||
"""Get the relative capacitance of all the input connections in the bank"""
|
|
||||||
# The enable is connected to an and2 for every row.
|
|
||||||
return self.and2.get_cin() * len(self.and2_insts)
|
|
||||||
|
|
|
||||||
|
|
@ -146,21 +146,4 @@ class pand2(pgate.pgate):
|
||||||
offset=pin.center(),
|
offset=pin.center(),
|
||||||
width=pin.width(),
|
width=pin.width(),
|
||||||
height=pin.height())
|
height=pin.height())
|
||||||
|
|
||||||
def get_stage_efforts(self, external_cout, inp_is_rise=False):
|
|
||||||
"""Get the stage efforts of the A or B -> Z path"""
|
|
||||||
stage_effort_list = []
|
|
||||||
stage1_cout = self.inv.get_cin()
|
|
||||||
stage1 = self.nand.get_stage_effort(stage1_cout, inp_is_rise)
|
|
||||||
stage_effort_list.append(stage1)
|
|
||||||
last_stage_is_rise = stage1.is_rise
|
|
||||||
|
|
||||||
stage2 = self.inv.get_stage_effort(external_cout, last_stage_is_rise)
|
|
||||||
stage_effort_list.append(stage2)
|
|
||||||
|
|
||||||
return stage_effort_list
|
|
||||||
|
|
||||||
def get_cin(self):
|
|
||||||
"""Return the relative input capacitance of a single input"""
|
|
||||||
return self.nand.get_cin()
|
|
||||||
|
|
||||||
|
|
@ -161,21 +161,4 @@ class pand3(pgate.pgate):
|
||||||
slew=nand_delay.slew,
|
slew=nand_delay.slew,
|
||||||
load=load)
|
load=load)
|
||||||
return nand_delay + inv_delay
|
return nand_delay + inv_delay
|
||||||
|
|
||||||
def get_stage_efforts(self, external_cout, inp_is_rise=False):
|
|
||||||
"""Get the stage efforts of the A or B -> Z path"""
|
|
||||||
stage_effort_list = []
|
|
||||||
stage1_cout = self.inv.get_cin()
|
|
||||||
stage1 = self.nand.get_stage_effort(stage1_cout, inp_is_rise)
|
|
||||||
stage_effort_list.append(stage1)
|
|
||||||
last_stage_is_rise = stage1.is_rise
|
|
||||||
|
|
||||||
stage2 = self.inv.get_stage_effort(external_cout, last_stage_is_rise)
|
|
||||||
stage_effort_list.append(stage2)
|
|
||||||
|
|
||||||
return stage_effort_list
|
|
||||||
|
|
||||||
def get_cin(self):
|
|
||||||
"""Return the relative input capacitance of a single input"""
|
|
||||||
return self.nand.get_cin()
|
|
||||||
|
|
||||||
|
|
@ -96,21 +96,4 @@ class pbuf(pgate.pgate):
|
||||||
offset=a_pin.center(),
|
offset=a_pin.center(),
|
||||||
width=a_pin.width(),
|
width=a_pin.width(),
|
||||||
height=a_pin.height())
|
height=a_pin.height())
|
||||||
|
|
||||||
def get_stage_efforts(self, external_cout, inp_is_rise=False):
|
|
||||||
"""Get the stage efforts of the A -> Z path"""
|
|
||||||
stage_effort_list = []
|
|
||||||
stage1_cout = self.inv2.get_cin()
|
|
||||||
stage1 = self.inv1.get_stage_effort(stage1_cout, inp_is_rise)
|
|
||||||
stage_effort_list.append(stage1)
|
|
||||||
last_stage_is_rise = stage1.is_rise
|
|
||||||
|
|
||||||
stage2 = self.inv2.get_stage_effort(external_cout, last_stage_is_rise)
|
|
||||||
stage_effort_list.append(stage2)
|
|
||||||
|
|
||||||
return stage_effort_list
|
|
||||||
|
|
||||||
def get_cin(self):
|
|
||||||
"""Returns the relative capacitance of the input"""
|
|
||||||
input_cin = self.inv1.get_cin()
|
|
||||||
return input_cin
|
|
||||||
|
|
@ -168,24 +168,4 @@ class pdriver(pgate.pgate):
|
||||||
def get_sizes(self):
|
def get_sizes(self):
|
||||||
""" Return the relative sizes of the buffers """
|
""" Return the relative sizes of the buffers """
|
||||||
return self.size_list
|
return self.size_list
|
||||||
|
|
||||||
def get_stage_efforts(self, external_cout, inp_is_rise=False):
|
|
||||||
""" Get the stage efforts of the A -> Z path """
|
|
||||||
cout_list = []
|
|
||||||
for prev_inv, inv in zip(self.inv_list, self.inv_list[1:]):
|
|
||||||
cout_list.append(inv.get_cin())
|
|
||||||
|
|
||||||
cout_list.append(external_cout)
|
|
||||||
|
|
||||||
stage_effort_list = []
|
|
||||||
last_inp_is_rise = inp_is_rise
|
|
||||||
for inv, cout in zip(self.inv_list, cout_list):
|
|
||||||
stage = inv.get_stage_effort(cout, last_inp_is_rise)
|
|
||||||
stage_effort_list.append(stage)
|
|
||||||
last_inp_is_rise = stage.is_rise
|
|
||||||
|
|
||||||
return stage_effort_list
|
|
||||||
|
|
||||||
def get_cin(self):
|
|
||||||
""" Returns the relative capacitance of the input """
|
|
||||||
return self.inv_list[0].get_cin()
|
|
||||||
|
|
@ -184,36 +184,3 @@ class pinvbuf(pgate.pgate):
|
||||||
self.add_layout_pin_rect_center(text="A",
|
self.add_layout_pin_rect_center(text="A",
|
||||||
layer=a_pin.layer,
|
layer=a_pin.layer,
|
||||||
offset=a_pin.center())
|
offset=a_pin.center())
|
||||||
|
|
||||||
def determine_clk_buf_stage_efforts(self, external_cout, inp_is_rise=False):
|
|
||||||
"""Get the stage efforts of the clk -> clk_buf path"""
|
|
||||||
stage_effort_list = []
|
|
||||||
stage1_cout = self.inv1.get_cin() + self.inv2.get_cin()
|
|
||||||
stage1 = self.inv.get_stage_effort(stage1_cout, inp_is_rise)
|
|
||||||
stage_effort_list.append(stage1)
|
|
||||||
last_stage_is_rise = stage1.is_rise
|
|
||||||
|
|
||||||
stage2 = self.inv2.get_stage_effort(external_cout, last_stage_is_rise)
|
|
||||||
stage_effort_list.append(stage2)
|
|
||||||
|
|
||||||
return stage_effort_list
|
|
||||||
|
|
||||||
def determine_clk_buf_bar_stage_efforts(self, external_cout, inp_is_rise=False):
|
|
||||||
"""Get the stage efforts of the clk -> clk_buf path"""
|
|
||||||
|
|
||||||
# After (almost) every stage, the direction of the signal inverts.
|
|
||||||
stage_effort_list = []
|
|
||||||
stage1_cout = self.inv1.get_cin() + self.inv2.get_cin()
|
|
||||||
stage1 = self.inv.get_stage_effort(stage1_cout, inp_is_rise)
|
|
||||||
stage_effort_list.append(stage1)
|
|
||||||
last_stage_is_rise = stage_effort_list[-1].is_rise
|
|
||||||
|
|
||||||
stage2_cout = self.inv2.get_cin()
|
|
||||||
stage2 = self.inv1.get_stage_effort(stage2_cout, last_stage_is_rise)
|
|
||||||
stage_effort_list.append(stage2)
|
|
||||||
last_stage_is_rise = stage_effort_list[-1].is_rise
|
|
||||||
|
|
||||||
stage3 = self.inv2.get_stage_effort(external_cout, last_stage_is_rise)
|
|
||||||
stage_effort_list.append(stage3)
|
|
||||||
|
|
||||||
return stage_effort_list
|
|
||||||
|
|
|
||||||
|
|
@ -300,11 +300,4 @@ class precharge(design.design):
|
||||||
self.add_path(self.bitline_layer,
|
self.add_path(self.bitline_layer,
|
||||||
[left_pos, right_pos],
|
[left_pos, right_pos],
|
||||||
width=pmos_pin.height())
|
width=pmos_pin.height())
|
||||||
|
|
||||||
def get_en_cin(self):
|
|
||||||
"""Get the relative capacitance of the enable in the precharge cell"""
|
|
||||||
# The enable connect to three pmos gates
|
|
||||||
# They all use the same size pmos.
|
|
||||||
pmos_cin = self.pmos.get_cin()
|
|
||||||
return 3 * pmos_cin
|
|
||||||
|
|
||||||
|
|
@ -241,18 +241,3 @@ class single_level_column_mux(pgate.pgate):
|
||||||
offset=vector(0, 0),
|
offset=vector(0, 0),
|
||||||
width=self.bitcell.width,
|
width=self.bitcell.width,
|
||||||
height=self.height)
|
height=self.height)
|
||||||
|
|
||||||
def get_stage_effort(self, corner, slew, load):
|
|
||||||
"""
|
|
||||||
Returns relative delay that the column mux.
|
|
||||||
Difficult to convert to LE model.
|
|
||||||
"""
|
|
||||||
parasitic_delay = 1
|
|
||||||
# This is not CMOS, so using this may be incorrect.
|
|
||||||
cin = 2 * self.tx_size
|
|
||||||
return logical_effort.logical_effort("column_mux",
|
|
||||||
self.tx_size,
|
|
||||||
cin,
|
|
||||||
load,
|
|
||||||
parasitic_delay,
|
|
||||||
False)
|
|
||||||
|
|
|
||||||
|
|
@ -626,20 +626,6 @@ class sram_1bank(sram_base):
|
||||||
# Insts located in control logic, exclusion function called here
|
# Insts located in control logic, exclusion function called here
|
||||||
for inst in self.control_logic_insts:
|
for inst in self.control_logic_insts:
|
||||||
inst.mod.graph_exclude_dffs()
|
inst.mod.graph_exclude_dffs()
|
||||||
|
|
||||||
def get_sen_name(self, sram_name, port=0):
|
|
||||||
"""Returns the s_en spice name."""
|
|
||||||
# Naming scheme is hardcoded using this function, should be built into the
|
|
||||||
# graph in someway.
|
|
||||||
sen_name = "s_en{}".format(port)
|
|
||||||
control_conns = self.get_conns(self.control_logic_insts[port])
|
|
||||||
# Sanity checks
|
|
||||||
if sen_name not in control_conns:
|
|
||||||
debug.error("Signal={} not contained in control logic connections={}".format(sen_name,
|
|
||||||
control_conns))
|
|
||||||
if sen_name in self.pins:
|
|
||||||
debug.error("Internal signal={} contained in port list. Name defined by the parent.".format(sen_name))
|
|
||||||
return "X{}.{}".format(sram_name, sen_name)
|
|
||||||
|
|
||||||
def get_cell_name(self, inst_name, row, col):
|
def get_cell_name(self, inst_name, row, col):
|
||||||
"""Gets the spice name of the target bitcell."""
|
"""Gets the spice name of the target bitcell."""
|
||||||
|
|
|
||||||
|
|
@ -630,50 +630,4 @@ class sram_base(design, verilog, lef):
|
||||||
|
|
||||||
def lvs_write(self, sp_name):
|
def lvs_write(self, sp_name):
|
||||||
self.sp_write(sp_name, lvs_netlist=True)
|
self.sp_write(sp_name, lvs_netlist=True)
|
||||||
|
|
||||||
def get_wordline_stage_efforts(self, inp_is_rise=True):
|
|
||||||
"""Get the all the stage efforts for each stage in the path from clk_buf to a wordline"""
|
|
||||||
stage_effort_list = []
|
|
||||||
|
|
||||||
# Clk_buf originates from the control logic so only the bank is related to the wordline path
|
|
||||||
# No loading on the wordline other than in the bank.
|
|
||||||
external_wordline_cout = 0
|
|
||||||
stage_effort_list += self.bank.determine_wordline_stage_efforts(external_wordline_cout, inp_is_rise)
|
|
||||||
|
|
||||||
return stage_effort_list
|
|
||||||
|
|
||||||
def get_wl_en_cin(self):
|
|
||||||
"""Gets the capacitive load the of clock (clk_buf) for the sram"""
|
|
||||||
# Only the wordline drivers within the bank use this signal
|
|
||||||
return self.bank.get_wl_en_cin()
|
|
||||||
|
|
||||||
def get_w_en_cin(self):
|
|
||||||
"""Gets the capacitive load the of write enable (w_en) for the sram"""
|
|
||||||
# Only the write drivers within the bank use this signal
|
|
||||||
return self.bank.get_w_en_cin()
|
|
||||||
|
|
||||||
def get_p_en_bar_cin(self):
|
|
||||||
"""Gets the capacitive load the of precharge enable (p_en_bar) for the sram"""
|
|
||||||
# Only the precharges within the bank use this signal
|
|
||||||
return self.bank.get_p_en_bar_cin()
|
|
||||||
|
|
||||||
def get_clk_bar_cin(self):
|
|
||||||
"""Gets the capacitive load the of clock (clk_buf_bar) for the sram"""
|
|
||||||
# As clk_buf_bar is an output of the control logic. The cap for that module is not determined here.
|
|
||||||
# Only the precharge cells use this signal (other than the control logic)
|
|
||||||
return self.bank.get_clk_bar_cin()
|
|
||||||
|
|
||||||
def get_sen_cin(self):
|
|
||||||
"""Gets the capacitive load the of sense amp enable for the sram"""
|
|
||||||
# Only the sense_amps use this signal (other than the control logic)
|
|
||||||
return self.bank.get_sen_cin()
|
|
||||||
|
|
||||||
def get_dff_clk_buf_cin(self):
|
|
||||||
"""Get the relative capacitance of the clk_buf signal.
|
|
||||||
Does not get the control logic loading but everything else"""
|
|
||||||
total_cin = 0
|
|
||||||
total_cin += self.row_addr_dff.get_clk_cin()
|
|
||||||
total_cin += self.data_dff.get_clk_cin()
|
|
||||||
if self.col_addr_size > 0:
|
|
||||||
total_cin += self.col_addr_dff.get_clk_cin()
|
|
||||||
return total_cin
|
|
||||||
Loading…
Reference in New Issue