mirror of https://github.com/VLSIDA/OpenRAM.git
Move label pins to center like layout pins.
Rework of control logic with vertical poly. Passes DRC/LVS. Single bank passing DRC.
This commit is contained in:
parent
8ca9ba4244
commit
b867e163a6
|
|
@ -282,7 +282,7 @@ class layout(lef.lef):
|
|||
height=height)
|
||||
self.add_label(text=text,
|
||||
layer=layer,
|
||||
offset=offset)
|
||||
offset=offset+vector(0.5*width,0.5*height))
|
||||
|
||||
|
||||
def add_label(self, text, layer, offset=[0,0],zoom=-1):
|
||||
|
|
|
|||
|
|
@ -60,6 +60,24 @@ class spice(verilog.verilog):
|
|||
else:
|
||||
return self.pin_type[name]
|
||||
|
||||
def get_inputs(self):
|
||||
""" These use pin types to determine pin lists. These
|
||||
may be over-ridden by submodules that didn't use pin directions yet."""
|
||||
input_list = []
|
||||
for pin in self.pins:
|
||||
if self.pin_type[pin]=="INPUT":
|
||||
input_list.append(pin)
|
||||
return input_list
|
||||
|
||||
def get_outputs(self):
|
||||
""" These use pin types to determine pin lists. These
|
||||
may be over-ridden by submodules that didn't use pin directions yet."""
|
||||
output_list = []
|
||||
for pin in self.pins:
|
||||
if self.pin_type[pin]=="OUTPUT":
|
||||
output_list.append(pin)
|
||||
return output_list
|
||||
|
||||
|
||||
def add_mod(self, mod):
|
||||
"""Adds a subckt/submodule to the subckt hierarchy"""
|
||||
|
|
|
|||
|
|
@ -74,17 +74,19 @@ class bank(design.design):
|
|||
def add_pins(self):
|
||||
""" Adding pins for Bank module"""
|
||||
for i in range(self.word_size):
|
||||
self.add_pin("DATA[{0}]".format(i))
|
||||
self.add_pin("DATA[{0}]".format(i),"INOUT")
|
||||
for i in range(self.addr_size):
|
||||
self.add_pin("A[{0}]".format(i))
|
||||
self.add_pin("A[{0}]".format(i),"INPUT")
|
||||
|
||||
# For more than one bank, we have a bank select and name
|
||||
# the signals gated_*.
|
||||
if self.num_banks > 1:
|
||||
self.add_pin("bank_sel")
|
||||
self.add_pin("bank_sel","INPUT")
|
||||
for pin in ["s_en","w_en","tri_en_bar","tri_en",
|
||||
"clk_bar","clk_buf","vdd","gnd"]:
|
||||
self.add_pin(pin)
|
||||
"clk_buf_bar","clk_buf"]:
|
||||
self.add_pin(pin,"INPUT")
|
||||
self.add_pin("vdd","POWER")
|
||||
self.add_pin("gnd","GROUND")
|
||||
|
||||
def route_layout(self):
|
||||
""" Create routing amoung the modules """
|
||||
|
|
@ -151,7 +153,7 @@ class bank(design.design):
|
|||
# Number of control lines in the bus
|
||||
self.num_control_lines = 6
|
||||
# The order of the control signals on the control bus:
|
||||
self.input_control_signals = ["clk_buf", "tri_en_bar", "tri_en", "clk_bar", "w_en", "s_en"]
|
||||
self.input_control_signals = ["clk_buf", "tri_en_bar", "tri_en", "clk_buf_bar", "w_en", "s_en"]
|
||||
# These will be outputs of the gaters if this is multibank, if not, normal signals.
|
||||
if self.num_banks > 1:
|
||||
self.control_signals = ["gated_"+str for str in self.input_control_signals]
|
||||
|
|
@ -259,7 +261,7 @@ class bank(design.design):
|
|||
for i in range(self.num_cols):
|
||||
temp.append("bl[{0}]".format(i))
|
||||
temp.append("br[{0}]".format(i))
|
||||
temp.extend([self.prefix+"clk_bar", "vdd"])
|
||||
temp.extend([self.prefix+"clk_buf_bar", "vdd"])
|
||||
self.connect_inst(temp)
|
||||
|
||||
def add_column_mux_array(self):
|
||||
|
|
@ -337,7 +339,7 @@ class bank(design.design):
|
|||
for i in range(self.word_size):
|
||||
temp.append("data_in[{0}]".format(i))
|
||||
temp.append("data_in_bar[{0}]".format(i))
|
||||
temp.extend([self.prefix+"clk_bar", "vdd", "gnd"])
|
||||
temp.extend([self.prefix+"clk_buf_bar", "vdd", "gnd"])
|
||||
self.connect_inst(temp)
|
||||
|
||||
def add_tri_gate_array(self):
|
||||
|
|
@ -534,8 +536,8 @@ class bank(design.design):
|
|||
# Add a vdd and gnd power rail above the array
|
||||
self.max_point += self.supply_rail_pitch + self.supply_rail_width
|
||||
|
||||
self.height = self.max_point - self.min_point
|
||||
self.width = self.right_vdd_x_offset - self.left_gnd_x_offset + self.supply_rail_width
|
||||
self.height = ur.y - ll.y + 4*self.supply_rail_pitch
|
||||
self.width = ur.x - ll.x + 4*self.supply_rail_pitch
|
||||
|
||||
|
||||
|
||||
|
|
@ -894,10 +896,10 @@ class bank(design.design):
|
|||
# Connection from the central bus to the main control block crosses
|
||||
# pre-decoder and this connection is in metal3
|
||||
connection = []
|
||||
connection.append((self.prefix+"clk_bar", self.msf_data_in_inst.get_pin("clk").lc()))
|
||||
connection.append((self.prefix+"clk_buf_bar", self.msf_data_in_inst.get_pin("clk").lc()))
|
||||
connection.append((self.prefix+"tri_en_bar", self.tri_gate_array_inst.get_pin("en_bar").lc()))
|
||||
connection.append((self.prefix+"tri_en", self.tri_gate_array_inst.get_pin("en").lc()))
|
||||
connection.append((self.prefix+"clk_bar", self.precharge_array_inst.get_pin("en").lc()))
|
||||
connection.append((self.prefix+"clk_buf_bar", self.precharge_array_inst.get_pin("en").lc()))
|
||||
connection.append((self.prefix+"w_en", self.write_driver_array_inst.get_pin("en").lc()))
|
||||
connection.append((self.prefix+"s_en", self.sense_amp_array_inst.get_pin("en").lc()))
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -41,8 +41,12 @@ class replica_bitline(design.design):
|
|||
self.offset_all_coordinates()
|
||||
|
||||
self.add_layout_pins()
|
||||
|
||||
#self.add_lvs_correspondence_points()
|
||||
|
||||
self.width = self.right_gnd_pin.rx() - self.left_gnd_pin.lx()
|
||||
self.height = self.left_gnd_pin.uy() - self.left_gnd_pin.by()
|
||||
|
||||
self.DRC_LVS()
|
||||
|
||||
def calculate_module_offsets(self):
|
||||
|
|
@ -124,9 +128,6 @@ class replica_bitline(design.design):
|
|||
self.connect_inst(["bl[0]", "br[0]"] + ["gnd"]*self.bitcell_loads + ["vdd", "gnd"])
|
||||
|
||||
|
||||
self.height = max(self.rbl_inst.uy(),self.dc_inst.uy()) + self.m2_pitch
|
||||
self.width = self.rbl_inst.rx() + self.m2_width
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -209,46 +210,28 @@ class replica_bitline(design.design):
|
|||
# Route the vdd lines from left to right
|
||||
|
||||
# Add via for the delay chain
|
||||
left_vdd_start = self.dc_inst.ll().scale(1,0) - vector(2*self.m2_pitch,2*self.m2_pitch)
|
||||
left_vdd_end = vector(left_vdd_start.x, self.rbl_inst.uy()+2*self.m2_pitch)
|
||||
left_vdd_pin=self.add_layout_pin_center_segment(text="vdd",
|
||||
layer="metal2",
|
||||
start=left_vdd_start,
|
||||
end=left_vdd_end)
|
||||
self.add_via_center(layers=("metal1", "via1", "metal2"),
|
||||
offset=left_vdd_start,
|
||||
rotate=90)
|
||||
self.add_via_center(layers=("metal1", "via1", "metal2"),
|
||||
offset=left_vdd_end,
|
||||
rotate=90)
|
||||
left_vdd_start = self.dc_inst.ll().scale(1,0)
|
||||
left_vdd_end = vector(left_vdd_start.x, self.rbl_inst.uy())
|
||||
self.left_vdd_pin=self.add_layout_pin_center_segment(text="vdd",
|
||||
layer="metal2",
|
||||
start=left_vdd_start,
|
||||
end=left_vdd_end)
|
||||
|
||||
# Vdd line to the left of the replica bitline
|
||||
center_vdd_start = self.rbc_inst.ll() - vector(3*self.m2_pitch,2*self.m2_pitch)
|
||||
center_vdd_end = vector(center_vdd_start.x, self.rbl_inst.uy()+2*self.m2_pitch)
|
||||
center_vdd_pin=self.add_layout_pin_center_segment(text="vdd",
|
||||
layer="metal2",
|
||||
start=center_vdd_start,
|
||||
end=center_vdd_end)
|
||||
self.add_via_center(layers=("metal1", "via1", "metal2"),
|
||||
offset=center_vdd_start,
|
||||
rotate=90)
|
||||
self.add_via_center(layers=("metal1", "via1", "metal2"),
|
||||
offset=center_vdd_end,
|
||||
rotate=90)
|
||||
center_vdd_start = self.rbc_inst.ll() - vector(3*self.m2_pitch,0)
|
||||
center_vdd_end = vector(center_vdd_start.x, self.rbl_inst.uy())
|
||||
self.center_vdd_pin=self.add_layout_pin_center_segment(text="vdd",
|
||||
layer="metal2",
|
||||
start=center_vdd_start,
|
||||
end=center_vdd_end)
|
||||
|
||||
# Vdd line to the right of the replica bitline
|
||||
right_vdd_start = self.rbc_inst.lr() + vector(2*self.m2_pitch,-2*self.m2_pitch)
|
||||
right_vdd_end = vector(right_vdd_start.x, self.rbl_inst.uy()+2*self.m2_pitch)
|
||||
right_vdd_pin=self.add_layout_pin_center_segment(text="vdd",
|
||||
layer="metal2",
|
||||
start=right_vdd_start,
|
||||
end=right_vdd_end)
|
||||
self.add_via_center(layers=("metal1", "via1", "metal2"),
|
||||
offset=right_vdd_start,
|
||||
rotate=90)
|
||||
self.add_via_center(layers=("metal1", "via1", "metal2"),
|
||||
offset=right_vdd_end,
|
||||
rotate=90)
|
||||
right_vdd_start = self.rbc_inst.lr() + vector(2*self.m2_pitch,0)
|
||||
right_vdd_end = vector(right_vdd_start.x, self.rbl_inst.uy())
|
||||
self.right_vdd_pin=self.add_layout_pin_center_segment(text="vdd",
|
||||
layer="metal2",
|
||||
start=right_vdd_start,
|
||||
end=right_vdd_end)
|
||||
|
||||
|
||||
|
||||
|
|
@ -258,8 +241,8 @@ class replica_bitline(design.design):
|
|||
for pin in rbl_vdd_pins:
|
||||
if pin.layer != "metal1":
|
||||
continue
|
||||
start = vector(center_vdd_pin.cx(),pin.cy())
|
||||
end = vector(right_vdd_pin.cx(),pin.cy())
|
||||
start = vector(self.center_vdd_pin.cx(),pin.cy())
|
||||
end = vector(self.right_vdd_pin.cx(),pin.cy())
|
||||
self.add_segment_center(layer="metal1",
|
||||
start=start,
|
||||
end=end)
|
||||
|
|
@ -277,7 +260,7 @@ class replica_bitline(design.design):
|
|||
for pin in dc_vdd_pins:
|
||||
if pin.layer != "metal1":
|
||||
continue
|
||||
start = vector(left_vdd_pin.cx(),pin.cy())
|
||||
start = vector(self.left_vdd_pin.cx(),pin.cy())
|
||||
# Note, we don't connect to center because of via conflicts
|
||||
# with the RBL pins
|
||||
#end = vector(center_vdd_pin.cx(),pin.cy())
|
||||
|
|
@ -289,15 +272,11 @@ class replica_bitline(design.design):
|
|||
offset=start,
|
||||
rotate=90)
|
||||
|
||||
# self.add_via_center(layers=("metal1", "via1", "metal2"),
|
||||
# offset=end,
|
||||
#rotate=90)
|
||||
|
||||
|
||||
# Add via for the inverter
|
||||
pin = self.rbl_inv_inst.get_pin("vdd")
|
||||
start = vector(left_vdd_pin.cx(),pin.cy())
|
||||
end = vector(center_vdd_pin.cx(),pin.cy())
|
||||
start = vector(self.left_vdd_pin.cx(),pin.cy())
|
||||
end = vector(self.center_vdd_pin.cx(),pin.cy())
|
||||
self.add_segment_center(layer="metal1",
|
||||
start=start,
|
||||
end=end)
|
||||
|
|
@ -313,7 +292,7 @@ class replica_bitline(design.design):
|
|||
# Add via for the RBC
|
||||
pin = self.rbc_inst.get_pin("vdd")
|
||||
start = pin.lc()
|
||||
end = vector(right_vdd_pin.cx(),pin.cy())
|
||||
end = vector(self.right_vdd_pin.cx(),pin.cy())
|
||||
self.add_segment_center(layer="metal1",
|
||||
start=start,
|
||||
end=end)
|
||||
|
|
@ -321,34 +300,18 @@ class replica_bitline(design.design):
|
|||
offset=end,
|
||||
rotate=90)
|
||||
|
||||
# Connect the RBL rails at the top and bottom
|
||||
# Create the RBL rails too
|
||||
rbl_pins = self.rbl_inst.get_pins("vdd")
|
||||
for pin in rbl_pins:
|
||||
if pin.layer != "metal2":
|
||||
continue
|
||||
end = vector(pin.cx(),right_vdd_pin.uy())
|
||||
self.add_segment_center(layer="metal2",
|
||||
start=pin.uc(),
|
||||
end=end)
|
||||
self.add_via_center(layers=("metal1", "via1", "metal2"),
|
||||
offset=end,
|
||||
rotate=90)
|
||||
|
||||
start = vector(pin.cx(),right_vdd_pin.by())
|
||||
self.add_segment_center(layer="metal2",
|
||||
start=pin.bc(),
|
||||
end=start)
|
||||
self.add_via_center(layers=("metal1", "via1", "metal2"),
|
||||
offset=start,
|
||||
rotate=90)
|
||||
start = vector(pin.cx(),self.right_vdd_pin.by())
|
||||
end = vector(pin.cx(),self.right_vdd_pin.uy())
|
||||
self.add_layout_pin_center_segment(text="vdd",
|
||||
layer="metal2",
|
||||
start=start,
|
||||
end=end)
|
||||
|
||||
# Connect the rails at the top and bottom
|
||||
self.add_segment_center(layer="metal1",
|
||||
start=left_vdd_end,
|
||||
end=right_vdd_end)
|
||||
self.add_segment_center(layer="metal1",
|
||||
start=left_vdd_start,
|
||||
end=right_vdd_start)
|
||||
|
||||
|
||||
|
||||
|
|
@ -359,46 +322,28 @@ class replica_bitline(design.design):
|
|||
# Route the gnd lines from left to right
|
||||
|
||||
# Add via for the delay chain
|
||||
left_gnd_start = self.dc_inst.ll().scale(1,0) - vector(self.m2_pitch,self.m2_pitch)
|
||||
left_gnd_start = self.dc_inst.ll().scale(1,0) - vector(self.m2_pitch,0)
|
||||
left_gnd_end = vector(left_gnd_start.x, self.rbl_inst.uy()+self.m2_pitch)
|
||||
left_gnd_pin=self.add_layout_pin_center_segment(text="gnd",
|
||||
layer="metal2",
|
||||
start=left_gnd_start,
|
||||
end=left_gnd_end)
|
||||
self.add_via_center(layers=("metal1", "via1", "metal2"),
|
||||
offset=left_gnd_start,
|
||||
rotate=90)
|
||||
self.add_via_center(layers=("metal1", "via1", "metal2"),
|
||||
offset=left_gnd_end,
|
||||
rotate=90)
|
||||
self.left_gnd_pin=self.add_layout_pin_center_segment(text="gnd",
|
||||
layer="metal2",
|
||||
start=left_gnd_start,
|
||||
end=left_gnd_end)
|
||||
|
||||
# Gnd line to the left of the replica bitline
|
||||
center_gnd_start = self.rbc_inst.ll().scale(1,0) - vector(2*self.m2_pitch,self.m2_pitch)
|
||||
center_gnd_start = self.rbc_inst.ll().scale(1,0) - vector(2*self.m2_pitch,0)
|
||||
center_gnd_end = vector(center_gnd_start.x, self.rbl_inst.uy()+self.m2_pitch)
|
||||
center_gnd_pin=self.add_layout_pin_center_segment(text="gnd",
|
||||
layer="metal2",
|
||||
start=center_gnd_start,
|
||||
end=center_gnd_end)
|
||||
self.add_via_center(layers=("metal1", "via1", "metal2"),
|
||||
offset=center_gnd_start,
|
||||
rotate=90)
|
||||
self.add_via_center(layers=("metal1", "via1", "metal2"),
|
||||
offset=center_gnd_end,
|
||||
rotate=90)
|
||||
self.center_gnd_pin=self.add_layout_pin_center_segment(text="gnd",
|
||||
layer="metal2",
|
||||
start=center_gnd_start,
|
||||
end=center_gnd_end)
|
||||
|
||||
# Gnd line to the right of the replica bitline
|
||||
right_gnd_start = self.rbc_inst.lr().scale(1,0) + vector(self.m2_pitch,-self.m2_pitch)
|
||||
right_gnd_start = self.rbc_inst.lr().scale(1,0) + vector(self.m2_pitch,0)
|
||||
right_gnd_end = vector(right_gnd_start.x, self.rbl_inst.uy()+self.m2_pitch)
|
||||
right_gnd_pin=self.add_layout_pin_center_segment(text="gnd",
|
||||
layer="metal2",
|
||||
start=right_gnd_start,
|
||||
end=right_gnd_end)
|
||||
self.add_via_center(layers=("metal1", "via1", "metal2"),
|
||||
offset=right_gnd_start,
|
||||
rotate=90)
|
||||
self.add_via_center(layers=("metal1", "via1", "metal2"),
|
||||
offset=right_gnd_end,
|
||||
rotate=90)
|
||||
self.right_gnd_pin=self.add_layout_pin_center_segment(text="gnd",
|
||||
layer="metal2",
|
||||
start=right_gnd_start,
|
||||
end=right_gnd_end)
|
||||
|
||||
|
||||
|
||||
|
|
@ -408,8 +353,8 @@ class replica_bitline(design.design):
|
|||
pin = self.rbl_inst.get_pin(wl)
|
||||
if pin.layer != "metal1":
|
||||
continue
|
||||
start = vector(center_gnd_pin.cx(),pin.cy())
|
||||
end = vector(right_gnd_pin.cx(),pin.cy())
|
||||
start = vector(self.center_gnd_pin.cx(),pin.cy())
|
||||
end = vector(self.right_gnd_pin.cx(),pin.cy())
|
||||
self.add_segment_center(layer="metal1",
|
||||
start=start,
|
||||
end=end)
|
||||
|
|
@ -426,8 +371,8 @@ class replica_bitline(design.design):
|
|||
for pin in rbl_gnd_pins:
|
||||
if pin.layer != "metal1":
|
||||
continue
|
||||
start = vector(center_gnd_pin.cx(),pin.cy())
|
||||
end = vector(right_gnd_pin.cx(),pin.cy())
|
||||
start = vector(self.center_gnd_pin.cx(),pin.cy())
|
||||
end = vector(self.right_gnd_pin.cx(),pin.cy())
|
||||
self.add_segment_center(layer="metal1",
|
||||
start=start,
|
||||
end=end)
|
||||
|
|
@ -445,10 +390,10 @@ class replica_bitline(design.design):
|
|||
for pin in dc_gnd_pins:
|
||||
if pin.layer != "metal1":
|
||||
continue
|
||||
start = vector(left_gnd_pin.cx(),pin.cy())
|
||||
start = vector(self.left_gnd_pin.cx(),pin.cy())
|
||||
# Note, we don't connect to the center rails because of
|
||||
# via conflicts with the RBL
|
||||
#end = vector(center_gnd_pin.cx(),pin.cy())
|
||||
#end = vector(self.center_gnd_pin.cx(),pin.cy())
|
||||
end = pin.rc()
|
||||
self.add_segment_center(layer="metal1",
|
||||
start=start,
|
||||
|
|
@ -464,8 +409,8 @@ class replica_bitline(design.design):
|
|||
|
||||
# Add via for the inverter
|
||||
# pin = self.rbl_inv_inst.get_pin("gnd")
|
||||
# start = vector(left_gnd_pin.cx(),pin.cy())
|
||||
# end = vector(center_gnd_pin.cx(),pin.cy())
|
||||
# start = vector(self.left_gnd_pin.cx(),pin.cy())
|
||||
# end = vector(self.center_gnd_pin.cx(),pin.cy())
|
||||
# self.add_segment_center(layer="metal1",
|
||||
# start=start,
|
||||
# end=end)
|
||||
|
|
@ -478,35 +423,18 @@ class replica_bitline(design.design):
|
|||
|
||||
|
||||
|
||||
# Connect the RBL rails at the top and bottom
|
||||
# Create RBL rails too
|
||||
rbl_pins = self.rbl_inst.get_pins("gnd")
|
||||
for pin in rbl_pins:
|
||||
if pin.layer != "metal2":
|
||||
continue
|
||||
end = vector(pin.cx(),right_gnd_pin.uy())
|
||||
self.add_segment_center(layer="metal2",
|
||||
start=pin.uc(),
|
||||
end=end)
|
||||
self.add_via_center(layers=("metal1", "via1", "metal2"),
|
||||
offset=end,
|
||||
rotate=90)
|
||||
|
||||
start = vector(pin.cx(),right_gnd_pin.by())
|
||||
self.add_segment_center(layer="metal2",
|
||||
start=pin.bc(),
|
||||
end=start)
|
||||
self.add_via_center(layers=("metal1", "via1", "metal2"),
|
||||
offset=start,
|
||||
rotate=90)
|
||||
start = vector(pin.cx(),self.right_gnd_pin.by())
|
||||
end = vector(pin.cx(),self.right_gnd_pin.uy())
|
||||
self.add_layout_pin_center_segment(text="gnd",
|
||||
layer="metal2",
|
||||
start=start,
|
||||
end=end)
|
||||
|
||||
# Connect the rails at the top and bottom
|
||||
self.add_segment_center(layer="metal1",
|
||||
start=left_gnd_end,
|
||||
end=right_gnd_end)
|
||||
self.add_segment_center(layer="metal1",
|
||||
start=left_gnd_start,
|
||||
end=right_gnd_start)
|
||||
|
||||
|
||||
|
||||
def add_layout_pins(self):
|
||||
|
|
|
|||
154
compiler/sram.py
154
compiler/sram.py
|
|
@ -16,7 +16,6 @@ class sram(design.design):
|
|||
Dynamically generated SRAM by connecting banks to control logic. The
|
||||
number of banks should be 1 , 2 or 4
|
||||
"""
|
||||
|
||||
def __init__(self, word_size, num_words, num_banks, name):
|
||||
|
||||
c = reload(__import__(OPTS.control_logic))
|
||||
|
|
@ -62,6 +61,7 @@ class sram(design.design):
|
|||
self.bank_to_bus_distance = 5*self.m3_width
|
||||
|
||||
self.compute_sizes()
|
||||
self.create_modules()
|
||||
self.add_pins()
|
||||
self.create_layout()
|
||||
|
||||
|
|
@ -146,8 +146,8 @@ class sram(design.design):
|
|||
self.add_pin("ADDR[{0}]".format(i),"INPUT")
|
||||
|
||||
# These are used to create the physical pins too
|
||||
self.control_logic_inputs=["CSb", "WEb", "OEb"]
|
||||
self.control_logic_outputs=["s_en", "w_en", "tri_en", "tri_en_bar", "clk_bar", "clk_buf"]
|
||||
self.control_logic_inputs=self.control_logic.get_inputs()
|
||||
self.control_logic_outputs=self.control_logic.get_outputs()
|
||||
|
||||
self.add_pin_list(self.control_logic_inputs + ["clk"],"INPUT")
|
||||
self.add_pin("vdd","POWER")
|
||||
|
|
@ -156,8 +156,6 @@ class sram(design.design):
|
|||
def create_layout(self):
|
||||
""" Layout creation """
|
||||
|
||||
self.create_modules()
|
||||
|
||||
if self.num_banks == 1:
|
||||
self.add_single_bank_modules()
|
||||
self.add_single_bank_pins()
|
||||
|
|
@ -366,7 +364,7 @@ class sram(design.design):
|
|||
""" Add the horizontal and vertical busses """
|
||||
# Vertical bus
|
||||
# The order of the control signals on the control bus:
|
||||
self.control_bus_names = ["clk_buf", "tri_en_bar", "tri_en", "clk_bar", "w_en", "s_en"]
|
||||
self.control_bus_names = ["clk_buf", "tri_en_bar", "tri_en", "clk_buf_bar", "w_en", "s_en"]
|
||||
self.vert_control_bus_positions = self.create_bus(layer="metal2",
|
||||
pitch=self.m2_pitch,
|
||||
offset=self.vertical_bus_offset,
|
||||
|
|
@ -430,7 +428,7 @@ class sram(design.design):
|
|||
def add_two_bank_logic(self):
|
||||
""" Add the control and MSB logic """
|
||||
|
||||
self.add_control_logic(position=self.control_logic_position, rotate=0)
|
||||
self.add_control_logic(position=self.control_logic_position)
|
||||
|
||||
self.msb_address_inst = self.add_inst(name="msb_address",
|
||||
mod=self.msb_address,
|
||||
|
|
@ -443,7 +441,7 @@ class sram(design.design):
|
|||
""" Add the control and MSB decode/bank select logic for four banks """
|
||||
|
||||
|
||||
self.add_control_logic(position=self.control_logic_position, rotate=0)
|
||||
self.add_control_logic(position=self.control_logic_position)
|
||||
|
||||
self.msb_address_inst = self.add_inst(name="msb_address",
|
||||
mod=self.msb_address,
|
||||
|
|
@ -797,8 +795,8 @@ class sram(design.design):
|
|||
self.control_logic = self.mod_control_logic(num_rows=self.num_rows)
|
||||
self.add_mod(self.control_logic)
|
||||
|
||||
# Create the address and control flops
|
||||
dff_size = self.addr_size + len(self.control_logic_inputs)
|
||||
# Create the address and control flops (but not the clk)
|
||||
dff_size = self.addr_size + len(self.control_logic.get_inputs())-1
|
||||
self.addr_ctrl_dff = self.mod_dff_array(rows=dff_size, columns=1)
|
||||
self.add_mod(self.addr_ctrl_dff)
|
||||
|
||||
|
|
@ -859,7 +857,7 @@ class sram(design.design):
|
|||
if(self.num_banks > 1):
|
||||
temp.append("bank_sel[{0}]".format(bank_num))
|
||||
temp.extend(["s_en", "w_en", "tri_en_bar", "tri_en",
|
||||
"clk_bar","clk_buf" , "vdd", "gnd"])
|
||||
"clk_buf_bar","clk_buf" , "vdd", "gnd"])
|
||||
self.connect_inst(temp)
|
||||
|
||||
return bank_inst
|
||||
|
|
@ -904,12 +902,11 @@ class sram(design.design):
|
|||
return line_positions
|
||||
|
||||
|
||||
def add_control_addr_dff(self, position, rotate=0):
|
||||
def add_control_addr_dff(self, position):
|
||||
""" Add and place address and control flops """
|
||||
self.addr_ctrl_dff_inst = self.add_inst(name="address",
|
||||
mod=self.addr_ctrl_dff,
|
||||
offset=position,
|
||||
rotate=rotate)
|
||||
mod=self.addr_ctrl_dff,
|
||||
offset=position)
|
||||
# inputs, outputs/output/bar
|
||||
inputs = []
|
||||
outputs = []
|
||||
|
|
@ -918,18 +915,19 @@ class sram(design.design):
|
|||
outputs.append("A[{}]".format(i))
|
||||
|
||||
for i in self.control_logic_inputs:
|
||||
if i == "clk":
|
||||
continue
|
||||
inputs.append(i)
|
||||
outputs.append(i+"_s")
|
||||
|
||||
|
||||
self.connect_inst(inputs + outputs + ["clk", "vdd", "gnd"])
|
||||
|
||||
def add_control_logic(self, position, rotate):
|
||||
def add_control_logic(self, position):
|
||||
""" Add and place control logic """
|
||||
self.control_logic_inst=self.add_inst(name="control",
|
||||
mod=self.control_logic,
|
||||
offset=position,
|
||||
rotate=rotate)
|
||||
self.connect_inst(self.control_logic_inputs + ["clk"] + self.control_logic_outputs + ["vdd", "gnd"])
|
||||
offset=position)
|
||||
self.connect_inst(self.control_logic_inputs + self.control_logic_outputs + ["vdd", "gnd"])
|
||||
|
||||
|
||||
def add_lvs_correspondence_points(self):
|
||||
|
|
@ -961,12 +959,13 @@ class sram(design.design):
|
|||
# are not recomputed using instance placement. So, place the control logic such that it aligns
|
||||
# with the top of the SRAM.
|
||||
control_gap = 2*self.m3_width
|
||||
control_pos = vector(-control_gap,
|
||||
self.bank.height-self.control_logic.width)
|
||||
self.add_control_logic(position=control_pos, rotate=90)
|
||||
control_pos = vector(-self.control_logic.width-control_gap,
|
||||
self.bank.height-self.control_logic.height-3*self.supply_rail_width)
|
||||
self.add_control_logic(position=control_pos)
|
||||
|
||||
addr_pos = vector(self.control_logic_inst.lx(),
|
||||
2*self.supply_rail_pitch)
|
||||
# Leave room for the control routes to the left of the flops
|
||||
addr_pos = vector(self.control_logic_inst.lx() + 4*self.m2_pitch,
|
||||
3*self.supply_rail_pitch)
|
||||
self.add_control_addr_dff(addr_pos)
|
||||
|
||||
self.width = self.bank.width + self.control_logic.height + control_gap
|
||||
|
|
@ -981,11 +980,13 @@ class sram(design.design):
|
|||
self.copy_layout_pin(self.bank_inst, "DATA[{}]".format(i))
|
||||
|
||||
for i in range(self.addr_size):
|
||||
self.copy_layout_pin(self.bank_inst, "A[{}]".format(i))
|
||||
self.copy_layout_pin(self.addr_ctrl_dff_inst, "din[{}]".format(i),"ADDR[{}]".format(i))
|
||||
|
||||
for (old,new) in zip(["csb","web","oeb","clk"],["CSb","WEb","OEb","clk"]):
|
||||
self.copy_layout_pin(self.control_logic_inst, old, new)
|
||||
ctrl_flops = ["din[{}]".format(i) for i in range(self.addr_size,self.addr_size+3)]
|
||||
for (old,new) in zip(ctrl_flops,["CSb","WEb","OEb"]):
|
||||
self.copy_layout_pin(self.addr_ctrl_dff_inst, old, new)
|
||||
|
||||
self.copy_layout_pin(self.control_logic_inst, "clk")
|
||||
self.copy_layout_pin(self.bank_inst, "vdd")
|
||||
self.copy_layout_pin(self.bank_inst, "gnd")
|
||||
|
||||
|
|
@ -1046,36 +1047,79 @@ class sram(design.design):
|
|||
dest_pin = self.bank_inst.get_pin(n)
|
||||
self.connect_rail_from_left_m2m3(src_pin, dest_pin)
|
||||
|
||||
|
||||
# Find the left-most metal2 rails
|
||||
leftmost_vdd_rail = None
|
||||
for vdd_pin in self.bank_inst.get_pins("vdd"):
|
||||
if vdd_pin.layer != "metal2":
|
||||
continue
|
||||
if leftmost_vdd_rail == None or vdd_pin.lx() < leftmost_vdd_rail.lx():
|
||||
leftmost_vdd_rail = vdd_pin
|
||||
leftmost_gnd_rail = None
|
||||
for gnd_pin in self.bank_inst.get_pins("gnd"):
|
||||
if gnd_pin.layer != "metal2":
|
||||
continue
|
||||
if leftmost_gnd_rail == None or gnd_pin.lx() < leftmost_gnd_rail.lx():
|
||||
leftmost_gnd_rail = gnd_pin
|
||||
|
||||
# Expand the ring around the bank
|
||||
bbox_lr = vector(self.control_logic_inst.lx(), self.bank_inst.by() + 2*self.supply_rail_pitch)
|
||||
bbox_ur = self.bank_inst.ur() - vector(2*self.supply_rail_pitch, 2*self.supply_rail_pitch)
|
||||
self.add_power_ring([bbox_lr, bbox_ur])
|
||||
self.route_single_bank_vdd()
|
||||
self.route_single_bank_gnd()
|
||||
|
||||
src_pins = self.control_logic_inst.get_pins("vdd")
|
||||
for src_pin in src_pins:
|
||||
if src_pin.layer != "metal2":
|
||||
continue
|
||||
self.connect_rail_from_left_m2m3(src_pin,leftmost_vdd_rail)
|
||||
|
||||
src_pins = self.control_logic_inst.get_pins("gnd")
|
||||
for src_pin in src_pins:
|
||||
if src_pin.layer != "metal2":
|
||||
continue
|
||||
self.add_path("metal2", [src_pin.rc(), vector(leftmost_gnd_rail.cx(), src_pin.cy())])
|
||||
|
||||
for i in range(self.addr_size):
|
||||
flop_name = "dout[{}]".format(i)
|
||||
bank_name = "A[{}]".format(i)
|
||||
flop_pin = self.addr_ctrl_dff_inst.get_pin(flop_name)
|
||||
bank_pin = self.bank_inst.get_pin(bank_name)
|
||||
flop_pos = flop_pin.center()
|
||||
bank_pos = bank_pin.lc()
|
||||
mid_x_pos = 0.5*(flop_pos.x + bank_pos.x)
|
||||
mid_pos = vector(mid_x_pos - i*self.m2_pitch, flop_pos.y)
|
||||
self.add_wire(("metal1","via1","metal2"),[flop_pos, mid_pos, bank_pos])
|
||||
# There should be M1 in the flop already, but just in case
|
||||
self.add_via_center(layers=("metal1","via1","metal2"),
|
||||
offset=flop_pos,
|
||||
rotate=90)
|
||||
|
||||
|
||||
for i in range(3):
|
||||
flop_name = "dout[{}]".format(self.addr_size+i)
|
||||
ctrl_name = ["csb","web","oeb"][i]
|
||||
flop_pin = self.addr_ctrl_dff_inst.get_pin(flop_name)
|
||||
ctrl_pin = self.control_logic_inst.get_pin(ctrl_name)
|
||||
flop_pos = flop_pin.center()
|
||||
ctrl_pos = ctrl_pin.bc()
|
||||
mid_pos = vector(ctrl_pos.x, flop_pos.y)
|
||||
self.add_wire(("metal3","via2","metal2"),[flop_pos, mid_pos, ctrl_pos])
|
||||
self.add_via_center(layers=("metal2","via2","metal3"),
|
||||
offset=flop_pos,
|
||||
rotate=90)
|
||||
|
||||
def route_single_bank_vdd(self):
|
||||
""" Route vdd for the control and dff array """
|
||||
|
||||
# Route the vdd rails to the LEFT
|
||||
modules = [ self.control_logic_inst, self.addr_ctrl_dff_inst]
|
||||
for inst in modules:
|
||||
for vdd_pin in inst.get_pins("vdd"):
|
||||
if vdd_pin.layer != "metal1":
|
||||
continue
|
||||
vdd_pos = vdd_pin.rc()
|
||||
left_rail_pos = vector(self.left_vdd_x_center, vdd_pos.y)
|
||||
self.add_path("metal1", [left_rail_pos, vdd_pos])
|
||||
self.add_via_center(layers=("metal1", "via1", "metal2"),
|
||||
offset=left_rail_pos,
|
||||
size = (1,3),
|
||||
rotate=90)
|
||||
|
||||
|
||||
def route_single_bank_gnd(self):
|
||||
""" Route gnd for the control and dff array """
|
||||
|
||||
# Route the gnd rails to the LEFT
|
||||
modules = [ self.control_logic_inst, self.addr_ctrl_dff_inst]
|
||||
for inst in modules:
|
||||
for gnd_pin in inst.get_pins("gnd"):
|
||||
if gnd_pin.layer != "metal1":
|
||||
continue
|
||||
gnd_pos = gnd_pin.rc()
|
||||
left_rail_pos = vector(self.left_gnd_x_center, gnd_pos.y)
|
||||
self.add_path("metal1", [left_rail_pos, gnd_pos])
|
||||
self.add_via_center(layers=("metal1", "via1", "metal2"),
|
||||
offset=left_rail_pos,
|
||||
size = (1,3),
|
||||
rotate=90)
|
||||
|
||||
|
||||
|
||||
def sp_write(self, sp_name):
|
||||
# Write the entire spice of the object to the file
|
||||
############################################################
|
||||
|
|
|
|||
Loading…
Reference in New Issue