Change pbuf/pinv to pdriver in control logic.

This commit is contained in:
Matt Guthaus
2019-01-23 12:03:52 -08:00
parent 23718b952f
commit b58fd03083
17 changed files with 157 additions and 110 deletions
+9 -7
View File
@@ -1253,20 +1253,22 @@ class bank(design.design):
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.
total_clk_cin = self.wordline_driver.get_wl_en_cin()
return total_clk_cin
return self.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.
return self.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]
total_clk_bar_cin = self.precharge_array[port].get_en_cin()
return total_clk_bar_cin
return self.precharge_array[port].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.
total_sen_cin = self.sense_amp_array.get_en_cin()
return total_sen_cin
return self.sense_amp_array.get_en_cin()
+44 -31
View File
@@ -14,20 +14,22 @@ class control_logic(design.design):
Dynamically generated Control logic for the total SRAM circuit.
"""
def __init__(self, num_rows, words_per_row, sram=None, port_type="rw"):
def __init__(self, num_rows, words_per_row, word_size, sram=None, port_type="rw"):
""" Constructor """
name = "control_logic_" + port_type
design.design.__init__(self, name)
debug.info(1, "Creating {}".format(name))
self.sram=sram
self.num_rows = num_rows
self.words_per_row = words_per_row
self.word_size = word_size
self.port_type = port_type
self.num_words = num_rows * words_per_row
self.enable_delay_chain_resizing = False
#This is needed to resize the delay chain. Likely to be changed at some point.
self.sram=sram
#self.sram=None #disable re-sizing for debugging, FIXME: resizing is not working, needs to be adjusted for new control logic.
self.wl_timing_tolerance = 1 #Determines how much larger the sen delay should be. Accounts for possible error in model.
self.parasitic_inv_delay = parameter["min_inv_para_delay"] #Keeping 0 for now until further testing.
@@ -82,33 +84,44 @@ class control_logic(design.design):
self.add_mod(self.and2)
# Special gates: inverters for buffering
# Size the clock for the number of rows (fanout)
clock_driver_size = max(1,int(self.num_rows/4))
self.clkbuf = factory.create(module_type="pbuf",
size=clock_driver_size,
# clk_buf drives a flop for every address and control bit
clock_fanout = math.log(self.num_words,2) + math.log(self.words_per_row,2) + self.num_control_signals
self.clkbuf = factory.create(module_type="pdriver",
fanout=clock_fanout,
height=dff_height)
self.add_mod(self.clkbuf)
self.buf16 = factory.create(module_type="pbuf",
size=16,
height=dff_height)
self.add_mod(self.buf16)
# wl_en drives every row in the bank
self.wl_en_driver = factory.create(module_type="pdriver",
fanout=self.num_rows,
height=dff_height)
self.add_mod(self.wl_en_driver)
self.buf8 = factory.create(module_type="pbuf",
size=8,
height=dff_height)
self.add_mod(self.buf8)
self.inv = self.inv1 = factory.create(module_type="pinv",
# w_en drives every write driver
self.w_en_driver = factory.create(module_type="pbuf",
size=self.word_size,
height=dff_height)
self.add_mod(self.w_en_driver)
# s_en drives every sense amp
self.s_en_driver = factory.create(module_type="pbuf",
size=8,
height=dff_height)
self.add_mod(self.s_en_driver)
# used to generate inverted signals with low fanout
self.inv = factory.create(module_type="pinv",
size=1,
height=dff_height)
self.add_mod(self.inv1)
self.inv8 = factory.create(module_type="pinv",
size=8,
height=dff_height)
self.add_mod(self.inv8)
self.add_mod(self.inv)
# p_en_bar drives every column in the bicell array
self.p_en_bar_driver = factory.create(module_type="pdriver",
fanout=8,
height=dff_height)
self.add_mod(self.p_en_bar_driver)
if (self.port_type == "rw") or (self.port_type == "r"):
delay_stages_heuristic, delay_fanout_heuristic = self.get_heuristic_delay_chain_size()
@@ -510,7 +523,7 @@ class control_logic(design.design):
def create_wlen_row(self):
# input pre_p_en, output: wl_en
self.wl_en_inst=self.add_inst(name="buf_wl_en",
mod=self.buf16)
mod=self.wl_en_driver)
self.connect_inst(["gated_clk_bar", "wl_en", "vdd", "gnd"])
def place_wlen_row(self, row):
@@ -580,7 +593,7 @@ class control_logic(design.design):
# input: pre_p_en, output: p_en_bar
self.p_en_bar_inst=self.add_inst(name="inv_p_en_bar",
mod=self.inv8)
mod=self.p_en_bar_driver)
self.connect_inst([input_name, "p_en_bar", "vdd", "gnd"])
@@ -620,7 +633,7 @@ class control_logic(design.design):
# BUFFER FOR S_EN
# input: pre_s_en, output: s_en
self.s_en_inst=self.add_inst(name="buf_s_en",
mod=self.buf8)
mod=self.s_en_driver)
self.connect_inst(["pre_s_en", "s_en", "vdd", "gnd"])
def place_sen_row(self,row):
@@ -657,7 +670,7 @@ class control_logic(design.design):
# BUFFER FOR W_EN
self.w_en_inst = self.add_inst(name="buf_w_en_buf",
mod=self.buf8)
mod=self.w_en_driver)
self.connect_inst([input_name, "w_en", "vdd", "gnd"])
@@ -814,7 +827,7 @@ class control_logic(design.design):
#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.clkbuf.get_output_stage_efforts(external_cout, is_clk_bar_rise)
stage_effort_list += self.clkbuf.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)
@@ -845,17 +858,17 @@ class control_logic(design.design):
#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_output_stage_efforts(stage1_cout, last_stage_rise)
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.buf8.get_cin()
stage2_cout = self.s_en_driver.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.buf8.get_output_stage_efforts(stage3_cout, last_stage_rise)
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
+1 -1
View File
@@ -230,7 +230,7 @@ class delay_chain(design.design):
stage_cout = self.inv.get_cin()*(stage_fanout+1)
if len(stage_effort_list) == len(self.fanout_list)-1: #last stage
stage_cout+=ext_delayed_en_cout
stage = self.inv.get_effort_stage(stage_cout, last_stage_is_rise)
stage = self.inv.get_stage_effort(stage_cout, last_stage_is_rise)
stage_effort_list.append(stage)
last_stage_is_rise = stage.is_rise
+1 -1
View File
@@ -614,7 +614,7 @@ class replica_bitline(design.design):
#The delay chain triggers the enable on the replica bitline (rbl). This is used to track the bitline delay whereas this
#model is intended to track every but that. Therefore, the next stage is the inverter after the rbl.
stage2 = self.inv.get_effort_stage(ext_cout, last_stage_is_rise)
stage2 = self.inv.get_stage_effort(ext_cout, last_stage_is_rise)
stage_effort_list.append(stage2)
return stage_effort_list
+2 -2
View File
@@ -224,11 +224,11 @@ class wordline_driver(design.design):
stage_effort_list = []
stage1_cout = self.inv.get_cin()
stage1 = self.nand2.get_effort_stage(stage1_cout, inp_is_rise)
stage1 = self.nand2.get_stage_effort(stage1_cout, inp_is_rise)
stage_effort_list.append(stage1)
last_stage_is_rise = stage1.is_rise
stage2 = self.inv.get_effort_stage(external_cout, last_stage_is_rise)
stage2 = self.inv.get_stage_effort(external_cout, last_stage_is_rise)
stage_effort_list.append(stage2)
return stage_effort_list
+5
View File
@@ -23,3 +23,8 @@ class write_driver(design.design):
self.height = write_driver.height
self.pin_map = write_driver.pin_map
def get_w_en_cin(self):
"""Get the relative capacitance of a single input"""
# This is approximated from SCMOS. It has roughly 5 3x transistor gates.
return 5*3
+4
View File
@@ -130,3 +130,7 @@ class write_driver_array(design.design):
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)