mirror of https://github.com/VLSIDA/OpenRAM.git
Change control layers in sky130.
This commit is contained in:
parent
bec948dcc3
commit
459e3789b8
|
|
@ -592,6 +592,18 @@ class bank(design.design):
|
|||
self.copy_power_pins(inst, "vdd", add_vias=False)
|
||||
self.copy_power_pins(inst, "gnd", add_vias=False)
|
||||
|
||||
# If we use the pinvbuf as the decoder, we need to add power pins.
|
||||
# Other decoders already have them.
|
||||
if self.col_addr_size == 1:
|
||||
for port in self.all_ports:
|
||||
inst = self.column_decoder_inst[port]
|
||||
for pin_name in ["vdd", "gnd"]:
|
||||
pin_list = inst.get_pins(pin_name)
|
||||
for pin in pin_list:
|
||||
self.add_power_pin(pin_name,
|
||||
pin.center(),
|
||||
start_layer=pin.layer)
|
||||
|
||||
def route_bank_select(self, port):
|
||||
""" Route the bank select logic. """
|
||||
|
||||
|
|
@ -862,6 +874,13 @@ class bank(design.design):
|
|||
if not self.col_addr_size>0:
|
||||
return
|
||||
|
||||
if OPTS.tech_name == "sky130":
|
||||
stack = self.m2_stack
|
||||
pitch = self.m3_pitch
|
||||
else:
|
||||
stack = self.m1_stack
|
||||
pitch = self.m2_pitch
|
||||
|
||||
if self.col_addr_size == 1:
|
||||
|
||||
# Connect to sel[0] and sel[1]
|
||||
|
|
@ -881,9 +900,9 @@ class bank(design.design):
|
|||
self.copy_layout_pin(self.column_decoder_inst[port], decoder_name, addr_name)
|
||||
|
||||
if port % 2:
|
||||
offset = self.column_decoder_inst[port].ll() - vector(self.num_col_addr_lines * self.m2_nonpref_pitch, 0)
|
||||
offset = self.column_decoder_inst[port].ll() - vector(self.num_col_addr_lines * pitch, 0)
|
||||
else:
|
||||
offset = self.column_decoder_inst[port].lr() + vector(self.m2_nonpref_pitch, 0)
|
||||
offset = self.column_decoder_inst[port].lr() + vector(pitch, 0)
|
||||
|
||||
decode_pins = [self.column_decoder_inst[port].get_pin(x) for x in decode_names]
|
||||
|
||||
|
|
@ -891,16 +910,9 @@ class bank(design.design):
|
|||
column_mux_pins = [self.port_data_inst[port].get_pin(x) for x in sel_names]
|
||||
|
||||
route_map = list(zip(decode_pins, column_mux_pins))
|
||||
if "li" in layer:
|
||||
stack = self.li_stack
|
||||
directions = "pref"
|
||||
else:
|
||||
stack = self.m1_stack
|
||||
directions = "pref"
|
||||
self.create_vertical_channel_route(route_map,
|
||||
offset,
|
||||
stack,
|
||||
directions=directions)
|
||||
stack)
|
||||
|
||||
def add_lvs_correspondence_points(self):
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -30,6 +30,11 @@ class precharge_array(design.design):
|
|||
self.bitcell_br = bitcell_br
|
||||
self.column_offset = column_offset
|
||||
|
||||
if OPTS.tech_name == "sky130":
|
||||
self.en_bar_layer = "m3"
|
||||
else:
|
||||
self.en_bar_layer = "m1"
|
||||
|
||||
self.create_netlist()
|
||||
if not OPTS.netlist_only:
|
||||
self.create_layout()
|
||||
|
|
@ -74,21 +79,18 @@ class precharge_array(design.design):
|
|||
|
||||
def add_layout_pins(self):
|
||||
|
||||
en_bar_pin = self.pc_cell.get_pin("en_bar")
|
||||
if en_bar_pin.layer =="li":
|
||||
en_bar_layer = "m3"
|
||||
else:
|
||||
en_bar_layer = en_bar_pin.layer
|
||||
r = self.add_layout_pin(text="en_bar",
|
||||
layer=en_bar_layer,
|
||||
offset=en_bar_pin.ll(),
|
||||
width=self.width,
|
||||
height=en_bar_pin.height())
|
||||
self.add_via_stack_center(from_layer=en_bar_pin.layer,
|
||||
to_layer=en_bar_layer,
|
||||
offset = r.center())
|
||||
en_pin = self.pc_cell.get_pin("en_bar")
|
||||
start_offset = en_pin.lc().scale(0, 1)
|
||||
end_offset = start_offset + vector(self.width, 0)
|
||||
self.add_layout_pin_segment_center(text="en_bar",
|
||||
layer=self.en_bar_layer,
|
||||
start=start_offset,
|
||||
end=end_offset)
|
||||
|
||||
for inst in self.local_insts:
|
||||
self.add_via_stack_center(from_layer=en_pin.layer,
|
||||
to_layer=self.en_bar_layer,
|
||||
offset=inst.get_pin("en_bar").center())
|
||||
self.copy_layout_pin(inst, "vdd")
|
||||
|
||||
for i in range(len(self.local_insts)):
|
||||
|
|
|
|||
|
|
@ -37,6 +37,11 @@ class sense_amp_array(design.design):
|
|||
self.column_offset = column_offset
|
||||
self.row_size = self.word_size * self.words_per_row
|
||||
|
||||
if OPTS.tech_name == "sky130":
|
||||
self.en_layer = "m3"
|
||||
else:
|
||||
self.en_layer = "m1"
|
||||
|
||||
self.create_netlist()
|
||||
if not OPTS.netlist_only:
|
||||
self.create_layout()
|
||||
|
|
@ -173,14 +178,18 @@ class sense_amp_array(design.design):
|
|||
height=dout_pin.height())
|
||||
|
||||
def route_rails(self):
|
||||
# add sclk rail across entire array
|
||||
sclk = self.amp.get_pin(self.amp.en_name)
|
||||
sclk_offset = self.amp.get_pin(self.amp.en_name).ll().scale(0, 1)
|
||||
self.add_layout_pin(text=self.en_name,
|
||||
layer=sclk.layer,
|
||||
offset=sclk_offset,
|
||||
width=self.width,
|
||||
height=drc("minwidth_" + sclk.layer))
|
||||
# Add enable across the array
|
||||
en_pin = self.amp.get_pin(self.amp.en_name)
|
||||
start_offset = en_pin.lc().scale(0, 1)
|
||||
end_offset = start_offset + vector(self.width, 0)
|
||||
self.add_layout_pin_segment_center(text=self.en_name,
|
||||
layer=self.en_layer,
|
||||
start=start_offset,
|
||||
end=end_offset)
|
||||
for inst in self.local_insts:
|
||||
self.add_via_stack_center(from_layer=en_pin.layer,
|
||||
to_layer=self.en_layer,
|
||||
offset=inst.get_pin(self.amp.en_name).center())
|
||||
|
||||
def input_load(self):
|
||||
return self.amp.input_load()
|
||||
|
|
|
|||
|
|
@ -32,14 +32,16 @@ class single_level_column_mux_array(design.design):
|
|||
self.bitcell_br = bitcell_br
|
||||
self.column_offset = column_offset
|
||||
|
||||
if "li" in layer:
|
||||
self.col_mux_stack = self.m1_stack[::-1]
|
||||
self.col_mux_stack_pitch = self.m2_pitch
|
||||
if OPTS.tech_name == "sky130":
|
||||
self.sel_layer = "m3"
|
||||
self.sel_pitch = self.m3_pitch
|
||||
self.bitline_layer = "m1"
|
||||
else:
|
||||
self.col_mux_stack = self.m1_stack
|
||||
self.col_mux_stack_pitch = self.m1_pitch
|
||||
self.sel_layer = "m1"
|
||||
self.sel_pitch = self.m2_pitch
|
||||
self.bitline_layer = "m2"
|
||||
|
||||
if preferred_directions[self.col_mux_stack[0]] == "V":
|
||||
if preferred_directions[self.sel_layer] == "V":
|
||||
self.via_directions = ("H", "H")
|
||||
else:
|
||||
self.via_directions = "pref"
|
||||
|
|
@ -96,7 +98,7 @@ class single_level_column_mux_array(design.design):
|
|||
self.width = self.columns * self.mux.width
|
||||
# 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.col_mux_stack_pitch
|
||||
self.route_height = (self.words_per_row + 3) * self.sel_pitch
|
||||
|
||||
def create_array(self):
|
||||
self.mux_inst = []
|
||||
|
|
@ -157,9 +159,9 @@ class single_level_column_mux_array(design.design):
|
|||
def add_horizontal_input_rail(self):
|
||||
""" Create address input rails below the mux transistors """
|
||||
for j in range(self.words_per_row):
|
||||
offset = vector(0, self.route_height + (j - self.words_per_row) * self.col_mux_stack_pitch)
|
||||
offset = vector(0, self.route_height + (j - self.words_per_row) * self.sel_pitch)
|
||||
self.add_layout_pin(text="sel_{}".format(j),
|
||||
layer=self.col_mux_stack[0],
|
||||
layer=self.sel_layer,
|
||||
offset=offset,
|
||||
width=self.mux.width * self.columns)
|
||||
|
||||
|
|
@ -178,7 +180,7 @@ class single_level_column_mux_array(design.design):
|
|||
offset = vector(gate_offset.x,
|
||||
self.get_pin("sel_{}".format(sel_index)).cy())
|
||||
self.add_via_stack_center(from_layer="poly",
|
||||
to_layer=self.col_mux_stack[0],
|
||||
to_layer=self.sel_layer,
|
||||
offset=offset,
|
||||
directions=self.via_directions)
|
||||
self.add_path("poly", [offset, gate_offset])
|
||||
|
|
@ -190,42 +192,44 @@ class single_level_column_mux_array(design.design):
|
|||
bl_offset_begin = self.mux_inst[j].get_pin("bl_out").bc()
|
||||
br_offset_begin = self.mux_inst[j].get_pin("br_out").bc()
|
||||
|
||||
bl_out_offset_begin = bl_offset_begin - vector(0, (self.words_per_row + 1) * self.col_mux_stack_pitch)
|
||||
br_out_offset_begin = br_offset_begin - vector(0, (self.words_per_row + 2) * self.col_mux_stack_pitch)
|
||||
bl_out_offset_begin = bl_offset_begin - vector(0, (self.words_per_row + 1) * self.sel_pitch)
|
||||
br_out_offset_begin = br_offset_begin - vector(0, (self.words_per_row + 2) * self.sel_pitch)
|
||||
|
||||
# Add the horizontal wires for the first bit
|
||||
if j % self.words_per_row == 0:
|
||||
bl_offset_end = self.mux_inst[j + self.words_per_row - 1].get_pin("bl_out").bc()
|
||||
br_offset_end = self.mux_inst[j + self.words_per_row - 1].get_pin("br_out").bc()
|
||||
bl_out_offset_end = bl_offset_end - vector(0, (self.words_per_row + 1) * self.col_mux_stack_pitch)
|
||||
br_out_offset_end = br_offset_end - vector(0, (self.words_per_row + 2) * self.col_mux_stack_pitch)
|
||||
bl_out_offset_end = bl_offset_end - vector(0, (self.words_per_row + 1) * self.sel_pitch)
|
||||
br_out_offset_end = br_offset_end - vector(0, (self.words_per_row + 2) * self.sel_pitch)
|
||||
|
||||
self.add_path(self.col_mux_stack[0], [bl_out_offset_begin, bl_out_offset_end])
|
||||
self.add_path(self.col_mux_stack[0], [br_out_offset_begin, br_out_offset_end])
|
||||
self.add_path(self.sel_layer, [bl_out_offset_begin, bl_out_offset_end])
|
||||
self.add_path(self.sel_layer, [br_out_offset_begin, br_out_offset_end])
|
||||
|
||||
# Extend the bitline output rails and gnd downward on the first bit of each n-way mux
|
||||
self.add_layout_pin_segment_center(text="bl_out_{}".format(int(j / self.words_per_row)),
|
||||
layer=self.col_mux_stack[2],
|
||||
layer=self.bitline_layer,
|
||||
start=bl_offset_begin,
|
||||
end=bl_out_offset_begin)
|
||||
self.add_layout_pin_segment_center(text="br_out_{}".format(int(j / self.words_per_row)),
|
||||
layer=self.col_mux_stack[2],
|
||||
layer=self.bitline_layer,
|
||||
start=br_offset_begin,
|
||||
end=br_out_offset_begin)
|
||||
|
||||
else:
|
||||
self.add_path(self.col_mux_stack[2], [bl_out_offset_begin, bl_offset_begin])
|
||||
self.add_path(self.col_mux_stack[2], [br_out_offset_begin, br_offset_begin])
|
||||
self.add_path(self.bitline_layer, [bl_out_offset_begin, bl_offset_begin])
|
||||
self.add_path(self.bitline_layer, [br_out_offset_begin, br_offset_begin])
|
||||
|
||||
# This via is on the right of the wire
|
||||
self.add_via_center(layers=self.col_mux_stack,
|
||||
offset=bl_out_offset_begin,
|
||||
directions=self.via_directions)
|
||||
self.add_via_stack_center(from_layer=self.bitline_layer,
|
||||
to_layer=self.sel_layer,
|
||||
offset=bl_out_offset_begin,
|
||||
directions=self.via_directions)
|
||||
|
||||
# This via is on the left of the wire
|
||||
self.add_via_center(layers=self.col_mux_stack,
|
||||
offset=br_out_offset_begin,
|
||||
directions=self.via_directions)
|
||||
self.add_via_stack_center(from_layer=self.bitline_layer,
|
||||
to_layer=self.sel_layer,
|
||||
offset=br_out_offset_begin,
|
||||
directions=self.via_directions)
|
||||
|
||||
def get_drain_cin(self):
|
||||
"""Get the relative capacitance of the drain of the NMOS pass TX"""
|
||||
|
|
|
|||
Loading…
Reference in New Issue