mirror of https://github.com/VLSIDA/OpenRAM.git
Merge branch 'multiport' into supply_routing
This commit is contained in:
commit
a094db9077
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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])
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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):
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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):
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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(),
|
||||
|
|
|
|||
|
|
@ -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'],
|
||||
|
|
|
|||
|
|
@ -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(),
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
|
|
|
|||
|
|
@ -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(),
|
||||
|
|
|
|||
|
|
@ -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 }
|
||||
|
|
|
|||
|
|
@ -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])
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
Loading…
Reference in New Issue