Use layer stacks from tech file in design class and throughout

This commit is contained in:
Matt Guthaus 2019-12-13 14:13:41 -08:00
parent 8d3f1d19cb
commit e143a6033f
28 changed files with 141 additions and 132 deletions

View File

@ -245,14 +245,14 @@ else:
lim1 = None
m1m2 = factory.create(module_type="contact",
layer_stack=metal1_stack,
layer_stack=m1_stack,
directions=("H", "V"))
m2m3 = factory.create(module_type="contact",
layer_stack=metal2_stack,
layer_stack=m2_stack,
directions=("V", "H"))
if "metal4" in layer.keys():
m3m4 = factory.create(module_type="contact",
layer_stack=metal3_stack,
layer_stack=m3_stack,
directions=("H", "V"))
else:
m3m4 = None

View File

@ -13,7 +13,7 @@ from globals import OPTS
class design(hierarchy_design):
"""
This is the same as the hierarchy_design class except it contains
some DRC constants and analytical models for other modules to reuse.
some DRC/layer constants and analytical models for other modules to reuse.
"""
@ -21,16 +21,28 @@ class design(hierarchy_design):
hierarchy_design.__init__(self, name)
self.setup_drc_constants()
self.setup_layer_constants()
self.setup_multiport_constants()
from tech import layer
def setup_layer_constants(self):
""" These are some layer constants used in many places in the compiler."""
import tech
self.m1_pitch = max(contact.m1m2.width, contact.m1m2.height) + max(self.m1_space, self.m2_space)
self.m2_pitch = max(contact.m2m3.width, contact.m2m3.height) + max(self.m2_space, self.m3_space)
if "metal4" in layer:
if "metal4" in tech.layer:
self.m3_pitch = max(contact.m3m4.width, contact.m3m4.height) + max(self.m3_space, self.m4_space)
else:
self.m3_pitch = self.m2_pitch
self.poly_stack = tech.poly_stack
self.active_stack = tech.active_stack
self.m1_stack = tech.m1_stack
self.m2_stack = tech.m2_stack
self.m3_stack = tech.m3_stack
def setup_drc_constants(self):
""" These are some DRC constants used in many places in the compiler."""
from tech import drc, layer

View File

