Getting single bank to work reliably. Removed tri_gate from bank

for now. Will add it in multibank arrays only. Not needed for
separate DIN and DOUT ports.
This commit is contained in:
Matt Guthaus 2018-07-13 14:45:46 -07:00
parent 834fbac8de
commit f3ae29fe0b
7 changed files with 181 additions and 97 deletions

View File

@ -39,6 +39,7 @@ class layout(lef.lef):
shift the origin in the lowest left corner """ shift the origin in the lowest left corner """
offset = self.find_lowest_coords() offset = self.find_lowest_coords()
self.translate_all(offset) self.translate_all(offset)
return offset
def get_gate_offset(self, x_offset, height, inv_num): def get_gate_offset(self, x_offset, height, inv_num):
"""Gets the base offset and y orientation of stacked rows of gates """Gets the base offset and y orientation of stacked rows of gates

View File

@ -66,7 +66,8 @@ class bank(design.design):
# Can remove the following, but it helps for debug! # Can remove the following, but it helps for debug!
self.add_lvs_correspondence_points() self.add_lvs_correspondence_points()
self.offset_all_coordinates() # Remember the bank center for further placement
self.bank_center=self.offset_all_coordinates()
self.DRC_LVS() self.DRC_LVS()
@ -75,7 +76,7 @@ class bank(design.design):
for i in range(self.word_size): for i in range(self.word_size):
self.add_pin("DOUT[{0}]".format(i),"OUT") self.add_pin("DOUT[{0}]".format(i),"OUT")
for i in range(self.word_size): for i in range(self.word_size):
self.add_pin("DIN[{0}]".format(i),"IN") self.add_pin("BANK_DIN[{0}]".format(i),"IN")
for i in range(self.addr_size): for i in range(self.addr_size):
self.add_pin("A[{0}]".format(i),"INPUT") self.add_pin("A[{0}]".format(i),"INPUT")
@ -95,8 +96,9 @@ class bank(design.design):
self.route_precharge_to_bitcell_array() self.route_precharge_to_bitcell_array()
self.route_col_mux_to_bitcell_array() self.route_col_mux_to_bitcell_array()
self.route_sense_amp_to_col_mux_or_bitcell_array() self.route_sense_amp_to_col_mux_or_bitcell_array()
self.route_sense_amp_to_trigate() #self.route_sense_amp_to_trigate()
self.route_tri_gate_out() #self.route_tri_gate_out()
self.route_sense_amp_out()
self.route_wordline_driver() self.route_wordline_driver()
self.route_write_driver() self.route_write_driver()
self.route_row_decoder() self.route_row_decoder()
@ -119,7 +121,8 @@ class bank(design.design):
self.add_column_mux_array() self.add_column_mux_array()
self.add_sense_amp_array() self.add_sense_amp_array()
self.add_write_driver_array() self.add_write_driver_array()
self.add_tri_gate_array() # Not needed for single bank
#self.add_tri_gate_array()
# To the left of the bitcell array # To the left of the bitcell array
self.add_row_decoder() self.add_row_decoder()
@ -294,14 +297,15 @@ class bank(design.design):
def add_write_driver_array(self): def add_write_driver_array(self):
""" Adding Write Driver """ """ Adding Write Driver """
y_offset = self.sense_amp_array.height + self.column_mux_height + + self.m2_gap + self.write_driver_array.height y_offset = self.sense_amp_array.height + self.column_mux_height \
+ self.m2_gap + self.write_driver_array.height
self.write_driver_array_inst=self.add_inst(name="write_driver_array", self.write_driver_array_inst=self.add_inst(name="write_driver_array",
mod=self.write_driver_array, mod=self.write_driver_array,
offset=vector(0,y_offset).scale(-1,-1)) offset=vector(0,y_offset).scale(-1,-1))
temp = [] temp = []
for i in range(self.word_size): for i in range(self.word_size):
temp.append("DIN[{0}]".format(i)) temp.append("BANK_DIN[{0}]".format(i))
for i in range(self.word_size): for i in range(self.word_size):
if (self.words_per_row == 1): if (self.words_per_row == 1):
temp.append("bl[{0}]".format(i)) temp.append("bl[{0}]".format(i))
@ -315,7 +319,7 @@ class bank(design.design):
def add_tri_gate_array(self): def add_tri_gate_array(self):
""" data tri gate to drive the data bus """ """ data tri gate to drive the data bus """
y_offset = self.sense_amp_array.height+self.column_mux_height \ y_offset = self.sense_amp_array.height+self.column_mux_height \
+ self.write_driver_array.height + self.m2_gap + self.tri_gate_array.height + self.m2_gap + self.tri_gate_array.height
self.tri_gate_array_inst=self.add_inst(name="tri_gate_array", self.tri_gate_array_inst=self.add_inst(name="tri_gate_array",
mod=self.tri_gate_array, mod=self.tri_gate_array,
offset=vector(0,y_offset).scale(-1,-1)) offset=vector(0,y_offset).scale(-1,-1))
@ -443,7 +447,7 @@ class bank(design.design):
self.precharge_array_inst, self.precharge_array_inst,
self.sense_amp_array_inst, self.sense_amp_array_inst,
self.write_driver_array_inst, self.write_driver_array_inst,
self.tri_gate_array_inst, # self.tri_gate_array_inst,
self.row_decoder_inst, self.row_decoder_inst,
self.wordline_driver_inst] self.wordline_driver_inst]
# Add these if we use the part... # Add these if we use the part...
@ -492,7 +496,8 @@ class bank(design.design):
#the column decoder (if there is one) or the tristate output #the column decoder (if there is one) or the tristate output
#driver. #driver.
# Leave room for the output below the tri gate. # Leave room for the output below the tri gate.
tri_gate_min_y_offset = self.tri_gate_array_inst.by() - 3*self.m2_pitch #tri_gate_min_y_offset = self.tri_gate_array_inst.by() - 3*self.m2_pitch
write_driver_min_y_offset = self.write_driver_array_inst.by() - 3*self.m2_pitch
row_decoder_min_y_offset = self.row_decoder_inst.by() row_decoder_min_y_offset = self.row_decoder_inst.by()
if self.col_addr_size > 0: if self.col_addr_size > 0:
col_decoder_min_y_offset = self.col_decoder_inst.by() col_decoder_min_y_offset = self.col_decoder_inst.by()
@ -502,10 +507,10 @@ class bank(design.design):
if self.num_banks>1: if self.num_banks>1:
# The control gating logic is below the decoder # The control gating logic is below the decoder
# Min of the control gating logic and tri gate. # Min of the control gating logic and tri gate.
self.min_y_offset = min(col_decoder_min_y_offset - self.bank_select.height, tri_gate_min_y_offset) self.min_y_offset = min(col_decoder_min_y_offset - self.bank_select.height, write_driver_min_y_offset)
else: else:
# Just the min of the decoder logic logic and tri gate. # Just the min of the decoder logic logic and tri gate.
self.min_y_offset = min(col_decoder_min_y_offset, tri_gate_min_y_offset) self.min_y_offset = min(col_decoder_min_y_offset, write_driver_min_y_offset)
# The max point is always the top of the precharge bitlines # The max point is always the top of the precharge bitlines
# Add a vdd and gnd power rail above the array # Add a vdd and gnd power rail above the array
@ -620,6 +625,16 @@ class bank(design.design):
offset=sa_data_out) offset=sa_data_out)
self.add_path("metal3",[sa_data_out,tri_gate_in]) self.add_path("metal3",[sa_data_out,tri_gate_in])
def route_sense_amp_out(self):
""" Add pins for the sense amp output """
for i in range(self.word_size):
data_pin = self.sense_amp_array_inst.get_pin("data[{}]".format(i))
self.add_layout_pin_rect_center(text="DOUT[{}]".format(i),
layer="metal2",
offset=data_pin.center(),
height=data_pin.height(),
width=data_pin.width()),
def route_tri_gate_out(self): def route_tri_gate_out(self):
""" Metal 3 routing of tri_gate output data """ """ Metal 3 routing of tri_gate output data """
for i in range(self.word_size): for i in range(self.word_size):
@ -647,7 +662,7 @@ class bank(design.design):
for i in range(self.word_size): for i in range(self.word_size):
data_name = "data[{}]".format(i) data_name = "data[{}]".format(i)
din_name = "DIN[{}]".format(i) din_name = "BANK_DIN[{}]".format(i)
self.copy_layout_pin(self.write_driver_array_inst, data_name, din_name) self.copy_layout_pin(self.write_driver_array_inst, data_name, din_name)
@ -749,13 +764,13 @@ class bank(design.design):
layer="metal2", layer="metal2",
offset=br_pin.center()) offset=br_pin.center())
# Add the data output names to the sense amp output # # Add the data output names to the sense amp output
for i in range(self.word_size): # for i in range(self.word_size):
data_name = "data[{}]".format(i) # data_name = "data[{}]".format(i)
data_pin = self.sense_amp_array_inst.get_pin(data_name) # data_pin = self.sense_amp_array_inst.get_pin(data_name)
self.add_label(text="sa_out[{}]".format(i), # self.add_label(text="sa_out[{}]".format(i),
layer="metal2", # layer="metal2",
offset=data_pin.center()) # offset=data_pin.center())
# Add labels on the decoder # Add labels on the decoder
for i in range(self.word_size): for i in range(self.word_size):
@ -775,8 +790,8 @@ class bank(design.design):
# Connection from the central bus to the main control block crosses # Connection from the central bus to the main control block crosses
# pre-decoder and this connection is in metal3 # pre-decoder and this connection is in metal3
connection = [] connection = []
connection.append((self.prefix+"tri_en_bar", self.tri_gate_array_inst.get_pin("en_bar").lc())) #connection.append((self.prefix+"tri_en_bar", self.tri_gate_array_inst.get_pin("en_bar").lc()))
connection.append((self.prefix+"tri_en", self.tri_gate_array_inst.get_pin("en").lc())) #connection.append((self.prefix+"tri_en", self.tri_gate_array_inst.get_pin("en").lc()))
connection.append((self.prefix+"clk_buf_bar", self.precharge_array_inst.get_pin("en").lc())) connection.append((self.prefix+"clk_buf_bar", self.precharge_array_inst.get_pin("en").lc()))
connection.append((self.prefix+"w_en", self.write_driver_array_inst.get_pin("en").lc())) connection.append((self.prefix+"w_en", self.write_driver_array_inst.get_pin("en").lc()))
connection.append((self.prefix+"s_en", self.sense_amp_array_inst.get_pin("en").lc())) connection.append((self.prefix+"s_en", self.sense_amp_array_inst.get_pin("en").lc()))

