mirror of https://github.com/VLSIDA/OpenRAM.git
Refactor add power pins
This commit is contained in:
parent
408ea15228
commit
01d312d65c
|
|
@ -56,6 +56,8 @@ class layout():
|
||||||
self.visited = []
|
self.visited = []
|
||||||
# Flag for library cells
|
# Flag for library cells
|
||||||
self.is_library_cell = False
|
self.is_library_cell = False
|
||||||
|
# Flag for top level (used for min area metal pins etc.)
|
||||||
|
self.is_top_level = False
|
||||||
|
|
||||||
self.gds_read()
|
self.gds_read()
|
||||||
|
|
||||||
|
|
@ -1220,30 +1222,21 @@ class layout():
|
||||||
pin.height())
|
pin.height())
|
||||||
|
|
||||||
elif add_vias:
|
elif add_vias:
|
||||||
self.add_power_pin(name, pin.center(), start_layer=pin.layer)
|
self.add_power_pin(pin)
|
||||||
|
|
||||||
def add_io_pin(self, instance, pin_name, new_name="", start_layer=None):
|
def add_io_pin(self, instance, pin_name, new_name, start_layer=None):
|
||||||
"""
|
"""
|
||||||
Add a signle input or output pin up to metal 3.
|
Add a signle input or output pin up to metal 3.
|
||||||
"""
|
"""
|
||||||
pin = instance.get_pin(pin_name)
|
pin = instance.get_pin(pin_name)
|
||||||
|
|
||||||
if new_name == "":
|
|
||||||
new_name = pin_name
|
|
||||||
|
|
||||||
if not start_layer:
|
if not start_layer:
|
||||||
start_layer = pin.layer
|
start_layer = pin.layer
|
||||||
|
|
||||||
# Just use the power pin function for now to save code
|
# Just use the power pin function for now to save code
|
||||||
self.add_power_pin(name=new_name, loc=pin.center(), start_layer=start_layer)
|
self.add_power_pin(new_name, pin.center(), start_layer=start_layer)
|
||||||
|
|
||||||
def add_power_pin(self, name, loc, size=[1, 1], directions=None, start_layer="m1"):
|
|
||||||
"""
|
|
||||||
Add a single power pin from the lowest power_grid layer down to M1 (or li) at
|
|
||||||
the given center location. The starting layer is specified to determine
|
|
||||||
which vias are needed.
|
|
||||||
"""
|
|
||||||
|
|
||||||
|
def add_power_pin(self, name, loc, directions=None, start_layer="m1"):
|
||||||
if start_layer == self.pwr_grid_layer:
|
if start_layer == self.pwr_grid_layer:
|
||||||
self.add_layout_pin_rect_center(text=name,
|
self.add_layout_pin_rect_center(text=name,
|
||||||
layer=self.pwr_grid_layer,
|
layer=self.pwr_grid_layer,
|
||||||
|
|
@ -1251,12 +1244,11 @@ class layout():
|
||||||
else:
|
else:
|
||||||
via = self.add_via_stack_center(from_layer=start_layer,
|
via = self.add_via_stack_center(from_layer=start_layer,
|
||||||
to_layer=self.pwr_grid_layer,
|
to_layer=self.pwr_grid_layer,
|
||||||
size=size,
|
|
||||||
offset=loc,
|
offset=loc,
|
||||||
directions=directions)
|
directions=directions)
|
||||||
|
|
||||||
# Hack for min area
|
# Hack for min area
|
||||||
if OPTS.tech_name == "sky130":
|
if OPTS.tech_name == "sky130" and self.is_top_level:
|
||||||
width = round_to_grid(sqrt(drc["minarea_m3"]))
|
width = round_to_grid(sqrt(drc["minarea_m3"]))
|
||||||
height = round_to_grid(drc["minarea_m3"] / width)
|
height = round_to_grid(drc["minarea_m3"] / width)
|
||||||
else:
|
else:
|
||||||
|
|
@ -1268,6 +1260,39 @@ class layout():
|
||||||
width=width,
|
width=width,
|
||||||
height=height)
|
height=height)
|
||||||
|
|
||||||
|
def copy_power_pin(self, pin, loc=None, directions=None):
|
||||||
|
"""
|
||||||
|
Add a single power pin from the lowest power_grid layer down to M1 (or li) at
|
||||||
|
the given center location. The starting layer is specified to determine
|
||||||
|
which vias are needed.
|
||||||
|
"""
|
||||||
|
|
||||||
|
if not loc:
|
||||||
|
loc = pin.center()
|
||||||
|
|
||||||
|
if pin.layer == self.pwr_grid_layer:
|
||||||
|
self.add_layout_pin_rect_center(text=pin.name,
|
||||||
|
layer=self.pwr_grid_layer,
|
||||||
|
offset=loc)
|
||||||
|
else:
|
||||||
|
via = self.add_via_stack_center(from_layer=pin.layer,
|
||||||
|
to_layer=self.pwr_grid_layer,
|
||||||
|
offset=loc,
|
||||||
|
directions=directions)
|
||||||
|
|
||||||
|
# Hack for min area
|
||||||
|
if OPTS.tech_name == "sky130" and self.is_top_level:
|
||||||
|
width = round_to_grid(sqrt(drc["minarea_m3"]))
|
||||||
|
height = round_to_grid(drc["minarea_m3"] / width)
|
||||||
|
else:
|
||||||
|
width = via.width
|
||||||
|
height = via.height
|
||||||
|
self.add_layout_pin_rect_center(text=pin.name,
|
||||||
|
layer=self.pwr_grid_layer,
|
||||||
|
offset=loc,
|
||||||
|
width=width,
|
||||||
|
height=height)
|
||||||
|
|
||||||
def add_perimeter_pin(self, name, pin, side, bbox):
|
def add_perimeter_pin(self, name, pin, side, bbox):
|
||||||
"""
|
"""
|
||||||
Add a pin along the perimeter side specified by the bbox with
|
Add a pin along the perimeter side specified by the bbox with
|
||||||
|
|
|
||||||
|
|
@ -615,9 +615,7 @@ class bank(design.design):
|
||||||
for pin_name in ["vdd", "gnd"]:
|
for pin_name in ["vdd", "gnd"]:
|
||||||
pin_list = inst.get_pins(pin_name)
|
pin_list = inst.get_pins(pin_name)
|
||||||
for pin in pin_list:
|
for pin in pin_list:
|
||||||
self.add_power_pin(pin_name,
|
self.copy_power_pin(pin, pin.center())
|
||||||
pin.center(),
|
|
||||||
start_layer=pin.layer)
|
|
||||||
|
|
||||||
def route_bank_select(self, port):
|
def route_bank_select(self, port):
|
||||||
""" Route the bank select logic. """
|
""" Route the bank select logic. """
|
||||||
|
|
|
||||||
|
|
@ -100,7 +100,5 @@ class col_cap_array(bitcell_base_array):
|
||||||
inst = self.cell_inst[row, col]
|
inst = self.cell_inst[row, col]
|
||||||
for pin_name in ["vdd", "gnd"]:
|
for pin_name in ["vdd", "gnd"]:
|
||||||
for pin in inst.get_pins(pin_name):
|
for pin in inst.get_pins(pin_name):
|
||||||
self.add_power_pin(name=pin_name,
|
self.copy_power_pin(pin)
|
||||||
loc=pin.center(),
|
|
||||||
start_layer=pin.layer)
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -177,14 +177,10 @@ class delay_chain(design.design):
|
||||||
load_list = self.load_inst_map[inst]
|
load_list = self.load_inst_map[inst]
|
||||||
for pin_name in ["vdd", "gnd"]:
|
for pin_name in ["vdd", "gnd"]:
|
||||||
pin = load_list[0].get_pin(pin_name)
|
pin = load_list[0].get_pin(pin_name)
|
||||||
self.add_power_pin(pin_name,
|
self.copy_power_pin(pin, loc=pin.rc() - vector(self.m1_pitch, 0))
|
||||||
pin.rc() - vector(self.m1_pitch, 0),
|
|
||||||
start_layer=pin.layer)
|
|
||||||
|
|
||||||
pin = load_list[-2].get_pin(pin_name)
|
pin = load_list[-2].get_pin(pin_name)
|
||||||
self.add_power_pin(pin_name,
|
self.copy_power_pin(pin, loc=pin.rc() - vector(self.m1_pitch, 0))
|
||||||
pin.rc() - vector(self.m1_pitch, 0),
|
|
||||||
start_layer=pin.layer)
|
|
||||||
|
|
||||||
def add_layout_pins(self):
|
def add_layout_pins(self):
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -112,11 +112,11 @@ class dff_array(design.design):
|
||||||
for col in range(self.columns):
|
for col in range(self.columns):
|
||||||
# Continous vdd rail along with label.
|
# Continous vdd rail along with label.
|
||||||
vdd_pin=self.dff_insts[row, col].get_pin("vdd")
|
vdd_pin=self.dff_insts[row, col].get_pin("vdd")
|
||||||
self.add_power_pin("vdd", vdd_pin.center(), start_layer=vdd_pin.layer)
|
self.copy_power_pin(vdd_pin)
|
||||||
|
|
||||||
# Continous gnd rail along with label.
|
# Continous gnd rail along with label.
|
||||||
gnd_pin=self.dff_insts[row, col].get_pin("gnd")
|
gnd_pin=self.dff_insts[row, col].get_pin("gnd")
|
||||||
self.add_power_pin("gnd", gnd_pin.center(), start_layer=gnd_pin.layer)
|
self.copy_power_pin(gnd_pin)
|
||||||
|
|
||||||
for row in range(self.rows):
|
for row in range(self.rows):
|
||||||
for col in range(self.columns):
|
for col in range(self.columns):
|
||||||
|
|
|
||||||
|
|
@ -159,11 +159,11 @@ class dff_buf_array(design.design):
|
||||||
for col in range(self.columns):
|
for col in range(self.columns):
|
||||||
# Continous vdd rail along with label.
|
# Continous vdd rail along with label.
|
||||||
vdd_pin=self.dff_insts[row, col].get_pin("vdd")
|
vdd_pin=self.dff_insts[row, col].get_pin("vdd")
|
||||||
self.add_power_pin("vdd", vdd_pin.lc(), start_layer=vdd_pin.layer)
|
self.copy_power_pin(vdd_pin, loc=vdd_pin.lc())
|
||||||
|
|
||||||
# Continous gnd rail along with label.
|
# Continous gnd rail along with label.
|
||||||
gnd_pin=self.dff_insts[row, col].get_pin("gnd")
|
gnd_pin=self.dff_insts[row, col].get_pin("gnd")
|
||||||
self.add_power_pin("gnd", gnd_pin.lc(), start_layer=gnd_pin.layer)
|
self.copy_power_pin(gnd_pin, loc=gnd_pin.lc())
|
||||||
|
|
||||||
def add_layout_pins(self):
|
def add_layout_pins(self):
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -130,12 +130,11 @@ class dff_inv_array(design.design):
|
||||||
for col in range(self.columns):
|
for col in range(self.columns):
|
||||||
# Adds power pin on left of row
|
# Adds power pin on left of row
|
||||||
vdd_pin=self.dff_insts[row,col].get_pin("vdd")
|
vdd_pin=self.dff_insts[row,col].get_pin("vdd")
|
||||||
self.add_power_pin("vdd", vdd_pin.lc())
|
self.add_power_pin(vdd_pin, loc=vdd_pin.lc())
|
||||||
|
|
||||||
# Adds gnd pin on left of row
|
# Adds gnd pin on left of row
|
||||||
gnd_pin=self.dff_insts[row,col].get_pin("gnd")
|
gnd_pin=self.dff_insts[row,col].get_pin("gnd")
|
||||||
self.add_power_pin("gnd", gnd_pin.lc())
|
self.add_power_pin(gnd_pin, loc=gnd_pin.lc())
|
||||||
|
|
||||||
|
|
||||||
for row in range(self.rows):
|
for row in range(self.rows):
|
||||||
for col in range(self.columns):
|
for col in range(self.columns):
|
||||||
|
|
|
||||||
|
|
@ -611,12 +611,7 @@ class hierarchical_decoder(design.design):
|
||||||
for i in self.and_inst[:-1]:
|
for i in self.and_inst[:-1]:
|
||||||
pins = i.get_pins(n)
|
pins = i.get_pins(n)
|
||||||
for pin in pins:
|
for pin in pins:
|
||||||
self.add_power_pin(name=n,
|
self.copy_power_pin(pin, loc=pin.uc())
|
||||||
loc=pin.uc(),
|
|
||||||
start_layer=pin.layer)
|
|
||||||
self.add_power_pin(name=n,
|
|
||||||
loc=pin.uc(),
|
|
||||||
start_layer=pin.layer)
|
|
||||||
|
|
||||||
for i in self.pre2x4_inst + self.pre3x8_inst:
|
for i in self.pre2x4_inst + self.pre3x8_inst:
|
||||||
self.copy_layout_pin(i, n)
|
self.copy_layout_pin(i, n)
|
||||||
|
|
@ -628,9 +623,7 @@ class hierarchical_decoder(design.design):
|
||||||
# The nand and inv are the same height rows...
|
# The nand and inv are the same height rows...
|
||||||
supply_pin = self.and_inst[row].get_pin(pin_name)
|
supply_pin = self.and_inst[row].get_pin(pin_name)
|
||||||
pin_pos = vector(xoffset, supply_pin.cy())
|
pin_pos = vector(xoffset, supply_pin.cy())
|
||||||
self.add_power_pin(name=pin_name,
|
self.copy_power_pin(supply_pin, loc=pin_pos)
|
||||||
loc=pin_pos,
|
|
||||||
start_layer=supply_pin.layer)
|
|
||||||
|
|
||||||
# Copy the pins from the predecoders
|
# Copy the pins from the predecoders
|
||||||
for pre in self.pre2x4_inst + self.pre3x8_inst + self.pre4x16_inst:
|
for pre in self.pre2x4_inst + self.pre3x8_inst + self.pre4x16_inst:
|
||||||
|
|
|
||||||
|
|
@ -330,12 +330,7 @@ class hierarchical_predecode(design.design):
|
||||||
for i in self.inv_inst[:-1:2] + self.and_inst[:-1:2]:
|
for i in self.inv_inst[:-1:2] + self.and_inst[:-1:2]:
|
||||||
pins = i.get_pins(n)
|
pins = i.get_pins(n)
|
||||||
for pin in pins:
|
for pin in pins:
|
||||||
self.add_power_pin(name=n,
|
self.copy_power_pin(pin, loc=pin.uc())
|
||||||
loc=pin.uc(),
|
|
||||||
start_layer=pin.layer)
|
|
||||||
self.add_power_pin(name=n,
|
|
||||||
loc=pin.uc(),
|
|
||||||
start_layer=pin.layer)
|
|
||||||
|
|
||||||
# In other techs, we are using standard cell decoder cells with horizontal power
|
# In other techs, we are using standard cell decoder cells with horizontal power
|
||||||
else:
|
else:
|
||||||
|
|
@ -353,9 +348,7 @@ class hierarchical_predecode(design.design):
|
||||||
for xoffset in [self.inv_inst[0].lx() - self.bus_space,
|
for xoffset in [self.inv_inst[0].lx() - self.bus_space,
|
||||||
self.and_inst[0].lx() - self.bus_space]:
|
self.and_inst[0].lx() - self.bus_space]:
|
||||||
pin_pos = vector(xoffset, and_pin.cy())
|
pin_pos = vector(xoffset, and_pin.cy())
|
||||||
self.add_power_pin(name=n,
|
self.copy_power_pin(and_pin, loc=pin_pos)
|
||||||
loc=pin_pos,
|
|
||||||
start_layer=and_pin.layer)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -186,9 +186,7 @@ class local_bitcell_array(bitcell_base_array.bitcell_base_array):
|
||||||
for inst in supply_insts:
|
for inst in supply_insts:
|
||||||
pin_list = inst.get_pins(pin_name)
|
pin_list = inst.get_pins(pin_name)
|
||||||
for pin in pin_list:
|
for pin in pin_list:
|
||||||
self.add_power_pin(name=pin_name,
|
self.copy_power_pin(pin)
|
||||||
loc=pin.center(),
|
|
||||||
start_layer=pin.layer)
|
|
||||||
|
|
||||||
def route(self):
|
def route(self):
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -82,9 +82,9 @@ class port_address(design.design):
|
||||||
|
|
||||||
for rbl_vdd_pin in self.rbl_driver_inst.get_pins("vdd"):
|
for rbl_vdd_pin in self.rbl_driver_inst.get_pins("vdd"):
|
||||||
if layer_props.port_address.supply_offset:
|
if layer_props.port_address.supply_offset:
|
||||||
self.add_power_pin("vdd", rbl_vdd_pin.center())
|
self.copy_power_pin(rbl_vdd_pin)
|
||||||
else:
|
else:
|
||||||
self.add_power_pin("vdd", rbl_vdd_pin.lc())
|
self.copy_power_pin(rbl_vdd_pin, loc=rbl_vdd_pin.lc())
|
||||||
|
|
||||||
# Also connect the B input of the RBL and_dec to vdd
|
# Also connect the B input of the RBL and_dec to vdd
|
||||||
if OPTS.local_array_size == 0:
|
if OPTS.local_array_size == 0:
|
||||||
|
|
|
||||||
|
|
@ -473,9 +473,7 @@ class replica_bitcell_array(bitcell_base_array):
|
||||||
for inst in supply_insts:
|
for inst in supply_insts:
|
||||||
pin_list = inst.get_pins(pin_name)
|
pin_list = inst.get_pins(pin_name)
|
||||||
for pin in pin_list:
|
for pin in pin_list:
|
||||||
self.add_power_pin(name=pin_name,
|
self.copy_power_pin(pin)
|
||||||
loc=pin.center(),
|
|
||||||
start_layer=pin.layer)
|
|
||||||
|
|
||||||
for inst in self.replica_col_insts:
|
for inst in self.replica_col_insts:
|
||||||
if inst:
|
if inst:
|
||||||
|
|
|
||||||
|
|
@ -190,7 +190,8 @@ class replica_column(bitcell_base_array):
|
||||||
for (index, inst) in enumerate(self.cell_inst):
|
for (index, inst) in enumerate(self.cell_inst):
|
||||||
for pin_name in ["vdd", "gnd"]:
|
for pin_name in ["vdd", "gnd"]:
|
||||||
if inst in [self.cell_inst[0], self.cell_inst[self.total_size - 1]]:
|
if inst in [self.cell_inst[0], self.cell_inst[self.total_size - 1]]:
|
||||||
self.copy_power_pins(inst, pin_name)
|
for pin in inst.get_pins(pin_name):
|
||||||
|
self.copy_power_pin(pin)
|
||||||
else:
|
else:
|
||||||
self.copy_layout_pin(inst, pin_name)
|
self.copy_layout_pin(inst, pin_name)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -113,7 +113,5 @@ class row_cap_array(bitcell_base_array):
|
||||||
inst = self.cell_inst[row, col]
|
inst = self.cell_inst[row, col]
|
||||||
for pin_name in ["vdd", "gnd"]:
|
for pin_name in ["vdd", "gnd"]:
|
||||||
for pin in inst.get_pins(pin_name):
|
for pin in inst.get_pins(pin_name):
|
||||||
self.add_power_pin(name=pin_name,
|
self.add_power_pin(pin)
|
||||||
loc=pin.center(),
|
|
||||||
start_layer=pin.layer)
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -146,16 +146,10 @@ class sense_amp_array(design.design):
|
||||||
inst = self.local_insts[i]
|
inst = self.local_insts[i]
|
||||||
|
|
||||||
for gnd_pin in inst.get_pins("gnd"):
|
for gnd_pin in inst.get_pins("gnd"):
|
||||||
self.add_power_pin(name="gnd",
|
self.copy_power_pin(gnd_pin, directions=("V", "V"))
|
||||||
loc=gnd_pin.center(),
|
|
||||||
start_layer=gnd_pin.layer,
|
|
||||||
directions=("V", "V"))
|
|
||||||
|
|
||||||
for vdd_pin in inst.get_pins("vdd"):
|
for vdd_pin in inst.get_pins("vdd"):
|
||||||
self.add_power_pin(name="vdd",
|
self.copy_power_pin(vdd_pin, directions=("V", "V"))
|
||||||
loc=vdd_pin.center(),
|
|
||||||
start_layer=vdd_pin.layer,
|
|
||||||
directions=("V", "V"))
|
|
||||||
|
|
||||||
bl_pin = inst.get_pin(inst.mod.get_bl_names())
|
bl_pin = inst.get_pin(inst.mod.get_bl_names())
|
||||||
br_pin = inst.get_pin(inst.mod.get_br_names())
|
br_pin = inst.get_pin(inst.mod.get_br_names())
|
||||||
|
|
|
||||||
|
|
@ -96,7 +96,7 @@ class wordline_buffer_array(design.design):
|
||||||
# Add pins in two locations
|
# Add pins in two locations
|
||||||
for xoffset in xoffset_list:
|
for xoffset in xoffset_list:
|
||||||
pin_pos = vector(xoffset, supply_pin.cy())
|
pin_pos = vector(xoffset, supply_pin.cy())
|
||||||
self.add_power_pin(name, pin_pos)
|
self.copy_power_pin(supply_pin, loc=pin_pos)
|
||||||
|
|
||||||
def create_drivers(self):
|
def create_drivers(self):
|
||||||
self.wld_inst = []
|
self.wld_inst = []
|
||||||
|
|
|
||||||
|
|
@ -97,7 +97,7 @@ class wordline_driver_array(design.design):
|
||||||
# Add pins in two locations
|
# Add pins in two locations
|
||||||
for xoffset in xoffset_list:
|
for xoffset in xoffset_list:
|
||||||
pin_pos = vector(xoffset, supply_pin.cy())
|
pin_pos = vector(xoffset, supply_pin.cy())
|
||||||
self.add_power_pin(name, pin_pos)
|
self.copy_power_pin(supply_pin, loc=pin_pos)
|
||||||
|
|
||||||
def create_drivers(self):
|
def create_drivers(self):
|
||||||
self.wld_inst = []
|
self.wld_inst = []
|
||||||
|
|
|
||||||
|
|
@ -208,10 +208,8 @@ class write_driver_array(design.design):
|
||||||
for n in ["vdd", "gnd"]:
|
for n in ["vdd", "gnd"]:
|
||||||
pin_list = self.driver_insts[i].get_pins(n)
|
pin_list = self.driver_insts[i].get_pins(n)
|
||||||
for pin in pin_list:
|
for pin in pin_list:
|
||||||
self.add_power_pin(name=n,
|
self.copy_power_pin(pin, directions=("V", "V"))
|
||||||
loc=pin.center(),
|
|
||||||
directions=("V", "V"),
|
|
||||||
start_layer=pin.layer)
|
|
||||||
if self.write_size:
|
if self.write_size:
|
||||||
for bit in range(self.num_wmasks):
|
for bit in range(self.num_wmasks):
|
||||||
inst = self.driver_insts[bit * self.write_size]
|
inst = self.driver_insts[bit * self.write_size]
|
||||||
|
|
|
||||||
|
|
@ -145,6 +145,6 @@ class write_mask_and_array(design.design):
|
||||||
left_loc = vector(0, supply_pin_yoffset)
|
left_loc = vector(0, supply_pin_yoffset)
|
||||||
right_loc = vector(self.width, supply_pin_yoffset)
|
right_loc = vector(self.width, supply_pin_yoffset)
|
||||||
self.add_path(supply_pin.layer, [left_loc, right_loc])
|
self.add_path(supply_pin.layer, [left_loc, right_loc])
|
||||||
self.add_power_pin(supply, left_loc, start_layer=supply_pin.layer)
|
self.copy_power_pin(supply_pin, loc=left_loc)
|
||||||
self.add_power_pin(supply, right_loc, start_layer=supply_pin.layer)
|
self.copy_power_pin(supply_pin, loc=right_loc)
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue