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 lim1 = None
m1m2 = factory.create(module_type="contact", m1m2 = factory.create(module_type="contact",
layer_stack=metal1_stack, layer_stack=m1_stack,
directions=("H", "V")) directions=("H", "V"))
m2m3 = factory.create(module_type="contact", m2m3 = factory.create(module_type="contact",
layer_stack=metal2_stack, layer_stack=m2_stack,
directions=("V", "H")) directions=("V", "H"))
if "metal4" in layer.keys(): if "metal4" in layer.keys():
m3m4 = factory.create(module_type="contact", m3m4 = factory.create(module_type="contact",
layer_stack=metal3_stack, layer_stack=m3_stack,
directions=("H", "V")) directions=("H", "V"))
else: else:
m3m4 = None m3m4 = None

View File

@ -13,7 +13,7 @@ from globals import OPTS
class design(hierarchy_design): class design(hierarchy_design):
""" """
This is the same as the hierarchy_design class except it contains 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) hierarchy_design.__init__(self, name)
self.setup_drc_constants() self.setup_drc_constants()
self.setup_layer_constants()
self.setup_multiport_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.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) 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) self.m3_pitch = max(contact.m3m4.width, contact.m3m4.height) + max(self.m3_space, self.m4_space)
else: else:
self.m3_pitch = self.m2_pitch 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): def setup_drc_constants(self):
""" These are some DRC constants used in many places in the compiler.""" """ These are some DRC constants used in many places in the compiler."""
from tech import drc, layer from tech import drc, layer

View File