View File

@ -18,7 +18,7 @@ class dff_array(design.design):
if name=="": if name=="":
name = "dff_array_{0}x{1}".format(rows, columns) name = "dff_array_{0}x{1}".format(rows, columns)
design.design.__init__(self, name) design.design.__init__(self, name)
debug.info(1, "Creating {}".format(self.name)) debug.info(1, "Creating {0} rows={1} cols={2}".format(self.name, self.rows, self.columns))
from importlib import reload from importlib import reload
c = reload(__import__(OPTS.dff)) c = reload(__import__(OPTS.dff))
@ -38,33 +38,33 @@ class dff_array(design.design):
self.DRC_LVS() self.DRC_LVS()
def add_pins(self): def add_pins(self):
for y in range(self.rows): for row in range(self.rows):
for x in range(self.columns): for col in range(self.columns):
self.add_pin(self.get_din_name(y,x)) self.add_pin(self.get_din_name(row,col))
for y in range(self.rows): for row in range(self.rows):
for x in range(self.columns): for col in range(self.columns):
self.add_pin(self.get_dout_name(y,x)) self.add_pin(self.get_dout_name(row,col))
self.add_pin("clk") self.add_pin("clk")
self.add_pin("vdd") self.add_pin("vdd")
self.add_pin("gnd") self.add_pin("gnd")
def create_dff_array(self): def create_dff_array(self):
self.dff_insts={} self.dff_insts={}
for y in range(self.rows): for row in range(self.rows):
for x in range(self.columns): for col in range(self.columns):
name = "Xdff_r{0}_c{1}".format(y,x) name = "Xdff_r{0}_c{1}".format(row,col)
if (y % 2 == 0): if (row % 2 == 0):
base = vector(x*self.dff.width,y*self.dff.height) base = vector(col*self.dff.width,row*self.dff.height)
mirror = "R0" mirror = "R0"
else: else:
base = vector(x*self.dff.width,(y+1)*self.dff.height) base = vector(col*self.dff.width,(row+1)*self.dff.height)
mirror = "MX" mirror = "MX"
self.dff_insts[x,y]=self.add_inst(name=name, self.dff_insts[row,col]=self.add_inst(name=name,
mod=self.dff, mod=self.dff,
offset=base, offset=base,
mirror=mirror) mirror=mirror)
self.connect_inst([self.get_din_name(y,x), self.connect_inst([self.get_din_name(row,col),
self.get_dout_name(y,x), self.get_dout_name(row,col),
"clk", "clk",
"vdd", "vdd",
"gnd"]) "gnd"])
@ -91,10 +91,9 @@ class dff_array(design.design):
def add_layout_pins(self): def add_layout_pins(self):
for row in range(self.rows):
for y in range(self.rows):
# Continous vdd rail along with label. # Continous vdd rail along with label.
vdd_pin=self.dff_insts[0,y].get_pin("vdd") vdd_pin=self.dff_insts[row,0].get_pin("vdd")
self.add_layout_pin(text="vdd", self.add_layout_pin(text="vdd",
layer="metal1", layer="metal1",
offset=vdd_pin.ll(), offset=vdd_pin.ll(),
@ -102,7 +101,7 @@ class dff_array(design.design):
height=self.m1_width) height=self.m1_width)
# Continous gnd rail along with label. # Continous gnd rail along with label.
gnd_pin=self.dff_insts[0,y].get_pin("gnd") gnd_pin=self.dff_insts[row,0].get_pin("gnd")
self.add_layout_pin(text="gnd", self.add_layout_pin(text="gnd",
layer="metal1", layer="metal1",
offset=gnd_pin.ll(), offset=gnd_pin.ll(),
@ -110,19 +109,19 @@ class dff_array(design.design):
height=self.m1_width) height=self.m1_width)
for y in range(self.rows): for row in range(self.rows):
for x in range(self.columns): for col in range(self.columns):
din_pin = self.dff_insts[x,y].get_pin("D") din_pin = self.dff_insts[row,col].get_pin("D")
debug.check(din_pin.layer=="metal2","DFF D pin not on metal2") debug.check(din_pin.layer=="metal2","DFF D pin not on metal2")
self.add_layout_pin(text=self.get_din_name(y,x), self.add_layout_pin(text=self.get_din_name(row,col),
layer=din_pin.layer, layer=din_pin.layer,
offset=din_pin.ll(), offset=din_pin.ll(),
width=din_pin.width(), width=din_pin.width(),
height=din_pin.height()) height=din_pin.height())
dout_pin = self.dff_insts[x,y].get_pin("Q") dout_pin = self.dff_insts[row,col].get_pin("Q")
debug.check(dout_pin.layer=="metal2","DFF Q pin not on metal2") debug.check(dout_pin.layer=="metal2","DFF Q pin not on metal2")
self.add_layout_pin(text=self.get_dout_name(y,x), self.add_layout_pin(text=self.get_dout_name(row,col),
layer=dout_pin.layer, layer=dout_pin.layer,
offset=dout_pin.ll(), offset=dout_pin.ll(),
width=dout_pin.width(), width=dout_pin.width(),
@ -145,8 +144,8 @@ class dff_array(design.design):
offset=vector(0,0), offset=vector(0,0),
width=self.width, width=self.width,
height=self.m3_width) height=self.m3_width)
for x in range(self.columns): for col in range(self.columns):
clk_pin = self.dff_insts[x,0].get_pin("clk") clk_pin = self.dff_insts[0,col].get_pin("clk")
# Make a vertical strip for each column # Make a vertical strip for each column
self.add_layout_pin(text="clk", self.add_layout_pin(text="clk",
layer="metal2", layer="metal2",

View File

@ -23,6 +23,8 @@ class sram():
num_words)) num_words))
start_time = datetime.datetime.now() start_time = datetime.datetime.now()
self.name = name
if num_banks == 1: if num_banks == 1:
from sram_1bank import sram_1bank from sram_1bank import sram_1bank
self.s=sram_1bank(word_size, num_words, name) self.s=sram_1bank(word_size, num_words, name)
@ -53,8 +55,6 @@ class sram():
if not OPTS.is_unit_test: if not OPTS.is_unit_test:
print_time("SRAM creation", datetime.datetime.now(), start_time) print_time("SRAM creation", datetime.datetime.now(), start_time)
def get_name(self):
return self.s.name
def sp_write(self,name): def sp_write(self,name):
self.s.sp_write(name) self.s.sp_write(name)

