Change control layers in sky130.

This commit is contained in:
mrg 2020-06-29 16:23:25 -07:00
parent bec948dcc3
commit 459e3789b8
4 changed files with 84 additions and 57 deletions

View File

@ -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):
"""

View File

@ -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)):

View File

@ -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()

View File

@ -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"""