mirror of https://github.com/VLSIDA/OpenRAM.git
more code cleaning
This commit is contained in:
parent
90cf382a43
commit
92251fe61e
|
|
@ -56,10 +56,8 @@ class rom_address_control_array(design):
|
|||
|
||||
|
||||
def create_modules(self):
|
||||
|
||||
self.addr_control = factory.create(module_type="rom_address_control_buf", size=self.inv_height)
|
||||
# For layout constants
|
||||
# self.poly_tap = factory.create(module_type="rom_poly_tap", strap_length=0)
|
||||
|
||||
|
||||
def add_pins(self):
|
||||
for col in range(self.cols):
|
||||
|
|
|
|||
|
|
@ -41,16 +41,13 @@ class rom_address_control_buf(design):
|
|||
self.height = self.inv.width + 2 * self.nand.width
|
||||
self.setup_layout_constants()
|
||||
self.place_instances()
|
||||
# self.place_vias()
|
||||
self.route_gates()
|
||||
self.route_sources()
|
||||
self.add_boundary()
|
||||
|
||||
def create_modules(self):
|
||||
|
||||
# self.inv1_mod = factory.create(module_type="pinv", module_name="inv_array_end_mod", height=self.inv_size, add_wells=False)
|
||||
self.inv = factory.create(module_type="pinv_dec", module_name="inv_array_mod", add_wells=False, size=self.size)
|
||||
# self.end_inv = factory.create(module_type="pinv", module_name="inv_array_end_mod", size=self.size, add_wells=True)
|
||||
self.nand = factory.create(module_type="nand2_dec", height=self.inv.height)
|
||||
# For layout constants
|
||||
self.cell = factory.create(module_type="rom_base_cell")
|
||||
|
|
@ -101,7 +98,6 @@ class rom_address_control_buf(design):
|
|||
def route_gates(self):
|
||||
clk1_pin = self.addr_nand.get_pin("A")
|
||||
clk2_pin = self.addr_bar_nand.get_pin("A")
|
||||
# self.add_label("HERE I AM", "poly", clk_pins.cl())
|
||||
|
||||
Abar_out = self.addr_bar_nand.get_pin("Z")
|
||||
A_out = self.addr_nand.get_pin("Z")
|
||||
|
|
|
|||
|
|
@ -115,21 +115,17 @@ class rom_base_array(bitcell_base_array):
|
|||
# list of current bitline interconnect nets,
|
||||
# starts as the same as the bitline list and is updated when new insts of cells are added
|
||||
self.int_bl_list = self.bitline_names[0].copy()
|
||||
#When rotated correctly rows are word lines
|
||||
|
||||
for row in range(self.row_size + 1):
|
||||
row_list = []
|
||||
|
||||
# for each new strap placed, offset the column index refrenced to get correct bit in the data array
|
||||
# cols are bit lines
|
||||
for col in range(self.column_size):
|
||||
|
||||
if col % self.strap_spacing == 0:
|
||||
self.create_poly_tap(row, col)
|
||||
|
||||
new_inst = self.create_cell(row, col)
|
||||
|
||||
self.cell_inst[row, col] = new_inst
|
||||
|
||||
row_list.append(new_inst)
|
||||
|
||||
name = "tap_r{0}_c{1}".format(row, self.array_col_size)
|
||||
|
|
@ -206,8 +202,8 @@ class rom_base_array(bitcell_base_array):
|
|||
def place_array(self):
|
||||
self.cell_pos = {}
|
||||
self.strap_pos = {}
|
||||
# rows are wordlines
|
||||
pitch_offset = 0
|
||||
|
||||
for row in range(self.row_size + 1):
|
||||
|
||||
if row % self.tap_spacing == 0 and self.pitch_match and row != self.row_size:
|
||||
|
|
@ -228,7 +224,6 @@ class rom_base_array(bitcell_base_array):
|
|||
self.cell_pos[row, col] = vector(cell_x, cell_y)
|
||||
self.cell_inst[row, col].place(self.cell_pos[row, col])
|
||||
cell_x += self.zero_cell.width
|
||||
# self.add_label("debug", "li", self.cell_pos[row, col])
|
||||
|
||||
self.strap_pos[row, self.column_size] = vector(cell_x, cell_y)
|
||||
self.tap_inst[row, self.column_size].place(self.strap_pos[row, self.column_size])
|
||||
|
|
@ -338,24 +333,6 @@ class rom_base_array(bitcell_base_array):
|
|||
array_pins = [self.tap_list[i].get_pin("poly_tap") for i in range(len(self.tap_list))]
|
||||
|
||||
self.connect_row_pins(layer=self.wordline_layer, pins=array_pins, name=None, round=False)
|
||||
# self.connect_row_pins(layer="poly", pins=array_pins, name=None, round=False)
|
||||
|
||||
if self.tap_direction == "col":
|
||||
self.route_vertical_pins("active_tap", insts=self.tap_list, layer=self.supply_stack[0], full_width=False)
|
||||
|
||||
def get_next_cell_in_bl(self, row_start, col):
|
||||
for row in range(row_start + 1, self.row_size):
|
||||
if self.data[row][col] == 1:
|
||||
return row
|
||||
return -1
|
||||
|
||||
|
||||
|
||||
def get_current_bl_interconnect(self, col):
|
||||
"""Get interconnect net for bitline(col) currently being connected """
|
||||
return "bli_{0}_{1}".format(self.current_row, col)
|
||||
|
||||
def create_next_bl_interconnect(self, row, col):
|
||||
"""create a new net name for a bitline interconnect"""
|
||||
self.current_row = row
|
||||
return "bli_{0}_{1}".format(row, col)
|
||||
self.route_vertical_pins("active_tap", insts=self.tap_list, layer=self.supply_stack[0], full_width=False)
|
||||
|
|
@ -11,7 +11,7 @@ from openram.base import vector
|
|||
from openram.base import design
|
||||
from openram import OPTS, debug
|
||||
from openram.sram_factory import factory
|
||||
from openram.tech import drc, layer
|
||||
from openram.tech import drc, layer, parameter
|
||||
|
||||
class rom_base_bank(design):
|
||||
|
||||
|
|
@ -165,7 +165,9 @@ class rom_base_bank(design):
|
|||
# TODO: provide technology-specific calculation of these parameters
|
||||
# in sky130 the address control buffer is composed of 2 size 2 NAND gates,
|
||||
# with a beta of 3, each of these gates has gate capacitance of 2 min sized inverters, therefor a load of 4
|
||||
addr_control_buffer_effort = 4
|
||||
|
||||
|
||||
addr_control_buffer_effort = parameter['beta'] + 1
|
||||
# a single min sized nmos makes up 1/4 of the input capacitance of a min sized inverter
|
||||
bitcell_effort = 0.25
|
||||
|
||||
|
|
|
|||
|
|
@ -23,13 +23,10 @@ class rom_base_cell(design):
|
|||
self.create_netlist()
|
||||
self.create_layout()
|
||||
|
||||
|
||||
|
||||
def create_netlist(self):
|
||||
self.add_pins()
|
||||
self.add_modules()
|
||||
|
||||
|
||||
def create_layout(self):
|
||||
|
||||
self.create_tx()
|
||||
|
|
@ -41,34 +38,10 @@ class rom_base_cell(design):
|
|||
if self.bit_value == 0:
|
||||
self.short_gate()
|
||||
|
||||
|
||||
|
||||
|
||||
# Calculates offsets of cell width and height so that tiling of cells does not violate any drc rules
|
||||
def setup_drc_offsets(self):
|
||||
|
||||
|
||||
|
||||
self.poly_size = (self.cell_inst.width + self.active_space) - (self.cell_inst.height + 2 * self.poly_extend_active)
|
||||
#nmos contact to gate distance
|
||||
self.contact_to_gate = 0.5 * (self.nmos.width - 2 * self.nmos.contact_width - self.nmos.poly_width - 2 * self.active_enclose_contact)
|
||||
|
||||
#height offset to account for active-to-active spacing between adjacent bitlines
|
||||
self.poly_extend_active_spacing = abs( 2 * self.nmos.poly_extend_active - drc("active_to_active") )
|
||||
|
||||
#contact to contact distance, minimum cell width before drc offsets
|
||||
self.base_width = self.nmos.width - 2 * self.active_enclose_contact - self.nmos.contact_width
|
||||
|
||||
#width offset to account for active-to-active spacing between cells on the same bitline
|
||||
#this is calculated as a negative value
|
||||
self.cell_diffusion_offset = ((self.base_width - 2 * self.active_enclose_contact - self.nmos.contact_width) - drc("active_to_active")) * 0.5
|
||||
|
||||
# width offset to account for poly-active spacing between base and dummy cells on the same bitline
|
||||
self.poly_active_offset = 0.5 * (self.base_width - 2 * self.cell_diffusion_offset - (self.poly_width + 2 * self.active_enclose_contact + self.nmos.contact_width)) - self.poly_to_active
|
||||
|
||||
#so that the poly taps are far enough apart
|
||||
self.poly_tap_offset = (self.base_width - self.cell_diffusion_offset - self.poly_contact.width - self.poly_active_offset) - drc("poly_to_poly")
|
||||
|
||||
|
||||
def add_boundary(self):
|
||||
|
||||
|
|
@ -76,8 +49,7 @@ class rom_base_cell(design):
|
|||
|
||||
#cell width with offsets applied, height becomes width when the cells are rotated
|
||||
width = self.cell_inst.height + 2 * self.poly_extend_active
|
||||
# cell height with offsets applied, width becomes height when the cells are rotated, if the offsets are positive (greater than 0) they are not applied
|
||||
# height = self.base_width - min(self.cell_diffusion_offset, 0) - min(self.poly_active_offset, 0) - min(self.poly_tap_offset, 0)
|
||||
|
||||
|
||||
# make the cells square so the pitch of wordlines will match bitlines
|
||||
|
||||
|
|
|
|||
|
|
@ -30,19 +30,12 @@ class rom_column_mux(pgate):
|
|||
self.output_layer= output_layer
|
||||
super().__init__(name)
|
||||
|
||||
|
||||
|
||||
def get_bl_names(self):
|
||||
return "bl"
|
||||
|
||||
|
||||
def create_netlist(self):
|
||||
self.add_pins()
|
||||
self.add_ptx()
|
||||
|
||||
def create_layout(self):
|
||||
|
||||
|
||||
self.pin_layer = self.input_layer
|
||||
self.pin_pitch = getattr(self, "{}_pitch".format(self.pin_layer))
|
||||
self.pin_width = getattr(self, "{}_width".format(self.pin_layer))
|
||||
|
|
@ -54,7 +47,6 @@ class rom_column_mux(pgate):
|
|||
else:
|
||||
self.col_mux_stack = self.m1_stack
|
||||
|
||||
|
||||
self.place_ptx()
|
||||
|
||||
self.width = self.bitcell.width
|
||||
|
|
@ -108,14 +100,6 @@ class rom_column_mux(pgate):
|
|||
+ vector(0.5 * self.bitcell.width- 0.5 * self.nmos.active_width, 0)
|
||||
self.nmos_lower.place(nmos_lower_position)
|
||||
|
||||
# # This aligns it directly above the other tx with gates abutting
|
||||
# nmos_upper_position = nmos_lower_position \
|
||||
# + vector(0, self.nmos.active_height + max(self.active_space, self.poly_space))
|
||||
# self.nmos_upper.place(nmos_upper_position)
|
||||
|
||||
# if cell_props.pgate.add_implants:
|
||||
# self.extend_implants()
|
||||
|
||||
def connect_poly(self):
|
||||
""" Connect the poly gate of the two pass transistors """
|
||||
|
||||
|
|
@ -137,7 +121,6 @@ class rom_column_mux(pgate):
|
|||
""" Connect the bitlines to the mux transistors """
|
||||
|
||||
bl_pin = self.get_pin("bl")
|
||||
# br_pin = self.get_pin("br")
|
||||
bl_out_pin = self.get_pin("bl_out")
|
||||
|
||||
nmos_lower_s_pin = self.nmos_lower.get_pin("S")
|
||||
|
|
@ -166,31 +149,11 @@ class rom_column_mux(pgate):
|
|||
self.add_path(self.output_layer,
|
||||
[bl_out_pin.uc(), mid1, mid2, nmos_lower_d_pin.center()])
|
||||
|
||||
|
||||
|
||||
def extend_implants(self):
|
||||
"""
|
||||
Add top-to-bottom implants for adjacency issues in s8.
|
||||
"""
|
||||
# Route to the bottom
|
||||
ll = (self.nmos_lower.ll() - vector(2 * [self.implant_enclose_active])).scale(1, 0)
|
||||
# Don't route to the top
|
||||
ur = self.nmos_upper.ur() + vector(self.implant_enclose_active, 0)
|
||||
self.add_rect("nimplant",
|
||||
ll,
|
||||
ur.x - ll.x,
|
||||
ur.y - ll.y)
|
||||
|
||||
def add_pn_wells(self):
|
||||
"""
|
||||
Add a well and implant over the whole cell. Also, add the
|
||||
pwell contact (if it exists)
|
||||
"""
|
||||
# if(cell_props.use_strap == True and OPTS.num_ports == 1):
|
||||
# strap = factory.create(module_type=cell_props.strap_module, version=cell_props.strap_version)
|
||||
# rbc_width = self.bitcell.width + strap.width
|
||||
# else:
|
||||
# rbc_width = self.bitcell.width
|
||||
# Add it to the right, aligned in between the two tx
|
||||
active_pos = vector(self.bitcell.width,
|
||||
self.nmos_lower.uy() + self.active_contact.height + self.active_space)
|
||||
|
|
|
|||
|
|
@ -30,7 +30,6 @@ class rom_column_mux_array(design):
|
|||
self.words_per_row = int(self.columns / self.word_size)
|
||||
self.input_layer = input_layer
|
||||
self.tap_spacing = tap_spacing
|
||||
# self.sel_layer = layer_props.column_mux_array.select_layer
|
||||
self.sel_layer = sel_layer
|
||||
|
||||
self.sel_pitch = getattr(self, self.sel_layer + "_pitch")
|
||||
|
|
@ -107,12 +106,6 @@ class rom_column_mux_array(design):
|
|||
|
||||
# For every column, add a pass gate
|
||||
for col_num, xoffset in enumerate(self.offsets[0:self.columns]):
|
||||
# if self.cell.mirror.y and (col_num + self.column_offset) % 2:
|
||||
# mirror = "MY"
|
||||
# xoffset = xoffset + self.mux.width
|
||||
# else:
|
||||
# mirror = ""
|
||||
|
||||
offset = vector(xoffset, self.route_height)
|
||||
self.mux_inst[col_num].place(offset=offset)
|
||||
|
||||
|
|
@ -206,11 +199,6 @@ class rom_column_mux_array(design):
|
|||
offset=bl_out_offset_begin,
|
||||
directions=self.via_directions)
|
||||
|
||||
|
||||
def add_taps(self):
|
||||
pass
|
||||
|
||||
|
||||
def graph_exclude_columns(self, column_include_num):
|
||||
"""
|
||||
Excludes all columns muxes unrelated to the target bit being simulated.
|
||||
|
|
|
|||
|
|
@ -14,9 +14,10 @@ from openram.tech import drc
|
|||
class rom_decoder(design):
|
||||
def __init__(self, num_outputs, fanout, strap_spacing, name="", route_layer="m1", output_layer="m1", invert_outputs=False):
|
||||
|
||||
# word lines/ rows / inputs in the base array become the address lines / cols / inputs in the decoder
|
||||
# bit lines / cols / outputs in the base array become the word lines / rows / outputs in the decoder
|
||||
# array gets rotated 90deg so that rows/cols switch
|
||||
# word lines in the base array become the address lines/cols in the decoder
|
||||
# bit lines in the base array become the word lines/rows in the decoder
|
||||
# array gets rotated 90deg so rows/cols switch
|
||||
|
||||
self.strap_spacing=strap_spacing
|
||||
self.num_outputs = num_outputs
|
||||
self.num_inputs = ceil(log(num_outputs, 2))
|
||||
|
|
@ -204,8 +205,6 @@ class rom_decoder(design):
|
|||
self.copy_layout_pin(self.wordline_buf_inst, "out_{}".format(j), "wl_{}".format(j))
|
||||
offset = self.wordline_buf_inst.get_pin("out_{}".format(j)).center()
|
||||
|
||||
# self.add_via_stack_center(offset, self.output_layer, self.wordline_buf.route_layer)
|
||||
|
||||
array_pins = [self.array_inst.get_pin("bl_0_{}".format(bl)) for bl in range(self.num_outputs)]
|
||||
driver_pins = [self.wordline_buf_inst.get_pin("in_{}".format(bl)) for bl in range(self.num_outputs)]
|
||||
|
||||
|
|
@ -233,8 +232,6 @@ class rom_decoder(design):
|
|||
self.add_path(self.inv_route_layer, [addr_bar_out_pin.center(), addr_bar_middle, addr_bar_pin.center()])
|
||||
self.copy_layout_pin(self.buf_inst, "A{}_in".format(i), "A{}".format(i))
|
||||
|
||||
# self.add_segment_center(self.inv_route_layer, addr_bar_middle + vector(0, self.inv_route_width * 0.5), addr_bar_out_pin.center() + vector(0, self.inv_route_width * 0.5), self.inv_route_width)
|
||||
|
||||
def route_supplies(self):
|
||||
|
||||
self.copy_layout_pin(self.array_inst, "vdd")
|
||||
|
|
|
|||
|
|
@ -38,8 +38,6 @@ class rom_poly_tap(design):
|
|||
|
||||
def add_boundary(self):
|
||||
contact_width = self.poly_contact.width
|
||||
|
||||
# offset = self.active_space - (contact_width - self.active_enclose_contact - self.active_extend_contact)
|
||||
self.height = self.dummy.height
|
||||
self.width = contact_width + self.pitch_offset
|
||||
|
||||
|
|
@ -82,7 +80,6 @@ class rom_poly_tap(design):
|
|||
def place_active_tap(self):
|
||||
gap = self.poly_extend_active - 0.5 * ( self.active_contact.height - self.poly_contact.width )
|
||||
offset = self.active_space - gap
|
||||
# tap_x = self.via.cx() + self.contact_width + self.active_enclose_contact + self.poly_enclose_contact
|
||||
tap_x = self.via.cx() + offset
|
||||
tap_y = self.via.cy() + self.dummy.width * 0.5
|
||||
contact_pos = vector(tap_x, tap_y)
|
||||
|
|
|
|||
|
|
@ -149,8 +149,6 @@ class rom_precharge_array(design):
|
|||
|
||||
def route_supply(self):
|
||||
|
||||
# self.vdd = self.add_layout_pin_segment_center("vdd", self.supply_layer, start, end)
|
||||
# vdd = [self.pmos_insts[i].get_pin("vdd") for i in range(self.cols)]routeroute_horizon_horizon
|
||||
self.route_horizontal_pins("vdd", insts=self.pmos_insts, layer=self.strap_layer)
|
||||
|
||||
def connect_taps(self):
|
||||
|
|
|
|||
|
|
@ -51,20 +51,10 @@ 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)
|
||||
|
||||
#contact to contact distance, minimum cell width before drc offsets
|
||||
self.base_width = self.pmos.width - 2 * self.active_enclose_contact - self.pmos.contact_width
|
||||
|
||||
# width offset to account for poly-active spacing between base and dummy cells on the same bitline
|
||||
self.poly_active_offset = 0.5 * (self.base_width - (self.poly_width + 2 * self.active_enclose_contact + self.pmos.contact_width)) - self.poly_to_active
|
||||
|
||||
#so that the poly taps are far enough apart
|
||||
self.poly_tap_offset = (self.base_width - self.poly_contact.width - self.poly_active_offset) - drc("poly_to_poly")
|
||||
|
||||
def extend_well(self):
|
||||
|
||||
well_y = self.get_pin("vdd").cy() - 0.5 * self.nwell_width
|
||||
well_ll = vector(0, well_y)
|
||||
# height = self.active_width + 2 * self.well_enclose_active
|
||||
height = self.get_pin("D").cy() + 0.5 * self.nwell_width - well_y
|
||||
self.add_rect("nwell", well_ll, self.width , height)
|
||||
|
||||
|
|
|
|||
|
|
@ -88,8 +88,6 @@ class rom_wordline_driver_array(design):
|
|||
"""
|
||||
|
||||
if layer_props.wordline_driver.vertical_supply:
|
||||
# self.route_vertical_pins("vdd", self.wld_inst)
|
||||
# self.route_vertical_pins("gnd", self.wld_inst)
|
||||
self.route_vertical_pins("vdd", [self], layer=self.supply_layer)
|
||||
self.route_vertical_pins("gnd", [self], layer=self.supply_layer)
|
||||
else:
|
||||
|
|
|
|||
Loading…
Reference in New Issue