View File

@ -37,14 +37,18 @@ class sram_1bank(sram_base):
self.add_control_logic(position=control_pos) self.add_control_logic(position=control_pos)
# Leave room for the control routes to the left of the flops # Leave room for the control routes to the left of the flops
addr_pos = vector(self.control_logic_inst.lx() + 4*self.m2_pitch, row_addr_pos = vector(self.control_logic_inst.lx() + 4*self.m2_pitch,
control_pos.y + self.control_logic.height + self.m1_pitch) control_pos.y + self.control_logic.height + self.m1_pitch)
self.add_addr_dff(addr_pos) self.add_row_addr_dff(row_addr_pos)
# Leave room for the control routes to the left of the flops # Add the column address below the bank under the control
data_pos = vector(self.control_logic_inst.lx() + 4*self.m2_pitch, if self.col_addr_dff:
control_pos.y + self.control_logic.height + self.m1_pitch) col_addr_pos = vector(-self.col_addr_dff.width, -1.5*self.col_addr_dff.height)
self.add_addr_dff(addr_pos) self.add_col_addr_dff(col_addr_pos)
# Add the data flops below the bank
data_pos = vector(-self.bank_inst.mod.bank_center.x, -1.5*self.data_dff.height)
self.add_data_dff(data_pos)
# two supply rails are already included in the bank, so just 2 here. # two supply rails are already included in the bank, so just 2 here.
self.width = self.bank.width + self.control_logic.width + 2*self.supply_rail_pitch self.width = self.bank.width + self.control_logic.width + 2*self.supply_rail_pitch
@ -54,15 +58,22 @@ class sram_1bank(sram_base):
""" """
Add the top-level pins for a single bank SRAM with control. Add the top-level pins for a single bank SRAM with control.
""" """
# Connect the control pins as inputs
for n in self.control_logic_inputs + ["clk"]:
self.copy_layout_pin(self.control_logic_inst, n)
for i in range(self.word_size): for i in range(self.word_size):
self.copy_layout_pin(self.bank_inst, "DOUT[{}]".format(i)) self.copy_layout_pin(self.bank_inst, "DOUT[{}]".format(i))
for i in range(self.addr_size): # Lower address bits
self.copy_layout_pin(self.addr_dff_inst, "din[{}]".format(i),"ADDR[{}]".format(i)) for i in range(self.col_addr_size):
self.copy_layout_pin(self.col_addr_dff_inst, "din[{}]".format(i),"ADDR[{}]".format(i))
# Upper address bits
for i in range(self.row_addr_size):
self.copy_layout_pin(self.row_addr_dff_inst, "din[{}]".format(i),"ADDR[{}]".format(i+self.col_addr_size))
for i in range(self.word_size): for i in range(self.word_size):
self.copy_layout_pin(self.addr_dff_inst, "din[{}]".format(i),"ADDR[{}]".format(i)) self.copy_layout_pin(self.data_dff_inst, "din[{}]".format(i),"DIN[{}]".format(i))
def route(self): def route(self):
""" Route a single bank SRAM """ """ Route a single bank SRAM """
@ -79,14 +90,28 @@ class sram_1bank(sram_base):
rotate=90) rotate=90)
# Connect the output of the flops to the bank pins # Connect the output of the row flops to the bank pins
for i in range(self.addr_size): for i in range(self.row_addr_size):
flop_name = "dout[{}]".format(i) flop_name = "dout[{}]".format(i)
bank_name = "A[{}]".format(i) bank_name = "A[{}]".format(i+self.col_addr_size)
flop_pin = self.addr_dff_inst.get_pin(flop_name) flop_pin = self.row_addr_dff_inst.get_pin(flop_name)
bank_pin = self.bank_inst.get_pin(bank_name) bank_pin = self.bank_inst.get_pin(bank_name)
flop_pos = flop_pin.center() flop_pos = flop_pin.center()
bank_pos = vector(bank_pin.cx(),flop_pos.y) bank_pos = bank_pin.center()
mid_pos = vector(bank_pos.x,flop_pos.y)
self.add_wire(("metal3","via2","metal2"),[flop_pos, mid_pos,bank_pos])
self.add_via_center(layers=("metal2","via2","metal3"),
offset=flop_pos,
rotate=90)
# Connect the output of the row flops to the bank pins
for i in range(self.col_addr_size):
flop_name = "dout[{}]".format(i)
bank_name = "A[{}]".format(i)
flop_pin = self.col_addr_dff_inst.get_pin(flop_name)
bank_pin = self.bank_inst.get_pin(bank_name)
flop_pos = flop_pin.center()
bank_pos = bank_pin.center()
self.add_path("metal3",[flop_pos, bank_pos]) self.add_path("metal3",[flop_pos, bank_pos])
self.add_via_center(layers=("metal2","via2","metal3"), self.add_via_center(layers=("metal2","via2","metal3"),
offset=flop_pos, offset=flop_pos,
@ -95,17 +120,28 @@ class sram_1bank(sram_base):
offset=bank_pos, offset=bank_pos,
rotate=90) rotate=90)
# Connect the control pins as inputs # Connect the output of the row flops to the bank pins
for n in self.control_logic_inputs + ["clk"]: for i in range(self.word_size):
self.copy_layout_pin(self.control_logic_inst, n) flop_name = "dout[{}]".format(i)
bank_name = "BANK_DIN[{}]".format(i)
flop_pin = self.data_dff_inst.get_pin(flop_name)
bank_pin = self.bank_inst.get_pin(bank_name)
flop_pos = flop_pin.center()
bank_pos = bank_pin.center()
mid_pos = vector(bank_pos.x,flop_pos.y)
self.add_wire(("metal3","via2","metal2"),[flop_pos, mid_pos,bank_pos])
self.add_via_center(layers=("metal2","via2","metal3"),
offset=flop_pos,
rotate=90)
# Connect the clock between the flops and control module
flop_pin = self.addr_dff_inst.get_pin("clk") # # Connect the clock between the flops and control module
ctrl_pin = self.control_logic_inst.get_pin("clk_buf") # flop_pin = self.addr_dff_inst.get_pin("clk")
flop_pos = flop_pin.uc() # ctrl_pin = self.control_logic_inst.get_pin("clk_buf")
ctrl_pos = ctrl_pin.bc() # flop_pos = flop_pin.uc()
mid_ypos = 0.5*(ctrl_pos.y+flop_pos.y) # ctrl_pos = ctrl_pin.bc()
mid1_pos = vector(flop_pos.x, mid_ypos) # mid_ypos = 0.5*(ctrl_pos.y+flop_pos.y)
mid2_pos = vector(ctrl_pos.x, mid_ypos) # mid1_pos = vector(flop_pos.x, mid_ypos)
self.add_wire(("metal1","via1","metal2"),[flop_pin.uc(), mid1_pos, mid2_pos, ctrl_pin.bc()]) # mid2_pos = vector(ctrl_pos.x, mid_ypos)
# self.add_wire(("metal1","via1","metal2"),[flop_pin.uc(), mid1_pos, mid2_pos, ctrl_pin.bc()])

