Merge branch 'multiport' into supply_routing

This commit is contained in:
Matt Guthaus 2018-10-11 09:56:38 -07:00
commit a094db9077
23 changed files with 330 additions and 330 deletions

View File

@ -38,9 +38,9 @@ class bitcell(design.design):
def list_bitcell_pins(self, col, row):
""" Creates a list of connections in the bitcell, indexed by column and row, for instance use in bitcell_array """
bitcell_pins = ["bl[{0}]".format(col),
"br[{0}]".format(col),
"wl[{0}]".format(row),
bitcell_pins = ["bl_{0}".format(col),
"br_{0}".format(col),
"wl_{0}".format(row),
"vdd",
"gnd"]
return bitcell_pins

View File

@ -1186,10 +1186,10 @@ class pbitcell(design.design):
""" Creates a list of connections in the bitcell, indexed by column and row, for instance use in bitcell_array """
bitcell_pins = []
for port in range(self.total_ports):
bitcell_pins.append("bl{0}[{1}]".format(port,col))
bitcell_pins.append("br{0}[{1}]".format(port,col))
bitcell_pins.append("bl{0}_{1}".format(port,col))
bitcell_pins.append("br{0}_{1}".format(port,col))
for port in range(self.total_ports):
bitcell_pins.append("wl{0}[{1}]".format(port,row))
bitcell_pins.append("wl{0}_{1}".format(port,row))
bitcell_pins.append("vdd")
bitcell_pins.append("gnd")
return bitcell_pins
@ -1242,4 +1242,4 @@ class pbitcell(design.design):
Q_bar_pos = self.inverter_pmos_left.get_pin("D").uc()
vdd_pos = vector(Q_bar_pos.x, self.vdd_position.y)
self.add_path("metal1", [Q_bar_pos, vdd_pos])
self.add_path("metal1", [Q_bar_pos, vdd_pos])

View File

@ -68,13 +68,13 @@ class bank(design.design):
""" Adding pins for Bank module"""
for port in range(self.total_read):
for bit in range(self.word_size):
self.add_pin("dout{0}[{1}]".format(self.read_index[port],bit),"OUT")
self.add_pin("dout{0}_{1}".format(self.read_index[port],bit),"OUT")
for port in range(self.total_write):
for bit in range(self.word_size):
self.add_pin("din{0}[{1}]".format(port,bit),"IN")
self.add_pin("din{0}_{1}".format(port,bit),"IN")
for port in range(self.total_ports):
for bit in range(self.addr_size):
self.add_pin("addr{0}[{1}]".format(port,bit),"INPUT")
self.add_pin("addr{0}_{1}".format(port,bit),"INPUT")
# For more than one bank, we have a bank select and name
# the signals gated_*.
@ -285,10 +285,10 @@ class bank(design.design):
temp = []
for col in range(self.num_cols):
for bitline in self.total_bitline_list:
temp.append(bitline+"[{0}]".format(col))
temp.append(bitline+"_{0}".format(col))
for row in range(self.num_rows):
for wordline in self.total_wl_list:
temp.append(wordline+"[{0}]".format(row))
temp.append(wordline+"_{0}".format(row))
temp.append("vdd")
temp.append("gnd")
self.connect_inst(temp)
@ -308,8 +308,8 @@ class bank(design.design):
mod=self.precharge_array[port]))
temp = []
for i in range(self.num_cols):
temp.append(self.read_bl_list[port]+"[{0}]".format(i))
temp.append(self.read_br_list[port]+"[{0}]".format(i))
temp.append(self.read_bl_list[port]+"_{0}".format(i))
temp.append(self.read_br_list[port]+"_{0}".format(i))
temp.extend([self.prefix+"clk_buf_bar{0}".format(self.read_index[port]), "vdd"])
self.connect_inst(temp)
@ -337,13 +337,13 @@ class bank(design.design):
temp = []
for col in range(self.num_cols):
temp.append(self.total_bl_list[port]+"[{0}]".format(col))
temp.append(self.total_br_list[port]+"[{0}]".format(col))
temp.append(self.total_bl_list[port]+"_{0}".format(col))
temp.append(self.total_br_list[port]+"_{0}".format(col))
for word in range(self.words_per_row):
temp.append("sel{0}[{1}]".format(port,word))
temp.append("sel{0}_{1}".format(port,word))
for bit in range(self.word_size):
temp.append(self.total_bl_list[port]+"_out[{0}]".format(bit))
temp.append(self.total_br_list[port]+"_out[{0}]".format(bit))
temp.append(self.total_bl_list[port]+"_out_{0}".format(bit))
temp.append(self.total_br_list[port]+"_out_{0}".format(bit))
temp.append("gnd")
self.connect_inst(temp)
@ -371,13 +371,13 @@ class bank(design.design):
temp = []
for bit in range(self.word_size):
temp.append("dout{0}[{1}]".format(self.read_index[port],bit))
temp.append("dout{0}_{1}".format(self.read_index[port],bit))
if self.words_per_row == 1:
temp.append(self.read_bl_list[port]+"[{0}]".format(bit))
temp.append(self.read_br_list[port]+"[{0}]".format(bit))
temp.append(self.read_bl_list[port]+"_{0}".format(bit))
temp.append(self.read_br_list[port]+"_{0}".format(bit))
else:
temp.append(self.read_bl_list[port]+"_out[{0}]".format(bit))
temp.append(self.read_br_list[port]+"_out[{0}]".format(bit))
temp.append(self.read_bl_list[port]+"_out_{0}".format(bit))
temp.append(self.read_br_list[port]+"_out_{0}".format(bit))
temp.extend([self.prefix+"s_en{}".format(self.read_index[port]), "vdd", "gnd"])
self.connect_inst(temp)
@ -402,14 +402,14 @@ class bank(design.design):
temp = []
for bit in range(self.word_size):
temp.append("din{0}[{1}]".format(port,bit))
temp.append("din{0}_{1}".format(port,bit))
for bit in range(self.word_size):
if (self.words_per_row == 1):
temp.append(self.write_bl_list[port]+"[{0}]".format(bit))
temp.append(self.write_br_list[port]+"[{0}]".format(bit))
temp.append(self.write_bl_list[port]+"_{0}".format(bit))
temp.append(self.write_br_list[port]+"_{0}".format(bit))
else:
temp.append(self.write_bl_list[port]+"_out[{0}]".format(bit))
temp.append(self.write_br_list[port]+"_out[{0}]".format(bit))
temp.append(self.write_bl_list[port]+"_out_{0}".format(bit))
temp.append(self.write_br_list[port]+"_out_{0}".format(bit))
temp.extend([self.prefix+"w_en{0}".format(port), "vdd", "gnd"])
self.connect_inst(temp)
@ -434,9 +434,9 @@ class bank(design.design):
temp = []
for bit in range(self.row_addr_size):
temp.append("addr{0}[{1}]".format(port,bit+self.col_addr_size))
temp.append("addr{0}_{1}".format(port,bit+self.col_addr_size))
for row in range(self.num_rows):
temp.append("dec_out{0}[{1}]".format(port,row))
temp.append("dec_out{0}_{1}".format(port,row))
temp.extend(["vdd", "gnd"])
self.connect_inst(temp)
@ -466,9 +466,9 @@ class bank(design.design):
temp = []
for row in range(self.num_rows):
temp.append("dec_out{0}[{1}]".format(port,row))
temp.append("dec_out{0}_{1}".format(port,row))
for row in range(self.num_rows):
temp.append(self.total_wl_list[port]+"[{0}]".format(row))
temp.append(self.total_wl_list[port]+"_{0}".format(row))
temp.append(self.prefix+"clk_buf{0}".format(port))
temp.append("vdd")
temp.append("gnd")
@ -510,9 +510,9 @@ class bank(design.design):
temp = []
for bit in range(self.col_addr_size):
temp.append("addr{0}[{1}]".format(port,bit))
temp.append("addr{0}_{1}".format(port,bit))
for bit in range(self.num_col_addr_lines):
temp.append("sel{0}[{1}]".format(port,bit))
temp.append("sel{0}_{1}".format(port,bit))
temp.extend(["vdd", "gnd"])
self.connect_inst(temp)
@ -679,10 +679,10 @@ class bank(design.design):
# FIXME: Update for multiport
for port in range(self.total_read):
for col in range(self.num_cols):
precharge_bl = self.precharge_array_inst[port].get_pin("bl[{}]".format(col)).bc()
precharge_br = self.precharge_array_inst[port].get_pin("br[{}]".format(col)).bc()
bitcell_bl = self.bitcell_array_inst.get_pin(self.read_bl_list[port]+"[{}]".format(col)).uc()
bitcell_br = self.bitcell_array_inst.get_pin(self.read_br_list[port]+"[{}]".format(col)).uc()
precharge_bl = self.precharge_array_inst[port].get_pin("bl_{}".format(col)).bc()
precharge_br = self.precharge_array_inst[port].get_pin("br_{}".format(col)).bc()
bitcell_bl = self.bitcell_array_inst.get_pin(self.read_bl_list[port]+"_{}".format(col)).uc()
bitcell_br = self.bitcell_array_inst.get_pin(self.read_br_list[port]+"_{}".format(col)).uc()
yoffset = 0.5*(precharge_bl.y+bitcell_bl.y)
self.add_path("metal2",[precharge_bl, vector(precharge_bl.x,yoffset),
@ -701,10 +701,10 @@ class bank(design.design):
# FIXME: Update for multiport
for port in range(self.total_ports):
for col in range(self.num_cols):
col_mux_bl = self.col_mux_array_inst[port].get_pin("bl[{}]".format(col)).uc()
col_mux_br = self.col_mux_array_inst[port].get_pin("br[{}]".format(col)).uc()
bitcell_bl = self.bitcell_array_inst.get_pin(self.total_bl_list[port]+"[{}]".format(col)).bc()
bitcell_br = self.bitcell_array_inst.get_pin(self.total_br_list[port]+"[{}]".format(col)).bc()
col_mux_bl = self.col_mux_array_inst[port].get_pin("bl_{}".format(col)).uc()
col_mux_br = self.col_mux_array_inst[port].get_pin("br_{}".format(col)).uc()
bitcell_bl = self.bitcell_array_inst.get_pin(self.total_bl_list[port]+"_{}".format(col)).bc()
bitcell_br = self.bitcell_array_inst.get_pin(self.total_br_list[port]+"_{}".format(col)).bc()
yoffset = 0.5*(col_mux_bl.y+bitcell_bl.y)
self.add_path("metal2",[col_mux_bl, vector(col_mux_bl.x,yoffset),
@ -718,17 +718,17 @@ class bank(design.design):
for port in range(self.total_read):
for bit in range(self.word_size):
sense_amp_bl = self.sense_amp_array_inst[port].get_pin("bl[{}]".format(bit)).uc()
sense_amp_br = self.sense_amp_array_inst[port].get_pin("br[{}]".format(bit)).uc()
sense_amp_bl = self.sense_amp_array_inst[port].get_pin("bl_{}".format(bit)).uc()
sense_amp_br = self.sense_amp_array_inst[port].get_pin("br_{}".format(bit)).uc()
if self.col_addr_size>0:
# Sense amp is connected to the col mux
connect_bl = self.col_mux_array_inst[port].get_pin("bl_out[{}]".format(bit)).bc()
connect_br = self.col_mux_array_inst[port].get_pin("br_out[{}]".format(bit)).bc()
connect_bl = self.col_mux_array_inst[port].get_pin("bl_out_{}".format(bit)).bc()
connect_br = self.col_mux_array_inst[port].get_pin("br_out_{}".format(bit)).bc()
else:
# Sense amp is directly connected to the bitcell array
connect_bl = self.bitcell_array_inst.get_pin(self.read_bl_list[port]+"[{}]".format(bit)).bc()
connect_br = self.bitcell_array_inst.get_pin(self.read_br_list[port]+"[{}]".format(bit)).bc()
connect_bl = self.bitcell_array_inst.get_pin(self.read_bl_list[port]+"_{}".format(bit)).bc()
connect_br = self.bitcell_array_inst.get_pin(self.read_br_list[port]+"_{}".format(bit)).bc()
yoffset = 0.5*(sense_amp_bl.y+connect_bl.y)
@ -744,8 +744,8 @@ class bank(design.design):
# FIXME: Update for multiport
for port in range(self.total_read):
for bit in range(self.word_size):
data_pin = self.sense_amp_array_inst[port].get_pin("data[{}]".format(bit))
self.add_layout_pin_rect_center(text="dout{0}[{1}]".format(self.read_index[port],bit),
data_pin = self.sense_amp_array_inst[port].get_pin("data_{}".format(bit))
self.add_layout_pin_rect_center(text="dout{0}_{1}".format(self.read_index[port],bit),
layer=data_pin.layer,
offset=data_pin.center(),
height=data_pin.height(),
@ -760,8 +760,8 @@ class bank(design.design):
for port in range(self.total_ports):
for row in range(self.row_addr_size):
addr_idx = row + self.col_addr_size
decoder_name = "addr[{}]".format(row)
addr_name = "addr{0}[{1}]".format(port,addr_idx)
decoder_name = "addr_{}".format(row)
addr_name = "addr{0}_{1}".format(port,addr_idx)
self.copy_layout_pin(self.row_decoder_inst[port], decoder_name, addr_name)
@ -769,8 +769,8 @@ class bank(design.design):
""" Connecting write driver """
for port in range(self.total_ports):
for row in range(self.word_size):
data_name = "data[{}]".format(row)
din_name = "din{0}[{1}]".format(port,row)
data_name = "data_{}".format(row)
din_name = "din{0}_{1}".format(port,row)
self.copy_layout_pin(self.write_driver_array_inst[port], data_name, din_name)
@ -779,15 +779,15 @@ class bank(design.design):
for port in range(self.total_ports):
for row in range(self.num_rows):
# The pre/post is to access the pin from "outside" the cell to avoid DRCs
decoder_out_pos = self.row_decoder_inst[port].get_pin("decode[{}]".format(row)).rc()
driver_in_pos = self.wordline_driver_inst[port].get_pin("in[{}]".format(row)).lc()
decoder_out_pos = self.row_decoder_inst[port].get_pin("decode_{}".format(row)).rc()
driver_in_pos = self.wordline_driver_inst[port].get_pin("in_{}".format(row)).lc()
mid1 = decoder_out_pos.scale(0.5,1)+driver_in_pos.scale(0.5,0)
mid2 = decoder_out_pos.scale(0.5,0)+driver_in_pos.scale(0.5,1)
self.add_path("metal1", [decoder_out_pos, mid1, mid2, driver_in_pos])
# The mid guarantees we exit the input cell to the right.
driver_wl_pos = self.wordline_driver_inst[port].get_pin("wl[{}]".format(row)).rc()
bitcell_wl_pos = self.bitcell_array_inst.get_pin(self.total_wl_list[port]+"[{}]".format(row)).lc()
driver_wl_pos = self.wordline_driver_inst[port].get_pin("wl_{}".format(row)).rc()
bitcell_wl_pos = self.bitcell_array_inst.get_pin(self.total_wl_list[port]+"_{}".format(row)).lc()
mid1 = driver_wl_pos.scale(0.5,1)+bitcell_wl_pos.scale(0.5,0)
mid2 = driver_wl_pos.scale(0.5,0)+bitcell_wl_pos.scale(0.5,1)
self.add_path("metal1", [driver_wl_pos, mid1, mid2, bitcell_wl_pos])
@ -805,25 +805,25 @@ class bank(design.design):
decode_names = ["Zb", "Z"]
# The Address LSB
self.copy_layout_pin(self.col_decoder_inst[port], "A", "addr{}[0]".format(port))
self.copy_layout_pin(self.col_decoder_inst[port], "A", "addr{}_0".format(port))
elif self.col_addr_size > 1:
decode_names = []
for i in range(self.num_col_addr_lines):
decode_names.append("out[{}]".format(i))
decode_names.append("out_{}".format(i))
for i in range(self.col_addr_size):
decoder_name = "in[{}]".format(i)
addr_name = "addr{0}[{1}]".format(port,i)
decoder_name = "in_{}".format(i)
addr_name = "addr{0}_{1}".format(port,i)
self.copy_layout_pin(self.col_decoder_inst[port], decoder_name, addr_name)
# This will do a quick "river route" on two layers.
# When above the top select line it will offset "inward" again to prevent conflicts.
# This could be done on a single layer, but we follow preferred direction rules for later routing.
top_y_offset = self.col_mux_array_inst[port].get_pin("sel[{}]".format(self.num_col_addr_lines-1)).cy()
top_y_offset = self.col_mux_array_inst[port].get_pin("sel_{}".format(self.num_col_addr_lines-1)).cy()
for (decode_name,i) in zip(decode_names,range(self.num_col_addr_lines)):
mux_name = "sel[{}]".format(i)
mux_name = "sel_{}".format(i)
mux_addr_pos = self.col_mux_array_inst[port].get_pin(mux_name).lc()
decode_out_pos = self.col_decoder_inst[port].get_pin(decode_name).center()
@ -846,7 +846,7 @@ class bank(design.design):
"""
# Add the wordline names
for i in range(self.num_rows):
wl_name = "wl[{}]".format(i)
wl_name = "wl_{}".format(i)
wl_pin = self.bitcell_array_inst.get_pin(wl_name)
self.add_label(text=wl_name,
layer="metal1",
@ -854,8 +854,8 @@ class bank(design.design):
# Add the bitline names
for i in range(self.num_cols):
bl_name = "bl[{}]".format(i)
br_name = "br[{}]".format(i)
bl_name = "bl_{}".format(i)
br_name = "br_{}".format(i)
bl_pin = self.bitcell_array_inst.get_pin(bl_name)
br_pin = self.bitcell_array_inst.get_pin(br_name)
self.add_label(text=bl_name,
@ -867,16 +867,16 @@ class bank(design.design):
# # Add the data output names to the sense amp output
# 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)
# self.add_label(text="sa_out[{}]".format(i),
# self.add_label(text="sa_out_{}".format(i),
# layer="metal2",
# offset=data_pin.center())
# Add labels on the decoder
for i in range(self.word_size):
data_name = "dec_out[{}]".format(i)
pin_name = "in[{}]".format(i)
data_name = "dec_out_{}".format(i)
pin_name = "in_{}".format(i)
data_pin = self.wordline_driver_inst[0].get_pin(pin_name)
self.add_label(text=data_name,
layer="metal1",

View File

@ -69,10 +69,10 @@ class bitcell_array(design.design):
column_list = self.cell.list_all_bitline_names()
for col in range(self.column_size):
for cell_column in column_list:
self.add_pin(cell_column+"[{0}]".format(col))
self.add_pin(cell_column+"_{0}".format(col))
for row in range(self.row_size):
for cell_row in row_list:
self.add_pin(cell_row+"[{0}]".format(row))
self.add_pin(cell_row+"_{0}".format(row))
self.add_pin("vdd")
self.add_pin("gnd")
@ -105,7 +105,7 @@ class bitcell_array(design.design):
for col in range(self.column_size):
for cell_column in column_list:
bl_pin = self.cell_inst[0,col].get_pin(cell_column)
self.add_layout_pin(text=cell_column+"[{0}]".format(col),
self.add_layout_pin(text=cell_column+"_{0}".format(col),
layer="metal2",
offset=bl_pin.ll(),
width=bl_pin.width(),
@ -118,7 +118,7 @@ class bitcell_array(design.design):
for row in range(self.row_size):
for cell_row in row_list:
wl_pin = self.cell_inst[row,0].get_pin(cell_row)
self.add_layout_pin(text=cell_row+"[{0}]".format(row),
self.add_layout_pin(text=cell_row+"_{0}".format(row),
layer="metal1",
offset=wl_pin.ll(),
width=self.width,

View File

@ -299,7 +299,7 @@ class control_logic(design.design):
control_inputs = ["cs"]
else:
control_inputs = ["cs", "we"]
dff_out_map = zip(["dout_bar[{}]".format(i) for i in range(2*self.num_control_signals - 1)], control_inputs)
dff_out_map = zip(["dout_bar_{}".format(i) for i in range(2*self.num_control_signals - 1)], control_inputs)
self.connect_vertical_bus(dff_out_map, self.ctrl_dff_inst, self.rail_offsets)
# Connect the clock rail to the other clock rail
@ -311,9 +311,9 @@ class control_logic(design.design):
offset=rail_pos,
rotate=90)
self.copy_layout_pin(self.ctrl_dff_inst, "din[0]", "csb")
self.copy_layout_pin(self.ctrl_dff_inst, "din_0", "csb")
if (self.port_type == "rw"):
self.copy_layout_pin(self.ctrl_dff_inst, "din[1]", "web")
self.copy_layout_pin(self.ctrl_dff_inst, "din_1", "web")
def create_dffs(self):

View File

@ -83,21 +83,21 @@ class dff_array(design.design):
def get_din_name(self, row, col):
if self.columns == 1:
din_name = "din[{0}]".format(row)
din_name = "din_{0}".format(row)
elif self.rows == 1:
din_name = "din[{0}]".format(col)
din_name = "din_{0}".format(col)
else:
din_name = "din[{0}][{1}]".format(row,col)
din_name = "din_{0}_{1}".format(row,col)
return din_name
def get_dout_name(self, row, col):
if self.columns == 1:
dout_name = "dout[{0}]".format(row)
dout_name = "dout_{0}".format(row)
elif self.rows == 1:
dout_name = "dout[{0}]".format(col)
dout_name = "dout_{0}".format(col)
else:
dout_name = "dout[{0}][{1}]".format(row,col)
dout_name = "dout_{0}_{1}".format(row,col)
return dout_name

View File

@ -84,31 +84,31 @@ class dff_buf_array(design.design):
def get_din_name(self, row, col):
if self.columns == 1:
din_name = "din[{0}]".format(row)
din_name = "din_{0}".format(row)
elif self.rows == 1:
din_name = "din[{0}]".format(col)
din_name = "din_{0}".format(col)
else:
din_name = "din[{0}][{1}]".format(row,col)
din_name = "din_{0}_{1}".format(row,col)
return din_name
def get_dout_name(self, row, col):
if self.columns == 1:
dout_name = "dout[{0}]".format(row)
dout_name = "dout_{0}".format(row)
elif self.rows == 1:
dout_name = "dout[{0}]".format(col)
dout_name = "dout_{0}".format(col)
else:
dout_name = "dout[{0}][{1}]".format(row,col)
dout_name = "dout_{0}_{1}".format(row,col)
return dout_name
def get_dout_bar_name(self, row, col):
if self.columns == 1:
dout_bar_name = "dout_bar[{0}]".format(row)
dout_bar_name = "dout_bar_{0}".format(row)
elif self.rows == 1:
dout_bar_name = "dout_bar[{0}]".format(col)
dout_bar_name = "dout_bar_{0}".format(col)
else:
dout_bar_name = "dout_bar[{0}][{1}]".format(row,col)
dout_bar_name = "dout_bar_{0}_{1}".format(row,col)
return dout_bar_name

View File

@ -84,31 +84,31 @@ class dff_inv_array(design.design):
def get_din_name(self, row, col):
if self.columns == 1:
din_name = "din[{0}]".format(row)
din_name = "din_{0}".format(row)
elif self.rows == 1:
din_name = "din[{0}]".format(col)
din_name = "din_{0}".format(col)
else:
din_name = "din[{0}][{1}]".format(row,col)
din_name = "din_{0}_{1}".format(row,col)
return din_name
def get_dout_name(self, row, col):
if self.columns == 1:
dout_name = "dout[{0}]".format(row)
dout_name = "dout_{0}".format(row)
elif self.rows == 1:
dout_name = "dout[{0}]".format(col)
dout_name = "dout_{0}".format(col)
else:
dout_name = "dout[{0}][{1}]".format(row,col)
dout_name = "dout_{0}_{1}".format(row,col)
return dout_name
def get_dout_bar_name(self, row, col):
if self.columns == 1:
dout_bar_name = "dout_bar[{0}]".format(row)
dout_bar_name = "dout_bar_{0}".format(row)
elif self.rows == 1:
dout_bar_name = "dout_bar[{0}]".format(col)
dout_bar_name = "dout_bar_{0}".format(col)
else:
dout_bar_name = "dout_bar[{0}][{1}]".format(row,col)
dout_bar_name = "dout_bar_{0}_{1}".format(row,col)
return dout_bar_name

View File

@ -27,8 +27,8 @@ class hierarchical_decoder(design.design):
b = self.mod_bitcell()
self.bitcell_height = b.height
self.NAND_FORMAT = "DEC_NAND[{0}]"
self.INV_FORMAT = "DEC_INV_[{0}]"
self.NAND_FORMAT = "DEC_NAND_{0}"
self.INV_FORMAT = "DEC_INV_{0}"
self.pre2x4_inst = []
self.pre3x8_inst = []
@ -168,7 +168,7 @@ class hierarchical_decoder(design.design):
min_x = min(min_x, -self.pre3_8.width)
input_offset=vector(min_x - self.input_routing_width,0)
input_bus_names = ["addr[{0}]".format(i) for i in range(self.num_inputs)]
input_bus_names = ["addr_{0}".format(i) for i in range(self.num_inputs)]
self.input_rails = self.create_vertical_pin_bus(layer="metal2",
pitch=self.m2_pitch,
offset=input_offset,
@ -184,9 +184,9 @@ class hierarchical_decoder(design.design):
for i in range(2):
index = pre_num * 2 + i
input_pos = self.input_rails["addr[{}]".format(index)]
input_pos = self.input_rails["addr_{}".format(index)]
in_name = "in[{}]".format(i)
in_name = "in_{}".format(i)
decoder_pin = self.pre2x4_inst[pre_num].get_pin(in_name)
# To prevent conflicts, we will offset each input connect so
@ -201,9 +201,9 @@ class hierarchical_decoder(design.design):
for i in range(3):
index = pre_num * 3 + i + self.no_of_pre2x4 * 2
input_pos = self.input_rails["addr[{}]".format(index)]
input_pos = self.input_rails["addr_{}".format(index)]
in_name = "in[{}]".format(i)
in_name = "in_{}".format(i)
decoder_pin = self.pre3x8_inst[pre_num].get_pin(in_name)
# To prevent conflicts, we will offset each input connect so
@ -230,10 +230,10 @@ class hierarchical_decoder(design.design):
""" Add the module pins """
for i in range(self.num_inputs):
self.add_pin("addr[{0}]".format(i))
self.add_pin("addr_{0}".format(i))
for j in range(self.rows):
self.add_pin("decode[{0}]".format(j))
self.add_pin("decode_{0}".format(j))
self.add_pin("vdd")
self.add_pin("gnd")
@ -258,12 +258,12 @@ class hierarchical_decoder(design.design):
pins = []
for input_index in range(2):
pins.append("addr[{0}]".format(input_index + index_off1))
pins.append("addr_{0}".format(input_index + index_off1))
for output_index in range(4):
pins.append("out[{0}]".format(output_index + index_off2))
pins.append("out_{0}".format(output_index + index_off2))
pins.extend(["vdd", "gnd"])
self.pre2x4_inst.append(self.add_inst(name="pre[{0}]".format(num),
self.pre2x4_inst.append(self.add_inst(name="pre_{0}".format(num),
mod=self.pre2_4))
self.connect_inst(pins)
@ -277,12 +277,12 @@ class hierarchical_decoder(design.design):
pins = []
for input_index in range(3):
pins.append("addr[{0}]".format(input_index + in_index_offset))
pins.append("addr_{0}".format(input_index + in_index_offset))
for output_index in range(8):
pins.append("out[{0}]".format(output_index + out_index_offset))
pins.append("out_{0}".format(output_index + out_index_offset))
pins.extend(["vdd", "gnd"])
self.pre3x8_inst.append(self.add_inst(name="pre3x8[{0}]".format(num),
self.pre3x8_inst.append(self.add_inst(name="pre3x8_{0}".format(num),
mod=self.pre3_8))
self.connect_inst(pins)
@ -340,9 +340,9 @@ class hierarchical_decoder(design.design):
name = self.NAND_FORMAT.format(row)
self.nand_inst.append(self.add_inst(name=name,
mod=self.nand2))
pins =["out[{0}]".format(i),
"out[{0}]".format(j + len(self.predec_groups[0])),
"Z[{0}]".format(row),
pins =["out_{0}".format(i),
"out_{0}".format(j + len(self.predec_groups[0])),
"Z_{0}".format(row),
"vdd", "gnd"]
self.connect_inst(pins)
@ -359,10 +359,10 @@ class hierarchical_decoder(design.design):
self.nand_inst.append(self.add_inst(name=name,
mod=self.nand3))
pins = ["out[{0}]".format(i),
"out[{0}]".format(j + len(self.predec_groups[0])),
"out[{0}]".format(k + len(self.predec_groups[0]) + len(self.predec_groups[1])),
"Z[{0}]".format(row),
pins = ["out_{0}".format(i),
"out_{0}".format(j + len(self.predec_groups[0])),
"out_{0}".format(k + len(self.predec_groups[0]) + len(self.predec_groups[1])),
"Z_{0}".format(row),
"vdd", "gnd"]
self.connect_inst(pins)
@ -377,8 +377,8 @@ class hierarchical_decoder(design.design):
name = self.INV_FORMAT.format(row)
self.inv_inst.append(self.add_inst(name=name,
mod=self.inv))
self.connect_inst(args=["Z[{0}]".format(row),
"decode[{0}]".format(row),
self.connect_inst(args=["Z_{0}".format(row),
"decode_{0}".format(row),
"vdd", "gnd"])
@ -466,7 +466,7 @@ class hierarchical_decoder(design.design):
self.add_path("metal1", [zr_pos, mid1_pos, mid2_pos, al_pos])
z_pin = self.inv_inst[row].get_pin("Z")
self.add_layout_pin(text="decode[{0}]".format(row),
self.add_layout_pin(text="decode_{0}".format(row),
layer="metal1",
offset=z_pin.ll(),
width=z_pin.width(),
@ -480,7 +480,7 @@ class hierarchical_decoder(design.design):
# This is not needed for inputs <4 since they have no pre/decode stages.
if (self.num_inputs >= 4):
input_offset = vector(0.5*self.m2_width,0)
input_bus_names = ["predecode[{0}]".format(i) for i in range(self.total_number_of_predecoder_outputs)]
input_bus_names = ["predecode_{0}".format(i) for i in range(self.total_number_of_predecoder_outputs)]
self.predecode_rails = self.create_vertical_pin_bus(layer="metal2",
pitch=self.m2_pitch,
offset=input_offset,
@ -497,8 +497,8 @@ class hierarchical_decoder(design.design):
# FIXME: convert to connect_bus
for pre_num in range(self.no_of_pre2x4):
for i in range(4):
predecode_name = "predecode[{}]".format(pre_num * 4 + i)
out_name = "out[{}]".format(i)
predecode_name = "predecode_{}".format(pre_num * 4 + i)
out_name = "out_{}".format(i)
pin = self.pre2x4_inst[pre_num].get_pin(out_name)
self.route_predecode_rail_m3(predecode_name, pin)
@ -506,8 +506,8 @@ class hierarchical_decoder(design.design):
# FIXME: convert to connect_bus
for pre_num in range(self.no_of_pre3x8):
for i in range(8):
predecode_name = "predecode[{}]".format(pre_num * 8 + i + self.no_of_pre2x4 * 4)
out_name = "out[{}]".format(i)
predecode_name = "predecode_{}".format(pre_num * 8 + i + self.no_of_pre2x4 * 4)
out_name = "out_{}".format(i)
pin = self.pre3x8_inst[pre_num].get_pin(out_name)
self.route_predecode_rail_m3(predecode_name, pin)
@ -526,9 +526,9 @@ class hierarchical_decoder(design.design):
for index_A in self.predec_groups[0]:
for index_B in self.predec_groups[1]:
# FIXME: convert to connect_bus?
predecode_name = "predecode[{}]".format(index_A)
predecode_name = "predecode_{}".format(index_A)
self.route_predecode_rail(predecode_name, self.nand_inst[row_index].get_pin("A"))
predecode_name = "predecode[{}]".format(index_B)
predecode_name = "predecode_{}".format(index_B)
self.route_predecode_rail(predecode_name, self.nand_inst[row_index].get_pin("B"))
row_index = row_index + 1
@ -537,11 +537,11 @@ class hierarchical_decoder(design.design):
for index_B in self.predec_groups[1]:
for index_C in self.predec_groups[2]:
# FIXME: convert to connect_bus?
predecode_name = "predecode[{}]".format(index_A)
predecode_name = "predecode_{}".format(index_A)
self.route_predecode_rail(predecode_name, self.nand_inst[row_index].get_pin("A"))
predecode_name = "predecode[{}]".format(index_B)
predecode_name = "predecode_{}".format(index_B)
self.route_predecode_rail(predecode_name, self.nand_inst[row_index].get_pin("B"))
predecode_name = "predecode[{}]".format(index_C)
predecode_name = "predecode_{}".format(index_C)
self.route_predecode_rail(predecode_name, self.nand_inst[row_index].get_pin("C"))
row_index = row_index + 1

View File

@ -25,9 +25,9 @@ class hierarchical_predecode(design.design):
def add_pins(self):
for k in range(self.number_of_inputs):
self.add_pin("in[{0}]".format(k))
self.add_pin("in_{0}".format(k))
for i in range(self.number_of_outputs):
self.add_pin("out[{0}]".format(i))
self.add_pin("out_{0}".format(i))
self.add_pin("vdd")
self.add_pin("gnd")
@ -67,7 +67,7 @@ class hierarchical_predecode(design.design):
def route_rails(self):
""" Create all of the rails for the inputs and vdd/gnd/inputs_bar/inputs """
input_names = ["in[{}]".format(x) for x in range(self.number_of_inputs)]
input_names = ["in_{}".format(x) for x in range(self.number_of_inputs)]
offset = vector(0.5*self.m2_width,2*self.m1_width)
self.input_rails = self.create_vertical_pin_bus(layer="metal2",
pitch=self.m2_pitch,
@ -75,8 +75,8 @@ class hierarchical_predecode(design.design):
names=input_names,
length=self.height - 2*self.m1_width)
invert_names = ["Abar[{}]".format(x) for x in range(self.number_of_inputs)]
non_invert_names = ["A[{}]".format(x) for x in range(self.number_of_inputs)]
invert_names = ["Abar_{}".format(x) for x in range(self.number_of_inputs)]
non_invert_names = ["A_{}".format(x) for x in range(self.number_of_inputs)]
decode_names = invert_names + non_invert_names
offset = vector(self.x_off_inv_1 + self.inv.width + 2*self.m2_pitch, 2*self.m1_width)
self.decode_rails = self.create_vertical_bus(layer="metal2",
@ -90,11 +90,11 @@ class hierarchical_predecode(design.design):
""" Create the input inverters to invert input signals for the decode stage. """
self.in_inst = []
for inv_num in range(self.number_of_inputs):
name = "Xpre_inv[{0}]".format(inv_num)
name = "Xpre_inv_{0}".format(inv_num)
self.in_inst.append(self.add_inst(name=name,
mod=self.inv))
self.connect_inst(["in[{0}]".format(inv_num),
"inbar[{0}]".format(inv_num),
self.connect_inst(["in_{0}".format(inv_num),
"inbar_{0}".format(inv_num),
"vdd", "gnd"])
def place_input_inverters(self):
@ -114,11 +114,11 @@ class hierarchical_predecode(design.design):
""" Create inverters for the inverted output decode signals. """
self.inv_inst = []
for inv_num in range(self.number_of_outputs):
name = "Xpre_nand_inv[{}]".format(inv_num)
name = "Xpre_nand_inv_{}".format(inv_num)
self.inv_inst.append(self.add_inst(name=name,
mod=self.inv))
self.connect_inst(["Z[{}]".format(inv_num),
"out[{}]".format(inv_num),
self.connect_inst(["Z_{}".format(inv_num),
"out_{}".format(inv_num),
"vdd", "gnd"])
@ -140,7 +140,7 @@ class hierarchical_predecode(design.design):
self.nand_inst = []
for nand_input in range(self.number_of_outputs):
inout = str(self.number_of_inputs)+"x"+str(self.number_of_outputs)
name = "Xpre{0}_nand[{1}]".format(inout,nand_input)
name = "Xpre{0}_nand_{1}".format(inout,nand_input)
self.nand_inst.append(self.add_inst(name=name,
mod=self.nand))
self.connect_inst(connections[nand_input])
@ -175,8 +175,8 @@ class hierarchical_predecode(design.design):
# typically where the p/n devices are and there are no
# pins in the nand gates.
y_offset = (num+self.number_of_inputs) * self.inv.height + contact.m1m2.width + self.m1_space
in_pin = "in[{}]".format(num)
a_pin = "A[{}]".format(num)
in_pin = "in_{}".format(num)
a_pin = "A_{}".format(num)
in_pos = vector(self.input_rails[in_pin].x,y_offset)
a_pos = vector(self.decode_rails[a_pin].x,y_offset)
self.add_path("metal1",[in_pos, a_pos])
@ -202,7 +202,7 @@ class hierarchical_predecode(design.design):
self.add_path("metal1", [zr_pos, mid1_pos, mid2_pos, al_pos])
z_pin = self.inv_inst[num].get_pin("Z")
self.add_layout_pin(text="out[{}]".format(num),
self.add_layout_pin(text="out_{}".format(num),
layer="metal1",
offset=z_pin.ll(),
height=z_pin.height(),
@ -214,8 +214,8 @@ class hierarchical_predecode(design.design):
Route all conections of the inputs inverters [Inputs, outputs, vdd, gnd]
"""
for inv_num in range(self.number_of_inputs):
out_pin = "Abar[{}]".format(inv_num)
in_pin = "in[{}]".format(inv_num)
out_pin = "Abar_{}".format(inv_num)
in_pin = "in_{}".format(inv_num)
#add output so that it is just below the vdd or gnd rail
# since this is where the p/n devices are and there are no

View File

@ -21,10 +21,10 @@ class hierarchical_predecode2x4(hierarchical_predecode):
self.create_modules()
self.create_input_inverters()
self.create_output_inverters()
connections =[["inbar[0]", "inbar[1]", "Z[0]", "vdd", "gnd"],
["in[0]", "inbar[1]", "Z[1]", "vdd", "gnd"],
["inbar[0]", "in[1]", "Z[2]", "vdd", "gnd"],
["in[0]", "in[1]", "Z[3]", "vdd", "gnd"]]
connections =[["inbar_0", "inbar_1", "Z_0", "vdd", "gnd"],
["in_0", "inbar_1", "Z_1", "vdd", "gnd"],
["inbar_0", "in_1", "Z_2", "vdd", "gnd"],
["in_0", "in_1", "Z_3", "vdd", "gnd"]]
self.create_nand_array(connections)
def create_layout(self):
@ -44,10 +44,10 @@ class hierarchical_predecode2x4(hierarchical_predecode):
def get_nand_input_line_combination(self):
""" These are the decoder connections of the NAND gates to the A,B pins """
combination = [["Abar[0]", "Abar[1]"],
["A[0]", "Abar[1]"],
["Abar[0]", "A[1]"],
["A[0]", "A[1]"]]
combination = [["Abar_0", "Abar_1"],
["A_0", "Abar_1"],
["Abar_0", "A_1"],
["A_0", "A_1"]]
return combination

View File

@ -21,14 +21,14 @@ class hierarchical_predecode3x8(hierarchical_predecode):
self.create_modules()
self.create_input_inverters()
self.create_output_inverters()
connections=[["inbar[0]", "inbar[1]", "inbar[2]", "Z[0]", "vdd", "gnd"],
["in[0]", "inbar[1]", "inbar[2]", "Z[1]", "vdd", "gnd"],
["inbar[0]", "in[1]", "inbar[2]", "Z[2]", "vdd", "gnd"],
["in[0]", "in[1]", "inbar[2]", "Z[3]", "vdd", "gnd"],
["inbar[0]", "inbar[1]", "in[2]", "Z[4]", "vdd", "gnd"],
["in[0]", "inbar[1]", "in[2]", "Z[5]", "vdd", "gnd"],
["inbar[0]", "in[1]", "in[2]", "Z[6]", "vdd", "gnd"],
["in[0]", "in[1]", "in[2]", "Z[7]", "vdd", "gnd"]]
connections=[["inbar_0", "inbar_1", "inbar_2", "Z_0", "vdd", "gnd"],
["in_0", "inbar_1", "inbar_2", "Z_1", "vdd", "gnd"],
["inbar_0", "in_1", "inbar_2", "Z_2", "vdd", "gnd"],
["in_0", "in_1", "inbar_2", "Z_3", "vdd", "gnd"],
["inbar_0", "inbar_1", "in_2", "Z_4", "vdd", "gnd"],
["in_0", "inbar_1", "in_2", "Z_5", "vdd", "gnd"],
["inbar_0", "in_1", "in_2", "Z_6", "vdd", "gnd"],
["in_0", "in_1", "in_2", "Z_7", "vdd", "gnd"]]
self.create_nand_array(connections)
def create_layout(self):
@ -49,14 +49,14 @@ class hierarchical_predecode3x8(hierarchical_predecode):
def get_nand_input_line_combination(self):
""" These are the decoder connections of the NAND gates to the A,B,C pins """
combination = [["Abar[0]", "Abar[1]", "Abar[2]"],
["A[0]", "Abar[1]", "Abar[2]"],
["Abar[0]", "A[1]", "Abar[2]"],
["A[0]", "A[1]", "Abar[2]"],
["Abar[0]", "Abar[1]", "A[2]"],
["A[0]", "Abar[1]", "A[2]"],
["Abar[0]", "A[1]", "A[2]"],
["A[0]", "A[1]", "A[2]"]]
combination = [["Abar_0", "Abar_1", "Abar_2"],
["A_0", "Abar_1", "Abar_2"],
["Abar_0", "A_1", "Abar_2"],
["A_0", "A_1", "Abar_2"],
["Abar_0", "Abar_1", "A_2"],
["A_0", "Abar_1", "A_2"],
["Abar_0", "A_1", "A_2"],
["A_0", "A_1", "A_2"]]
return combination

View File

@ -75,11 +75,11 @@ class multibank(design.design):
def add_pins(self):
""" Adding pins for Bank module"""
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):
self.add_pin("BANK_DIN[{0}]".format(i),"IN")
self.add_pin("BANK_DIN_{0}".format(i),"IN")
for i in range(self.addr_size):
self.add_pin("A[{0}]".format(i),"INPUT")
self.add_pin("A_{0}".format(i),"INPUT")
# For more than one bank, we have a bank select and name
# the signals gated_*.
@ -227,10 +227,10 @@ class multibank(design.design):
offset=vector(0,0))
temp = []
for i in range(self.num_cols):
temp.append("bl[{0}]".format(i))
temp.append("br[{0}]".format(i))
temp.append("bl_{0}".format(i))
temp.append("br_{0}".format(i))
for j in range(self.num_rows):
temp.append("wl[{0}]".format(j))
temp.append("wl_{0}".format(j))
temp.extend(["vdd", "gnd"])
self.connect_inst(temp)
@ -246,8 +246,8 @@ class multibank(design.design):
offset=vector(0,y_offset))
temp = []
for i in range(self.num_cols):
temp.append("bl[{0}]".format(i))
temp.append("br[{0}]".format(i))
temp.append("bl_{0}".format(i))
temp.append("br_{0}".format(i))
temp.extend([self.prefix+"clk_buf_bar", "vdd"])
self.connect_inst(temp)
@ -265,13 +265,13 @@ class multibank(design.design):
offset=vector(0,y_offset).scale(-1,-1))
temp = []
for i in range(self.num_cols):
temp.append("bl[{0}]".format(i))
temp.append("br[{0}]".format(i))
temp.append("bl_{0}".format(i))
temp.append("br_{0}".format(i))
for k in range(self.words_per_row):
temp.append("sel[{0}]".format(k))
temp.append("sel_{0}".format(k))
for j in range(self.word_size):
temp.append("bl_out[{0}]".format(j))
temp.append("br_out[{0}]".format(j))
temp.append("bl_out_{0}".format(j))
temp.append("br_out_{0}".format(j))
temp.append("gnd")
self.connect_inst(temp)
@ -284,13 +284,13 @@ class multibank(design.design):
offset=vector(0,y_offset).scale(-1,-1))
temp = []
for i in range(self.word_size):
temp.append("sa_out[{0}]".format(i))
temp.append("sa_out_{0}".format(i))
if self.words_per_row == 1:
temp.append("bl[{0}]".format(i))
temp.append("br[{0}]".format(i))
temp.append("bl_{0}".format(i))
temp.append("br_{0}".format(i))
else:
temp.append("bl_out[{0}]".format(i))
temp.append("br_out[{0}]".format(i))
temp.append("bl_out_{0}".format(i))
temp.append("br_out_{0}".format(i))
temp.extend([self.prefix+"s_en", "vdd", "gnd"])
self.connect_inst(temp)
@ -306,14 +306,14 @@ class multibank(design.design):
temp = []
for i in range(self.word_size):
temp.append("BANK_DIN[{0}]".format(i))
temp.append("BANK_DIN_{0}".format(i))
for i in range(self.word_size):
if (self.words_per_row == 1):
temp.append("bl[{0}]".format(i))
temp.append("br[{0}]".format(i))
temp.append("bl_{0}".format(i))
temp.append("br_{0}".format(i))
else:
temp.append("bl_out[{0}]".format(i))
temp.append("br_out[{0}]".format(i))
temp.append("bl_out_{0}".format(i))
temp.append("br_out_{0}".format(i))
temp.extend([self.prefix+"w_en", "vdd", "gnd"])
self.connect_inst(temp)
@ -327,9 +327,9 @@ class multibank(design.design):
temp = []
for i in range(self.word_size):
temp.append("sa_out[{0}]".format(i))
temp.append("sa_out_{0}".format(i))
for i in range(self.word_size):
temp.append("DOUT[{0}]".format(i))
temp.append("DOUT_{0}".format(i))
temp.extend([self.prefix+"tri_en", self.prefix+"tri_en_bar", "vdd", "gnd"])
self.connect_inst(temp)
@ -350,9 +350,9 @@ class multibank(design.design):
temp = []
for i in range(self.row_addr_size):
temp.append("A[{0}]".format(i+self.col_addr_size))
temp.append("A_{0}".format(i+self.col_addr_size))
for j in range(self.num_rows):
temp.append("dec_out[{0}]".format(j))
temp.append("dec_out_{0}".format(j))
temp.extend(["vdd", "gnd"])
self.connect_inst(temp)
@ -367,9 +367,9 @@ class multibank(design.design):
temp = []
for i in range(self.num_rows):
temp.append("dec_out[{0}]".format(i))
temp.append("dec_out_{0}".format(i))
for i in range(self.num_rows):
temp.append("wl[{0}]".format(i))
temp.append("wl_{0}".format(i))
temp.append(self.prefix+"clk_buf")
temp.append("vdd")
temp.append("gnd")
@ -389,9 +389,9 @@ class multibank(design.design):
temp = []
for i in range(self.col_addr_size):
temp.append("A[{0}]".format(i))
temp.append("A_{0}".format(i))
for j in range(self.num_col_addr_lines):
temp.append("sel[{0}]".format(j))
temp.append("sel_{0}".format(j))
temp.extend(["vdd", "gnd"])
self.connect_inst(temp)
@ -528,10 +528,10 @@ class multibank(design.design):
""" Routing of BL and BR between pre-charge and bitcell array """
for i in range(self.num_cols):
precharge_bl = self.precharge_array_inst.get_pin("bl[{}]".format(i)).bc()
precharge_br = self.precharge_array_inst.get_pin("br[{}]".format(i)).bc()
bitcell_bl = self.bitcell_array_inst.get_pin("bl[{}]".format(i)).uc()
bitcell_br = self.bitcell_array_inst.get_pin("br[{}]".format(i)).uc()
precharge_bl = self.precharge_array_inst.get_pin("bl_{}".format(i)).bc()
precharge_br = self.precharge_array_inst.get_pin("br_{}".format(i)).bc()
bitcell_bl = self.bitcell_array_inst.get_pin("bl_{}".format(i)).uc()
bitcell_br = self.bitcell_array_inst.get_pin("br_{}".format(i)).uc()
yoffset = 0.5*(precharge_bl.y+bitcell_bl.y)
self.add_path("metal2",[precharge_bl, vector(precharge_bl.x,yoffset),
@ -548,10 +548,10 @@ class multibank(design.design):
return
for i in range(self.num_cols):
col_mux_bl = self.col_mux_array_inst.get_pin("bl[{}]".format(i)).uc()
col_mux_br = self.col_mux_array_inst.get_pin("br[{}]".format(i)).uc()
bitcell_bl = self.bitcell_array_inst.get_pin("bl[{}]".format(i)).bc()
bitcell_br = self.bitcell_array_inst.get_pin("br[{}]".format(i)).bc()
col_mux_bl = self.col_mux_array_inst.get_pin("bl_{}".format(i)).uc()
col_mux_br = self.col_mux_array_inst.get_pin("br_{}".format(i)).uc()
bitcell_bl = self.bitcell_array_inst.get_pin("bl_{}".format(i)).bc()
bitcell_br = self.bitcell_array_inst.get_pin("br_{}".format(i)).bc()
yoffset = 0.5*(col_mux_bl.y+bitcell_bl.y)
self.add_path("metal2",[col_mux_bl, vector(col_mux_bl.x,yoffset),
@ -563,17 +563,17 @@ class multibank(design.design):
""" Routing of BL and BR between sense_amp and column mux or bitcell array """
for i in range(self.word_size):
sense_amp_bl = self.sense_amp_array_inst.get_pin("bl[{}]".format(i)).uc()
sense_amp_br = self.sense_amp_array_inst.get_pin("br[{}]".format(i)).uc()
sense_amp_bl = self.sense_amp_array_inst.get_pin("bl_{}".format(i)).uc()
sense_amp_br = self.sense_amp_array_inst.get_pin("br_{}".format(i)).uc()
if self.col_addr_size>0:
# Sense amp is connected to the col mux
connect_bl = self.col_mux_array_inst.get_pin("bl_out[{}]".format(i)).bc()
connect_br = self.col_mux_array_inst.get_pin("br_out[{}]".format(i)).bc()
connect_bl = self.col_mux_array_inst.get_pin("bl_out_{}".format(i)).bc()
connect_br = self.col_mux_array_inst.get_pin("br_out_{}".format(i)).bc()
else:
# Sense amp is directly connected to the bitcell array
connect_bl = self.bitcell_array_inst.get_pin("bl[{}]".format(i)).bc()
connect_br = self.bitcell_array_inst.get_pin("br[{}]".format(i)).bc()
connect_bl = self.bitcell_array_inst.get_pin("bl_{}".format(i)).bc()
connect_br = self.bitcell_array_inst.get_pin("br_{}".format(i)).bc()
yoffset = 0.5*(sense_amp_bl.y+connect_bl.y)
@ -587,8 +587,8 @@ class multibank(design.design):
for i in range(self.word_size):
# Connection of data_out of sense amp to data_in
tri_gate_in = self.tri_gate_array_inst.get_pin("in[{}]".format(i)).lc()
sa_data_out = self.sense_amp_array_inst.get_pin("data[{}]".format(i)).bc()
tri_gate_in = self.tri_gate_array_inst.get_pin("in_{}".format(i)).lc()
sa_data_out = self.sense_amp_array_inst.get_pin("data_{}".format(i)).bc()
self.add_via_center(layers=("metal2", "via2", "metal3"),
offset=tri_gate_in)
@ -599,8 +599,8 @@ class multibank(design.design):
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),
data_pin = self.sense_amp_array_inst.get_pin("data_{}".format(i))
self.add_layout_pin_rect_center(text="DOUT_{}".format(i),
layer=data_pin.layer,
offset=data_pin.center(),
height=data_pin.height(),
@ -609,8 +609,8 @@ class multibank(design.design):
def route_tri_gate_out(self):
""" Metal 3 routing of tri_gate output data """
for i in range(self.word_size):
data_pin = self.tri_gate_array_inst.get_pin("out[{}]".format(i))
self.add_layout_pin_rect_center(text="DOUT[{}]".format(i),
data_pin = self.tri_gate_array_inst.get_pin("out_{}".format(i))
self.add_layout_pin_rect_center(text="DOUT_{}".format(i),
layer=data_pin.layer,
offset=data_pin.center(),
height=data_pin.height(),
@ -623,8 +623,8 @@ class multibank(design.design):
# Create inputs for the row address lines
for i in range(self.row_addr_size):
addr_idx = i + self.col_addr_size
decoder_name = "A[{}]".format(i)
addr_name = "A[{}]".format(addr_idx)
decoder_name = "A_{}".format(i)
addr_name = "A_{}".format(addr_idx)
self.copy_layout_pin(self.row_decoder_inst, decoder_name, addr_name)
@ -632,8 +632,8 @@ class multibank(design.design):
""" Connecting write driver """
for i in range(self.word_size):
data_name = "data[{}]".format(i)
din_name = "BANK_DIN[{}]".format(i)
data_name = "data_{}".format(i)
din_name = "BANK_DIN_{}".format(i)
self.copy_layout_pin(self.write_driver_array_inst, data_name, din_name)
@ -644,15 +644,15 @@ class multibank(design.design):
# we don't care about bends after connecting to the input pin, so let the path code decide.
for i in range(self.num_rows):
# The pre/post is to access the pin from "outside" the cell to avoid DRCs
decoder_out_pos = self.row_decoder_inst.get_pin("decode[{}]".format(i)).rc()
driver_in_pos = self.wordline_driver_inst.get_pin("in[{}]".format(i)).lc()
decoder_out_pos = self.row_decoder_inst.get_pin("decode_{}".format(i)).rc()
driver_in_pos = self.wordline_driver_inst.get_pin("in_{}".format(i)).lc()
mid1 = decoder_out_pos.scale(0.5,1)+driver_in_pos.scale(0.5,0)
mid2 = decoder_out_pos.scale(0.5,0)+driver_in_pos.scale(0.5,1)
self.add_path("metal1", [decoder_out_pos, mid1, mid2, driver_in_pos])
# The mid guarantees we exit the input cell to the right.
driver_wl_pos = self.wordline_driver_inst.get_pin("wl[{}]".format(i)).rc()
bitcell_wl_pos = self.bitcell_array_inst.get_pin("wl[{}]".format(i)).lc()
driver_wl_pos = self.wordline_driver_inst.get_pin("wl_{}".format(i)).rc()
bitcell_wl_pos = self.bitcell_array_inst.get_pin("wl_{}".format(i)).lc()
mid1 = driver_wl_pos.scale(0.5,1)+bitcell_wl_pos.scale(0.5,0)
mid2 = driver_wl_pos.scale(0.5,0)+bitcell_wl_pos.scale(0.5,1)
self.add_path("metal1", [driver_wl_pos, mid1, mid2, bitcell_wl_pos])
@ -677,20 +677,20 @@ class multibank(design.design):
elif self.col_addr_size > 1:
decode_names = []
for i in range(self.num_col_addr_lines):
decode_names.append("out[{}]".format(i))
decode_names.append("out_{}".format(i))
for i in range(self.col_addr_size):
decoder_name = "in[{}]".format(i)
addr_name = "A[{}]".format(i)
decoder_name = "in_{}".format(i)
addr_name = "A_{}".format(i)
self.copy_layout_pin(self.col_decoder_inst, decoder_name, addr_name)
# This will do a quick "river route" on two layers.
# When above the top select line it will offset "inward" again to prevent conflicts.
# This could be done on a single layer, but we follow preferred direction rules for later routing.
top_y_offset = self.col_mux_array_inst.get_pin("sel[{}]".format(self.num_col_addr_lines-1)).cy()
top_y_offset = self.col_mux_array_inst.get_pin("sel_{}".format(self.num_col_addr_lines-1)).cy()
for (decode_name,i) in zip(decode_names,range(self.num_col_addr_lines)):
mux_name = "sel[{}]".format(i)
mux_name = "sel_{}".format(i)
mux_addr_pos = self.col_mux_array_inst.get_pin(mux_name).lc()
decode_out_pos = self.col_decoder_inst.get_pin(decode_name).center()
@ -716,7 +716,7 @@ class multibank(design.design):
"""
# Add the wordline names
for i in range(self.num_rows):
wl_name = "wl[{}]".format(i)
wl_name = "wl_{}".format(i)
wl_pin = self.bitcell_array_inst.get_pin(wl_name)
self.add_label(text=wl_name,
layer="metal1",
@ -724,8 +724,8 @@ class multibank(design.design):
# Add the bitline names
for i in range(self.num_cols):
bl_name = "bl[{}]".format(i)
br_name = "br[{}]".format(i)
bl_name = "bl_{}".format(i)
br_name = "br_{}".format(i)
bl_pin = self.bitcell_array_inst.get_pin(bl_name)
br_pin = self.bitcell_array_inst.get_pin(br_name)
self.add_label(text=bl_name,
@ -737,16 +737,16 @@ class multibank(design.design):
# # Add the data output names to the sense amp output
# 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)
# self.add_label(text="sa_out[{}]".format(i),
# self.add_label(text="sa_out_{}".format(i),
# layer="metal2",
# offset=data_pin.center())
# Add labels on the decoder
for i in range(self.word_size):
data_name = "dec_out[{}]".format(i)
pin_name = "in[{}]".format(i)
data_name = "dec_out_{}".format(i)
pin_name = "in_{}".format(i)
data_pin = self.wordline_driver_inst.get_pin(pin_name)
self.add_label(text=data_name,
layer="metal1",

View File

@ -31,8 +31,8 @@ class precharge_array(design.design):
def add_pins(self):
"""Adds pins for spice file"""
for i in range(self.columns):
self.add_pin("bl[{0}]".format(i))
self.add_pin("br[{0}]".format(i))
self.add_pin("bl_{0}".format(i))
self.add_pin("br_{0}".format(i))
self.add_pin("en")
self.add_pin("vdd")
@ -71,13 +71,13 @@ class precharge_array(design.design):
for i in range(len(self.local_insts)):
inst = self.local_insts[i]
bl_pin = inst.get_pin("bl")
self.add_layout_pin(text="bl[{0}]".format(i),
self.add_layout_pin(text="bl_{0}".format(i),
layer="metal2",
offset=bl_pin.ll(),
width=drc["minwidth_metal2"],
height=bl_pin.height())
br_pin = inst.get_pin("br")
self.add_layout_pin(text="br[{0}]".format(i),
self.add_layout_pin(text="br_{0}".format(i),
layer="metal2",
offset=br_pin.ll(),
width=drc["minwidth_metal2"],
@ -94,7 +94,7 @@ class precharge_array(design.design):
mod=self.pc_cell,
offset=offset)
self.local_insts.append(inst)
self.connect_inst(["bl[{0}]".format(i), "br[{0}]".format(i), "en", "vdd"])
self.connect_inst(["bl_{0}".format(i), "br_{0}".format(i), "en", "vdd"])
def place_insts(self):

View File

@ -111,12 +111,12 @@ class replica_bitline(design.design):
# This is the threshold detect inverter on the output of the RBL
self.rbl_inv_inst=self.add_inst(name="rbl_inv",
mod=self.inv)
self.connect_inst(["bl0[0]", "out", "vdd", "gnd"])
self.connect_inst(["bl0_0", "out", "vdd", "gnd"])
self.tx_inst=self.add_inst(name="rbl_access_tx",
mod=self.access_tx)
# D, G, S, B
self.connect_inst(["vdd", "delayed_en", "bl0[0]", "vdd"])
self.connect_inst(["vdd", "delayed_en", "bl0_0", "vdd"])
# add the well and poly contact
self.dc_inst=self.add_inst(name="delay_chain",
@ -127,22 +127,22 @@ class replica_bitline(design.design):
mod=self.replica_bitcell)
temp = []
for port in range(self.total_ports):
temp.append("bl{}[0]".format(port))
temp.append("br{}[0]".format(port))
temp.append("bl{}_0".format(port))
temp.append("br{}_0".format(port))
for port in range(self.total_ports):
temp.append("delayed_en")
temp.append("vdd")
temp.append("gnd")
self.connect_inst(temp)
#self.connect_inst(["bl[0]", "br[0]", "delayed_en", "vdd", "gnd"])
#self.connect_inst(["bl_0", "br_0", "delayed_en", "vdd", "gnd"])
self.rbl_inst=self.add_inst(name="load",
mod=self.rbl)
temp = []
for port in range(self.total_ports):
temp.append("bl{}[0]".format(port))
temp.append("br{}[0]".format(port))
temp.append("bl{}_0".format(port))
temp.append("br{}_0".format(port))
for wl in range(self.bitcell_loads):
for port in range(self.total_ports):
temp.append("gnd")
@ -180,7 +180,7 @@ class replica_bitline(design.design):
""" Connect the RBL word lines to gnd """
# Connect the WL and gnd pins directly to the center and right gnd rails
for row in range(self.bitcell_loads):
wl = self.wl_list[0]+"[{}]".format(row)
wl = self.wl_list[0]+"_{}".format(row)
pin = self.rbl_inst.get_pin(wl)
# Route the connection to the right so that it doesn't interfere with the cells
@ -199,7 +199,7 @@ class replica_bitline(design.design):
self.add_power_pin("gnd", pin_extension2)
# for multiport, need to short wordlines to each other so they all connect to gnd
wl_last = self.wl_list[self.total_ports-1]+"[{}]".format(row)
wl_last = self.wl_list[self.total_ports-1]+"_{}".format(row)
pin_last = self.rbl_inst.get_pin(wl_last)
correct = vector(0.5*drc["minwidth_metal1"], 0)
@ -414,7 +414,7 @@ class replica_bitline(design.design):
# Connect the WL and gnd pins directly to the center and right gnd rails
for row in range(self.bitcell_loads):
wl = self.wl_list[0]+"[{}]".format(row)
wl = self.wl_list[0]+"_{}".format(row)
pin = self.rbl_inst.get_pin(wl)
if pin.layer != "metal1":
continue

View File

@ -43,9 +43,9 @@ class sense_amp_array(design.design):
def add_pins(self):
for i in range(0,self.word_size):
self.add_pin("data[{0}]".format(i))
self.add_pin("bl[{0}]".format(i))
self.add_pin("br[{0}]".format(i))
self.add_pin("data_{0}".format(i))
self.add_pin("bl_{0}".format(i))
self.add_pin("br_{0}".format(i))
self.add_pin("en")
self.add_pin("vdd")
self.add_pin("gnd")
@ -70,9 +70,9 @@ class sense_amp_array(design.design):
name = "sa_d{0}".format(i)
self.local_insts.append(self.add_inst(name=name,
mod=self.amp))
self.connect_inst(["bl[{0}]".format(i),
"br[{0}]".format(i),
"data[{0}]".format(i),
self.connect_inst(["bl_{0}".format(i),
"br_{0}".format(i),
"data_{0}".format(i),
"en", "vdd", "gnd"])
def place_sense_amp_array(self):
@ -107,18 +107,18 @@ class sense_amp_array(design.design):
br_pin = inst.get_pin("br")
dout_pin = inst.get_pin("dout")
self.add_layout_pin(text="bl[{0}]".format(i),
self.add_layout_pin(text="bl_{0}".format(i),
layer="metal2",
offset=bl_pin.ll(),
width=bl_pin.width(),
height=bl_pin.height())
self.add_layout_pin(text="br[{0}]".format(i),
self.add_layout_pin(text="br_{0}".format(i),
layer="metal2",
offset=br_pin.ll(),
width=br_pin.width(),
height=br_pin.height())
self.add_layout_pin(text="data[{0}]".format(i),
self.add_layout_pin(text="data_{0}".format(i),
layer="metal2",
offset=dout_pin.ll(),
width=dout_pin.width(),

View File

@ -50,13 +50,13 @@ class single_level_column_mux_array(design.design):
def add_pins(self):
for i in range(self.columns):
self.add_pin("bl[{}]".format(i))
self.add_pin("br[{}]".format(i))
self.add_pin("bl_{}".format(i))
self.add_pin("br_{}".format(i))
for i in range(self.words_per_row):
self.add_pin("sel[{}]".format(i))
self.add_pin("sel_{}".format(i))
for i in range(self.word_size):
self.add_pin("bl_out[{}]".format(i))
self.add_pin("br_out[{}]".format(i))
self.add_pin("bl_out_{}".format(i))
self.add_pin("br_out_{}".format(i))
self.add_pin("gnd")
@ -83,11 +83,11 @@ class single_level_column_mux_array(design.design):
self.mux_inst.append(self.add_inst(name=name,
mod=self.mux))
self.connect_inst(["bl[{}]".format(col_num),
"br[{}]".format(col_num),
"bl_out[{}]".format(int(col_num/self.words_per_row)),
"br_out[{}]".format(int(col_num/self.words_per_row)),
"sel[{}]".format(col_num % self.words_per_row),
self.connect_inst(["bl_{}".format(col_num),
"br_{}".format(col_num),
"bl_out_{}".format(int(col_num/self.words_per_row)),
"br_out_{}".format(int(col_num/self.words_per_row)),
"sel_{}".format(col_num % self.words_per_row),
"gnd"])
def place_array(self):
@ -104,13 +104,13 @@ class single_level_column_mux_array(design.design):
for col_num in range(self.columns):
mux_inst = self.mux_inst[col_num]
offset = mux_inst.get_pin("bl").ll()
self.add_layout_pin(text="bl[{}]".format(col_num),
self.add_layout_pin(text="bl_{}".format(col_num),
layer="metal2",
offset=offset,
height=self.height-offset.y)
offset = mux_inst.get_pin("br").ll()
self.add_layout_pin(text="br[{}]".format(col_num),
self.add_layout_pin(text="br_{}".format(col_num),
layer="metal2",
offset=offset,
height=self.height-offset.y)
@ -128,7 +128,7 @@ class single_level_column_mux_array(design.design):
""" Create address input rails on M1 below the mux transistors """
for j in range(self.words_per_row):
offset = vector(0, self.route_height + (j-self.words_per_row)*self.m1_pitch)
self.add_layout_pin(text="sel[{}]".format(j),
self.add_layout_pin(text="sel_{}".format(j),
layer="metal1",
offset=offset,
width=self.mux.width * self.columns,
@ -144,9 +144,9 @@ class single_level_column_mux_array(design.design):
# Add the column x offset to find the right select bit
gate_offset = self.mux_inst[col].get_pin("sel").bc()
# height to connect the gate to the correct horizontal row
sel_height = self.get_pin("sel[{}]".format(sel_index)).by()
sel_height = self.get_pin("sel_{}".format(sel_index)).by()
# use the y offset from the sel pin and the x offset from the gate
offset = vector(gate_offset.x,self.get_pin("sel[{}]".format(sel_index)).cy())
offset = vector(gate_offset.x,self.get_pin("sel_{}".format(sel_index)).cy())
# Add the poly contact with a shift to account for the rotation
self.add_via_center(layers=("metal1", "contact", "poly"),
offset=offset,
@ -178,12 +178,12 @@ class single_level_column_mux_array(design.design):
# Extend the bitline output rails and gnd downward on the first bit of each n-way mux
self.add_layout_pin(text="bl_out[{}]".format(int(j/self.words_per_row)),
self.add_layout_pin(text="bl_out_{}".format(int(j/self.words_per_row)),
layer="metal2",
offset=bl_out_offset.scale(1,0),
width=drc['minwidth_metal2'],
height=self.route_height)
self.add_layout_pin(text="br_out[{}]".format(int(j/self.words_per_row)),
self.add_layout_pin(text="br_out_{}".format(int(j/self.words_per_row)),
layer="metal2",
offset=br_out_offset.scale(1,0),
width=drc['minwidth_metal2'],

View File

@ -45,9 +45,9 @@ class tri_gate_array(design.design):
def add_pins(self):
"""create the name of pins depend on the word size"""
for i in range(self.word_size):
self.add_pin("in[{0}]".format(i))
self.add_pin("in_{0}".format(i))
for i in range(self.word_size):
self.add_pin("out[{0}]".format(i))
self.add_pin("out_{0}".format(i))
for pin in ["en", "en_bar", "vdd", "gnd"]:
self.add_pin(pin)
@ -59,8 +59,8 @@ class tri_gate_array(design.design):
self.tri_inst[i]=self.add_inst(name=name,
mod=self.tri)
index = int(i/self.words_per_row)
self.connect_inst(["in[{0}]".format(index),
"out[{0}]".format(index),
self.connect_inst(["in_{0}".format(index),
"out_{0}".format(index),
"en", "en_bar", "vdd", "gnd"])
def place_array(self):
@ -76,14 +76,14 @@ class tri_gate_array(design.design):
index = int(i/self.words_per_row)
in_pin = self.tri_inst[i].get_pin("in")
self.add_layout_pin(text="in[{0}]".format(index),
self.add_layout_pin(text="in_{0}".format(index),
layer="metal2",
offset=in_pin.ll(),
width=in_pin.width(),
height=in_pin.height())
out_pin = self.tri_inst[i].get_pin("out")
self.add_layout_pin(text="out[{0}]".format(index),
self.add_layout_pin(text="out_{0}".format(index),
layer="metal2",
offset=out_pin.ll(),
width=out_pin.width(),

View File

@ -40,10 +40,10 @@ class wordline_driver(design.design):
def add_pins(self):
# inputs to wordline_driver.
for i in range(self.rows):
self.add_pin("in[{0}]".format(i))
self.add_pin("in_{0}".format(i))
# Outputs from wordline_driver.
for i in range(self.rows):
self.add_pin("wl[{0}]".format(i))
self.add_pin("wl_{0}".format(i))
self.add_pin("en")
self.add_pin("vdd")
self.add_pin("gnd")
@ -107,20 +107,20 @@ class wordline_driver(design.design):
self.inv1_inst.append(self.add_inst(name=name_inv1,
mod=self.inv_no_output))
self.connect_inst(["en",
"en_bar[{0}]".format(row),
"en_bar_{0}".format(row),
"vdd", "gnd"])
# add nand 2
self.nand_inst.append(self.add_inst(name=name_nand,
mod=self.nand2))
self.connect_inst(["en_bar[{0}]".format(row),
"in[{0}]".format(row),
"wl_bar[{0}]".format(row),
self.connect_inst(["en_bar_{0}".format(row),
"in_{0}".format(row),
"wl_bar_{0}".format(row),
"vdd", "gnd"])
# add inv2
self.inv2_inst.append(self.add_inst(name=name_inv2,
mod=self.inv))
self.connect_inst(["wl_bar[{0}]".format(row),
"wl[{0}]".format(row),
self.connect_inst(["wl_bar_{0}".format(row),
"wl_{0}".format(row),
"vdd", "gnd"])
@ -205,7 +205,7 @@ class wordline_driver(design.design):
input_offset = vector(0,b_pos.y + up_or_down)
mid_via_offset = vector(clk_offset.x,input_offset.y) + vector(0.5*self.m2_width+self.m2_space+0.5*contact.m1m2.width,0)
# must under the clk line in M1
self.add_layout_pin_segment_center(text="in[{0}]".format(row),
self.add_layout_pin_segment_center(text="in_{0}".format(row),
layer="metal1",
start=input_offset,
end=mid_via_offset)
@ -221,7 +221,7 @@ class wordline_driver(design.design):
# output each WL on the right
wl_offset = inv2_inst.get_pin("Z").rc()
self.add_layout_pin_segment_center(text="wl[{0}]".format(row),
self.add_layout_pin_segment_center(text="wl_{0}".format(row),
layer="metal1",
start=wl_offset,
end=wl_offset-vector(self.m1_width,0))

View File

@ -44,10 +44,10 @@ class write_driver_array(design.design):
def add_pins(self):
for i in range(self.word_size):
self.add_pin("data[{0}]".format(i))
self.add_pin("data_{0}".format(i))
for i in range(self.word_size):
self.add_pin("bl[{0}]".format(i))
self.add_pin("br[{0}]".format(i))
self.add_pin("bl_{0}".format(i))
self.add_pin("br_{0}".format(i))
self.add_pin("en")
self.add_pin("vdd")
self.add_pin("gnd")
@ -73,9 +73,9 @@ class write_driver_array(design.design):
self.driver_insts[index]=self.add_inst(name=name,
mod=self.driver)
self.connect_inst(["data[{0}]".format(index),
"bl[{0}]".format(index),
"br[{0}]".format(index),
self.connect_inst(["data_{0}".format(index),
"bl_{0}".format(index),
"br_{0}".format(index),
"en", "vdd", "gnd"])
@ -94,20 +94,20 @@ class write_driver_array(design.design):
def add_layout_pins(self):
for i in range(self.word_size):
din_pin = self.driver_insts[i].get_pin("din")
self.add_layout_pin(text="data[{0}]".format(i),
self.add_layout_pin(text="data_{0}".format(i),
layer="metal2",
offset=din_pin.ll(),
width=din_pin.width(),
height=din_pin.height())
bl_pin = self.driver_insts[i].get_pin("bl")
self.add_layout_pin(text="bl[{0}]".format(i),
self.add_layout_pin(text="bl_{0}".format(i),
layer="metal2",
offset=bl_pin.ll(),
width=bl_pin.width(),
height=bl_pin.height())
br_pin = self.driver_insts[i].get_pin("br")
self.add_layout_pin(text="br[{0}]".format(i),
self.add_layout_pin(text="br_{0}".format(i),
layer="metal2",
offset=br_pin.ll(),
width=br_pin.width(),

View File

@ -100,17 +100,17 @@ class sram_1bank(sram_base):
self.copy_layout_pin(self.control_logic_inst[port], signal, signal+"{}".format(port))
for bit in range(self.word_size):
self.copy_layout_pin(self.bank_inst, "dout{0}[{1}]".format(port,bit), "DOUT{0}[{1}]".format(port,bit))
self.copy_layout_pin(self.bank_inst, "dout{0}_{1}".format(port,bit), "DOUT{0}[{1}]".format(port,bit))
# Lower address bits
for bit in range(self.col_addr_size):
self.copy_layout_pin(self.col_addr_dff_inst[port], "din[{}]".format(bit),"ADDR{0}[{1}]".format(port,bit))
self.copy_layout_pin(self.col_addr_dff_inst[port], "din_{}".format(bit),"ADDR{0}[{1}]".format(port,bit))
# Upper address bits
for bit in range(self.row_addr_size):
self.copy_layout_pin(self.row_addr_dff_inst[port], "din[{}]".format(bit),"ADDR{0}[{1}]".format(port,bit+self.col_addr_size))
self.copy_layout_pin(self.row_addr_dff_inst[port], "din_{}".format(bit),"ADDR{0}[{1}]".format(port,bit+self.col_addr_size))
for bit in range(self.word_size):
self.copy_layout_pin(self.data_dff_inst[port], "din[{}]".format(bit), "DIN{0}[{1}]".format(port,bit))
self.copy_layout_pin(self.data_dff_inst[port], "din_{}".format(bit), "DIN{0}[{1}]".format(port,bit))
def route(self):
""" Route a single bank SRAM """
@ -186,8 +186,8 @@ class sram_1bank(sram_base):
""" Connect the output of the row flops to the bank pins """
for port in range(self.total_ports):
for bit in range(self.row_addr_size):
flop_name = "dout[{}]".format(bit)
bank_name = "addr{0}[{1}]".format(port,bit+self.col_addr_size)
flop_name = "dout_{}".format(bit)
bank_name = "addr{0}_{1}".format(port,bit+self.col_addr_size)
flop_pin = self.row_addr_dff_inst[port].get_pin(flop_name)
bank_pin = self.bank_inst.get_pin(bank_name)
flop_pos = flop_pin.center()
@ -201,18 +201,18 @@ class sram_1bank(sram_base):
def route_col_addr_dff(self):
""" Connect the output of the row flops to the bank pins """
for port in range(self.total_ports):
bus_names = ["addr[{}]".format(x) for x in range(self.col_addr_size)]
bus_names = ["addr_{}".format(x) for x in range(self.col_addr_size)]
col_addr_bus_offsets = self.create_horizontal_bus(layer="metal1",
pitch=self.m1_pitch,
offset=self.col_addr_dff_inst[port].ul() + vector(0, self.m1_pitch),
names=bus_names,
length=self.col_addr_dff_inst[port].width)
dff_names = ["dout[{}]".format(x) for x in range(self.col_addr_size)]
dff_names = ["dout_{}".format(x) for x in range(self.col_addr_size)]
data_dff_map = zip(dff_names, bus_names)
self.connect_horizontal_bus(data_dff_map, self.col_addr_dff_inst[port], col_addr_bus_offsets)
bank_names = ["addr{0}[{1}]".format(port,x) for x in range(self.col_addr_size)]
bank_names = ["addr{0}_{1}".format(port,x) for x in range(self.col_addr_size)]
data_bank_map = zip(bank_names, bus_names)
self.connect_horizontal_bus(data_bank_map, self.bank_inst, col_addr_bus_offsets)
@ -223,8 +223,8 @@ class sram_1bank(sram_base):
for port in range(self.total_write):
offset = self.data_dff_inst[port].ul() + vector(0, self.m1_pitch)
dff_names = ["dout[{}]".format(x) for x in range(self.word_size)]
bank_names = ["din{0}[{1}]".format(port,x) for x in range(self.word_size)]
dff_names = ["dout_{}".format(x) for x in range(self.word_size)]
bank_names = ["din{0}_{1}".format(port,x) for x in range(self.word_size)]
route_map = list(zip(bank_names, dff_names))
dff_pins = {key: self.data_dff_inst[port].get_pin(key) for key in dff_names }

View File

@ -123,7 +123,7 @@ class sram_4bank(sram_base):
# connect the MSB flops to the address input bus
for i in [0,1]:
msb_pins = self.msb_address_inst.get_pins("din[{}]".format(i))
msb_pins = self.msb_address_inst.get_pins("din_{}".format(i))
for msb_pin in msb_pins:
if msb_pin.layer == "metal3":
msb_pin_pos = msb_pin.lc()
@ -141,7 +141,7 @@ class sram_4bank(sram_base):
# Connect bank decoder outputs to the bank select vertical bus wires
for i in range(self.num_banks):
msb_pin = self.msb_decoder_inst.get_pin("out[{}]".format(i))
msb_pin = self.msb_decoder_inst.get_pin("out_{}".format(i))
msb_pin_pos = msb_pin.lc()
rail_pos = vector(self.vert_control_bus_positions["bank_sel[{}]".format(i)].x,msb_pin_pos.y)
self.add_path("metal1",[msb_pin_pos,rail_pos])

View File

@ -158,7 +158,7 @@ class sram_base(design):
length=self.addr_bus_height))
self.bank_sel_bus_names = ["bank_sel{0}[{1}]".format(port,i) for i in range(self.num_banks)]
self.bank_sel_bus_names = ["bank_sel{0}_{1}".format(port,i) for i in range(self.num_banks)]
self.vert_control_bus_positions.update(self.create_vertical_pin_bus(layer="metal2",
pitch=self.m2_pitch,
offset=self.bank_sel_bus_offset,