mirror of https://github.com/VLSIDA/OpenRAM.git
Clean up column mux by moving pins to own function. Adjust spacing between column mux and bitcell to prevent DRCs. Fix up find lowest/highest functions when no objects or instances in a module.
This commit is contained in:
parent
9d043b904e
commit
ffcf58100e
|
|
@ -99,8 +99,8 @@ class bank(design.design):
|
|||
self.add_precharge_array()
|
||||
|
||||
if self.col_addr_size > 0:
|
||||
self.column_mux_height = self.column_mux_array.height + 0.5*self.m2_width
|
||||
self.add_column_mux_array()
|
||||
self.column_mux_height = self.column_mux_array.height
|
||||
else:
|
||||
self.column_mux_height = 0
|
||||
if self.col_addr_size > 1: # size 1 is from addr FF
|
||||
|
|
@ -249,7 +249,7 @@ class bank(design.design):
|
|||
def add_column_mux_array(self):
|
||||
""" Adding Column Mux when words_per_row > 1 . """
|
||||
|
||||
y_offset = self.column_mux_array.height
|
||||
y_offset = self.column_mux_height
|
||||
self.col_mux_array_inst=self.add_inst(name="column_mux_array",
|
||||
mod=self.column_mux_array,
|
||||
offset=vector(0,y_offset).scale(-1,-1))
|
||||
|
|
|
|||
|
|
@ -60,21 +60,44 @@ class layout(lef.lef):
|
|||
def find_lowest_coords(self):
|
||||
"""Finds the lowest set of 2d cartesian coordinates within
|
||||
this layout"""
|
||||
|
||||
lowestx1 = min(obj.lx() for obj in self.objs if obj.name!="label")
|
||||
lowesty1 = min(obj.by() for obj in self.objs if obj.name!="label")
|
||||
lowestx2 = min(inst.lx() for inst in self.insts)
|
||||
lowesty2 = min(inst.by() for inst in self.insts)
|
||||
return vector(min(lowestx1, lowestx2), min(lowesty1, lowesty2))
|
||||
|
||||
if len(self.objs)>0:
|
||||
lowestx1 = min(obj.lx() for obj in self.objs if obj.name!="label")
|
||||
lowesty1 = min(obj.by() for obj in self.objs if obj.name!="label")
|
||||
else:
|
||||
lowestx1=lowesty1=None
|
||||
if len(self.insts)>0:
|
||||
lowestx2 = min(inst.lx() for inst in self.insts)
|
||||
lowesty2 = min(inst.by() for inst in self.insts)
|
||||
else:
|
||||
lowestx2=lowesty2=None
|
||||
if lowestx1==None:
|
||||
return vector(lowestx2,lowesty2)
|
||||
elif lowestx2==None:
|
||||
return vector(lowestx1,lowesty1)
|
||||
else:
|
||||
return vector(min(lowestx1, lowestx2), min(lowesty1, lowesty2))
|
||||
|
||||
def find_highest_coords(self):
|
||||
"""Finds the highest set of 2d cartesian coordinates within
|
||||
this layout"""
|
||||
highestx1 = min(obj.rx() for obj in self.objs if obj.name!="label")
|
||||
highesty1 = min(obj.uy() for obj in self.objs if obj.name!="label")
|
||||
highestx2 = min(inst.rx() for inst in self.insts)
|
||||
highesty2 = min(inst.uy() for inst in self.insts)
|
||||
return vector(min(highestx1, highestx2), min(highesty1, highesty2))
|
||||
|
||||
if len(self.objs)>0:
|
||||
highestx1 = max(obj.rx() for obj in self.objs if obj.name!="label")
|
||||
highesty1 = max(obj.uy() for obj in self.objs if obj.name!="label")
|
||||
else:
|
||||
highestx1=highesty1=None
|
||||
if len(self.insts)>0:
|
||||
highestx2 = max(inst.rx() for inst in self.insts)
|
||||
highesty2 = max(inst.uy() for inst in self.insts)
|
||||
else:
|
||||
highestx2=highesty2=None
|
||||
if highestx1==None:
|
||||
return vector(highestx2,highesty2)
|
||||
elif highestx2==None:
|
||||
return vector(highestx1,highesty1)
|
||||
else:
|
||||
return vector(max(highestx1, highestx2), max(highesty1, highesty2))
|
||||
|
||||
|
||||
def translate_all(self, offset):
|
||||
|
|
|
|||
|
|
@ -28,9 +28,9 @@ class single_level_column_mux(design.design):
|
|||
def create_layout(self):
|
||||
|
||||
self.add_ptx()
|
||||
|
||||
self.pin_height = 2*self.m2_width
|
||||
self.width = self.bitcell.width
|
||||
self.height = self.nmos2.uy()
|
||||
self.height = self.nmos2.uy() + self.pin_height
|
||||
self.connect_poly()
|
||||
self.add_gnd_rail()
|
||||
self.add_bitline_pins()
|
||||
|
|
@ -43,26 +43,25 @@ class single_level_column_mux(design.design):
|
|||
bl_pos = vector(self.bitcell.get_pin("BL").lx(), 0)
|
||||
br_pos = vector(self.bitcell.get_pin("BR").lx(), 0)
|
||||
|
||||
pin_height = 2*self.m2_width
|
||||
# bl and br
|
||||
self.add_layout_pin(text="bl",
|
||||
layer="metal2",
|
||||
offset=bl_pos + vector(0,self.height - pin_height),
|
||||
height=pin_height)
|
||||
offset=bl_pos + vector(0,self.height - self.pin_height),
|
||||
height=self.pin_height)
|
||||
self.add_layout_pin(text="br",
|
||||
layer="metal2",
|
||||
offset=br_pos + vector(0,self.height - pin_height),
|
||||
height=pin_height)
|
||||
offset=br_pos + vector(0,self.height - self.pin_height),
|
||||
height=self.pin_height)
|
||||
|
||||
# bl_out and br_out
|
||||
self.add_layout_pin(text="bl_out",
|
||||
layer="metal2",
|
||||
offset=bl_pos,
|
||||
height=pin_height)
|
||||
height=self.pin_height)
|
||||
self.add_layout_pin(text="br_out",
|
||||
layer="metal2",
|
||||
offset=br_pos,
|
||||
height=pin_height)
|
||||
height=self.pin_height)
|
||||
|
||||
|
||||
def add_ptx(self):
|
||||
|
|
|
|||
|
|
@ -40,8 +40,14 @@ class single_level_column_mux_array(design.design):
|
|||
self.setup_layout_constants()
|
||||
self.create_array()
|
||||
self.add_routing()
|
||||
# Find the highest shapes to determine height before adding well
|
||||
highest = self.find_highest_coords()
|
||||
self.height = highest.y
|
||||
self.add_layout_pins()
|
||||
self.add_enclosure(self.mux_inst, "pwell")
|
||||
|
||||
|
||||
|
||||
def add_modules(self):
|
||||
# FIXME: Why is this 8x?
|
||||
self.mux = single_level_column_mux(tx_size=8)
|
||||
|
|
@ -51,16 +57,11 @@ class single_level_column_mux_array(design.design):
|
|||
def setup_layout_constants(self):
|
||||
self.column_addr_size = num_of_inputs = int(self.words_per_row / 2)
|
||||
self.width = self.columns * self.mux.width
|
||||
|
||||
self.m1_pitch = contact.m1m2.width + max(drc["metal1_to_metal1"],drc["metal2_to_metal2"])
|
||||
# To correct the offset between M1 and M2 via enclosures
|
||||
self.offset_fix = vector(0,0.5*(drc["minwidth_metal2"]-drc["minwidth_metal1"]))
|
||||
# one set of metal1 routes for select signals and a pair to interconnect the mux outputs bl/br
|
||||
# one extra route pitch is to space from the sense amp
|
||||
self.route_height = (self.words_per_row + 3)*self.m1_pitch
|
||||
|
||||
# mux height plus routing signal height plus well spacing at the top
|
||||
self.height = self.mux.height + self.route_height + drc["pwell_to_nwell"]
|
||||
|
||||
|
||||
def create_array(self):
|
||||
|
|
@ -73,28 +74,6 @@ class single_level_column_mux_array(design.design):
|
|||
self.mux_inst.append(self.add_inst(name=name,
|
||||
mod=self.mux,
|
||||
offset=x_off))
|
||||
|
||||
offset = self.mux_inst[-1].get_pin("bl").ll()
|
||||
self.add_layout_pin(text="bl[{}]".format(col_num),
|
||||
layer="metal2",
|
||||
offset=offset,
|
||||
height=self.height-offset.y)
|
||||
|
||||
offset = self.mux_inst[-1].get_pin("br").ll()
|
||||
self.add_layout_pin(text="br[{}]".format(col_num),
|
||||
layer="metal2",
|
||||
offset=offset,
|
||||
height=self.height-offset.y)
|
||||
|
||||
gnd_pins = self.mux_inst[-1].get_pins("gnd")
|
||||
for gnd_pin in gnd_pins:
|
||||
# only do even colums to avoid duplicates
|
||||
offset = gnd_pin.ll()
|
||||
if col_num % 2 == 0:
|
||||
self.add_layout_pin(text="gnd",
|
||||
layer="metal2",
|
||||
offset=offset.scale(1,0),
|
||||
height=self.height)
|
||||
|
||||
self.connect_inst(["bl[{}]".format(col_num),
|
||||
"br[{}]".format(col_num),
|
||||
|
|
@ -103,7 +82,34 @@ class single_level_column_mux_array(design.design):
|
|||
"sel[{}]".format(col_num % self.words_per_row),
|
||||
"gnd"])
|
||||
|
||||
|
||||
|
||||
def add_layout_pins(self):
|
||||
""" Add the pins after we determine the height. """
|
||||
# For every column, add a pass gate
|
||||
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),
|
||||
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),
|
||||
layer="metal2",
|
||||
offset=offset,
|
||||
height=self.height-offset.y)
|
||||
|
||||
gnd_pins = mux_inst.get_pins("gnd")
|
||||
for gnd_pin in gnd_pins:
|
||||
# only do even colums to avoid duplicates
|
||||
offset = gnd_pin.ll()
|
||||
if col_num % 2 == 0:
|
||||
self.add_layout_pin(text="gnd",
|
||||
layer="metal2",
|
||||
offset=offset.scale(1,0),
|
||||
height=self.height)
|
||||
|
||||
|
||||
def add_routing(self):
|
||||
self.add_horizontal_input_rail()
|
||||
|
|
|
|||
Loading…
Reference in New Issue