@ -824,7 +824,7 @@ class layout():
def create_channel_route(self, netlist, def create_channel_route(self, netlist,
offset, offset,
layer_stack=("metal1", "via1", "metal2"), layer_stack,
vertical=False): vertical=False):
""" """
The net list is a list of the nets. Each net is a list of pins 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) offset += vector(0,self.horizontal_pitch)
def create_vertical_channel_route(self, netlist, offset, def create_vertical_channel_route(self, netlist, offset, layer_stack):
layer_stack=("metal1", "via1", "metal2")):
""" """
Wrapper to create a vertical channel route Wrapper to create a vertical channel route
""" """
self.create_channel_route(netlist, offset, layer_stack, vertical=True) self.create_channel_route(netlist, offset, layer_stack, vertical=True)
def create_horizontal_channel_route(self, netlist, offset, def create_horizontal_channel_route(self, netlist, offset, layer_stack):
layer_stack=("metal1", "via1", "metal2")):
""" """
Wrapper to create a horizontal channel route Wrapper to create a horizontal channel route
""" """
@ -1028,13 +1026,13 @@ class layout():
direction=("H","H") direction=("H","H")
if start_layer=="metal1": if start_layer=="metal1":
self.add_via_center(layers=("metal1", "via1", "metal2"), self.add_via_center(layers=self.m1_stack,
offset=loc, offset=loc,
directions=direction) directions=direction)
if start_layer=="metal1" or start_layer=="metal2": 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, offset=loc,
directions=direction) directions=direction)
@ -1159,7 +1157,7 @@ class layout():
vector(self.right_vdd_x_center, self.top_vdd_y_center)] vector(self.right_vdd_x_center, self.top_vdd_y_center)]
for pt in via_points: for pt in via_points:
self.add_via_center(layers=("metal1", "via1", "metal2"), self.add_via_center(layers=self.m1_stack,
offset=pt, offset=pt,
size = (self.supply_vias, self.supply_vias)) 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 \ contact_offset_left = vector(self.inverter_nmos_left.get_pin("D").rc().x \
+ 0.5 * contact.poly.height, + 0.5 * contact.poly.height,
self.cross_couple_upper_ypos) 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, offset=contact_offset_left,
directions=("H", "H")) 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 \ contact_offset_right = vector(self.inverter_nmos_right.get_pin("S").lc().x \
- 0.5*contact.poly.height, - 0.5*contact.poly.height,
self.cross_couple_lower_ypos) 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, offset=contact_offset_right,
directions=("H", "H")) directions=("H", "H"))
@ -771,7 +771,7 @@ class pbitcell(bitcell_base.bitcell_base):
# first transistor on either side of the cross coupled inverters # first transistor on either side of the cross coupled inverters
# does not need to route to wordline on metal2 # does not need to route to wordline on metal2
if (k == 0) or (k == 1): 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) offset=port_contact_offset)
self.add_path("poly", [gate_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]) [port_contact_offset, wl_contact_offset])
else: else:
self.add_via_center(layers=("poly", "contact", "metal1"), self.add_via_center(layers=self.poly_stack,
offset=port_contact_offset) offset=port_contact_offset)
self.add_via_center(layers=("metal1", "via1", "metal2"), self.add_via_center(layers=self.m1_stack,
offset=port_contact_offset) offset=port_contact_offset)
self.add_via_center(layers=("metal1", "via1", "metal2"), self.add_via_center(layers=self.m1_stack,
offset=wl_contact_offset, offset=wl_contact_offset,
directions=("H", "H")) directions=("H", "H"))
@ -824,7 +824,7 @@ class pbitcell(bitcell_base.bitcell_base):
# Leave bitline disconnected if a dummy cell # Leave bitline disconnected if a dummy cell
if not self.dummy_bitcell: 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) offset=port_contact_offest)
self.add_path("metal2", self.add_path("metal2",
@ -836,7 +836,7 @@ class pbitcell(bitcell_base.bitcell_base):
# Leave bitline disconnected if a dummy cell # Leave bitline disconnected if a dummy cell
if not self.dummy_bitcell: 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) offset=port_contact_offest)
self.add_path("metal2", 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()) nmos_contact_positions.append(self.read_access_nmos_right[k].get_pin("S").center())
for position in nmos_contact_positions: for position in nmos_contact_positions:
self.add_via_center(layers=("metal1", "via1", "metal2"), self.add_via_center(layers=self.m1_stack,
offset=position) offset=position)
if position.x > 0: if position.x > 0:
@ -862,7 +862,7 @@ class pbitcell(bitcell_base.bitcell_base):
contact_correct = -0.5 * contact.m1m2.height contact_correct = -0.5 * contact.m1m2.height
supply_offset = vector(position.x + contact_correct, supply_offset = vector(position.x + contact_correct,
self.gnd_position.y) self.gnd_position.y)
self.add_via_center(layers=("metal1", "via1", "metal2"), self.add_via_center(layers=self.m1_stack,
offset=supply_offset, offset=supply_offset,
directions=("H", "H")) 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 \ left_storage_contact = vector(self.inverter_nmos_left.get_pin("G").lc().x \
- self.poly_to_contact - 0.5*contact.poly.width, - self.poly_to_contact - 0.5*contact.poly.width,
self.cross_couple_upper_ypos) 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, offset=left_storage_contact,
directions=("H", "H")) directions=("H", "H"))
right_storage_contact = vector(self.inverter_nmos_right.get_pin("G").rc().x \ right_storage_contact = vector(self.inverter_nmos_right.get_pin("G").rc().x \
+ self.poly_to_contact + 0.5*contact.poly.width, + self.poly_to_contact + 0.5*contact.poly.width,
self.cross_couple_upper_ypos) 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, offset=right_storage_contact,
directions=("H", "H")) directions=("H", "H"))
@ -952,7 +952,7 @@ class pbitcell(bitcell_base.bitcell_base):
+ vector(0, + vector(0,
self.gate_contact_yoffset - self.poly_extend_active) 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) offset=port_contact_offset)
self.add_path("poly", self.add_path("poly",
@ -967,7 +967,7 @@ class pbitcell(bitcell_base.bitcell_base):
+ vector(0, + vector(0,
self.gate_contact_yoffset - self.poly_extend_active) 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) offset=port_contact_offset)
self.add_path("poly", self.add_path("poly",

View File

@ -606,11 +606,11 @@ class bank(design.design):
name = self.control_signals[port][signal] name = self.control_signals[port][signal]
bus_pos = vector(self.bus_xoffset[port][name].x, out_pos.y) bus_pos = vector(self.bus_xoffset[port][name].x, out_pos.y)
self.add_path("metal3",[out_pos, bus_pos]) 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) offset=bus_pos)
self.add_via_center(layers=("metal1", "via1", "metal2"), self.add_via_center(layers=self.m1_stack,
offset=out_pos) offset=out_pos)
self.add_via_center(layers=("metal2", "via2", "metal3"), self.add_via_center(layers=self.m2_stack,
offset=out_pos) 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))] 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))] 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)) 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): 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] 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)) 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): def add_lvs_correspondence_points(self):
@ -942,7 +942,7 @@ class bank(design.design):
control_mid_pos = self.bus_xoffset[port][control_signal] control_mid_pos = self.bus_xoffset[port][control_signal]
control_pos = vector(self.bus_xoffset[port][control_signal].x ,pin_pos.y) 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_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) offset=control_pos)
@ -957,7 +957,7 @@ class bank(design.design):
control_x_offset = self.bus_xoffset[port][control_signal].x control_x_offset = self.bus_xoffset[port][control_signal].x
control_pos = vector(control_x_offset, mid_pos.y) control_pos = vector(control_x_offset, mid_pos.y)
self.add_wire(("metal1","via1","metal2"),[pin_pos, mid_pos, control_pos]) 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) offset=control_pos)
def determine_wordline_stage_efforts(self, external_cout, inp_is_rise=True): 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) logic_pos = logic_inst.get_pin("B").lc() - vector(0.5*contact.m1m2.height,0)
input_pos = vector(xoffset_bank_signal, logic_pos.y) input_pos = vector(xoffset_bank_signal, logic_pos.y)
self.add_path("metal2",[logic_pos, input_pos]) 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, offset=logic_pos,
directions=("H","H")) directions=("H","H"))
@ -266,10 +266,10 @@ class bank_select(design.design):
# Connect the logic A input to the input pin # Connect the logic A input to the input pin
logic_pos = logic_inst.get_pin("A").lc() logic_pos = logic_inst.get_pin("A").lc()
input_pos = vector(0,logic_pos.y) 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, offset=logic_pos,
directions=("H","H")) directions=("H","H"))
self.add_via_center(layers=("metal2", "via2", "metal3"), self.add_via_center(layers=self.m2_stack,
offset=logic_pos, offset=logic_pos,
directions=("H","H")) directions=("H","H"))
self.add_layout_pin_segment_center(text=input_name, self.add_layout_pin_segment_center(text=input_name,
@ -301,10 +301,10 @@ class bank_select(design.design):
# Add pins in two locations # Add pins in two locations
for xoffset in [a_xoffset, b_xoffset]: for xoffset in [a_xoffset, b_xoffset]:
pin_pos = vector(xoffset, supply_pin.cy()) 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, offset=pin_pos,
directions=("H","H")) directions=("H","H"))
self.add_via_center(layers=("metal2", "via2", "metal3"), self.add_via_center(layers=self.m2_stack,
offset=pin_pos, offset=pin_pos,
directions=("H","H")) directions=("H","H"))
self.add_layout_pin_rect_center(text=n, 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): def route_input_rail(self, input_offset, output_offset):
""" Route a vertical M2 coordinate to another vertical M2 coordinate to the predecode inputs """ """ 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) offset=input_offset)
self.add_via_center(layers=("metal2", "via2", "metal3"), self.add_via_center(layers=self.m2_stack,
offset=output_offset) offset=output_offset)
self.add_path(("metal3"), [input_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 """ """ Connect the routing rail to the given metal1 pin """
rail_pos = vector(self.predecode_rails[rail_name].x,pin.lc().y) rail_pos = vector(self.predecode_rails[rail_name].x,pin.lc().y)
self.add_path("metal1", [rail_pos, pin.lc()]) 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) offset=rail_pos)
@ -595,10 +595,10 @@ class hierarchical_decoder(design.design):
# It would be fixed with a channel router. # It would be fixed with a channel router.
mid_point = vector(pin.cx(), pin.cy()+self.inv.height/2) mid_point = vector(pin.cx(), pin.cy()+self.inv.height/2)
rail_pos = vector(self.predecode_rails[rail_name].x,mid_point.y) 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()) offset=pin.center())
self.add_wire(("metal3","via2","metal2"), [rail_pos, mid_point, pin.uc()]) 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) offset=rail_pos)
def input_load(self): 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) in_pos = vector(self.input_rails[in_pin].x,y_offset)
a_pos = vector(self.decode_rails[a_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_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]) 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]) offset=[self.decode_rails[a_pin].x, y_offset])
def route_output_inverters(self): 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) 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) 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_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) offset=rail_pos)
@ -235,7 +235,7 @@ class hierarchical_predecode(design.design):
inv_in_pos = self.in_inst[inv_num].get_pin("A").lc() 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) in_pos = vector(self.input_rails[in_pin].x,inv_in_pos.y)
self.add_path("metal1", [in_pos, inv_in_pos]) 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) offset=in_pos)
@ -256,7 +256,7 @@ class hierarchical_predecode(design.design):
pin_pos = self.nand_inst[k].get_pin(gate_pin).lc() pin_pos = self.nand_inst[k].get_pin(gate_pin).lc()
rail_pos = vector(self.decode_rails[rail_pin].x, pin_pos.y) rail_pos = vector(self.decode_rails[rail_pin].x, pin_pos.y)
self.add_path("metal1", [rail_pos, pin_pos]) 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) offset=rail_pos)

