mirror of https://github.com/VLSIDA/OpenRAM.git
Add copy power pin function
This commit is contained in:
parent
280488b3ad
commit
3244e01ca1
|
|
@ -885,6 +885,22 @@ class layout(lef.lef):
|
||||||
width=xmax-xmin,
|
width=xmax-xmin,
|
||||||
height=ymax-ymin)
|
height=ymax-ymin)
|
||||||
|
|
||||||
|
|
||||||
|
def copy_power_pins(self, inst, name):
|
||||||
|
"""
|
||||||
|
This will copy a power pin if it is on M3. If it is on M1, it will add a power via too.
|
||||||
|
"""
|
||||||
|
pins=inst.get_pins(name)
|
||||||
|
for pin in pins:
|
||||||
|
if pin.layer=="metal3":
|
||||||
|
self.add_layout_pin(name, pin.layer, pin.ll(), pin.width(), pin.height())
|
||||||
|
elif pin.layer=="metal1":
|
||||||
|
self.add_power_pin(name, pin.center())
|
||||||
|
else:
|
||||||
|
debug.warning("{0} pins of {1} should be on metal3 or metal1 for supply router.".format(name,inst.name))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def add_power_pin(self, name, loc, rotate=90):
|
def add_power_pin(self, name, loc, rotate=90):
|
||||||
"""
|
"""
|
||||||
Add a single power pin from M3 down to M1 at the given center location
|
Add a single power pin from M3 down to M1 at the given center location
|
||||||
|
|
|
||||||
|
|
@ -515,10 +515,13 @@ class bank(design.design):
|
||||||
|
|
||||||
# FIXME: place for multiport
|
# FIXME: place for multiport
|
||||||
for port in range(self.total_ports):
|
for port in range(self.total_ports):
|
||||||
|
col_decoder_inst = self.col_decoder_inst[port]
|
||||||
|
|
||||||
# Place the col decoder right aligned with row decoder
|
# Place the col decoder right aligned with row decoder
|
||||||
x_off = -(self.central_bus_width + self.wordline_driver.width + self.col_decoder.width)
|
x_off = -(self.central_bus_width + self.wordline_driver.width + self.col_decoder.width)
|
||||||
y_off = -(self.col_decoder.height + 2*drc["well_to_well"])
|
y_off = -(self.col_decoder.height + 2*drc["well_to_well"])
|
||||||
self.col_decoder_inst[port].place(vector(x_off,y_off))
|
col_decoder_inst.place(vector(x_off,y_off))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def create_bank_select(self):
|
def create_bank_select(self):
|
||||||
|
|
@ -559,38 +562,9 @@ class bank(design.design):
|
||||||
|
|
||||||
def route_vdd_gnd(self):
|
def route_vdd_gnd(self):
|
||||||
""" Propagate all vdd/gnd pins up to this level for all modules """
|
""" Propagate all vdd/gnd pins up to this level for all modules """
|
||||||
|
for inst in self.insts:
|
||||||
# These are the instances that every bank has
|
self.copy_power_pins(inst,"vdd")
|
||||||
top_instances = [self.bitcell_array_inst]
|
self.copy_power_pins(inst,"gnd")
|
||||||
for port in range(self.total_read):
|
|
||||||
#top_instances.append(self.precharge_array_inst[port])
|
|
||||||
top_instances.append(self.sense_amp_array_inst[port])
|
|
||||||
for port in range(self.total_write):
|
|
||||||
top_instances.append(self.write_driver_array_inst[port])
|
|
||||||
for port in range(self.total_ports):
|
|
||||||
top_instances.extend([self.row_decoder_inst[port],
|
|
||||||
self.wordline_driver_inst[port]])
|
|
||||||
# Add these if we use the part...
|
|
||||||
if self.col_addr_size > 0:
|
|
||||||
top_instances.append(self.col_decoder_inst[port])
|
|
||||||
#top_instances.append(self.col_mux_array_inst[port])
|
|
||||||
|
|
||||||
if self.num_banks > 1:
|
|
||||||
top_instances.append(self.bank_select_inst[port])
|
|
||||||
|
|
||||||
if self.col_addr_size > 0:
|
|
||||||
for port in range(self.total_ports):
|
|
||||||
self.copy_layout_pin(self.col_mux_array_inst[port], "gnd")
|
|
||||||
for port in range(self.total_read):
|
|
||||||
self.copy_layout_pin(self.precharge_array_inst[port], "vdd")
|
|
||||||
|
|
||||||
for inst in top_instances:
|
|
||||||
# Column mux has no vdd
|
|
||||||
#if self.col_addr_size==0 or (self.col_addr_size>0 and inst != self.col_mux_array_inst[0]):
|
|
||||||
self.copy_layout_pin(inst, "vdd")
|
|
||||||
# Precharge has no gnd
|
|
||||||
#if inst != self.precharge_array_inst[port]:
|
|
||||||
self.copy_layout_pin(inst, "gnd")
|
|
||||||
|
|
||||||
def route_bank_select(self):
|
def route_bank_select(self):
|
||||||
""" Route the bank select logic. """
|
""" Route the bank select logic. """
|
||||||
|
|
|
||||||
|
|
@ -97,13 +97,13 @@ class pinvbuf(design.design):
|
||||||
# Add INV1 to the left (capacitance shield)
|
# Add INV1 to the left (capacitance shield)
|
||||||
self.inv1_inst.place(vector(0,0))
|
self.inv1_inst.place(vector(0,0))
|
||||||
|
|
||||||
# Add INV2 to the right of INVX1
|
# Add INV2 to the right of INV1
|
||||||
self.inv2_inst.place(vector(self.inv1_inst.rx(),0))
|
self.inv2_inst.place(vector(self.inv1_inst.rx(),0))
|
||||||
|
|
||||||
# Add INV3 to the right of INVX2
|
# Add INV3 to the right of INV2
|
||||||
self.inv3_inst.place(vector(self.inv2_inst.rx(),0))
|
self.inv3_inst.place(vector(self.inv2_inst.rx(),0))
|
||||||
|
|
||||||
# Add INV4 flipped to the bottom aligned with INVX2
|
# Add INV4 flipped to the bottom aligned with INV2
|
||||||
self.inv4_inst.place(offset=vector(self.inv2_inst.rx(),2*self.inv2.height),
|
self.inv4_inst.place(offset=vector(self.inv2_inst.rx(),2*self.inv2.height),
|
||||||
mirror = "MX")
|
mirror = "MX")
|
||||||
|
|
||||||
|
|
@ -135,18 +135,27 @@ class pinvbuf(design.design):
|
||||||
|
|
||||||
# Continous vdd rail along with label.
|
# Continous vdd rail along with label.
|
||||||
vdd_pin=self.inv1_inst.get_pin("vdd")
|
vdd_pin=self.inv1_inst.get_pin("vdd")
|
||||||
self.add_power_pin(name="vdd",
|
self.add_layout_pin(text="vdd",
|
||||||
loc=vdd_pin.lc())
|
layer="metal1",
|
||||||
|
offset=vdd_pin.ll().scale(0,1),
|
||||||
|
width=self.width,
|
||||||
|
height=vdd_pin.height())
|
||||||
|
|
||||||
# Continous vdd rail along with label.
|
# Continous vdd rail along with label.
|
||||||
gnd_pin=self.inv4_inst.get_pin("gnd")
|
gnd_pin=self.inv4_inst.get_pin("gnd")
|
||||||
self.add_power_pin(name="gnd",
|
self.add_layout_pin(text="gnd",
|
||||||
loc=gnd_pin.lc())
|
layer="metal1",
|
||||||
|
offset=gnd_pin.ll().scale(0,1),
|
||||||
|
width=self.width,
|
||||||
|
height=gnd_pin.height())
|
||||||
|
|
||||||
# Continous gnd rail along with label.
|
# Continous gnd rail along with label.
|
||||||
gnd_pin=self.inv1_inst.get_pin("gnd")
|
gnd_pin=self.inv1_inst.get_pin("gnd")
|
||||||
self.add_power_pin(name="gnd",
|
self.add_layout_pin(text="gnd",
|
||||||
loc=gnd_pin.lc())
|
layer="metal1",
|
||||||
|
offset=gnd_pin.ll().scale(0,1),
|
||||||
|
width=self.width,
|
||||||
|
height=vdd_pin.height())
|
||||||
|
|
||||||
z_pin = self.inv4_inst.get_pin("Z")
|
z_pin = self.inv4_inst.get_pin("Z")
|
||||||
self.add_layout_pin_rect_center(text="Z",
|
self.add_layout_pin_rect_center(text="Z",
|
||||||
|
|
|
||||||
|
|
@ -115,8 +115,8 @@ class sram_base(design):
|
||||||
""" Route the supply grid and connect the pins to them. """
|
""" Route the supply grid and connect the pins to them. """
|
||||||
|
|
||||||
for inst in self.insts:
|
for inst in self.insts:
|
||||||
self.copy_layout_pin(inst, "vdd")
|
self.copy_power_pins(inst,"vdd")
|
||||||
self.copy_layout_pin(inst, "gnd")
|
self.copy_power_pins(inst,"gnd")
|
||||||
|
|
||||||
from supply_router import supply_router as router
|
from supply_router import supply_router as router
|
||||||
layer_stack =("metal3","via3","metal4")
|
layer_stack =("metal3","via3","metal4")
|
||||||
|
|
@ -223,6 +223,7 @@ class sram_base(design):
|
||||||
self.tri_gate_array_inst,
|
self.tri_gate_array_inst,
|
||||||
self.row_decoder_inst,
|
self.row_decoder_inst,
|
||||||
self.wordline_driver_inst]
|
self.wordline_driver_inst]
|
||||||
|
|
||||||
# Add these if we use the part...
|
# Add these if we use the part...
|
||||||
if self.col_addr_size > 0:
|
if self.col_addr_size > 0:
|
||||||
top_instances.append(self.col_decoder_inst)
|
top_instances.append(self.col_decoder_inst)
|
||||||
|
|
@ -233,11 +234,7 @@ class sram_base(design):
|
||||||
|
|
||||||
|
|
||||||
for inst in top_instances:
|
for inst in top_instances:
|
||||||
# Column mux has no vdd
|
|
||||||
if self.col_addr_size==0 or (self.col_addr_size>0 and inst != self.col_mux_array_inst):
|
|
||||||
self.copy_layout_pin(inst, "vdd")
|
self.copy_layout_pin(inst, "vdd")
|
||||||
# Precharge has no gnd
|
|
||||||
if inst != self.precharge_array_inst:
|
|
||||||
self.copy_layout_pin(inst, "gnd")
|
self.copy_layout_pin(inst, "gnd")
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue