Merge branch 'tech_migration' into dev

This commit is contained in:
mrg 2020-06-08 12:54:41 -07:00
commit 77fb7017c4
7 changed files with 105 additions and 101 deletions

View File

@ -219,8 +219,6 @@ class layout():
if not height:
height = drc["minwidth_{}".format(layer)]
lpp = techlayer[layer]
if abs(offset[0]-5.16250)<0.01 and abs(offset[1]-8.70750)<0.01:
import pdb; pdb.set_trace()
self.objs.append(geometry.rectangle(lpp,
offset,
width,
@ -838,51 +836,57 @@ class layout():
if not pitch:
pitch = getattr(self, "{}_pitch".format(layer))
line_positions = {}
pins = {}
if vertical:
for i in range(len(names)):
line_offset = offset + vector(i * pitch,
0)
if make_pins:
self.add_layout_pin(text=names[i],
layer=layer,
offset=line_offset,
height=length)
new_pin = self.add_layout_pin(text=names[i],
layer=layer,
offset=line_offset,
height=length)
else:
self.add_rect(layer=layer,
offset=line_offset,
height=length)
line_positions[names[i]] = line_offset + vector(half_minwidth, 0)
rect = self.add_rect(layer=layer,
offset=line_offset,
height=length)
new_pin = pin_layout(names[i],
[rect.ll(), rect.ur()],
layer)
pins[names[i]] = new_pin
else:
for i in range(len(names)):
line_offset = offset + vector(0,
i * pitch + half_minwidth)
if make_pins:
self.add_layout_pin(text=names[i],
layer=layer,
offset=line_offset,
width=length)
new_pin = self.add_layout_pin(text=names[i],
layer=layer,
offset=line_offset,
width=length)
else:
self.add_rect(layer=layer,
offset=line_offset,
width=length)
# Make this the center of the rail
line_positions[names[i]] = line_offset + vector(0.5 * length,
half_minwidth)
rect = self.add_rect(layer=layer,
offset=line_offset,
width=length)
new_pin = pin_layout(names[i],
[rect.ll(), rect.ur()],
layer)
pins[names[i]] = new_pin
return line_positions
return pins
def connect_horizontal_bus(self, mapping, inst, bus_offsets,
def connect_horizontal_bus(self, mapping, inst, bus_pins,
layer_stack=("m1", "via1", "m2")):
""" Horizontal version of connect_bus. """
self.connect_bus(mapping, inst, bus_offsets, layer_stack, True)
self.connect_bus(mapping, inst, bus_pins, layer_stack, True)
def connect_vertical_bus(self, mapping, inst, bus_offsets,
def connect_vertical_bus(self, mapping, inst, bus_pins,
layer_stack=("m1", "via1", "m2")):
""" Vertical version of connect_bus. """
self.connect_bus(mapping, inst, bus_offsets, layer_stack, False)
self.connect_bus(mapping, inst, bus_pins, layer_stack, False)
def connect_bus(self, mapping, inst, bus_offsets, layer_stack, horizontal):
def connect_bus(self, mapping, inst, bus_pins, layer_stack, horizontal):
"""
Connect a mapping of pin -> name for a bus. This could be
replaced with a channel router in the future.
@ -898,7 +902,7 @@ class layout():
for (pin_name, bus_name) in mapping:
pin = inst.get_pin(pin_name)
pin_pos = pin.center()
bus_pos = bus_offsets[bus_name]
bus_pos = bus_pins[bus_name].center()
if horizontal:
# up/down then left/right

View File

@ -601,7 +601,7 @@ class bank(design.design):
# Connect the inverter output to the central bus
out_pos = self.bank_select_inst[port].get_pin(gated_bank_sel_signals[signal]).rc()
name = self.control_signals[port][signal]
bus_pos = vector(self.bus_xoffset[port][name].x, out_pos.y)
bus_pos = vector(self.bus_pins[port][name].cx(), out_pos.y)
self.add_path("m3", [out_pos, bus_pos])
self.add_via_center(layers=self.m2_stack,
offset=bus_pos)
@ -636,19 +636,19 @@ class bank(design.design):
# Overall central bus width. It includes all the column mux lines,
# and control lines.
self.bus_xoffset = [None] * len(self.all_ports)
self.bus_pins = [None] * len(self.all_ports)
# Port 0
# The bank is at (0,0), so this is to the left of the y-axis.
# 2 pitches on the right for vias/jogs to access the inputs
control_bus_offset = vector(-self.m3_pitch * self.num_control_lines[0] - self.m3_pitch, self.min_y_offset)
# The control bus is routed up to two pitches below the bitcell array
control_bus_length = self.main_bitcell_array_bottom - self.min_y_offset - 2 * self.m1_pitch
self.bus_xoffset[0] = self.create_bus(layer="m2",
offset=control_bus_offset,
names=self.control_signals[0],
length=control_bus_length,
vertical=True,
make_pins=(self.num_banks==1))
self.bus_pins[0] = self.create_bus(layer="m2",
offset=control_bus_offset,
names=self.control_signals[0],
length=control_bus_length,
vertical=True,
make_pins=(self.num_banks==1))
# Port 1
if len(self.all_ports)==2:
@ -657,12 +657,12 @@ class bank(design.design):
control_bus_offset = vector(self.bitcell_array_right + self.m3_pitch,
self.max_y_offset - control_bus_length)
# The bus for the right port is reversed so that the rbl_wl is closest to the array
self.bus_xoffset[1] = self.create_bus(layer="m2",
offset=control_bus_offset,
names=list(reversed(self.control_signals[1])),
length=control_bus_length,
vertical=True,
make_pins=(self.num_banks==1))
self.bus_pins[1] = self.create_bus(layer="m2",
offset=control_bus_offset,
names=list(reversed(self.control_signals[1])),
length=control_bus_length,
vertical=True,
make_pins=(self.num_banks==1))
def route_port_data_to_bitcell_array(self, port):
""" Routing of BL and BR between port data and bitcell array """
@ -937,39 +937,32 @@ class bank(design.design):
# pre-decoder and this connection is in metal3
connection = []
connection.append((self.prefix + "p_en_bar{}".format(port),
self.port_data_inst[port].get_pin("p_en_bar").lc(),
self.port_data_inst[port].get_pin("p_en_bar").layer))
self.port_data_inst[port].get_pin("p_en_bar")))
rbl_wl_name = self.bitcell_array.get_rbl_wl_name(self.port_rbl_map[port])
connection.append((self.prefix + "wl_en{}".format(port),
self.bitcell_array_inst.get_pin(rbl_wl_name).lc(),
self.bitcell_array_inst.get_pin(rbl_wl_name).layer))
self.bitcell_array_inst.get_pin(rbl_wl_name)))
if port in self.write_ports:
if port % 2:
connection.append((self.prefix + "w_en{}".format(port),
self.port_data_inst[port].get_pin("w_en").rc(),
self.port_data_inst[port].get_pin("w_en").layer))
else:
connection.append((self.prefix + "w_en{}".format(port),
self.port_data_inst[port].get_pin("w_en").lc(),
self.port_data_inst[port].get_pin("w_en").layer))
connection.append((self.prefix + "w_en{}".format(port),
self.port_data_inst[port].get_pin("w_en")))
if port in self.read_ports:
connection.append((self.prefix + "s_en{}".format(port),
self.port_data_inst[port].get_pin("s_en").lc(),
self.port_data_inst[port].get_pin("s_en").layer))
self.port_data_inst[port].get_pin("s_en")))
for (control_signal, pin_pos, pin_layer) in connection:
if port==0:
y_offset = self.min_y_offset
else:
y_offset = self.max_y_offset
control_pos = vector(self.bus_xoffset[port][control_signal].x, y_offset)
if pin_layer == "m1":
self.add_wire(self.m1_stack, [control_pos, pin_pos])
elif pin_layer == "m3":
self.add_wire(self.m2_stack[::-1], [control_pos, pin_pos])
for (control_signal, pin) in connection:
control_pin = self.bus_pins[port][control_signal]
control_pos = vector(control_pin.cx(), pin.cy())
# If the y doesn't overlap the bus, add a segment
if pin.cy() < control_pin.by():
self.add_path("m2", [control_pos, control_pin.bc()])
elif pin.cy() > control_pin.uy():
self.add_path("m2", [control_pos, control_pin.uc()])
self.add_path(pin.layer, [control_pos, pin.center()])
self.add_via_stack_center(from_layer=pin.layer,
to_layer="m2",
offset=control_pos)
# clk to wordline_driver
control_signal = self.prefix + "wl_en{}".format(port)
@ -979,7 +972,7 @@ class bank(design.design):
else:
pin_pos = self.port_address_inst[port].get_pin("wl_en").bc()
mid_pos = pin_pos - vector(0, 2 * self.m2_gap) # to route down to the top of the bus
control_x_offset = self.bus_xoffset[port][control_signal].x
control_x_offset = self.bus_pins[port][control_signal].cx()
control_pos = vector(control_x_offset, mid_pos.y)
self.add_wire(self.m1_stack, [pin_pos, mid_pos, control_pos])
self.add_via_center(layers=self.m1_stack,

View File

@ -389,10 +389,10 @@ class control_logic(design.design):
height = self.control_logic_center.y - self.m2_pitch
offset = vector(self.ctrl_dff_array.width, 0)
self.rail_offsets = self.create_vertical_bus("m2",
offset,
self.internal_bus_list,
height)
self.input_bus = self.create_vertical_bus("m2",
offset,
self.internal_bus_list,
height)
def create_instances(self):
""" Create all the instances """
@ -498,7 +498,7 @@ class control_logic(design.design):
# Connect to the rail level with the vdd rail
# Use pen since it is in every type of control logic
vdd_ypos = self.p_en_bar_nand_inst.get_pin("vdd").by()
in_pos = vector(self.rail_offsets["rbl_bl_delay"].x, vdd_ypos)
in_pos = vector(self.input_bus["rbl_bl_delay"].cx(), vdd_ypos)
mid1 = vector(out_pos.x, in_pos.y)
self.add_wire(self.m1_stack, [out_pos, mid1, in_pos])
self.add_via_center(layers=self.m1_stack,
@ -553,7 +553,7 @@ class control_logic(design.design):
def route_gated_clk_bar(self):
clkbuf_map = zip(["A"], ["clk_buf"])
self.connect_vertical_bus(clkbuf_map, self.clk_bar_inst, self.rail_offsets)
self.connect_vertical_bus(clkbuf_map, self.clk_bar_inst, self.input_bus)
out_pos = self.clk_bar_inst.get_pin("Z").center()
in_pos = self.gated_clk_bar_inst.get_pin("A").center()
@ -563,7 +563,7 @@ class control_logic(design.design):
clkbuf_map = zip(["B"], ["cs"])
self.connect_vertical_bus(clkbuf_map,
self.gated_clk_bar_inst,
self.rail_offsets,
self.input_bus,
self.m2_stack[::-1])
# The pin is on M1, so we need another via as well
b_pin = self.gated_clk_bar_inst.get_pin("B")
@ -591,12 +591,12 @@ class control_logic(design.design):
clkbuf_map = zip(["A", "B"], ["clk_buf", "cs"])
self.connect_vertical_bus(clkbuf_map,
self.gated_clk_buf_inst,
self.rail_offsets)
self.input_bus)
clkbuf_map = zip(["Z"], ["gated_clk_buf"])
self.connect_vertical_bus(clkbuf_map,
self.gated_clk_buf_inst,
self.rail_offsets,
self.input_bus,
self.m2_stack[::-1])
# The pin is on M1, so we need another via as well
z_pin = self.gated_clk_buf_inst.get_pin("Z")
@ -619,7 +619,7 @@ class control_logic(design.design):
def route_wlen(self):
wlen_map = zip(["A"], ["gated_clk_bar"])
self.connect_vertical_bus(wlen_map, self.wl_en_inst, self.rail_offsets)
self.connect_vertical_bus(wlen_map, self.wl_en_inst, self.input_bus)
self.connect_output(self.wl_en_inst, "Z", "wl_en")
@ -644,7 +644,7 @@ class control_logic(design.design):
def route_pen(self):
in_map = zip(["A", "B"], ["gated_clk_buf", "rbl_bl_delay"])
self.connect_vertical_bus(in_map, self.p_en_bar_nand_inst, self.rail_offsets)
self.connect_vertical_bus(in_map, self.p_en_bar_nand_inst, self.input_bus)
out_pin = self.p_en_bar_nand_inst.get_pin("Z")
out_pos = out_pin.center()
@ -687,7 +687,7 @@ class control_logic(design.design):
input_name = "cs"
sen_map = zip(["A", "B", "C"], ["rbl_bl_delay", "gated_clk_bar", input_name])
self.connect_vertical_bus(sen_map, self.s_en_gate_inst, self.rail_offsets)
self.connect_vertical_bus(sen_map, self.s_en_gate_inst, self.input_bus)
self.connect_output(self.s_en_gate_inst, "Z", "s_en")
@ -711,7 +711,7 @@ class control_logic(design.design):
self.route_output_to_bus_jogged(self.rbl_bl_delay_inv_inst, "rbl_bl_delay_bar")
rbl_map = zip(["A"], ["rbl_bl_delay"])
self.connect_vertical_bus(rbl_map, self.rbl_bl_delay_inv_inst, self.rail_offsets)
self.connect_vertical_bus(rbl_map, self.rbl_bl_delay_inv_inst, self.input_bus)
def create_wen_row(self):
@ -743,7 +743,7 @@ class control_logic(design.design):
input_name = "cs"
wen_map = zip(["A", "B", "C"], [input_name, "rbl_bl_delay_bar", "gated_clk_bar"])
self.connect_vertical_bus(wen_map, self.w_en_gate_inst, self.rail_offsets)
self.connect_vertical_bus(wen_map, self.w_en_gate_inst, self.input_bus)
self.connect_output(self.w_en_gate_inst, "Z", "w_en")
@ -766,13 +766,13 @@ class control_logic(design.design):
dff_out_map = zip(["dout_bar_0", "dout_0"], ["cs", "cs_bar"])
else:
dff_out_map = zip(["dout_bar_0"], ["cs"])
self.connect_vertical_bus(dff_out_map, self.ctrl_dff_inst, self.rail_offsets, self.m2_stack[::-1])
self.connect_vertical_bus(dff_out_map, self.ctrl_dff_inst, self.input_bus, self.m2_stack[::-1])
# Connect the clock rail to the other clock rail
# by routing in the supply rail track to avoid channel conflicts
in_pos = self.ctrl_dff_inst.get_pin("clk").uc()
mid_pos = in_pos + vector(0, self.and2.height)
rail_pos = vector(self.rail_offsets["clk_buf"].x, mid_pos.y)
rail_pos = vector(self.input_bus["clk_buf"].cx(), mid_pos.y)
self.add_wire(self.m1_stack, [in_pos, mid_pos, rail_pos])
self.add_via_center(layers=self.m1_stack,
offset=rail_pos)
@ -1006,8 +1006,8 @@ class control_logic(design.design):
# Connect this at the bottom of the buffer
out_pos = inst.get_pin("Z").center()
mid1 = vector(out_pos.x, out_pos.y - 0.25 * inst.mod.height)
mid2 = vector(self.rail_offsets[name].x, mid1.y)
bus_pos = self.rail_offsets[name]
mid2 = vector(self.input_bus[name].cx(), mid1.y)
bus_pos = self.input_bus[name].center()
self.add_wire(self.m2_stack[::-1], [out_pos, mid1, mid2, bus_pos])
# The pin is on M1, so we need another via as well
self.add_via_center(layers=self.m1_stack,

View File

@ -209,7 +209,7 @@ class hierarchical_decoder(design.design):
for i in range(2):
index = pre_num * 2 + i
input_pos = self.input_bus["addr_{}".format(index)]
input_pos = self.input_bus["addr_{}".format(index)].center()
in_name = "in_{}".format(i)
decoder_pin = self.pre2x4_inst[pre_num].get_pin(in_name)
@ -223,7 +223,7 @@ class hierarchical_decoder(design.design):
for i in range(3):
index = pre_num * 3 + i + self.no_of_pre2x4 * 2
input_pos = self.input_bus["addr_{}".format(index)]
input_pos = self.input_bus["addr_{}".format(index)].center()
in_name = "in_{}".format(i)
decoder_pin = self.pre3x8_inst[pre_num].get_pin(in_name)
@ -572,7 +572,7 @@ class hierarchical_decoder(design.design):
"""
pin_pos = pin.center()
rail_pos = vector(self.predecode_bus[rail_name].x, pin_pos.y)
rail_pos = vector(self.predecode_bus[rail_name].cx(), pin_pos.y)
self.add_path(self.input_layer, [rail_pos, pin_pos])
self.add_via_stack_center(from_layer=self.bus_layer,
@ -595,11 +595,11 @@ class hierarchical_decoder(design.design):
pin_pos = pin.rc()
mid_point1 = vector(x_offset, pin_pos.y)
mid_point2 = vector(x_offset, y_offset)
rail_pos = vector(self.predecode_bus[rail_name].x, mid_point2.y)
rail_pos = vector(self.predecode_bus[rail_name].cx(), mid_point2.y)
self.add_path(self.output_layer, [pin_pos, mid_point1, mid_point2, rail_pos])
# pin_pos = pin.center()
# rail_pos = vector(self.predecode_bus[rail_name].x, pin_pos.y)
# rail_pos = vector(self.predecode_bus[rail_name].cx(), pin_pos.y)
# self.add_path(self.output_layer, [pin_pos, rail_pos])
self.add_via_stack_center(from_layer=pin.layer,
to_layer=self.output_layer,

View File

@ -202,15 +202,15 @@ class hierarchical_predecode(design.design):
y_offset = pin.cy()
in_pin = "in_{}".format(num)
a_pin = "A_{}".format(num)
in_pos = vector(self.input_rails[in_pin].x, y_offset)
a_pos = vector(self.decode_rails[a_pin].x, y_offset)
in_pos = vector(self.input_rails[in_pin].cx(), y_offset)
a_pos = vector(self.decode_rails[a_pin].cx(), y_offset)
self.add_path(self.input_layer, [in_pos, a_pos])
self.add_via_stack_center(from_layer=self.input_layer,
to_layer=self.bus_layer,
offset=[self.input_rails[in_pin].x, y_offset])
offset=[self.input_rails[in_pin].cx(), y_offset])
self.add_via_stack_center(from_layer=self.input_layer,
to_layer=self.bus_layer,
offset=[self.decode_rails[a_pin].x, y_offset])
offset=[self.decode_rails[a_pin].cx(), y_offset])
def route_output_and(self):
"""
@ -240,12 +240,12 @@ class hierarchical_predecode(design.design):
# since this is where the p/n devices are and there are no
# pins in the and gates.
if OPTS.tech_name == "s8":
rail_pos = vector(self.decode_rails[out_pin].x, inv_out_pos.y)
rail_pos = vector(self.decode_rails[out_pin].cx(), inv_out_pos.y)
self.add_path(self.output_layer, [inv_out_pos, rail_pos])
else:
y_offset = (inv_num + 1) * self.inv.height - self.output_layer_pitch
right_pos = inv_out_pos + vector(self.inv.width - self.inv.get_pin("Z").rx(), 0)
rail_pos = vector(self.decode_rails[out_pin].x, y_offset)
rail_pos = vector(self.decode_rails[out_pin].cx(), y_offset)
self.add_path(self.output_layer, [inv_out_pos, right_pos, vector(right_pos.x, y_offset), rail_pos])
self.add_via_stack_center(from_layer=inv_out_pin.layer,
@ -259,7 +259,7 @@ class hierarchical_predecode(design.design):
# route input
pin = self.inv_inst[inv_num].get_pin("A")
inv_in_pos = pin.center()
in_pos = vector(self.input_rails[in_pin].x, inv_in_pos.y)
in_pos = vector(self.input_rails[in_pin].cx(), inv_in_pos.y)
self.add_path(self.input_layer, [in_pos, inv_in_pos])
self.add_via_stack_center(from_layer=pin.layer,
to_layer=self.input_layer,
@ -290,7 +290,7 @@ class hierarchical_predecode(design.design):
for rail_pin, gate_pin in zip(index_lst, gate_lst):
pin = self.and_inst[k].get_pin(gate_pin)
pin_pos = pin.center()
rail_pos = vector(self.decode_rails[rail_pin].x, pin_pos.y)
rail_pos = vector(self.decode_rails[rail_pin].cx(), pin_pos.y)
self.add_path(self.input_layer, [rail_pos, pin_pos])
self.add_via_stack_center(from_layer=self.input_layer,
to_layer=self.bus_layer,

View File

@ -10,6 +10,7 @@ import debug
from vector import vector
from sram_factory import factory
from globals import OPTS
from tech import layer
class precharge_array(design.design):

View File

@ -13,7 +13,7 @@ from tech import parameter
from vector import vector
from globals import OPTS
from sram_factory import factory
from tech import drc
from tech import drc, layer
class precharge(design.design):
@ -38,10 +38,16 @@ class precharge(design.design):
if self.bitcell_bl_pin.layer == "m1":
self.bitline_layer = "m1"
self.en_layer = "m2"
if "li" in layer:
self.en_layer = "li"
else:
self.en_layer = "m2"
else:
self.bitline_layer = "m2"
self.en_layer = "m1"
if "li" in layer:
self.en_layer = "li"
else:
self.en_layer = "m1"
# Creates the netlist and layout
# Since it has variable height, it is not a pgate.