View File

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

View File

@ -475,7 +475,7 @@ class port_data(design.design):
end_pos = vector(length, wdriver_en_pin.cy()) end_pos = vector(length, wdriver_en_pin.cy())
# Add via for the write driver array's enable input # 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) offset=end_pos)
# Route between write mask AND array and write driver array # 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))] 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))] 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)) 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, 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] inst = self.local_insts[i]
gnd_pos = inst.get_pin("gnd").center() 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) offset=gnd_pos)
self.add_layout_pin_rect_center(text="gnd", self.add_layout_pin_rect_center(text="gnd",
layer="metal3", layer="metal3",
offset=gnd_pos) offset=gnd_pos)
vdd_pos = inst.get_pin("vdd").center() 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) offset=vdd_pos)
self.add_layout_pin_rect_center(text="vdd", self.add_layout_pin_rect_center(text="vdd",
layer="metal3", 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 # 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) offset=bl_out_offset)
# This via is on the left of the wire # 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) offset=br_out_offset)
else: else:
@ -204,10 +204,10 @@ class single_level_column_mux_array(design.design):
self.add_path("metal2", [ br_out_offset, br_out_offset_end]) self.add_path("metal2", [ br_out_offset, br_out_offset_end])
# This via is on the right of the wire # 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) offset=bl_out_offset)
# This via is on the left of the wire # 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) offset=br_out_offset)
def get_drain_cin(self): def get_drain_cin(self):

View File

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

View File

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

View File

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

View File

@ -117,9 +117,9 @@ class write_mask_and_array(design.design):
layer="metal3", layer="metal3",
offset=beg_en_pin.bc(), offset=beg_en_pin.bc(),
width=end_en_pin.cx() - beg_en_pin.cx() + en_to_edge) 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())) 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())) offset=vector(end_en_pin.cx() + en_to_edge, end_en_pin.cy()))
else: else:
self.add_layout_pin(text="en", 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 # Add via connections to metal3 for AND array's B pin
en_pin = self.and2_insts[i].get_pin("B") 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()) offset=en_pin.center())
self.add_via_center(layers=("metal2", "via2", "metal3"), self.add_via_center(layers=self.m2_stack,
offset=en_pin.center()) offset=en_pin.center())
self.add_power_pin("gnd", vector(supply_pin.width() + i * self.wmask_en_len, 0)) 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 # Non-preferred direction via
self.add_via_center(layers=("poly", "contact", "metal1"), self.add_via_center(layers=self.poly_stack,
offset=contact_offset, offset=contact_offset,
directions=directions) directions=directions)