View File

@ -32,9 +32,6 @@ class sram_base(design):
self.num_words = num_words self.num_words = num_words
self.num_banks = num_banks self.num_banks = num_banks
def whoami():
print("abstract")
def compute_sizes(self): def compute_sizes(self):
""" Computes the organization of the memory using bitcell size by trying to make it square.""" """ Computes the organization of the memory using bitcell size by trying to make it square."""
@ -258,10 +255,18 @@ class sram_base(design):
self.add_mod(self.control_logic) self.add_mod(self.control_logic)
# Create the address and control flops (but not the clk) # Create the address and control flops (but not the clk)
dff_size = self.addr_size
from dff_array import dff_array from dff_array import dff_array
self.addr_dff = dff_array(name="dff_array", rows=dff_size, columns=1) self.row_addr_dff = dff_array(name="row_addr_dff", rows=self.row_addr_size, columns=1)
self.add_mod(self.addr_dff) self.add_mod(self.row_addr_dff)
if self.col_addr_size > 0:
self.col_addr_dff = dff_array(name="col_addr_dff", rows=1, columns=self.col_addr_size)
self.add_mod(self.col_addr_dff)
else:
self.col_addr_dff = None
self.data_dff = dff_array(name="data_dff", rows=1, columns=self.word_size)
self.add_mod(self.data_dff)
# Create the bank module (up to four are instantiated) # Create the bank module (up to four are instantiated)
from bank import bank from bank import bank
@ -329,21 +334,49 @@ class sram_base(design):
return bank_inst return bank_inst
def add_row_addr_dff(self, position):
def add_addr_dff(self, position): """ Add and place all address flops for the main decoder """
""" Add and place address and control flops """ self.row_addr_dff_inst = self.add_inst(name="row_address",
self.addr_dff_inst = self.add_inst(name="address", mod=self.row_addr_dff,
mod=self.addr_dff, offset=position)
offset=position)
# inputs, outputs/output/bar # inputs, outputs/output/bar
inputs = [] inputs = []
outputs = [] outputs = []
for i in range(self.addr_size): for i in range(self.row_addr_size):
inputs.append("ADDR[{}]".format(i+self.col_addr_size))
outputs.append("A[{}]".format(i+self.col_addr_size))
self.connect_inst(inputs + outputs + ["clk_buf", "vdd", "gnd"])
def add_col_addr_dff(self, position):
""" Add and place all address flops for the column decoder """
self.col_addr_dff_inst = self.add_inst(name="row_address",
mod=self.col_addr_dff,
offset=position)
# inputs, outputs/output/bar
inputs = []
outputs = []
for i in range(self.col_addr_size):
inputs.append("ADDR[{}]".format(i)) inputs.append("ADDR[{}]".format(i))
outputs.append("A[{}]".format(i)) outputs.append("A[{}]".format(i))
self.connect_inst(inputs + outputs + ["clk_buf", "vdd", "gnd"]) self.connect_inst(inputs + outputs + ["clk_buf", "vdd", "gnd"])
def add_data_dff(self, position):
""" Add and place all data flops """
self.data_dff_inst = self.add_inst(name="data_dff",
mod=self.data_dff,
offset=position)
# inputs, outputs/output/bar
inputs = []
outputs = []
for i in range(self.word_size):
inputs.append("DIN[{}]".format(i))
outputs.append("BANK_DIN[{}]".format(i))
self.connect_inst(inputs + outputs + ["clk_buf_bar", "vdd", "gnd"])
def add_control_logic(self, position): def add_control_logic(self, position):
""" Add and place control logic """ """ Add and place control logic """
inputs = [] inputs = []

View File

@ -32,14 +32,14 @@ class openram_test(unittest.TestCase):
a.gds_write(tempgds) a.gds_write(tempgds)
import verify import verify
result=verify.run_drc(a.get_name(), tempgds) result=verify.run_drc(a.name, tempgds)
if result != 0: if result != 0:
self.fail("DRC failed: {}".format(a.get_name())) self.fail("DRC failed: {}".format(a.name))
result=verify.run_lvs(a.get_name(), tempgds, tempspice, final_verification) result=verify.run_lvs(a.name, tempgds, tempspice, final_verification)
if result != 0: if result != 0:
self.fail("LVS mismatch: {}".format(a.get_name())) self.fail("LVS mismatch: {}".format(a.name))
if OPTS.purge_temp: if OPTS.purge_temp:
self.cleanup() self.cleanup()