mirror of
https://github.com/VLSIDA/OpenRAM.git
synced 2026-09-04 16:51:40 +02:00
Change pbuf/pinv to pdriver in control logic.
This commit is contained in:
@@ -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()
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user