View File

@ -115,8 +115,8 @@ class pinv(pgate.pgate):
# Divide the height in half. Could divide proportional to beta, # Divide the height in half. Could divide proportional to beta,
# but this makes connecting wells of multiple cells easier. # but this makes connecting wells of multiple cells easier.
# Subtract the poly space under the rail of the tx # Subtract the poly space under the rail of the tx
nmos_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 * drc("poly_to_poly") pmos_height_available = 0.5 * tx_height_available - 0.5 * self.poly_space
debug.info(2, debug.info(2,
"Height avail {0:.4f} PMOS {1:.4f} NMOS {2:.4f}".format(tx_height_available, "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") z1_pin = self.inv1_inst.get_pin("Z")
a4_pin = self.inv4_inst.get_pin("A") a4_pin = self.inv4_inst.get_pin("A")
mid_point = vector(z1_pin.cx(), a4_pin.cy()) 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()]) [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()) offset=z1_pin.center())
def add_layout_pins(self): def add_layout_pins(self):
@ -161,21 +161,21 @@ class pinvbuf(pgate.pgate):
self.add_layout_pin_rect_center(text="Z", self.add_layout_pin_rect_center(text="Z",
layer="metal2", layer="metal2",
offset=z_pin.center()) offset=z_pin.center())
self.add_via_center(layers=("metal1", "via1", "metal2"), self.add_via_center(layers=self.m1_stack,
offset=z_pin.center()) offset=z_pin.center())
zb_pin = self.inv3_inst.get_pin("Z") zb_pin = self.inv3_inst.get_pin("Z")
self.add_layout_pin_rect_center(text="Zb", self.add_layout_pin_rect_center(text="Zb",
layer="metal2", layer="metal2",
offset=zb_pin.center()) offset=zb_pin.center())
self.add_via_center(layers=("metal1", "via1", "metal2"), self.add_via_center(layers=self.m1_stack,
offset=zb_pin.center()) offset=zb_pin.center())
a_pin = self.inv1_inst.get_pin("A") a_pin = self.inv1_inst.get_pin("A")
self.add_layout_pin_rect_center(text="A", self.add_layout_pin_rect_center(text="A",
layer="metal2", layer="metal2",
offset=a_pin.center()) offset=a_pin.center())
self.add_via_center(layers=("metal1", "via1", "metal2"), self.add_via_center(layers=self.m1_stack,
offset=a_pin.center()) offset=a_pin.center())
def determine_clk_buf_stage_efforts(self, external_cout, inp_is_rise=False): 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) mid1_offset = vector(out_offset.x, top_pin_offset.y)
mid2_offset = vector(out_offset.x, bottom_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(), offset=pmos_pin.center(),
directions=("V", "H")) directions=("V", "H"))
self.add_via_center(layers=("metal1", "via1", "metal2"), self.add_via_center(layers=self.m1_stack,
offset=nmos_pin.center(), offset=nmos_pin.center(),
directions=("V", "H")) directions=("V", "H"))
self.add_via_center(layers=("metal1", "via1", "metal2"), self.add_via_center(layers=self.m1_stack,
offset=out_offset) offset=out_offset)
# PMOS1 to mid-drain to NMOS2 drain # 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") nmos3_pin = self.nmos3_inst.get_pin("D")
# Go up to metal2 for ease on all output pins # 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()) offset=pmos1_pin.center())
self.add_via_center(layers=("metal1", "via1", "metal2"), self.add_via_center(layers=self.m1_stack,
offset=pmos3_pin.center()) offset=pmos3_pin.center())
self.add_via_center(layers=("metal1", "via1", "metal2"), self.add_via_center(layers=self.m1_stack,
offset=nmos3_pin.center()) offset=nmos3_pin.center())
# PMOS3 and NMOS3 are drain aligned # 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()]) self.add_path("metal2", [pmos1_pin.bc(), mid_offset, nmos3_pin.uc()])
# This extends the output to the edge of the cell # 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) offset=mid_offset)
self.add_layout_pin_rect_center(text="Z", self.add_layout_pin_rect_center(text="Z",
layer="metal1", layer="metal1",

View File

@ -216,9 +216,9 @@ class pnor2(pgate.pgate):
nmos2_pin = self.nmos2_inst.get_pin("D") nmos2_pin = self.nmos2_inst.get_pin("D")
# Go up to metal2 for ease on all output pins # 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()) 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()) offset=nmos_pin.center())
mid1_offset = vector(pmos_pin.center().x, nmos2_pin.center().y) mid1_offset = vector(pmos_pin.center().x, nmos2_pin.center().y)
@ -231,7 +231,7 @@ class pnor2(pgate.pgate):
self.add_path("metal2", self.add_path("metal2",
[nmos_pin.rc(), mid1_offset, mid2_offset]) [nmos_pin.rc(), mid1_offset, mid2_offset])
# This extends the output to the edge of the cell # 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) offset=mid3_offset)
self.add_layout_pin_rect_center(text="Z", self.add_layout_pin_rect_center(text="Z",
layer="metal1", 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 # adds the en contact to connect the gates to the en rail on metal1
offset = self.lower_pmos_inst.get_pin("G").ul() \ offset = self.lower_pmos_inst.get_pin("G").ul() \
+ vector(0, 0.5 * self.poly_space) + 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) offset=offset)
# adds the en rail on metal1 # adds the en rail on metal1
@ -202,7 +202,6 @@ class precharge(design.design):
self.bl_pin = self.add_layout_pin(text="bl", self.bl_pin = self.add_layout_pin(text="bl",
layer="metal2", layer="metal2",
offset=offset, offset=offset,
width=drc("minwidth_metal2"),
height=self.height) height=self.height)
# adds the BR on metal 2 # adds the BR on metal 2
@ -211,7 +210,6 @@ class precharge(design.design):
self.br_pin = self.add_layout_pin(text="br", self.br_pin = self.add_layout_pin(text="br",
layer="metal2", layer="metal2",
offset=offset, offset=offset,
width=drc("minwidth_metal2"),
height=self.height) height=self.height)
def connect_to_bitlines(self): def connect_to_bitlines(self):
@ -233,23 +231,22 @@ class precharge(design.design):
Adds contacts/via from metal1 to metal2 for bit-lines Adds contacts/via from metal1 to metal2 for bit-lines
""" """
stack = ("metal1", "via1", "metal2")
upper_pin = self.upper_pmos1_inst.get_pin("S") upper_pin = self.upper_pmos1_inst.get_pin("S")
lower_pin = self.lower_pmos_inst.get_pin("S") lower_pin = self.lower_pmos_inst.get_pin("S")
# BL goes up to M2 at the transistor # 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(), offset=upper_pin.center(),
directions=("V", "V")) directions=("V", "V"))
self.add_via_center(layers=stack, self.add_via_center(layers=self.m1_stack,
offset=lower_pin.center(), offset=lower_pin.center(),
directions=("V", "V")) directions=("V", "V"))
# BR routes over on M1 first # 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()), offset=vector(self.br_pin.cx(), upper_pin.cy()),
directions=("V", "V")) 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()), offset=vector(self.br_pin.cx(), lower_pin.cy()),
directions=("V", "V")) directions=("V", "V"))

