mirror of https://github.com/VLSIDA/OpenRAM.git
bunch of cleanups to core rom classes
This commit is contained in:
parent
ddba3b3718
commit
9b99e6c124
|
|
@ -113,8 +113,7 @@ class rom_bank(design,rom_verilog):
|
||||||
# FIXME: Somehow ROM layout behaves weird and doesn't add all the pin
|
# FIXME: Somehow ROM layout behaves weird and doesn't add all the pin
|
||||||
# shapes before routing supplies
|
# shapes before routing supplies
|
||||||
init_bbox = self.get_bbox()
|
init_bbox = self.get_bbox()
|
||||||
if OPTS.route_supplies:
|
self.route_supplies(init_bbox)
|
||||||
self.route_supplies(init_bbox)
|
|
||||||
# Route the pins to the perimeter
|
# Route the pins to the perimeter
|
||||||
if OPTS.perimeter_pins:
|
if OPTS.perimeter_pins:
|
||||||
# We now route the escape routes far enough out so that they will
|
# We now route the escape routes far enough out so that they will
|
||||||
|
|
@ -368,8 +367,11 @@ class rom_bank(design,rom_verilog):
|
||||||
|
|
||||||
# Route precharge to col decoder
|
# Route precharge to col decoder
|
||||||
start = prechrg_control.center()
|
start = prechrg_control.center()
|
||||||
mid1 = vector(self.control_inst.rx() + self.interconnect_layer_pitch, prechrg_control.cy())
|
|
||||||
mid2 = vector(self.control_inst.rx() + self.interconnect_layer_pitch, col_decode_prechrg.cy())
|
path_x = self.control_inst.rx() + 1.2 * self.route_layer_pitch
|
||||||
|
|
||||||
|
mid1 = vector(path_x, prechrg_control.cy())
|
||||||
|
mid2 = vector(path_x, col_decode_prechrg.cy())
|
||||||
end = col_decode_prechrg.center()
|
end = col_decode_prechrg.center()
|
||||||
self.add_path(self.route_stack[0], [start, mid1, mid2, end])
|
self.add_path(self.route_stack[0], [start, mid1, mid2, end])
|
||||||
|
|
||||||
|
|
@ -378,7 +380,7 @@ class rom_bank(design,rom_verilog):
|
||||||
offset=end)
|
offset=end)
|
||||||
|
|
||||||
start = mid1
|
start = mid1
|
||||||
mid1 = vector(self.control_inst.rx() + self.interconnect_layer_pitch, start.y)
|
mid1 = vector(path_x, start.y)
|
||||||
mid2 = vector(mid1.x, col_decode_clk.cy())
|
mid2 = vector(mid1.x, col_decode_clk.cy())
|
||||||
end = col_decode_clk.center()
|
end = col_decode_clk.center()
|
||||||
self.add_path(self.route_stack[0], [start, mid1, mid2, end])
|
self.add_path(self.route_stack[0], [start, mid1, mid2, end])
|
||||||
|
|
@ -388,6 +390,10 @@ class rom_bank(design,rom_verilog):
|
||||||
mid = vector(col_decode_prechrg.cx(), array_prechrg.cy() )
|
mid = vector(col_decode_prechrg.cx(), array_prechrg.cy() )
|
||||||
self.add_path(self.route_stack[0], [array_prechrg.center(), mid, col_decode_prechrg.center()])
|
self.add_path(self.route_stack[0], [array_prechrg.center(), mid, col_decode_prechrg.center()])
|
||||||
|
|
||||||
|
self.add_via_stack_center(from_layer=self.route_stack[0],
|
||||||
|
to_layer=array_prechrg.layer,
|
||||||
|
offset=array_prechrg.center())
|
||||||
|
|
||||||
|
|
||||||
def route_clock(self):
|
def route_clock(self):
|
||||||
clk_out = self.control_inst.get_pin("clk_out")
|
clk_out = self.control_inst.get_pin("clk_out")
|
||||||
|
|
@ -409,6 +415,10 @@ class rom_bank(design,rom_verilog):
|
||||||
to_layer=row_decode_clk.layer,
|
to_layer=row_decode_clk.layer,
|
||||||
offset=addr_control_clk)
|
offset=addr_control_clk)
|
||||||
|
|
||||||
|
self.add_via_stack_center(from_layer=self.route_stack[2],
|
||||||
|
to_layer=row_decode_prechrg.layer,
|
||||||
|
offset=row_decode_prechrg.center())
|
||||||
|
|
||||||
self.add_segment_center(row_decode_clk.layer, addr_control_clk, row_decode_clk.rc())
|
self.add_segment_center(row_decode_clk.layer, addr_control_clk, row_decode_clk.rc())
|
||||||
|
|
||||||
def route_array_outputs(self):
|
def route_array_outputs(self):
|
||||||
|
|
@ -417,7 +427,7 @@ class rom_bank(design,rom_verilog):
|
||||||
inv_out_pins = [self.bitline_inv_inst.get_pin("out_{}".format(bl)) for bl in range(self.cols)]
|
inv_out_pins = [self.bitline_inv_inst.get_pin("out_{}".format(bl)) for bl in range(self.cols)]
|
||||||
mux_pins = [self.mux_inst.get_pin("bl_{}".format(bl)) for bl in range(self.cols)]
|
mux_pins = [self.mux_inst.get_pin("bl_{}".format(bl)) for bl in range(self.cols)]
|
||||||
|
|
||||||
self.connect_col_pins(self.interconnect_layer, array_out_pins + inv_in_pins, round=True, directions="nonpref")
|
self.connect_col_pins(self.route_stack[2], array_out_pins + inv_in_pins, round=True, directions="nonpref")
|
||||||
self.connect_col_pins(self.interconnect_layer, inv_out_pins + mux_pins, round=True, directions="nonpref")
|
self.connect_col_pins(self.interconnect_layer, inv_out_pins + mux_pins, round=True, directions="nonpref")
|
||||||
|
|
||||||
def route_output_buffers(self):
|
def route_output_buffers(self):
|
||||||
|
|
@ -450,34 +460,36 @@ class rom_bank(design,rom_verilog):
|
||||||
for inst in self.insts:
|
for inst in self.insts:
|
||||||
self.copy_power_pins(inst, pin_name)
|
self.copy_power_pins(inst, pin_name)
|
||||||
|
|
||||||
from openram.router import supply_router as router
|
if OPTS.route_supplies:
|
||||||
rtr = router(layers=self.supply_stack,
|
|
||||||
design=self,
|
|
||||||
bbox=bbox,
|
|
||||||
pin_type=OPTS.supply_pin_type)
|
|
||||||
rtr.route()
|
|
||||||
|
|
||||||
if OPTS.supply_pin_type in ["left", "right", "top", "bottom", "ring"]:
|
from openram.router import supply_router as router
|
||||||
# Find the lowest leftest pin for vdd and gnd
|
rtr = router(layers=self.supply_stack,
|
||||||
for pin_name in ["vdd", "gnd"]:
|
design=self,
|
||||||
# Copy the pin shape(s) to rectangles
|
bbox=bbox,
|
||||||
for pin in self.get_pins(pin_name):
|
pin_type=OPTS.supply_pin_type)
|
||||||
self.add_rect(layer=pin.layer,
|
rtr.route()
|
||||||
offset=pin.ll(),
|
|
||||||
width=pin.width(),
|
|
||||||
height=pin.height())
|
|
||||||
|
|
||||||
# Remove the pin shape(s)
|
if OPTS.supply_pin_type in ["left", "right", "top", "bottom", "ring"]:
|
||||||
self.remove_layout_pin(pin_name)
|
# Find the lowest leftest pin for vdd and gnd
|
||||||
|
for pin_name in ["vdd", "gnd"]:
|
||||||
|
# Copy the pin shape(s) to rectangles
|
||||||
|
for pin in self.get_pins(pin_name):
|
||||||
|
self.add_rect(layer=pin.layer,
|
||||||
|
offset=pin.ll(),
|
||||||
|
width=pin.width(),
|
||||||
|
height=pin.height())
|
||||||
|
|
||||||
# Get new pins
|
# Remove the pin shape(s)
|
||||||
pins = rtr.get_new_pins(pin_name)
|
self.remove_layout_pin(pin_name)
|
||||||
for pin in pins:
|
|
||||||
self.add_layout_pin(pin_name,
|
# Get new pins
|
||||||
pin.layer,
|
pins = rtr.get_new_pins(pin_name)
|
||||||
pin.ll(),
|
for pin in pins:
|
||||||
pin.width(),
|
self.add_layout_pin(pin_name,
|
||||||
pin.height())
|
pin.layer,
|
||||||
|
pin.ll(),
|
||||||
|
pin.width(),
|
||||||
|
pin.height())
|
||||||
|
|
||||||
def route_escape_pins(self, bbox):
|
def route_escape_pins(self, bbox):
|
||||||
pins_to_route = []
|
pins_to_route = []
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,9 @@ class rom_base_array(bitcell_base_array):
|
||||||
|
|
||||||
self.data = bitmap
|
self.data = bitmap
|
||||||
self.tap_direction = tap_direction
|
self.tap_direction = tap_direction
|
||||||
self.pitch_match = pitch_match
|
# This attribute is redundant with the tap direction
|
||||||
|
# TODO: consolidate pitch matching logic to just be based on tap direction
|
||||||
|
self.pitch_match = tap_direction == "row"
|
||||||
self.bitline_layer = bitline_layer
|
self.bitline_layer = bitline_layer
|
||||||
self.strap_spacing = strap_spacing
|
self.strap_spacing = strap_spacing
|
||||||
self.wordline_layer = wordline_layer
|
self.wordline_layer = wordline_layer
|
||||||
|
|
@ -89,7 +91,6 @@ class rom_base_array(bitcell_base_array):
|
||||||
self.poly_tap = factory.create(module_type="rom_poly_tap", add_active_tap=True)
|
self.poly_tap = factory.create(module_type="rom_poly_tap", add_active_tap=True)
|
||||||
self.end_poly_tap = factory.create(module_type="rom_poly_tap", place_poly=True)
|
self.end_poly_tap = factory.create(module_type="rom_poly_tap", place_poly=True)
|
||||||
|
|
||||||
print("poly tap width", self.poly_tap.width, "height", self.poly_tap.height, self.tap_direction)
|
|
||||||
self.precharge_array = factory.create(module_type="rom_precharge_array",
|
self.precharge_array = factory.create(module_type="rom_precharge_array",
|
||||||
cols=self.column_size,
|
cols=self.column_size,
|
||||||
strap_spacing=self.strap_spacing,
|
strap_spacing=self.strap_spacing,
|
||||||
|
|
@ -102,7 +103,6 @@ class rom_base_array(bitcell_base_array):
|
||||||
self.route_pitch = drc("{0}_to_{0}".format(self.bitline_layer))
|
self.route_pitch = drc("{0}_to_{0}".format(self.bitline_layer))
|
||||||
|
|
||||||
def add_pins(self):
|
def add_pins(self):
|
||||||
print(self.get_wordline_names())
|
|
||||||
for bl_name in self.get_bitline_names():
|
for bl_name in self.get_bitline_names():
|
||||||
self.add_pin(bl_name, "OUTPUT")
|
self.add_pin(bl_name, "OUTPUT")
|
||||||
for wl_name in self.get_wordline_names():
|
for wl_name in self.get_wordline_names():
|
||||||
|
|
@ -234,12 +234,10 @@ class rom_base_array(bitcell_base_array):
|
||||||
bottom = vector(pin.cx(), pin.by())
|
bottom = vector(pin.cx(), pin.by())
|
||||||
top = vector(pin.cx(), gnd_y)
|
top = vector(pin.cx(), gnd_y)
|
||||||
self.add_via_stack_center(offset=top, from_layer=self.bitline_layer, to_layer=self.supply_stack[0])
|
self.add_via_stack_center(offset=top, from_layer=self.bitline_layer, to_layer=self.supply_stack[0])
|
||||||
# self.add_via_center(offset=bottom, layers=self.supply_stack)
|
|
||||||
|
|
||||||
self.add_layout_pin_rect_ends(name="gnd", layer=self.supply_stack[0], start=bottom, end=top)
|
self.add_layout_pin_rect_ends(name="gnd", layer=self.supply_stack[0], start=bottom, end=top)
|
||||||
|
|
||||||
self.remove_layout_pin("gnd_tmp")
|
self.remove_layout_pin("gnd_tmp")
|
||||||
# self.add_segment_center(layer=self.supply_stack[2], start=vector(min_x, bottom.y), end=vector(max_x, bottom.y))
|
|
||||||
self.add_segment_center(layer=self.bitline_layer, start=gnd_l, end=vector(min_x, gnd_l.y))
|
self.add_segment_center(layer=self.bitline_layer, start=gnd_l, end=vector(min_x, gnd_l.y))
|
||||||
self.add_segment_center(layer=self.bitline_layer, start=gnd_r, end=vector(max_x, gnd_r.y))
|
self.add_segment_center(layer=self.bitline_layer, start=gnd_r, end=vector(max_x, gnd_r.y))
|
||||||
|
|
||||||
|
|
@ -333,7 +331,6 @@ class rom_base_array(bitcell_base_array):
|
||||||
else:
|
else:
|
||||||
output_layer = "m3"
|
output_layer = "m3"
|
||||||
rail_y = self.precharge_inst.get_pins("vdd")[0].cy()
|
rail_y = self.precharge_inst.get_pins("vdd")[0].cy()
|
||||||
print("cols ", self.bitline_names[0])
|
|
||||||
for bl in range(self.column_size):
|
for bl in range(self.column_size):
|
||||||
|
|
||||||
src_pin = self.cell_list[0][bl].get_pin("S")
|
src_pin = self.cell_list[0][bl].get_pin("S")
|
||||||
|
|
|
||||||
|
|
@ -80,7 +80,6 @@ class rom_base_cell(design):
|
||||||
self.cell_inst = self.add_inst( name=self.name + "_nmos",
|
self.cell_inst = self.add_inst( name=self.name + "_nmos",
|
||||||
mod=self.nmos,
|
mod=self.nmos,
|
||||||
)
|
)
|
||||||
print("bitmos", self.cell_inst.height, self.cell_inst.width)
|
|
||||||
|
|
||||||
if self.bit_value == 0:
|
if self.bit_value == 0:
|
||||||
self.connect_inst(["bl", "wl", "bl", "gnd"])
|
self.connect_inst(["bl", "wl", "bl", "gnd"])
|
||||||
|
|
|
||||||
|
|
@ -231,6 +231,14 @@ class rom_decoder(design):
|
||||||
|
|
||||||
self.add_path(self.inv_route_layer, [addr_out_pin.center(), addr_middle, addr_pin.center()])
|
self.add_path(self.inv_route_layer, [addr_out_pin.center(), addr_middle, addr_pin.center()])
|
||||||
self.add_path(self.inv_route_layer, [addr_bar_out_pin.center(), addr_bar_middle, addr_bar_pin.center()])
|
self.add_path(self.inv_route_layer, [addr_bar_out_pin.center(), addr_bar_middle, addr_bar_pin.center()])
|
||||||
|
|
||||||
|
self.add_via_stack_center(offset=addr_pin.center(),
|
||||||
|
from_layer=addr_pin.layer,
|
||||||
|
to_layer=self.inv_route_layer)
|
||||||
|
|
||||||
|
self.add_via_stack_center(offset=addr_bar_pin.center(),
|
||||||
|
from_layer=addr_bar_pin.layer,
|
||||||
|
to_layer=self.inv_route_layer)
|
||||||
self.copy_layout_pin(self.buf_inst, "A{}_in".format(i), "A{}".format(i))
|
self.copy_layout_pin(self.buf_inst, "A{}_in".format(i), "A{}".format(i))
|
||||||
|
|
||||||
def route_supplies(self):
|
def route_supplies(self):
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,6 @@ class rom_poly_tap(design):
|
||||||
def create_layout(self):
|
def create_layout(self):
|
||||||
|
|
||||||
self.place_via()
|
self.place_via()
|
||||||
# self.extend_poly()
|
|
||||||
|
|
||||||
if self.add_tap or self.place_poly:
|
if self.add_tap or self.place_poly:
|
||||||
self.place_active_tap()
|
self.place_active_tap()
|
||||||
|
|
@ -47,7 +46,6 @@ class rom_poly_tap(design):
|
||||||
contact_width = self.poly_contact.width
|
contact_width = self.poly_contact.width
|
||||||
self.height = self.dummy.height
|
self.height = self.dummy.height
|
||||||
self.width = contact_width + self.pitch_offset
|
self.width = contact_width + self.pitch_offset
|
||||||
print("pitch off", self.pitch_offset)
|
|
||||||
super().add_boundary()
|
super().add_boundary()
|
||||||
|
|
||||||
def place_via(self):
|
def place_via(self):
|
||||||
|
|
@ -83,12 +81,9 @@ class rom_poly_tap(design):
|
||||||
tap_y = self.via.cy() + self.dummy.width * 0.5
|
tap_y = self.via.cy() + self.dummy.width * 0.5
|
||||||
contact_pos = vector(tap_x, tap_y)
|
contact_pos = vector(tap_x, tap_y)
|
||||||
|
|
||||||
# edge of the next nmos
|
|
||||||
active_edge = self.dummy.width - self.dummy.cell_inst.height - self.poly_extend_active
|
|
||||||
|
|
||||||
# edge of the active contact
|
# This pitch offset is used throughout the memory bank to make sure the pitch of the decoder outputs matches the pitch of the array inputs
|
||||||
tap_edge = tap_x + 0.5 * self.active_contact.height
|
self.pitch_offset = 0.5 * self.active_contact.width + self.active_space + 0.5 * self.contact_width + self.active_enclose_contact
|
||||||
self.pitch_offset += (self.active_space * 2) - (tap_edge - active_edge) + self.contact_x_offset
|
|
||||||
|
|
||||||
if self.tx_type == "nmos" and self.add_tap:
|
if self.tx_type == "nmos" and self.add_tap:
|
||||||
self.add_via_center(layers=self.active_stack,
|
self.add_via_center(layers=self.active_stack,
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,6 @@ class rom_precharge_cell(rom_base_cell):
|
||||||
|
|
||||||
self.place_tap()
|
self.place_tap()
|
||||||
self.extend_well()
|
self.extend_well()
|
||||||
print("precharge", self.height, self.width)
|
|
||||||
|
|
||||||
|
|
||||||
def add_modules(self):
|
def add_modules(self):
|
||||||
|
|
@ -44,7 +43,6 @@ class rom_precharge_cell(rom_base_cell):
|
||||||
self.cell_inst = self.add_inst( name="precharge_pmos",
|
self.cell_inst = self.add_inst( name="precharge_pmos",
|
||||||
mod=self.pmos,
|
mod=self.pmos,
|
||||||
)
|
)
|
||||||
print("premos", self.cell_inst.height, self.cell_inst.width)
|
|
||||||
self.connect_inst(["bitline", "gate", "vdd", "vdd"])
|
self.connect_inst(["bitline", "gate", "vdd", "vdd"])
|
||||||
|
|
||||||
def add_pins(self):
|
def add_pins(self):
|
||||||
|
|
@ -58,7 +56,6 @@ class rom_precharge_cell(rom_base_cell):
|
||||||
self.poly_size = (self.cell_inst.width + self.active_space) - (self.cell_inst.height + 2 * self.poly_extend_active)
|
self.poly_size = (self.cell_inst.width + self.active_space) - (self.cell_inst.height + 2 * self.poly_extend_active)
|
||||||
|
|
||||||
def extend_well(self):
|
def extend_well(self):
|
||||||
print(self.nwell_enclose_active)
|
|
||||||
well_y = self.get_pin("vdd").cy() - 0.5 * self.tap.height - self.nwell_enclose_active
|
well_y = self.get_pin("vdd").cy() - 0.5 * self.tap.height - self.nwell_enclose_active
|
||||||
well_ll = vector(0, well_y)
|
well_ll = vector(0, well_y)
|
||||||
height = self.get_pin("D").cy() + self.nwell_enclose_active - well_y
|
height = self.get_pin("D").cy() + self.nwell_enclose_active - well_y
|
||||||
|
|
@ -91,5 +88,4 @@ class rom_precharge_cell(rom_base_cell):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def short_gate(self):
|
def short_gate(self):
|
||||||
print("not shorting")
|
|
||||||
pass
|
pass
|
||||||
Loading…
Reference in New Issue