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

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()

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

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

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

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

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

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)

View File

@ -113,15 +113,15 @@ class pand2(pgate.pgate):
inv_delay = self.inv.analytical_delay(slew=nand_delay.slew, load=load)
return nand_delay + inv_delay
def get_output_stage_efforts(self, external_cout, inp_is_rise=False):
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_effort_stage(stage1_cout, inp_is_rise)
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_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

View File

@ -115,15 +115,15 @@ class pbuf(pgate.pgate):
inv2_delay = self.inv2.analytical_delay(slew=inv1_delay.slew, load=load)
return inv1_delay + inv2_delay
def get_output_stage_efforts(self, external_cout, inp_is_rise=False):
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_effort_stage(stage1_cout, inp_is_rise)
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_effort_stage(external_cout, last_stage_is_rise)
stage2 = self.inv2.get_stage_effort(external_cout, last_stage_is_rise)
stage_effort_list.append(stage2)
return stage_effort_list

View File

@ -11,16 +11,16 @@ class pdriver(pgate.pgate):
"""
This instantiates an even or odd number of inverters sized for driving a load.
"""
def __init__(self, name, neg_polarity=False, fanout_size=8, size_list = [], height=None):
def __init__(self, name, neg_polarity=False, fanout=0, size_list=None, height=None):
self.stage_effort = 4
self.height = height
self.neg_polarity = neg_polarity
self.size_list = size_list
self.fanout_size = fanout_size
self.fanout = fanout
if len(self.size_list) > 0 and (self.fanout_size != 8 or self.neg_polarity):
debug.error("Cannot specify both size_list and neg_polarity or fanout_size.", -1)
if self.size_list and (self.fanout != 0 or self.neg_polarity):
debug.error("Cannot specify both size_list and neg_polarity or fanout.", -1)
pgate.pgate.__init__(self, name, height)
debug.info(1, "Creating {}".format(self.name))
@ -33,14 +33,14 @@ class pdriver(pgate.pgate):
def compute_sizes(self):
# size_list specified
if len(self.size_list) > 0:
if self.size_list:
if not len(self.size_list) % 2:
neg_polarity = True
self.num_inv = len(self.size_list)
else:
# find the number of stages
#fanout_size is a unit inverter fanout, not a capacitance so c_in=1
num_stages = max(1,int(round(log(self.fanout_size)/log(4))))
#fanout is a unit inverter fanout, not a capacitance so c_in=1
num_stages = max(1,int(round(log(self.fanout)/log(4))))
# find inv_num and compute sizes
if self.neg_polarity:
@ -53,42 +53,42 @@ class pdriver(pgate.pgate):
self.same_polarity(num_stages=num_stages)
else:
self.diff_polarity(num_stages=num_stages)
def same_polarity(self, num_stages):
self.calc_size_list = []
self.size_list = []
self.num_inv = num_stages
# compute sizes
fanout_size_prev = self.fanout_size
fanout_prev = self.fanout
for x in range(self.num_inv-1,-1,-1):
fanout_size_prev = int(round(fanout_size_prev/self.stage_effort))
self.calc_size_list.append(fanout_size_prev)
fanout_prev = max(round(fanout_prev/self.stage_effort),1)
self.size_list.append(fanout_prev)
self.size_list.reverse()
def diff_polarity(self, num_stages):
self.calc_size_list = []
self.size_list = []
# find which delay is smaller
if (num_stages > 1):
delay_below = ((num_stages-1)*(self.fanout_size**(1/num_stages-1))) + num_stages-1
delay_above = ((num_stages+1)*(self.fanout_size**(1/num_stages+1))) + num_stages+1
delay_below = ((num_stages-1)*(self.fanout**(1/num_stages-1))) + num_stages-1
delay_above = ((num_stages+1)*(self.fanout**(1/num_stages+1))) + num_stages+1
if (delay_above < delay_below):
# recompute stage_effort for this delay
self.num_inv = num_stages+1
polarity_stage_effort = self.fanout_size**(1/self.num_inv)
polarity_stage_effort = self.fanout**(1/self.num_inv)
else:
self.num_inv = num_stages-1
polarity_stage_effort = self.fanout_size**(1/self.num_inv)
polarity_stage_effort = self.fanout**(1/self.num_inv)
else: # num_stages is 1, can't go to 0
self.num_inv = num_stages+1
polarity_stage_effort = self.fanout_size**(1/self.num_inv)
polarity_stage_effort = self.fanout**(1/self.num_inv)
# compute sizes
fanout_size_prev = self.fanout_size
fanout_prev = self.fanout
for x in range(self.num_inv-1,-1,-1):
fanout_size_prev = int(round(fanout_size_prev/polarity_stage_effort))
self.calc_size_list.append(fanout_size_prev)
fanout_prev = round(fanout_prev/polarity_stage_effort)
self.size_list.append(fanout_prev)
self.size_list.reverse()
def create_netlist(self):
inv_list = []
@ -115,16 +115,10 @@ class pdriver(pgate.pgate):
def add_modules(self):
self.inv_list = []
if len(self.size_list) > 0: # size list specified
for x in range(len(self.size_list)):
temp_inv = factory.create(module_type="pinv", size=self.size_list[x], height=self.height)
self.inv_list.append(temp_inv)
self.add_mod(self.inv_list[x])
else: # find inv sizes
for x in range(len(self.calc_size_list)):
temp_inv = factory.create(module_type="pinv", size=self.calc_size_list[x], height=self.height)
self.inv_list.append(temp_inv)
self.add_mod(self.inv_list[x])
for size in self.size_list:
temp_inv = factory.create(module_type="pinv", size=size, height=self.height)
self.inv_list.append(temp_inv)
self.add_mod(temp_inv)
def create_insts(self):
@ -226,3 +220,24 @@ class pdriver(pgate.pgate):
return delay
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[prev_inv]=inv.get_cin()
cout_list[self.inv_list[-1]]=external_cout
stage_effort_list = []
last_inp_is_rise = inp_is_rise
for inv in self.inv_list:
stage = inv.get_stage_effort(cout_list[inv], 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()

View File

@ -286,7 +286,7 @@ class pinv(pgate.pgate):
"""Return the capacitance of the gate connection in generic capacitive units relative to the minimum width of a transistor"""
return self.nmos_size + self.pmos_size
def get_effort_stage(self, cout, inp_is_rise=True):
def get_stage_effort(self, cout, inp_is_rise=True):
"""Returns an object representing the parameters for delay in tau units.
Optional is_rise refers to the input direction rise/fall. Input inverted by this stage.
"""

View File

@ -186,11 +186,11 @@ class pinvbuf(design.design):
"""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_effort_stage(stage1_cout, inp_is_rise)
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_effort_stage(external_cout, last_stage_is_rise)
stage2 = self.inv2.get_stage_effort(external_cout, last_stage_is_rise)
stage_effort_list.append(stage2)
return stage_effort_list
@ -200,16 +200,16 @@ class pinvbuf(design.design):
#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_effort_stage(stage1_cout, inp_is_rise)
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_effort_stage(stage2_cout, last_stage_is_rise)
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_effort_stage(external_cout, last_stage_is_rise)
stage3 = self.inv2.get_stage_effort(external_cout, last_stage_is_rise)
stage_effort_list.append(stage3)
return stage_effort_list

View File

@ -252,7 +252,7 @@ class pnand2(pgate.pgate):
"""Return the relative input capacitance of a single input"""
return self.nmos_size+self.pmos_size
def get_effort_stage(self, cout, inp_is_rise=True):
def get_stage_effort(self, cout, inp_is_rise=True):
"""Returns an object representing the parameters for delay in tau units.
Optional is_rise refers to the input direction rise/fall. Input inverted by this stage.
"""

View File

@ -264,7 +264,7 @@ class pnand3(pgate.pgate):
"""Return the relative input capacitance of a single input"""
return self.nmos_size+self.pmos_size
def get_effort_stage(self, cout, inp_is_rise=True):
def get_stage_effort(self, cout, inp_is_rise=True):
"""Returns an object representing the parameters for delay in tau units.
Optional is_rise refers to the input direction rise/fall. Input inverted by this stage.
"""

View File

@ -279,20 +279,23 @@ class sram_base(design, verilog, lef):
# Create the control logic module for each port type
if len(self.readwrite_ports)>0:
self.control_logic_rw = self.mod_control_logic(num_rows=self.num_rows,
self.control_logic_rw = self.mod_control_logic(num_rows=self.num_rows,
words_per_row=self.words_per_row,
word_size=self.word_size,
sram=self,
port_type="rw")
self.add_mod(self.control_logic_rw)
if len(self.writeonly_ports)>0:
self.control_logic_w = self.mod_control_logic(num_rows=self.num_rows,
words_per_row=self.words_per_row,
word_size=self.word_size,
sram=self,
port_type="w")
self.add_mod(self.control_logic_w)
if len(self.readonly_ports)>0:
self.control_logic_r = self.mod_control_logic(num_rows=self.num_rows,
words_per_row=self.words_per_row,
word_size=self.word_size,
sram=self,
port_type="r")
self.add_mod(self.control_logic_r)
@ -512,25 +515,30 @@ class sram_base(design, verilog, lef):
def get_wl_en_cin(self):
"""Gets the capacitive load the of clock (clk_buf) for the sram"""
#As clk_buf is an output of the control logic. The cap for that module is not determined here.
#Only the wordline drivers within the bank use this signal
bank_clk_cin = self.bank.get_wl_en_cin()
return bank_clk_cin
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)
bank_clk_cin = self.bank.get_clk_bar_cin()
return bank_clk_cin
return self.bank.get_clk_bar_cin()
def get_sen_cin(self):
"""Gets the capacitive load the of sense amp enable 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 sense_amps use this signal (other than the control logic)
bank_sen_cin = self.bank.get_sen_cin()
return bank_sen_cin
return self.bank.get_sen_cin()

View File

@ -22,22 +22,22 @@ class pdriver_test(openram_test):
debug.info(2, "Testing inverter/buffer 4x 8x")
# a tests the error message for specifying conflicting conditions
#a = pdriver.pdriver(fanout_size = 4,size_list = [1,2,4,8])
#a = pdriver.pdriver(fanout = 4,size_list = [1,2,4,8])
#self.local_check(a)
b = pdriver.pdriver(name="pdriver1", size_list = [1,2,4,8])
self.local_check(b)
c = pdriver.pdriver(name="pdriver2", fanout_size = 50)
c = pdriver.pdriver(name="pdriver2", fanout = 50)
self.local_check(c)
d = pdriver.pdriver(name="pdriver3", fanout_size = 50, neg_polarity = True)
d = pdriver.pdriver(name="pdriver3", fanout = 50, neg_polarity = True)
self.local_check(d)
e = pdriver.pdriver(name="pdriver4", fanout_size = 64)
e = pdriver.pdriver(name="pdriver4", fanout = 64)
self.local_check(e)
f = pdriver.pdriver(name="pdriver5", fanout_size = 64, neg_polarity = True)
f = pdriver.pdriver(name="pdriver5", fanout = 64, neg_polarity = True)
self.local_check(f)
globals.end_openram()

View File

@ -20,7 +20,7 @@ class control_logic_test(openram_test):
# check control logic for single port
debug.info(1, "Testing sample for control_logic")
a = control_logic.control_logic(num_rows=128, words_per_row=1)
a = control_logic.control_logic(num_rows=128, words_per_row=1, word_size=32)
self.local_check(a)
# check control logic for multi-port
@ -31,7 +31,7 @@ class control_logic_test(openram_test):
OPTS.num_r_ports = 0
debug.info(1, "Testing sample for control_logic for multiport")
a = control_logic.control_logic(num_rows=128, words_per_row=1)
a = control_logic.control_logic(num_rows=128, words_per_row=1, word_size=8)
self.local_check(a)
# Check port specific control logic
@ -40,15 +40,15 @@ class control_logic_test(openram_test):
OPTS.num_r_ports = 1
debug.info(1, "Testing sample for control_logic for multiport, only write control logic")
a = control_logic.control_logic(num_rows=128, words_per_row=1, port_type="rw")
a = control_logic.control_logic(num_rows=128, words_per_row=1, word_size=8, port_type="rw")
self.local_check(a)
debug.info(1, "Testing sample for control_logic for multiport, only write control logic")
a = control_logic.control_logic(num_rows=128, words_per_row=1, port_type="w")
a = control_logic.control_logic(num_rows=128, words_per_row=1, word_size=8, port_type="w")
self.local_check(a)
debug.info(1, "Testing sample for control_logic for multiport, only read control logic")
a = control_logic.control_logic(num_rows=128, words_per_row=1, port_type="r")
a = control_logic.control_logic(num_rows=128, words_per_row=1, word_size=8, port_type="r")
self.local_check(a)
globals.end_openram()