View File

@ -52,7 +52,6 @@ class ptx(design.design):
self.connect_poly = connect_poly self.connect_poly = connect_poly
self.num_contacts = num_contacts 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. # Since it has variable height, it is not a pgate.
self.create_netlist() self.create_netlist()
# We must always create ptx layout for pbitcell # 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") nmos_upper_d_pin = self.nmos_upper.get_pin("D")
# Add vias to bl, br_out, nmos_upper/S, nmos_lower/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(), offset=bl_pin.bc(),
directions=("V", "V")) directions=("V", "V"))
self.add_via_center(layers=("metal1", "via1", "metal2"), self.add_via_center(layers=self.m1_stack,
offset=br_out_pin.uc(), offset=br_out_pin.uc(),
directions=("V", "V")) 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(), offset=nmos_upper_s_pin.center(),
directions=("V", "V")) 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(), offset=nmos_lower_d_pin.center(),
directions=("V", "V")) directions=("V", "V"))
@ -181,9 +181,9 @@ class single_level_column_mux(pgate.pgate):
well_type="p") well_type="p")
# Add the M1->M2->M3 stack # 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) offset=active_pos)
self.add_via_center(layers=("metal2", "via2", "metal3"), self.add_via_center(layers=self.m2_stack,
offset=active_pos) offset=active_pos)
self.add_layout_pin_rect_center(text="gnd", self.add_layout_pin_rect_center(text="gnd",
layer="metal3", layer="metal3",

View File

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

View File

@ -25,7 +25,7 @@ class wire_test(openram_test):
min_space = 2 * (tech.drc["minwidth_poly"] + min_space = 2 * (tech.drc["minwidth_poly"] +
tech.drc["minwidth_metal1"]) tech.drc["minwidth_metal1"])
layer_stack = ("poly", "contact", "metal1") layer_stack = tech.poly_stack
old_position_list = [[0, 0], old_position_list = [[0, 0],
[0, 3 * min_space], [0, 3 * min_space],
[1 * min_space, 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"] + min_space = 2 * (tech.drc["minwidth_poly"] +
tech.drc["minwidth_metal1"]) tech.drc["minwidth_metal1"])
layer_stack = ("poly", "contact", "metal1") layer_stack = tech.poly_stack
old_position_list = [[0, 0], old_position_list = [[0, 0],
[0, 3 * min_space], [0, 3 * min_space],
[1 * min_space, 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"] + min_space = 2 * (tech.drc["minwidth_metal2"] +
tech.drc["minwidth_metal1"]) tech.drc["minwidth_metal1"])
layer_stack = ("metal1", "via1", "metal2") layer_stack = tech.m1_stack
position_list = [[0, 0], position_list = [[0, 0],
[0, 3 * min_space], [0, 3 * min_space],
[1 * min_space, 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"] + min_space = 2 * (tech.drc["minwidth_metal2"] +
tech.drc["minwidth_metal1"]) tech.drc["minwidth_metal1"])
layer_stack = ("metal2", "via1", "metal1") layer_stack = tech.m2_stack[::-1]
position_list = [[0, 0], position_list = [[0, 0],
[0, 3 * min_space], [0, 3 * min_space],
[1 * min_space, 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"] + min_space = 2 * (tech.drc["minwidth_metal2"] +
tech.drc["minwidth_metal3"]) tech.drc["minwidth_metal3"])
layer_stack = ("metal2", "via2", "metal3") layer_stack = tech.m2_stack
position_list = [[0, 0], position_list = [[0, 0],
[0, 3 * min_space], [0, 3 * min_space],
[1 * min_space, 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"] + min_space = 2 * (tech.drc["minwidth_metal2"] +
tech.drc["minwidth_metal3"]) tech.drc["minwidth_metal3"])
layer_stack = ("metal3", "via2", "metal2") layer_stack = tech.m2_stack[::-1]
position_list = [[0, 0], position_list = [[0, 0],
[0, 3 * min_space], [0, 3 * min_space],
[1 * min_space, 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") poly_stack = ("poly", "poly_contact", "metal1")
active_stack = ("active", "active_contact", "metal1") active_stack = ("active", "active_contact", "metal1")
metal1_stack = ("metal1", "via1", "metal2") m1_stack = ("metal1", "via1", "metal2")
metal2_stack = ("metal2", "via2", "metal3") m2_stack = ("metal2", "via2", "metal3")
metal3_stack = ("metal3", "via3", "metal4") m3_stack = ("metal3", "via3", "metal4")
# The FEOL stacks get us up to metal1 # The FEOL stacks get us up to metal1
feol_stacks = [poly_stack, feol_stacks = [poly_stack,
active_stack] active_stack]
# The BEOL stacks are metal1 and up # The BEOL stacks are metal1 and up
beol_stacks = [metal1_stack, beol_stacks = [m1_stack,
metal2_stack, m2_stack,
metal3_stack] m3_stack]
layer_stacks = feol_stacks + beol_stacks layer_stacks = feol_stacks + beol_stacks