@ -824,7 +824,7 @@ class layout():
def create_channel_route(self, netlist,
offset,
layer_stack=("metal1", "via1", "metal2"),
layer_stack,
vertical=False):
"""
The net list is a list of the nets. Each net is a list of pins
@ -950,15 +950,13 @@ class layout():
offset += vector(0,self.horizontal_pitch)
def create_vertical_channel_route(self, netlist, offset,
layer_stack=("metal1", "via1", "metal2")):
def create_vertical_channel_route(self, netlist, offset, layer_stack):
"""
Wrapper to create a vertical channel route
"""
self.create_channel_route(netlist, offset, layer_stack, vertical=True)
def create_horizontal_channel_route(self, netlist, offset,
layer_stack=("metal1", "via1", "metal2")):
def create_horizontal_channel_route(self, netlist, offset, layer_stack):
"""
Wrapper to create a horizontal channel route
"""
@ -1028,13 +1026,13 @@ class layout():
direction=("H","H")
if start_layer=="metal1":
self.add_via_center(layers=("metal1", "via1", "metal2"),
self.add_via_center(layers=self.m1_stack,
offset=loc,
directions=direction)
if start_layer=="metal1" or start_layer=="metal2":
via=self.add_via_center(layers=("metal2", "via2", "metal3"),
via=self.add_via_center(layers=self.m2_stack,
offset=loc,
directions=direction)
@ -1159,7 +1157,7 @@ class layout():
vector(self.right_vdd_x_center, self.top_vdd_y_center)]
for pt in via_points:
self.add_via_center(layers=("metal1", "via1", "metal2"),
self.add_via_center(layers=self.m1_stack,
offset=pt,
size = (self.supply_vias, self.supply_vias))

View File

@ -378,7 +378,7 @@ class pbitcell(bitcell_base.bitcell_base):
contact_offset_left = vector(self.inverter_nmos_left.get_pin("D").rc().x \
+ 0.5 * contact.poly.height,
self.cross_couple_upper_ypos)
self.add_via_center(layers=("poly", "contact", "metal1"),
self.add_via_center(layers=self.poly_stack,
offset=contact_offset_left,
directions=("H", "H"))
@ -386,7 +386,7 @@ class pbitcell(bitcell_base.bitcell_base):
contact_offset_right = vector(self.inverter_nmos_right.get_pin("S").lc().x \
- 0.5*contact.poly.height,
self.cross_couple_lower_ypos)
self.add_via_center(layers=("poly", "contact", "metal1"),
self.add_via_center(layers=self.poly_stack,
offset=contact_offset_right,
directions=("H", "H"))
@ -771,7 +771,7 @@ class pbitcell(bitcell_base.bitcell_base):
# first transistor on either side of the cross coupled inverters
# does not need to route to wordline on metal2
if (k == 0) or (k == 1):
self.add_via_center(layers=("poly", "contact", "metal1"),
self.add_via_center(layers=self.poly_stack,
offset=port_contact_offset)
self.add_path("poly", [gate_offset, port_contact_offset])
@ -779,12 +779,12 @@ class pbitcell(bitcell_base.bitcell_base):
[port_contact_offset, wl_contact_offset])
else:
self.add_via_center(layers=("poly", "contact", "metal1"),
self.add_via_center(layers=self.poly_stack,
offset=port_contact_offset)
self.add_via_center(layers=("metal1", "via1", "metal2"),
self.add_via_center(layers=self.m1_stack,
offset=port_contact_offset)
self.add_via_center(layers=("metal1", "via1", "metal2"),
self.add_via_center(layers=self.m1_stack,
offset=wl_contact_offset,
directions=("H", "H"))
@ -824,7 +824,7 @@ class pbitcell(bitcell_base.bitcell_base):
# Leave bitline disconnected if a dummy cell
if not self.dummy_bitcell:
self.add_via_center(layers=("metal1", "via1", "metal2"),
self.add_via_center(layers=self.m1_stack,
offset=port_contact_offest)
self.add_path("metal2",
@ -836,7 +836,7 @@ class pbitcell(bitcell_base.bitcell_base):
# Leave bitline disconnected if a dummy cell
if not self.dummy_bitcell:
self.add_via_center(layers=("metal1", "via1", "metal2"),
self.add_via_center(layers=self.m1_stack,
offset=port_contact_offest)
self.add_path("metal2",
@ -853,7 +853,7 @@ class pbitcell(bitcell_base.bitcell_base):
nmos_contact_positions.append(self.read_access_nmos_right[k].get_pin("S").center())
for position in nmos_contact_positions:
self.add_via_center(layers=("metal1", "via1", "metal2"),
self.add_via_center(layers=self.m1_stack,
offset=position)
if position.x > 0:
@ -862,7 +862,7 @@ class pbitcell(bitcell_base.bitcell_base):
contact_correct = -0.5 * contact.m1m2.height
supply_offset = vector(position.x + contact_correct,
self.gnd_position.y)
self.add_via_center(layers=("metal1", "via1", "metal2"),
self.add_via_center(layers=self.m1_stack,
offset=supply_offset,
directions=("H", "H"))
@ -928,14 +928,14 @@ class pbitcell(bitcell_base.bitcell_base):
left_storage_contact = vector(self.inverter_nmos_left.get_pin("G").lc().x \
- self.poly_to_contact - 0.5*contact.poly.width,
self.cross_couple_upper_ypos)
self.add_via_center(layers=("poly", "contact", "metal1"),
self.add_via_center(layers=self.poly_stack,
offset=left_storage_contact,
directions=("H", "H"))
right_storage_contact = vector(self.inverter_nmos_right.get_pin("G").rc().x \
+ self.poly_to_contact + 0.5*contact.poly.width,
self.cross_couple_upper_ypos)
self.add_via_center(layers=("poly", "contact", "metal1"),
self.add_via_center(layers=self.poly_stack,
offset=right_storage_contact,
directions=("H", "H"))
@ -952,7 +952,7 @@ class pbitcell(bitcell_base.bitcell_base):
+ vector(0,
self.gate_contact_yoffset - self.poly_extend_active)
self.add_via_center(layers=("poly", "contact", "metal1"),
self.add_via_center(layers=self.poly_stack,
offset=port_contact_offset)
self.add_path("poly",
@ -967,7 +967,7 @@ class pbitcell(bitcell_base.bitcell_base):
+ vector(0,
self.gate_contact_yoffset - self.poly_extend_active)
self.add_via_center(layers=("poly", "contact", "metal1"),
self.add_via_center(layers=self.poly_stack,
offset=port_contact_offset)
self.add_path("poly",

View File

@ -606,11 +606,11 @@ class bank(design.design):
name = self.control_signals[port][signal]
bus_pos = vector(self.bus_xoffset[port][name].x, out_pos.y)
self.add_path("metal3",[out_pos, bus_pos])
self.add_via_center(layers=("metal2", "via2", "metal3"),
self.add_via_center(layers=self.m2_stack,
offset=bus_pos)
self.add_via_center(layers=("metal1", "via1", "metal2"),
self.add_via_center(layers=self.m1_stack,
offset=out_pos)
self.add_via_center(layers=("metal2", "via2", "metal3"),
self.add_via_center(layers=self.m2_stack,
offset=out_pos)
@ -756,7 +756,7 @@ class bank(design.design):
bottom_names = [bottom_inst.get_pin(bottom_bl_name.format(bit)), bottom_inst.get_pin(bottom_br_name.format(bit))]
top_names = [top_inst.get_pin(top_bl_name.format(bit)), top_inst.get_pin(top_br_name.format(bit))]
route_map = list(zip(bottom_names, top_names))
self.create_horizontal_channel_route(route_map, offset)
self.create_horizontal_channel_route(route_map, offset, self.m1_stack)
def connect_bitline(self, inst1, inst2, inst1_name, inst2_name):
"""
@ -865,7 +865,7 @@ 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))
self.create_vertical_channel_route(route_map, offset)
self.create_vertical_channel_route(route_map, offset, self.m1_stack)
def add_lvs_correspondence_points(self):
@ -942,7 +942,7 @@ class bank(design.design):
control_mid_pos = self.bus_xoffset[port][control_signal]
control_pos = vector(self.bus_xoffset[port][control_signal].x ,pin_pos.y)
self.add_wire(("metal1","via1","metal2"), [control_mid_pos, control_pos, pin_pos])
self.add_via_center(layers=("metal1", "via1", "metal2"),
self.add_via_center(layers=self.m1_stack,
offset=control_pos)
@ -957,7 +957,7 @@ class bank(design.design):
control_x_offset = self.bus_xoffset[port][control_signal].x
control_pos = vector(control_x_offset, mid_pos.y)
self.add_wire(("metal1","via1","metal2"),[pin_pos, mid_pos, control_pos])
self.add_via_center(layers=("metal1", "via1", "metal2"),
self.add_via_center(layers=self.m1_stack,
offset=control_pos)
def determine_wordline_stage_efforts(self, external_cout, inp_is_rise=True):

View File

@ -258,7 +258,7 @@ class bank_select(design.design):
logic_pos = logic_inst.get_pin("B").lc() - vector(0.5*contact.m1m2.height,0)
input_pos = vector(xoffset_bank_signal, logic_pos.y)
self.add_path("metal2",[logic_pos, input_pos])
self.add_via_center(layers=("metal1", "via1", "metal2"),
self.add_via_center(layers=self.m1_stack,
offset=logic_pos,
directions=("H","H"))
@ -266,10 +266,10 @@ class bank_select(design.design):
# Connect the logic A input to the input pin
logic_pos = logic_inst.get_pin("A").lc()
input_pos = vector(0,logic_pos.y)
self.add_via_center(layers=("metal1", "via1", "metal2"),
self.add_via_center(layers=self.m1_stack,
offset=logic_pos,
directions=("H","H"))
self.add_via_center(layers=("metal2", "via2", "metal3"),
self.add_via_center(layers=self.m2_stack,
offset=logic_pos,
directions=("H","H"))
self.add_layout_pin_segment_center(text=input_name,
@ -301,10 +301,10 @@ class bank_select(design.design):
# Add pins in two locations
for xoffset in [a_xoffset, b_xoffset]:
pin_pos = vector(xoffset, supply_pin.cy())
self.add_via_center(layers=("metal1", "via1", "metal2"),
self.add_via_center(layers=self.m1_stack,
offset=pin_pos,
directions=("H","H"))
self.add_via_center(layers=("metal2", "via2", "metal3"),
self.add_via_center(layers=self.m2_stack,
offset=pin_pos,
directions=("H","H"))
self.add_layout_pin_rect_center(text=n,

View File

@ -221,9 +221,9 @@ class hierarchical_decoder(design.design):
def route_input_rail(self, input_offset, output_offset):
""" Route a vertical M2 coordinate to another vertical M2 coordinate to the predecode inputs """
self.add_via_center(layers=("metal2", "via2", "metal3"),
self.add_via_center(layers=self.m2_stack,
offset=input_offset)
self.add_via_center(layers=("metal2", "via2", "metal3"),
self.add_via_center(layers=self.m2_stack,
offset=output_offset)
self.add_path(("metal3"), [input_offset, output_offset])
@ -585,7 +585,7 @@ class hierarchical_decoder(design.design):
""" Connect the routing rail to the given metal1 pin """
rail_pos = vector(self.predecode_rails[rail_name].x,pin.lc().y)
self.add_path("metal1", [rail_pos, pin.lc()])
self.add_via_center(layers=("metal1", "via1", "metal2"),
self.add_via_center(layers=self.m1_stack,
offset=rail_pos)
@ -595,10 +595,10 @@ class hierarchical_decoder(design.design):
# It would be fixed with a channel router.
mid_point = vector(pin.cx(), pin.cy()+self.inv.height/2)
rail_pos = vector(self.predecode_rails[rail_name].x,mid_point.y)
self.add_via_center(layers=("metal1", "via1", "metal2"),
self.add_via_center(layers=self.m1_stack,
offset=pin.center())
self.add_wire(("metal3","via2","metal2"), [rail_pos, mid_point, pin.uc()])
self.add_via_center(layers=("metal2", "via2", "metal3"),
self.add_via_center(layers=self.m2_stack,
offset=rail_pos)
def input_load(self):

View File

@ -184,9 +184,9 @@ class hierarchical_predecode(design.design):
in_pos = vector(self.input_rails[in_pin].x,y_offset)
a_pos = vector(self.decode_rails[a_pin].x,y_offset)
self.add_path("metal1",[in_pos, a_pos])
self.add_via_center(layers = ("metal1", "via1", "metal2"),
self.add_via_center(layers = self.m1_stack,
offset=[self.input_rails[in_pin].x, y_offset])
self.add_via_center(layers = ("metal1", "via1", "metal2"),
self.add_via_center(layers = self.m1_stack,
offset=[self.decode_rails[a_pin].x, y_offset])
def route_output_inverters(self):
@ -227,7 +227,7 @@ class hierarchical_predecode(design.design):
right_pos = inv_out_pos + vector(self.inv.width - self.inv.get_pin("Z").lx(),0)
rail_pos = vector(self.decode_rails[out_pin].x,y_offset)
self.add_path("metal1", [inv_out_pos, right_pos, vector(right_pos.x, y_offset), rail_pos])
self.add_via_center(layers = ("metal1", "via1", "metal2"),
self.add_via_center(layers = self.m1_stack,
offset=rail_pos)
@ -235,7 +235,7 @@ class hierarchical_predecode(design.design):
inv_in_pos = self.in_inst[inv_num].get_pin("A").lc()
in_pos = vector(self.input_rails[in_pin].x,inv_in_pos.y)
self.add_path("metal1", [in_pos, inv_in_pos])
self.add_via_center(layers=("metal1", "via1", "metal2"),
self.add_via_center(layers=self.m1_stack,
offset=in_pos)
@ -256,7 +256,7 @@ class hierarchical_predecode(design.design):
pin_pos = self.nand_inst[k].get_pin(gate_pin).lc()
rail_pos = vector(self.decode_rails[rail_pin].x, pin_pos.y)
self.add_path("metal1", [rail_pos, pin_pos])
self.add_via_center(layers=("metal1", "via1", "metal2"),
self.add_via_center(layers=self.m1_stack,
offset=rail_pos)

View File

@ -452,13 +452,13 @@ class multibank(design.design):
out_pos = self.bank_select_inst.get_pin(gated_name).rc()
bus_pos = vector(self.bus_xoffset[gated_name], out_pos.y)
self.add_path("metal3",[out_pos, bus_pos])
self.add_via_center(layers=("metal2", "via2", "metal3"),
self.add_via_center(layers=self.m2_stack,
offset=bus_pos,
rotate=90)
self.add_via_center(layers=("metal1", "via1", "metal2"),
self.add_via_center(layers=self.m1_stack,
offset=out_pos,
rotate=90)
self.add_via_center(layers=("metal2", "via2", "metal3"),
self.add_via_center(layers=self.m2_stack,
offset=out_pos,
rotate=90)
@ -586,9 +586,9 @@ class multibank(design.design):
tri_gate_in = self.tri_gate_array_inst.get_pin("in_{}".format(i)).lc()
sa_data_out = self.sense_amp_array_inst.get_pin("data_{}".format(i)).bc()
self.add_via_center(layers=("metal2", "via2", "metal3"),
self.add_via_center(layers=self.m2_stack,
offset=tri_gate_in)
self.add_via_center(layers=("metal2", "via2", "metal3"),
self.add_via_center(layers=self.m2_stack,
offset=sa_data_out)
self.add_path("metal3",[sa_data_out,tri_gate_in])
@ -766,7 +766,7 @@ class multibank(design.design):
for (control_signal, pin_pos) in connection:
control_pos = vector(self.bus_xoffset[control_signal].x ,pin_pos.y)
self.add_path("metal1", [control_pos, pin_pos])
self.add_via_center(layers=("metal1", "via1", "metal2"),
self.add_via_center(layers=self.m1_stack,
offset=control_pos,
rotate=90)
@ -778,7 +778,7 @@ class multibank(design.design):
control_pos = vector(control_x_offset + self.m1_width, mid_pos.y)
self.add_wire(("metal1","via1","metal2"),[pin_pos, mid_pos, control_pos])
control_via_pos = vector(control_x_offset, mid_pos.y)
self.add_via_center(layers=("metal1", "via1", "metal2"),
self.add_via_center(layers=self.m1_stack,
offset=control_via_pos,
rotate=90)

View File

@ -475,7 +475,7 @@ class port_data(design.design):
end_pos = vector(length, wdriver_en_pin.cy())
# Add via for the write driver array's enable input
self.add_via_center(layers=("metal1", "via1", "metal2"),
self.add_via_center(layers=self.m1_stack,
offset=end_pos)
# Route between write mask AND array and write driver array
@ -626,7 +626,7 @@ class port_data(design.design):
bottom_names = [bottom_inst.get_pin(bottom_bl_name.format(bit+bottom_start_bit)), bottom_inst.get_pin(bottom_br_name.format(bit+bottom_start_bit))]
top_names = [top_inst.get_pin(top_bl_name.format(bit+top_start_bit)), top_inst.get_pin(top_br_name.format(bit+top_start_bit))]
route_map = list(zip(bottom_names, top_names))
self.create_horizontal_channel_route(route_map, offset)
self.create_horizontal_channel_route(route_map, offset, self.m1_stack)
def connect_bitlines(self, inst1, inst2, num_bits,

View File

@ -99,13 +99,13 @@ class sense_amp_array(design.design):
inst = self.local_insts[i]
gnd_pos = inst.get_pin("gnd").center()
self.add_via_center(layers=("metal2", "via2", "metal3"),
self.add_via_center(layers=self.m2_stack,
offset=gnd_pos)
self.add_layout_pin_rect_center(text="gnd",
layer="metal3",
offset=gnd_pos)
vdd_pos = inst.get_pin("vdd").center()
self.add_via_center(layers=("metal2", "via2", "metal3"),
self.add_via_center(layers=self.m2_stack,
offset=vdd_pos)
self.add_layout_pin_rect_center(text="vdd",
layer="metal3",

View File

@ -191,11 +191,11 @@ class single_level_column_mux_array(design.design):
# This via is on the right of the wire
self.add_via_center(layers=("metal1", "via1", "metal2"),
self.add_via_center(layers=self.m1_stack,
offset=bl_out_offset)
# This via is on the left of the wire
self.add_via_center(layers=("metal1", "via1", "metal2"),
self.add_via_center(layers=self.m1_stack,
offset=br_out_offset)
else:
@ -204,10 +204,10 @@ class single_level_column_mux_array(design.design):
self.add_path("metal2", [ br_out_offset, br_out_offset_end])
# This via is on the right of the wire
self.add_via_center(layers=("metal1", "via1", "metal2"),
self.add_via_center(layers=self.m1_stack,
offset=bl_out_offset)
# This via is on the left of the wire
self.add_via_center(layers=("metal1", "via1", "metal2"),
self.add_via_center(layers=self.m1_stack,
offset=br_out_offset)
def get_drain_cin(self):

View File

@ -100,7 +100,7 @@ class tri_gate_array(design.design):
for n in ["vdd", "gnd"]:
for supply_pin in self.tri_inst[i].get_pins(n):
pin_pos = supply_pin.center()
self.add_via_center(layers=("metal2", "via2", "metal3"),
self.add_via_center(layers=self.m2_stack,
offset=pin_pos)
self.add_layout_pin_rect_center(text=n,
layer="metal3",

View File

@ -158,7 +158,7 @@ class wordline_driver(design.design):
self.add_segment_center(layer="metal1",
start=clk_offset,
end=a_pos)
self.add_via_center(layers=("metal1", "via1", "metal2"),
self.add_via_center(layers=self.m1_stack,
offset=clk_offset)
# Nand2 out to 2nd inv
@ -185,14 +185,14 @@ class wordline_driver(design.design):
layer="metal1",
start=input_offset,
end=mid_via_offset)
self.add_via_center(layers=("metal1", "via1", "metal2"),
self.add_via_center(layers=self.m1_stack,
offset=mid_via_offset,
directions=("V", "V"))
# now connect to the nand2 B
self.add_path("metal2", [mid_via_offset, b_pos])
contact_offset = b_pos - vector(0.5 * contact.m1m2.height, 0)
self.add_via_center(layers=("metal1", "via1", "metal2"),
self.add_via_center(layers=self.m1_stack,
offset=contact_offset,
directions=("H", "H"))

View File

@ -143,7 +143,7 @@ class write_driver_array(design.design):
for pin in pin_list:
pin_pos = pin.center()
# Add the M2->M3 stack
self.add_via_center(layers=("metal2", "via2", "metal3"),
self.add_via_center(layers=self.m2_stack,
offset=pin_pos)
self.add_layout_pin_rect_center(text=n,
layer="metal3",

View File

@ -117,9 +117,9 @@ class write_mask_and_array(design.design):
layer="metal3",
offset=beg_en_pin.bc(),
width=end_en_pin.cx() - beg_en_pin.cx() + en_to_edge)
self.add_via_center(layers=("metal1", "via1", "metal2"),
self.add_via_center(layers=self.m1_stack,
offset=vector(end_en_pin.cx() + en_to_edge, end_en_pin.cy()))
self.add_via_center(layers=("metal2", "via2", "metal3"),
self.add_via_center(layers=self.m2_stack,
offset=vector(end_en_pin.cx() + en_to_edge, end_en_pin.cy()))
else:
self.add_layout_pin(text="en",
@ -134,9 +134,9 @@ class write_mask_and_array(design.design):
# Add via connections to metal3 for AND array's B pin
en_pin = self.and2_insts[i].get_pin("B")
self.add_via_center(layers=("metal1", "via1", "metal2"),
self.add_via_center(layers=self.m1_stack,
offset=en_pin.center())
self.add_via_center(layers=("metal2", "via2", "metal3"),
self.add_via_center(layers=self.m2_stack,
offset=en_pin.center())
self.add_power_pin("gnd", vector(supply_pin.width() + i * self.wmask_en_len, 0))

View File

@ -115,7 +115,7 @@ class pgate(design.design):
# Non-preferred direction via
self.add_via_center(layers=("poly", "contact", "metal1"),
self.add_via_center(layers=self.poly_stack,
offset=contact_offset,
directions=directions)

View File

@ -115,8 +115,8 @@ class pinv(pgate.pgate):
# Divide the height in half. Could divide proportional to beta,
# but this makes connecting wells of multiple cells easier.
# Subtract the poly space under the rail of the tx
nmos_height_available = 0.5 * tx_height_available - 0.5 * drc("poly_to_poly")
pmos_height_available = 0.5 * tx_height_available - 0.5 * drc("poly_to_poly")
nmos_height_available = 0.5 * tx_height_available - 0.5 * self.poly_space
pmos_height_available = 0.5 * tx_height_available - 0.5 * self.poly_space
debug.info(2,
"Height avail {0:.4f} PMOS {1:.4f} NMOS {2:.4f}".format(tx_height_available,

View File

@ -126,9 +126,9 @@ class pinvbuf(pgate.pgate):
z1_pin = self.inv1_inst.get_pin("Z")
a4_pin = self.inv4_inst.get_pin("A")
mid_point = vector(z1_pin.cx(), a4_pin.cy())
self.add_wire(("metal1", "via1", "metal2"),
self.add_wire(self.m1_stack,
[z1_pin.center(), mid_point, a4_pin.center()])
self.add_via_center(layers=("metal1", "via1", "metal2"),
self.add_via_center(layers=self.m1_stack,
offset=z1_pin.center())
def add_layout_pins(self):
@ -161,21 +161,21 @@ class pinvbuf(pgate.pgate):
self.add_layout_pin_rect_center(text="Z",
layer="metal2",
offset=z_pin.center())
self.add_via_center(layers=("metal1", "via1", "metal2"),
self.add_via_center(layers=self.m1_stack,
offset=z_pin.center())
zb_pin = self.inv3_inst.get_pin("Z")
self.add_layout_pin_rect_center(text="Zb",
layer="metal2",
offset=zb_pin.center())
self.add_via_center(layers=("metal1", "via1", "metal2"),
self.add_via_center(layers=self.m1_stack,
offset=zb_pin.center())
a_pin = self.inv1_inst.get_pin("A")
self.add_layout_pin_rect_center(text="A",
layer="metal2",
offset=a_pin.center())
self.add_via_center(layers=("metal1", "via1", "metal2"),
self.add_via_center(layers=self.m1_stack,
offset=a_pin.center())
def determine_clk_buf_stage_efforts(self, external_cout, inp_is_rise=False):

View File

@ -225,13 +225,13 @@ class pnand2(pgate.pgate):
mid1_offset = vector(out_offset.x, top_pin_offset.y)
mid2_offset = vector(out_offset.x, bottom_pin_offset.y)
self.add_via_center(layers=("metal1", "via1", "metal2"),
self.add_via_center(layers=self.m1_stack,
offset=pmos_pin.center(),
directions=("V", "H"))
self.add_via_center(layers=("metal1", "via1", "metal2"),
self.add_via_center(layers=self.m1_stack,
offset=nmos_pin.center(),
directions=("V", "H"))
self.add_via_center(layers=("metal1", "via1", "metal2"),
self.add_via_center(layers=self.m1_stack,
offset=out_offset)
# PMOS1 to mid-drain to NMOS2 drain

View File

@ -237,11 +237,11 @@ class pnand3(pgate.pgate):
nmos3_pin = self.nmos3_inst.get_pin("D")
# Go up to metal2 for ease on all output pins
self.add_via_center(layers=("metal1", "via1", "metal2"),
self.add_via_center(layers=self.m1_stack,
offset=pmos1_pin.center())
self.add_via_center(layers=("metal1", "via1", "metal2"),
self.add_via_center(layers=self.m1_stack,
offset=pmos3_pin.center())
self.add_via_center(layers=("metal1", "via1", "metal2"),
self.add_via_center(layers=self.m1_stack,
offset=nmos3_pin.center())
# PMOS3 and NMOS3 are drain aligned
@ -251,7 +251,7 @@ class pnand3(pgate.pgate):
self.add_path("metal2", [pmos1_pin.bc(), mid_offset, nmos3_pin.uc()])
# This extends the output to the edge of the cell
self.add_via_center(layers=("metal1", "via1", "metal2"),
self.add_via_center(layers=self.m1_stack,
offset=mid_offset)
self.add_layout_pin_rect_center(text="Z",
layer="metal1",

View File

@ -216,9 +216,9 @@ class pnor2(pgate.pgate):
nmos2_pin = self.nmos2_inst.get_pin("D")
# Go up to metal2 for ease on all output pins
self.add_via_center(layers=("metal1", "via1", "metal2"),
self.add_via_center(layers=self.m1_stack,
offset=pmos_pin.center())
m1m2_contact = self.add_via_center(layers=("metal1", "via1", "metal2"),
m1m2_contact = self.add_via_center(layers=self.m1_stack,
offset=nmos_pin.center())
mid1_offset = vector(pmos_pin.center().x, nmos2_pin.center().y)
@ -231,7 +231,7 @@ class pnor2(pgate.pgate):
self.add_path("metal2",
[nmos_pin.rc(), mid1_offset, mid2_offset])
# This extends the output to the edge of the cell
self.add_via_center(layers=("metal1", "via1", "metal2"),
self.add_via_center(layers=self.m1_stack,
offset=mid3_offset)
self.add_layout_pin_rect_center(text="Z",
layer="metal1",

View File

@ -159,7 +159,7 @@ class precharge(design.design):
# adds the en contact to connect the gates to the en rail on metal1
offset = self.lower_pmos_inst.get_pin("G").ul() \
+ vector(0, 0.5 * self.poly_space)
self.add_via_center(layers=("poly", "contact", "metal1"),
self.add_via_center(layers=self.poly_stack,
offset=offset)
# adds the en rail on metal1
@ -202,7 +202,6 @@ class precharge(design.design):
self.bl_pin = self.add_layout_pin(text="bl",
layer="metal2",
offset=offset,
width=drc("minwidth_metal2"),
height=self.height)
# adds the BR on metal 2
@ -211,7 +210,6 @@ class precharge(design.design):
self.br_pin = self.add_layout_pin(text="br",
layer="metal2",
offset=offset,
width=drc("minwidth_metal2"),
height=self.height)
def connect_to_bitlines(self):
@ -233,23 +231,22 @@ class precharge(design.design):
Adds contacts/via from metal1 to metal2 for bit-lines
"""
stack = ("metal1", "via1", "metal2")
upper_pin = self.upper_pmos1_inst.get_pin("S")
lower_pin = self.lower_pmos_inst.get_pin("S")
# BL goes up to M2 at the transistor
self.bl_contact =self.add_via_center(layers=stack,
self.bl_contact =self.add_via_center(layers=self.m1_stack,
offset=upper_pin.center(),
directions=("V", "V"))
self.add_via_center(layers=stack,
self.add_via_center(layers=self.m1_stack,
offset=lower_pin.center(),
directions=("V", "V"))
# BR routes over on M1 first
self.add_via_center(layers=stack,
self.add_via_center(layers=self.m1_stack,
offset=vector(self.br_pin.cx(), upper_pin.cy()),
directions=("V", "V"))
self.add_via_center(layers=stack,
self.add_via_center(layers=self.m1_stack,
offset=vector(self.br_pin.cx(), lower_pin.cy()),
directions=("V", "V"))

View File

@ -52,7 +52,6 @@ class ptx(design.design):
self.connect_poly = connect_poly
self.num_contacts = num_contacts
# Do NOT create the netlist and layout (not a pgate)
# Since it has variable height, it is not a pgate.
self.create_netlist()
# We must always create ptx layout for pbitcell

View File

@ -126,16 +126,16 @@ class single_level_column_mux(pgate.pgate):
nmos_upper_d_pin = self.nmos_upper.get_pin("D")
# Add vias to bl, br_out, nmos_upper/S, nmos_lower/D
self.add_via_center(layers=("metal1", "via1", "metal2"),
self.add_via_center(layers=self.m1_stack,
offset=bl_pin.bc(),
directions=("V", "V"))
self.add_via_center(layers=("metal1", "via1", "metal2"),
self.add_via_center(layers=self.m1_stack,
offset=br_out_pin.uc(),
directions=("V", "V"))
self.add_via_center(layers=("metal1", "via1", "metal2"),
self.add_via_center(layers=self.m1_stack,
offset=nmos_upper_s_pin.center(),
directions=("V", "V"))
self.add_via_center(layers=("metal1", "via1", "metal2"),
self.add_via_center(layers=self.m1_stack,
offset=nmos_lower_d_pin.center(),
directions=("V", "V"))
@ -181,9 +181,9 @@ class single_level_column_mux(pgate.pgate):
well_type="p")
# Add the M1->M2->M3 stack
self.add_via_center(layers=("metal1", "via1", "metal2"),
self.add_via_center(layers=self.m1_stack,
offset=active_pos)
self.add_via_center(layers=("metal2", "via2", "metal3"),
self.add_via_center(layers=self.m2_stack,
offset=active_pos)
self.add_layout_pin_rect_center(text="gnd",
layer="metal3",

View File

@ -371,12 +371,12 @@ class sram_1bank(sram_base):
if self.write_size:
for x in dff_names:
pin_offset = self.data_dff_insts[port].get_pin(x).center()
self.add_via_center(layers=("metal1", "via1", "metal2"),
self.add_via_center(layers=self.m1_stack,
offset=pin_offset,
directions = ("V", "V"))
self.add_via_center(layers=("metal2", "via2", "metal3"),
self.add_via_center(layers=self.m2_stack,
offset=pin_offset)
self.add_via_center(layers=("metal3", "via3", "metal4"),
self.add_via_center(layers=self.m3_stack,
offset=pin_offset)
bank_names = ["din{0}_{1}".format(port,x) for x in range(self.word_size)]
@ -387,20 +387,21 @@ class sram_1bank(sram_base):
pin_offset = self.bank_inst.get_pin(x).uc()
else:
pin_offset = self.bank_inst.get_pin(x).bc()
self.add_via_center(layers=("metal1", "via1", "metal2"),
self.add_via_center(layers=self.m1_stack,
offset=pin_offset)
self.add_via_center(layers=("metal2", "via2", "metal3"),
self.add_via_center(layers=self.m2_stack,
offset=pin_offset)
self.add_via_center(layers=("metal3", "via3", "metal4"),
self.add_via_center(layers=self.m3_stack,
offset=pin_offset)
route_map = list(zip(bank_pins, dff_pins))
if self.write_size:
self.create_horizontal_channel_route(netlist=route_map,
offset=offset,
layer_stack=("metal3", "via3", "metal4"))
layer_stack = self.m3_stack
else:
self.create_horizontal_channel_route(route_map, offset)
layer_stack = self.m1_stack
self.create_horizontal_channel_route(netlist=route_map,
offset=offset,
layer_stack=layer_stack)
def route_wmask_dff(self):
""" Connect the output of the wmask flops to the write mask AND array """
@ -415,7 +416,7 @@ class sram_1bank(sram_base):
dff_pins = [self.wmask_dff_insts[port].get_pin(x) for x in dff_names]
for x in dff_names:
offset_pin = self.wmask_dff_insts[port].get_pin(x).center()
self.add_via_center(layers=("metal1", "via1", "metal2"),
self.add_via_center(layers=self.m1_stack,
offset=offset_pin,
directions=("V", "V"))
@ -423,12 +424,14 @@ class sram_1bank(sram_base):
bank_pins = [self.bank_inst.get_pin(x) for x in bank_names]
for x in bank_names:
offset_pin = self.bank_inst.get_pin(x).center()
self.add_via_center(layers=("metal1", "via1", "metal2"),
self.add_via_center(layers=self.m1_stack,
offset=offset_pin)
route_map = list(zip(bank_pins, dff_pins))
self.create_horizontal_channel_route(route_map,offset)
self.create_horizontal_channel_route(netlist=route_map,
offset=offset,
layer_stack=self.m1_stack)
def add_lvs_correspondence_points(self):

View File

@ -25,7 +25,7 @@ class wire_test(openram_test):
min_space = 2 * (tech.drc["minwidth_poly"] +
tech.drc["minwidth_metal1"])
layer_stack = ("poly", "contact", "metal1")
layer_stack = tech.poly_stack
old_position_list = [[0, 0],
[0, 3 * min_space],
[1 * min_space, 3 * min_space],
@ -42,7 +42,7 @@ class wire_test(openram_test):
min_space = 2 * (tech.drc["minwidth_poly"] +
tech.drc["minwidth_metal1"])
layer_stack = ("poly", "contact", "metal1")
layer_stack = tech.poly_stack
old_position_list = [[0, 0],
[0, 3 * min_space],
[1 * min_space, 3 * min_space],
@ -59,7 +59,7 @@ class wire_test(openram_test):
min_space = 2 * (tech.drc["minwidth_metal2"] +
tech.drc["minwidth_metal1"])
layer_stack = ("metal1", "via1", "metal2")
layer_stack = tech.m1_stack
position_list = [[0, 0],
[0, 3 * min_space],
[1 * min_space, 3 * min_space],
@ -76,7 +76,7 @@ class wire_test(openram_test):
min_space = 2 * (tech.drc["minwidth_metal2"] +
tech.drc["minwidth_metal1"])
layer_stack = ("metal2", "via1", "metal1")
layer_stack = tech.m2_stack[::-1]
position_list = [[0, 0],
[0, 3 * min_space],
[1 * min_space, 3 * min_space],
@ -92,7 +92,7 @@ class wire_test(openram_test):
min_space = 2 * (tech.drc["minwidth_metal2"] +
tech.drc["minwidth_metal3"])
layer_stack = ("metal2", "via2", "metal3")
layer_stack = tech.m2_stack
position_list = [[0, 0],
[0, 3 * min_space],
[1 * min_space, 3 * min_space],
@ -109,7 +109,7 @@ class wire_test(openram_test):
min_space = 2 * (tech.drc["minwidth_metal2"] +
tech.drc["minwidth_metal3"])
layer_stack = ("metal3", "via2", "metal2")
layer_stack = tech.m2_stack[::-1]
position_list = [[0, 0],
[0, 3 * min_space],
[1 * min_space, 3 * min_space],

View File

@ -34,18 +34,18 @@ GDS["zoom"] = 0.5
poly_stack = ("poly", "poly_contact", "metal1")
active_stack = ("active", "active_contact", "metal1")
metal1_stack = ("metal1", "via1", "metal2")
metal2_stack = ("metal2", "via2", "metal3")
metal3_stack = ("metal3", "via3", "metal4")
m1_stack = ("metal1", "via1", "metal2")
m2_stack = ("metal2", "via2", "metal3")
m3_stack = ("metal3", "via3", "metal4")
# The FEOL stacks get us up to metal1
feol_stacks = [poly_stack,
active_stack]
# The BEOL stacks are metal1 and up
beol_stacks = [metal1_stack,
metal2_stack,
metal3_stack]
beol_stacks = [m1_stack,
m2_stack,
m3_stack]
layer_stacks = feol_stacks + beol_stacks