Clean up and generalize layer rules.

Convert metalN to mN.
Generalize helper constants in modules for
space, width, enclose, etc.
Use layer stacks whever possible.
Try to remove drc() calls in liu of helper constants.
This commit is contained in:
Matt Guthaus
2019-12-17 11:03:36 -08:00
parent a79d03fef4
commit ed28b4983b
52 changed files with 604 additions and 578 deletions
+13 -13
View File
@@ -333,7 +333,7 @@ class bank(design.design):
self.col_addr_bus_width = self.m2_pitch*self.num_col_addr_lines
# A space for wells or jogging m2
self.m2_gap = max(2*drc("pwell_to_nwell") + drc("well_enclosure_active"),
self.m2_gap = max(2*drc("pwell_to_nwell") + drc("well_enclose_active"),
3*self.m2_pitch)
@@ -605,7 +605,7 @@ class bank(design.design):
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)
self.add_path("metal3",[out_pos, bus_pos])
self.add_path("m3",[out_pos, bus_pos])
self.add_via_center(layers=self.m2_stack,
offset=bus_pos)
self.add_via_center(layers=self.m1_stack,
@@ -648,7 +648,7 @@ class bank(design.design):
control_bus_offset = vector(-self.m2_pitch * self.num_control_lines[0] - self.m2_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="metal2",
self.bus_xoffset[0] = self.create_bus(layer="m2",
pitch=self.m2_pitch,
offset=control_bus_offset,
names=self.control_signals[0],
@@ -663,7 +663,7 @@ class bank(design.design):
control_bus_offset = vector(self.bitcell_array_right + self.m2_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="metal2",
self.bus_xoffset[1] = self.create_bus(layer="m2",
pitch=self.m2_pitch,
offset=control_bus_offset,
names=list(reversed(self.control_signals[1])),
@@ -817,7 +817,7 @@ class bank(design.design):
bitcell_wl_pos = self.bitcell_array_inst.get_pin(self.wl_names[port]+"_{}".format(row)).lc()
mid1 = driver_wl_pos.scale(0,1) + vector(0.5*self.port_address_inst[port].rx() + 0.5*self.bitcell_array_inst.lx(),0)
mid2 = mid1.scale(1,0)+bitcell_wl_pos.scale(0.5,1)
self.add_path("metal1", [driver_wl_pos, mid1, mid2, bitcell_wl_pos])
self.add_path("m1", [driver_wl_pos, mid1, mid2, bitcell_wl_pos])
def route_port_address_right(self, port):
@@ -829,7 +829,7 @@ class bank(design.design):
bitcell_wl_pos = self.bitcell_array_inst.get_pin(self.wl_names[port]+"_{}".format(row)).rc()
mid1 = driver_wl_pos.scale(0,1) + vector(0.5*self.port_address_inst[port].lx() + 0.5*self.bitcell_array_inst.rx(),0)
mid2 = mid1.scale(1,0)+bitcell_wl_pos.scale(0,1)
self.add_path("metal1", [driver_wl_pos, mid1, mid2, bitcell_wl_pos])
self.add_path("m1", [driver_wl_pos, mid1, mid2, bitcell_wl_pos])
def route_column_address_lines(self, port):
""" Connecting the select lines of column mux to the address bus """
@@ -878,7 +878,7 @@ class bank(design.design):
wl_name = "wl_{}".format(i)
wl_pin = self.bitcell_array_inst.get_pin(wl_name)
self.add_label(text=wl_name,
layer="metal1",
layer="m1",
offset=wl_pin.center())
# Add the bitline names
@@ -888,10 +888,10 @@ class bank(design.design):
bl_pin = self.bitcell_array_inst.get_pin(bl_name)
br_pin = self.bitcell_array_inst.get_pin(br_name)
self.add_label(text=bl_name,
layer="metal2",
layer="m2",
offset=bl_pin.center())
self.add_label(text=br_name,
layer="metal2",
layer="m2",
offset=br_pin.center())
# # Add the data output names to the sense amp output
@@ -899,7 +899,7 @@ class bank(design.design):
# data_name = "data_{}".format(i)
# data_pin = self.sense_amp_array_inst.get_pin(data_name)
# self.add_label(text="sa_out_{}".format(i),
# layer="metal2",
# layer="m2",
# offset=data_pin.center())
# Add labels on the decoder
@@ -909,7 +909,7 @@ class bank(design.design):
pin_name = "in_{}".format(i)
data_pin = self.wordline_driver_inst[port].get_pin(pin_name)
self.add_label(text=data_name,
layer="metal1",
layer="m1",
offset=data_pin.center())
@@ -941,7 +941,7 @@ class bank(design.design):
for (control_signal, pin_pos) in connection:
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_wire(self.m1_stack, [control_mid_pos, control_pos, pin_pos])
self.add_via_center(layers=self.m1_stack,
offset=control_pos)
@@ -956,7 +956,7 @@ class bank(design.design):
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_pos = vector(control_x_offset, mid_pos.y)
self.add_wire(("metal1","via1","metal2"),[pin_pos, mid_pos, control_pos])
self.add_wire(self.m1_stack,[pin_pos, mid_pos, control_pos])
self.add_via_center(layers=self.m1_stack,
offset=control_pos)
+13 -13
View File
@@ -208,18 +208,18 @@ class bank_select(design.design):
xoffset_bank_sel = bank_sel_inv_pin.lx()
bank_sel_line_pos = vector(xoffset_bank_sel, 0)
bank_sel_line_end = vector(xoffset_bank_sel, self.yoffset_maxpoint)
self.add_path("metal2", [bank_sel_line_pos, bank_sel_line_end])
self.add_via_center(layers=("metal1","via1","metal2"),
self.add_path("m2", [bank_sel_line_pos, bank_sel_line_end])
self.add_via_center(layers=self.m1_stack,
offset=bank_sel_inv_pin.lc())
# Route the pin to the left edge as well
bank_sel_pin_pos=vector(0, 0)
bank_sel_pin_end=vector(bank_sel_line_pos.x, bank_sel_pin_pos.y)
self.add_layout_pin_segment_center(text="bank_sel",
layer="metal3",
layer="m3",
start=bank_sel_pin_pos,
end=bank_sel_pin_end)
self.add_via_center(layers=("metal2","via2","metal3"),
self.add_via_center(layers=self.m2_stack,
offset=bank_sel_pin_end,
directions=("H","H"))
@@ -227,10 +227,10 @@ class bank_select(design.design):
bank_sel_bar_pin = self.bank_sel_inv.get_pin("Z")
xoffset_bank_sel_bar = bank_sel_bar_pin.rx()
self.add_label_pin(text="bank_sel_bar",
layer="metal2",
layer="m2",
offset=vector(xoffset_bank_sel_bar, 0),
height=self.inv4x.height)
self.add_via_center(layers=("metal1","via1","metal2"),
self.add_via_center(layers=self.m1_stack,
offset=bank_sel_bar_pin.rc())
@@ -251,13 +251,13 @@ class bank_select(design.design):
out_position = logic_inst.get_pin("Z").rc() + vector(0.5*self.m1_width,0)
in_position = inv_inst.get_pin("A").lc() + vector(0.5*self.m1_width,0)
post = inv_inst.get_pin("A").rc()
self.add_path("metal1", [pre, out_position, in_position, post])
self.add_path("m1", [pre, out_position, in_position, post])
# Connect the logic B input to bank_sel/bank_sel_bar
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_path("m2",[logic_pos, input_pos])
self.add_via_center(layers=self.m1_stack,
offset=logic_pos,
directions=("H","H"))
@@ -273,7 +273,7 @@ class bank_select(design.design):
offset=logic_pos,
directions=("H","H"))
self.add_layout_pin_segment_center(text=input_name,
layer="metal3",
layer="m3",
start=input_pos,
end=logic_pos)
@@ -294,7 +294,7 @@ class bank_select(design.design):
for n in ["vdd", "gnd"]:
supply_pin = self.inv_inst[num].get_pin(n)
supply_offset = supply_pin.ll().scale(0,1)
self.add_rect(layer="metal1",
self.add_rect(layer="m1",
offset=supply_offset,
width=self.width)
@@ -308,20 +308,20 @@ class bank_select(design.design):
offset=pin_pos,
directions=("H","H"))
self.add_layout_pin_rect_center(text=n,
layer="metal3",
layer="m3",
offset=pin_pos)
# Add vdd/gnd supply rails
gnd_pin = inv_inst.get_pin("gnd")
left_gnd_pos = vector(0, gnd_pin.cy())
self.add_layout_pin_segment_center(text="gnd",
layer="metal1",
layer="m1",
start=left_gnd_pos,
end=gnd_pin.rc())
vdd_pin = inv_inst.get_pin("vdd")
left_vdd_pos = vector(0, vdd_pin.cy())
self.add_layout_pin_segment_center(text="vdd",
layer="metal1",
layer="m1",
start=left_vdd_pos,
end=vdd_pin.rc())
+2 -2
View File
@@ -173,7 +173,7 @@ class bitcell_array(design.design):
width = 0
else:
width = self.width
wl_wire = self.generate_rc_net(int(self.column_size), width, drc("minwidth_metal1"))
wl_wire = self.generate_rc_net(int(self.column_size), width, drc("minwidth_m1"))
wl_wire.wire_c = 2*spice["min_tx_gate_c"] + wl_wire.wire_c # 2 access tx gate per cell
return wl_wire
@@ -183,7 +183,7 @@ class bitcell_array(design.design):
else:
height = self.height
bl_pos = 0
bl_wire = self.generate_rc_net(int(self.row_size-bl_pos), height, drc("minwidth_metal1"))
bl_wire = self.generate_rc_net(int(self.row_size-bl_pos), height, drc("minwidth_m1"))
bl_wire.wire_c =spice["min_tx_drain_c"] + bl_wire.wire_c # 1 access tx d/s per cell
return bl_wire
+27 -27
View File
@@ -371,7 +371,7 @@ 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("metal2", self.m2_pitch, offset, self.internal_bus_list, height)
self.rail_offsets = self.create_vertical_bus("m2", self.m2_pitch, offset, self.internal_bus_list, height)
def create_instances(self):
@@ -483,8 +483,8 @@ class control_logic(design.design):
vdd_ypos = self.p_en_bar_nand_inst.get_pin("vdd").by()
in_pos = vector(self.rail_offsets["rbl_bl_delay"].x,vdd_ypos)
mid1 = vector(out_pos.x,in_pos.y)
self.add_wire(("metal1","via1","metal2"),[out_pos, mid1, in_pos])
self.add_via_center(layers=("metal1","via1","metal2"),
self.add_wire(self.m1_stack,[out_pos, mid1, in_pos])
self.add_via_center(layers=self.m1_stack,
offset=in_pos)
@@ -509,10 +509,10 @@ class control_logic(design.design):
clk_pin = self.clk_buf_inst.get_pin("A")
clk_pos = clk_pin.center()
self.add_layout_pin_segment_center(text="clk",
layer="metal2",
layer="m2",
start=clk_pos,
end=clk_pos.scale(1,0))
self.add_via_center(layers=("metal1","via1","metal2"),
self.add_via_center(layers=self.m1_stack,
offset=clk_pos)
@@ -521,9 +521,9 @@ class control_logic(design.design):
mid1 = vector(out_pos.x,2*self.m2_pitch)
mid2 = vector(self.rail_offsets["clk_buf"].x, mid1.y)
bus_pos = self.rail_offsets["clk_buf"]
self.add_wire(("metal3","via2","metal2"),[out_pos, mid1, mid2, bus_pos])
self.add_wire(("m3","via2","m2"),[out_pos, mid1, mid2, bus_pos])
# The pin is on M1, so we need another via as well
self.add_via_center(layers=("metal1","via1","metal2"),
self.add_via_center(layers=self.m1_stack,
offset=self.clk_buf_inst.get_pin("Z").center())
self.connect_output(self.clk_buf_inst, "Z", "clk_buf")
@@ -552,21 +552,21 @@ class control_logic(design.design):
out_pos = self.clk_bar_inst.get_pin("Z").center()
in_pos = self.gated_clk_bar_inst.get_pin("B").center()
mid1 = vector(in_pos.x,out_pos.y)
self.add_path("metal1",[out_pos, mid1, in_pos])
self.add_path("m1",[out_pos, mid1, in_pos])
# This is the second gate over, so it needs to be on M3
clkbuf_map = zip(["A"], ["cs"])
self.connect_vertical_bus(clkbuf_map, self.gated_clk_bar_inst, self.rail_offsets, ("metal3", "via2", "metal2"))
self.connect_vertical_bus(clkbuf_map, self.gated_clk_bar_inst, self.rail_offsets, ("m3", "via2", "m2"))
# The pin is on M1, so we need another via as well
self.add_via_center(layers=("metal1","via1","metal2"),
self.add_via_center(layers=self.m1_stack,
offset=self.gated_clk_bar_inst.get_pin("A").center())
# This is the second gate over, so it needs to be on M3
clkbuf_map = zip(["Z"], ["gated_clk_bar"])
self.connect_vertical_bus(clkbuf_map, self.gated_clk_bar_inst, self.rail_offsets, ("metal3", "via2", "metal2"))
self.connect_vertical_bus(clkbuf_map, self.gated_clk_bar_inst, self.rail_offsets, ("m3", "via2", "m2"))
# The pin is on M1, so we need another via as well
self.add_via_center(layers=("metal1","via1","metal2"),
self.add_via_center(layers=self.m1_stack,
offset=self.gated_clk_bar_inst.get_pin("Z").center())
def create_gated_clk_buf_row(self):
@@ -587,9 +587,9 @@ class control_logic(design.design):
clkbuf_map = zip(["Z"], ["gated_clk_buf"])
self.connect_vertical_bus(clkbuf_map, self.gated_clk_buf_inst, self.rail_offsets, ("metal3", "via2", "metal2"))
self.connect_vertical_bus(clkbuf_map, self.gated_clk_buf_inst, self.rail_offsets, ("m3", "via2", "m2"))
# The pin is on M1, so we need another via as well
self.add_via_center(layers=("metal1","via1","metal2"),
self.add_via_center(layers=self.m1_stack,
offset=self.gated_clk_buf_inst.get_pin("Z").center())
def create_wlen_row(self):
@@ -637,7 +637,7 @@ class control_logic(design.design):
out_pos = self.p_en_bar_nand_inst.get_pin("Z").rc()
in_pos = self.p_en_bar_driver_inst.get_pin("A").lc()
mid1 = vector(out_pos.x,in_pos.y)
self.add_wire(("metal1","via1","metal2"),[out_pos, mid1,in_pos])
self.add_wire(self.m1_stack,[out_pos, mid1,in_pos])
self.connect_output(self.p_en_bar_driver_inst, "Z", "p_en_bar")
@@ -694,9 +694,9 @@ class control_logic(design.design):
# Connect to rail
rbl_map = zip(["Z"], ["rbl_bl_delay_bar"])
self.connect_vertical_bus(rbl_map, self.rbl_bl_delay_inv_inst, self.rail_offsets, ("metal3", "via2", "metal2"))
self.connect_vertical_bus(rbl_map, self.rbl_bl_delay_inv_inst, self.rail_offsets, ("m3", "via2", "m2"))
# The pin is on M1, so we need another via as well
self.add_via_center(layers=("metal1","via1","metal2"),
self.add_via_center(layers=self.m1_stack,
offset=self.rbl_bl_delay_inv_inst.get_pin("Z").center())
@@ -754,14 +754,14 @@ 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, ("metal3", "via2", "metal2"))
self.connect_vertical_bus(dff_out_map, self.ctrl_dff_inst, self.rail_offsets, ("m3", "via2", "m2"))
# Connect the clock rail to the other clock rail
in_pos = self.ctrl_dff_inst.get_pin("clk").uc()
mid_pos = in_pos + vector(0,2*self.m2_pitch)
rail_pos = vector(self.rail_offsets["clk_buf"].x, mid_pos.y)
self.add_wire(("metal1","via1","metal2"),[in_pos, mid_pos, rail_pos])
self.add_via_center(layers=("metal1","via1","metal2"),
self.add_wire(self.m1_stack,[in_pos, mid_pos, rail_pos])
self.add_via_center(layers=self.m1_stack,
offset=rail_pos)
self.copy_layout_pin(self.ctrl_dff_inst, "din_0", "csb")
@@ -786,7 +786,7 @@ class control_logic(design.design):
out_pin = inst.get_pin(pin_name)
right_pos=out_pin.center() + vector(self.width-out_pin.cx(),0)
self.add_layout_pin_segment_center(text=out_name,
layer="metal1",
layer="m1",
start=out_pin.center(),
end=right_pos)
@@ -799,19 +799,19 @@ class control_logic(design.design):
for inst in self.row_end_inst:
pins = inst.get_pins("vdd")
for pin in pins:
if pin.layer == "metal1":
if pin.layer == "m1":
row_loc = pin.rc()
pin_loc = vector(max_row_x_loc, pin.rc().y)
self.add_power_pin("vdd", pin_loc)
self.add_path("metal1", [row_loc, pin_loc])
self.add_path("m1", [row_loc, pin_loc])
pins = inst.get_pins("gnd")
for pin in pins:
if pin.layer == "metal1":
if pin.layer == "m1":
row_loc = pin.rc()
pin_loc = vector(max_row_x_loc, pin.rc().y)
self.add_power_pin("gnd", pin_loc)
self.add_path("metal1", [row_loc, pin_loc])
self.add_path("m1", [row_loc, pin_loc])
self.copy_layout_pin(self.delay_inst,"gnd")
self.copy_layout_pin(self.delay_inst,"vdd")
@@ -828,14 +828,14 @@ class control_logic(design.design):
"""
# pin=self.clk_inv1.get_pin("Z")
# self.add_label_pin(text="clk1_bar",
# layer="metal1",
# layer="m1",
# offset=pin.ll(),
# height=pin.height(),
# width=pin.width())
# pin=self.clk_inv2.get_pin("Z")
# self.add_label_pin(text="clk2",
# layer="metal1",
# layer="m1",
# offset=pin.ll(),
# height=pin.height(),
# width=pin.width())
+14 -14
View File
@@ -132,11 +132,11 @@ class delay_chain(design.design):
pin1_pos = pin1.center()
pin2_pos = pin2.center()
if pin1_pos.y == pin2_pos.y:
self.add_path("metal2", [pin1_pos, pin2_pos])
self.add_path("m2", [pin1_pos, pin2_pos])
else:
mid_point = vector(pin2_pos.x, 0.5*(pin1_pos.y+pin2_pos.y))
# Written this way to guarantee it goes right first if we are switching rows
self.add_path("metal2", [pin1_pos, vector(pin1_pos.x,mid_point.y), mid_point, vector(mid_point.x,pin2_pos.y), pin2_pos])
self.add_path("m2", [pin1_pos, vector(pin1_pos.x,mid_point.y), mid_point, vector(mid_point.x,pin2_pos.y), pin2_pos])
def route_inverters(self):
""" Add metal routing for each of the fanout stages """
@@ -146,22 +146,22 @@ class delay_chain(design.design):
for load in self.load_inst_map[inv]:
# Drop a via on each A pin
a_pin = load.get_pin("A")
self.add_via_center(layers=("metal1","via1","metal2"),
self.add_via_center(layers=self.m1_stack,
offset=a_pin.center())
self.add_via_center(layers=("metal2","via2","metal3"),
self.add_via_center(layers=self.m2_stack,
offset=a_pin.center())
# Route an M3 horizontal wire to the furthest
z_pin = inv.get_pin("Z")
a_pin = inv.get_pin("A")
a_max = self.rightest_load_inst[inv].get_pin("A")
self.add_via_center(layers=("metal1","via1","metal2"),
self.add_via_center(layers=self.m1_stack,
offset=a_pin.center())
self.add_via_center(layers=("metal1","via1","metal2"),
self.add_via_center(layers=self.m1_stack,
offset=z_pin.center())
self.add_via_center(layers=("metal2","via2","metal3"),
self.add_via_center(layers=self.m2_stack,
offset=z_pin.center())
self.add_path("metal3",[z_pin.center(), a_max.center()])
self.add_path("m3",[z_pin.center(), a_max.center()])
# Route Z to the A of the next stage
@@ -172,7 +172,7 @@ class delay_chain(design.design):
y_mid = (z_pin.cy() + next_a_pin.cy())/2
mid1_point = vector(z_pin.cx(), y_mid)
mid2_point = vector(next_a_pin.cx(), y_mid)
self.add_path("metal2",[z_pin.center(), mid1_point, mid2_point, next_a_pin.center()])
self.add_path("m2",[z_pin.center(), mid1_point, mid2_point, next_a_pin.center()])
def add_layout_pins(self):
@@ -205,10 +205,10 @@ class delay_chain(design.design):
# input is A pin of first inverter
a_pin = self.driver_inst_list[0].get_pin("A")
self.add_via_center(layers=("metal1","via1","metal2"),
self.add_via_center(layers=self.m1_stack,
offset=a_pin.center())
self.add_layout_pin(text="in",
layer="metal2",
layer="m2",
offset=a_pin.ll().scale(1,0),
height=a_pin.cy())
@@ -216,12 +216,12 @@ class delay_chain(design.design):
# output is A pin of last load inverter
last_driver_inst = self.driver_inst_list[-1]
a_pin = self.rightest_load_inst[last_driver_inst].get_pin("A")
self.add_via_center(layers=("metal1","via1","metal2"),
self.add_via_center(layers=self.m1_stack,
offset=a_pin.center())
mid_point = vector(a_pin.cx()+3*self.m2_width,a_pin.cy())
self.add_path("metal2",[a_pin.center(), mid_point, mid_point.scale(1,0)])
self.add_path("m2",[a_pin.center(), mid_point, mid_point.scale(1,0)])
self.add_layout_pin_segment_center(text="out",
layer="metal2",
layer="m2",
start=mid_point,
end=mid_point.scale(1,0))
+6 -6
View File
@@ -124,7 +124,7 @@ class dff_array(design.design):
for row in range(self.rows):
for col in range(self.columns):
din_pin = self.dff_insts[row,col].get_pin("D")
debug.check(din_pin.layer=="metal2","DFF D pin not on metal2")
debug.check(din_pin.layer=="m2","DFF D pin not on metal2")
self.add_layout_pin(text=self.get_din_name(row,col),
layer=din_pin.layer,
offset=din_pin.ll(),
@@ -132,7 +132,7 @@ class dff_array(design.design):
height=din_pin.height())
dout_pin = self.dff_insts[row,col].get_pin("Q")
debug.check(dout_pin.layer=="metal2","DFF Q pin not on metal2")
debug.check(dout_pin.layer=="m2","DFF Q pin not on metal2")
self.add_layout_pin(text=self.get_dout_name(row,col),
layer=dout_pin.layer,
offset=dout_pin.ll(),
@@ -144,20 +144,20 @@ class dff_array(design.design):
# Create vertical spines to a single horizontal rail
clk_pin = self.dff_insts[0,0].get_pin("clk")
clk_ypos = 2*self.m3_pitch+self.m3_width
debug.check(clk_pin.layer=="metal2","DFF clk pin not on metal2")
debug.check(clk_pin.layer=="m2","DFF clk pin not on metal2")
self.add_layout_pin_segment_center(text="clk",
layer="metal3",
layer="m3",
start=vector(0,clk_ypos),
end=vector(self.width,clk_ypos))
for col in range(self.columns):
clk_pin = self.dff_insts[0,col].get_pin("clk")
# Make a vertical strip for each column
self.add_rect(layer="metal2",
self.add_rect(layer="m2",
offset=clk_pin.ll().scale(1,0),
width=self.m2_width,
height=self.height)
# Drop a via to the M3 pin
self.add_via_center(layers=("metal2","via2","metal3"),
self.add_via_center(layers=self.m2_stack,
offset=vector(clk_pin.cx(),clk_ypos))
def get_clk_cin(self):
+13 -13
View File
@@ -112,12 +112,12 @@ class dff_buf(design.design):
mid_x_offset = 0.5*(a1_pin.cx() + q_pin.cx())
mid1 = vector(mid_x_offset, q_pin.cy())
mid2 = vector(mid_x_offset, a1_pin.cy())
self.add_path("metal3", [q_pin.center(), mid1, mid2, a1_pin.center()])
self.add_via_center(layers=("metal2","via2","metal3"),
self.add_path("m3", [q_pin.center(), mid1, mid2, a1_pin.center()])
self.add_via_center(layers=self.m2_stack,
offset=q_pin.center())
self.add_via_center(layers=("metal2","via2","metal3"),
self.add_via_center(layers=self.m2_stack,
offset=a1_pin.center())
self.add_via_center(layers=("metal1","via1","metal2"),
self.add_via_center(layers=self.m1_stack,
offset=a1_pin.center())
# Route inv1 z to inv2 a
@@ -126,14 +126,14 @@ class dff_buf(design.design):
mid_x_offset = 0.5*(z1_pin.cx() + a2_pin.cx())
self.mid_qb_pos = vector(mid_x_offset, z1_pin.cy())
mid2 = vector(mid_x_offset, a2_pin.cy())
self.add_path("metal1", [z1_pin.center(), self.mid_qb_pos, mid2, a2_pin.center()])
self.add_path("m1", [z1_pin.center(), self.mid_qb_pos, mid2, a2_pin.center()])
def add_layout_pins(self):
# Continous vdd rail along with label.
vdd_pin=self.dff_inst.get_pin("vdd")
self.add_layout_pin(text="vdd",
layer="metal1",
layer="m1",
offset=vdd_pin.ll(),
width=self.width,
height=vdd_pin.height())
@@ -141,7 +141,7 @@ class dff_buf(design.design):
# Continous gnd rail along with label.
gnd_pin=self.dff_inst.get_pin("gnd")
self.add_layout_pin(text="gnd",
layer="metal1",
layer="m1",
offset=gnd_pin.ll(),
width=self.width,
height=vdd_pin.height())
@@ -164,18 +164,18 @@ class dff_buf(design.design):
mid_pos = dout_pin.center() + vector(self.m1_pitch,0)
q_pos = mid_pos - vector(0,self.m2_pitch)
self.add_layout_pin_rect_center(text="Q",
layer="metal2",
layer="m2",
offset=q_pos)
self.add_path("metal1", [dout_pin.center(), mid_pos, q_pos])
self.add_via_center(layers=("metal1","via1","metal2"),
self.add_path("m1", [dout_pin.center(), mid_pos, q_pos])
self.add_via_center(layers=self.m1_stack,
offset=q_pos)
qb_pos = self.mid_qb_pos + vector(0,self.m2_pitch)
self.add_layout_pin_rect_center(text="Qb",
layer="metal2",
layer="m2",
offset=qb_pos)
self.add_path("metal1", [self.mid_qb_pos, qb_pos])
self.add_via_center(layers=("metal1","via1","metal2"),
self.add_path("m1", [self.mid_qb_pos, qb_pos])
self.add_via_center(layers=self.m1_stack,
offset=qb_pos)
def get_clk_cin(self):
+8 -8
View File
@@ -142,7 +142,7 @@ class dff_buf_array(design.design):
for row in range(self.rows):
for col in range(self.columns):
din_pin = self.dff_insts[row,col].get_pin("D")
debug.check(din_pin.layer=="metal2","DFF D pin not on metal2")
debug.check(din_pin.layer=="m2","DFF D pin not on metal2")
self.add_layout_pin(text=self.get_din_name(row,col),
layer=din_pin.layer,
offset=din_pin.ll(),
@@ -150,7 +150,7 @@ class dff_buf_array(design.design):
height=din_pin.height())
dout_pin = self.dff_insts[row,col].get_pin("Q")
debug.check(dout_pin.layer=="metal2","DFF Q pin not on metal2")
debug.check(dout_pin.layer=="m2","DFF Q pin not on metal2")
self.add_layout_pin(text=self.get_dout_name(row,col),
layer=dout_pin.layer,
offset=dout_pin.ll(),
@@ -158,7 +158,7 @@ class dff_buf_array(design.design):
height=dout_pin.height())
dout_bar_pin = self.dff_insts[row,col].get_pin("Qb")
debug.check(dout_bar_pin.layer=="metal2","DFF Qb pin not on metal2")
debug.check(dout_bar_pin.layer=="m2","DFF Qb pin not on metal2")
self.add_layout_pin(text=self.get_dout_bar_name(row,col),
layer=dout_bar_pin.layer,
offset=dout_bar_pin.ll(),
@@ -169,28 +169,28 @@ class dff_buf_array(design.design):
# Create vertical spines to a single horizontal rail
clk_pin = self.dff_insts[0,0].get_pin("clk")
clk_ypos = 2*self.m3_pitch+self.m3_width
debug.check(clk_pin.layer=="metal2","DFF clk pin not on metal2")
debug.check(clk_pin.layer=="m2","DFF clk pin not on metal2")
if self.columns==1:
self.add_layout_pin(text="clk",
layer="metal2",
layer="m2",
offset=clk_pin.ll().scale(1,0),
width=self.m2_width,
height=self.height)
else:
self.add_layout_pin_segment_center(text="clk",
layer="metal3",
layer="m3",
start=vector(0,clk_ypos),
end=vector(self.width,clk_ypos))
for col in range(self.columns):
clk_pin = self.dff_insts[0,col].get_pin("clk")
# Make a vertical strip for each column
self.add_rect(layer="metal2",
self.add_rect(layer="m2",
offset=clk_pin.ll().scale(1,0),
width=self.m2_width,
height=self.height)
# Drop a via to the M3 pin
self.add_via_center(layers=("metal2","via2","metal3"),
self.add_via_center(layers=self.m2_stack,
offset=vector(clk_pin.cx(),clk_ypos))
def get_clk_cin(self):
+8 -8
View File
@@ -97,13 +97,13 @@ class dff_inv(design.design):
mid_x_offset = 0.5*(a1_pin.cx() + q_pin.cx())
mid1 = vector(mid_x_offset, q_pin.cy())
mid2 = vector(mid_x_offset, a1_pin.cy())
self.add_path("metal3",
self.add_path("m3",
[q_pin.center(), mid1, mid2, a1_pin.center()])
self.add_via_center(layers=("metal2","via2","metal3"),
self.add_via_center(layers=self.m2_stack,
offset=q_pin.center())
self.add_via_center(layers=("metal2","via2","metal3"),
self.add_via_center(layers=self.m2_stack,
offset=a1_pin.center())
self.add_via_center(layers=("metal1","via1","metal2"),
self.add_via_center(layers=self.m1_stack,
offset=a1_pin.center())
@@ -112,7 +112,7 @@ class dff_inv(design.design):
# Continous vdd rail along with label.
vdd_pin=self.dff_inst.get_pin("vdd")
self.add_layout_pin(text="vdd",
layer="metal1",
layer="m1",
offset=vdd_pin.ll(),
width=self.width,
height=vdd_pin.height())
@@ -120,7 +120,7 @@ class dff_inv(design.design):
# Continous gnd rail along with label.
gnd_pin=self.dff_inst.get_pin("gnd")
self.add_layout_pin(text="gnd",
layer="metal1",
layer="m1",
offset=gnd_pin.ll(),
width=self.width,
height=vdd_pin.height())
@@ -146,9 +146,9 @@ class dff_inv(design.design):
dout_pin = self.inv1_inst.get_pin("Z")
self.add_layout_pin_rect_center(text="Qb",
layer="metal2",
layer="m2",
offset=dout_pin.center())
self.add_via_center(layers=("metal1","via1","metal2"),
self.add_via_center(layers=self.m1_stack,
offset=dout_pin.center())
def get_clk_cin(self):
+8 -8
View File
@@ -140,7 +140,7 @@ class dff_inv_array(design.design):
for row in range(self.rows):
for col in range(self.columns):
din_pin = self.dff_insts[row,col].get_pin("D")
debug.check(din_pin.layer=="metal2","DFF D pin not on metal2")
debug.check(din_pin.layer=="m2","DFF D pin not on metal2")
self.add_layout_pin(text=self.get_din_name(row,col),
layer=din_pin.layer,
offset=din_pin.ll(),
@@ -148,7 +148,7 @@ class dff_inv_array(design.design):
height=din_pin.height())
dout_pin = self.dff_insts[row,col].get_pin("Q")
debug.check(dout_pin.layer=="metal2","DFF Q pin not on metal2")
debug.check(dout_pin.layer=="m2","DFF Q pin not on metal2")
self.add_layout_pin(text=self.get_dout_name(row,col),
layer=dout_pin.layer,
offset=dout_pin.ll(),
@@ -156,7 +156,7 @@ class dff_inv_array(design.design):
height=dout_pin.height())
dout_bar_pin = self.dff_insts[row,col].get_pin("Qb")
debug.check(dout_bar_pin.layer=="metal2","DFF Qb pin not on metal2")
debug.check(dout_bar_pin.layer=="m2","DFF Qb pin not on metal2")
self.add_layout_pin(text=self.get_dout_bar_name(row,col),
layer=dout_bar_pin.layer,
offset=dout_bar_pin.ll(),
@@ -167,27 +167,27 @@ class dff_inv_array(design.design):
# Create vertical spines to a single horizontal rail
clk_pin = self.dff_insts[0,0].get_pin("clk")
clk_ypos = 2*self.m3_pitch+self.m3_width
debug.check(clk_pin.layer=="metal2","DFF clk pin not on metal2")
debug.check(clk_pin.layer=="m2","DFF clk pin not on metal2")
if self.columns==1:
self.add_layout_pin(text="clk",
layer="metal2",
layer="m2",
offset=clk_pin.ll().scale(1,0),
width=self.m2_width,
height=self.height)
else:
self.add_layout_pin_segment_center(text="clk",
layer="metal3",
layer="m3",
start=vector(0,clk_ypos),
end=vector(self.width,clk_ypos))
for col in range(self.columns):
clk_pin = self.dff_insts[0,col].get_pin("clk")
# Make a vertical strip for each column
self.add_rect(layer="metal2",
self.add_rect(layer="m2",
offset=clk_pin.ll().scale(1,0),
width=self.m2_width,
height=self.height)
# Drop a via to the M3 pin
self.add_via_center(layers=("metal2","via2","metal3"),
self.add_via_center(layers=self.m2_stack,
offset=vector(clk_pin.cx(),clk_ypos))
def get_clk_cin(self):
+2 -2
View File
@@ -122,7 +122,7 @@ class dummy_array(design.design):
for cell_column in column_list:
bl_pin = self.cell_inst[0,col].get_pin(cell_column)
self.add_layout_pin(text=cell_column+"_{0}".format(col),
layer="metal2",
layer="m2",
offset=bl_pin.ll(),
width=bl_pin.width(),
height=self.height)
@@ -131,7 +131,7 @@ class dummy_array(design.design):
for cell_row in row_list:
wl_pin = self.cell_inst[row,0].get_pin(cell_row)
self.add_layout_pin(text=cell_row+"_{0}".format(row),
layer="metal1",
layer="m1",
offset=wl_pin.ll(),
width=self.width,
height=wl_pin.height())
+8 -8
View File
@@ -173,7 +173,7 @@ class hierarchical_decoder(design.design):
input_offset=vector(min_x - self.input_routing_width,0)
input_bus_names = ["addr_{0}".format(i) for i in range(self.num_inputs)]
self.input_rails = self.create_vertical_pin_bus(layer="metal2",
self.input_rails = self.create_vertical_pin_bus(layer="m2",
pitch=self.m2_pitch,
offset=input_offset,
names=input_bus_names,
@@ -225,7 +225,7 @@ class hierarchical_decoder(design.design):
offset=input_offset)
self.add_via_center(layers=self.m2_stack,
offset=output_offset)
self.add_path(("metal3"), [input_offset, output_offset])
self.add_path(("m3"), [input_offset, output_offset])
def add_pins(self):
@@ -467,11 +467,11 @@ class hierarchical_decoder(design.design):
# ensure the bend is in the middle
mid1_pos = vector(0.5*(zr_pos.x+al_pos.x), zr_pos.y)
mid2_pos = vector(0.5*(zr_pos.x+al_pos.x), al_pos.y)
self.add_path("metal1", [zr_pos, mid1_pos, mid2_pos, al_pos])
self.add_path("m1", [zr_pos, mid1_pos, mid2_pos, al_pos])
z_pin = self.inv_inst[row].get_pin("Z")
self.add_layout_pin(text="decode_{0}".format(row),
layer="metal1",
layer="m1",
offset=z_pin.ll(),
width=z_pin.width(),
height=z_pin.height())
@@ -485,7 +485,7 @@ class hierarchical_decoder(design.design):
if (self.num_inputs >= 4):
input_offset = vector(0.5*self.m2_width,0)
input_bus_names = ["predecode_{0}".format(i) for i in range(self.total_number_of_predecoder_outputs)]
self.predecode_rails = self.create_vertical_pin_bus(layer="metal2",
self.predecode_rails = self.create_vertical_pin_bus(layer="m2",
pitch=self.m2_pitch,
offset=input_offset,
names=input_bus_names,
@@ -570,7 +570,7 @@ class hierarchical_decoder(design.design):
start = self.nand_inst[num].get_pin(pin_name).lc()
end = self.inv_inst[num].get_pin(pin_name).rc()
mid = (start+end).scale(0.5,0.5)
self.add_rect_center(layer="metal1",
self.add_rect_center(layer="m1",
offset=mid,
width=end.x-start.x)
@@ -584,7 +584,7 @@ class hierarchical_decoder(design.design):
def route_predecode_rail(self, rail_name, pin):
""" 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_path("m1", [rail_pos, pin.lc()])
self.add_via_center(layers=self.m1_stack,
offset=rail_pos)
@@ -597,7 +597,7 @@ class hierarchical_decoder(design.design):
rail_pos = vector(self.predecode_rails[rail_name].x,mid_point.y)
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_wire(("m3","via2","m2"), [rail_pos, mid_point, pin.uc()])
self.add_via_center(layers=self.m2_stack,
offset=rail_pos)
+9 -9
View File
@@ -73,7 +73,7 @@ class hierarchical_predecode(design.design):
""" Create all of the rails for the inputs and vdd/gnd/inputs_bar/inputs """
input_names = ["in_{}".format(x) for x in range(self.number_of_inputs)]
offset = vector(0.5*self.m2_width,2*self.m1_width)
self.input_rails = self.create_vertical_pin_bus(layer="metal2",
self.input_rails = self.create_vertical_pin_bus(layer="m2",
pitch=self.m2_pitch,
offset=offset,
names=input_names,
@@ -83,7 +83,7 @@ class hierarchical_predecode(design.design):
non_invert_names = ["A_{}".format(x) for x in range(self.number_of_inputs)]
decode_names = invert_names + non_invert_names
offset = vector(self.x_off_inv_1 + self.inv.width + 2*self.m2_pitch, 2*self.m1_width)
self.decode_rails = self.create_vertical_bus(layer="metal2",
self.decode_rails = self.create_vertical_bus(layer="m2",
pitch=self.m2_pitch,
offset=offset,
names=decode_names,
@@ -183,7 +183,7 @@ class hierarchical_predecode(design.design):
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)
self.add_path("metal1",[in_pos, a_pos])
self.add_path("m1",[in_pos, a_pos])
self.add_via_center(layers = self.m1_stack,
offset=[self.input_rails[in_pin].x, y_offset])
self.add_via_center(layers = self.m1_stack,
@@ -201,11 +201,11 @@ class hierarchical_predecode(design.design):
# ensure the bend is in the middle
mid1_pos = vector(0.5*(zr_pos.x+al_pos.x), zr_pos.y)
mid2_pos = vector(0.5*(zr_pos.x+al_pos.x), al_pos.y)
self.add_path("metal1", [zr_pos, mid1_pos, mid2_pos, al_pos])
self.add_path("m1", [zr_pos, mid1_pos, mid2_pos, al_pos])
z_pin = self.inv_inst[num].get_pin("Z")
self.add_layout_pin(text="out_{}".format(num),
layer="metal1",
layer="m1",
offset=z_pin.ll(),
height=z_pin.height(),
width=z_pin.width())
@@ -226,7 +226,7 @@ class hierarchical_predecode(design.design):
inv_out_pos = self.in_inst[inv_num].get_pin("Z").rc()
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_path("m1", [inv_out_pos, right_pos, vector(right_pos.x, y_offset), rail_pos])
self.add_via_center(layers = self.m1_stack,
offset=rail_pos)
@@ -234,7 +234,7 @@ class hierarchical_predecode(design.design):
#route input
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_path("m1", [in_pos, inv_in_pos])
self.add_via_center(layers=self.m1_stack,
offset=in_pos)
@@ -255,7 +255,7 @@ class hierarchical_predecode(design.design):
for rail_pin,gate_pin in zip(index_lst,gate_lst):
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_path("m1", [rail_pos, pin_pos])
self.add_via_center(layers=self.m1_stack,
offset=rail_pos)
@@ -275,7 +275,7 @@ class hierarchical_predecode(design.design):
for n in ["vdd", "gnd"]:
nand_pin = self.nand_inst[num].get_pin(n)
supply_offset = nand_pin.ll().scale(0,1)
self.add_rect(layer="metal1",
self.add_rect(layer="m1",
offset=supply_offset,
width=self.inv_inst[num].rx())
+29 -29
View File
@@ -160,7 +160,7 @@ class multibank(design.design):
self.central_bus_width = self.m2_pitch * self.num_control_lines + 2*self.m2_width
# A space for wells or jogging m2
self.m2_gap = max(2*drc("pwell_to_nwell"] + drc["well_enclosure_active"),
self.m2_gap = max(2*drc("pwell_to_nwell"] + drc["well_enclose_active"),
2*self.m2_pitch)
@@ -451,7 +451,7 @@ class multibank(design.design):
# Connect the inverter output to the central bus
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_path("m3",[out_pos, bus_pos])
self.add_via_center(layers=self.m2_stack,
offset=bus_pos,
rotate=90)
@@ -512,7 +512,7 @@ class multibank(design.design):
# 2 pitches on the right for vias/jogs to access the inputs
control_bus_offset = vector(-self.m2_pitch * self.num_control_lines - self.m2_width, 0)
control_bus_length = self.bitcell_array_inst.uy()
self.bus_xoffset = self.create_vertical_bus(layer="metal2",
self.bus_xoffset = self.create_vertical_bus(layer="m2",
pitch=self.m2_pitch,
offset=control_bus_offset,
names=self.control_signals,
@@ -530,9 +530,9 @@ class multibank(design.design):
bitcell_br = self.bitcell_array_inst.get_pin("br_{}".format(i)).uc()
yoffset = 0.5*(precharge_bl.y+bitcell_bl.y)
self.add_path("metal2",[precharge_bl, vector(precharge_bl.x,yoffset),
self.add_path("m2",[precharge_bl, vector(precharge_bl.x,yoffset),
vector(bitcell_bl.x,yoffset), bitcell_bl])
self.add_path("metal2",[precharge_br, vector(precharge_br.x,yoffset),
self.add_path("m2",[precharge_br, vector(precharge_br.x,yoffset),
vector(bitcell_br.x,yoffset), bitcell_br])
@@ -550,9 +550,9 @@ class multibank(design.design):
bitcell_br = self.bitcell_array_inst.get_pin("br_{}".format(i)).bc()
yoffset = 0.5*(col_mux_bl.y+bitcell_bl.y)
self.add_path("metal2",[col_mux_bl, vector(col_mux_bl.x,yoffset),
self.add_path("m2",[col_mux_bl, vector(col_mux_bl.x,yoffset),
vector(bitcell_bl.x,yoffset), bitcell_bl])
self.add_path("metal2",[col_mux_br, vector(col_mux_br.x,yoffset),
self.add_path("m2",[col_mux_br, vector(col_mux_br.x,yoffset),
vector(bitcell_br.x,yoffset), bitcell_br])
def route_sense_amp_to_col_mux_or_bitcell_array(self):
@@ -573,9 +573,9 @@ class multibank(design.design):
yoffset = 0.5*(sense_amp_bl.y+connect_bl.y)
self.add_path("metal2",[sense_amp_bl, vector(sense_amp_bl.x,yoffset),
self.add_path("m2",[sense_amp_bl, vector(sense_amp_bl.x,yoffset),
vector(connect_bl.x,yoffset), connect_bl])
self.add_path("metal2",[sense_amp_br, vector(sense_amp_br.x,yoffset),
self.add_path("m2",[sense_amp_br, vector(sense_amp_br.x,yoffset),
vector(connect_br.x,yoffset), connect_br])
def route_sense_amp_to_trigate(self):
@@ -590,7 +590,7 @@ class multibank(design.design):
offset=tri_gate_in)
self.add_via_center(layers=self.m2_stack,
offset=sa_data_out)
self.add_path("metal3",[sa_data_out,tri_gate_in])
self.add_path("m3",[sa_data_out,tri_gate_in])
def route_sense_amp_out(self):
""" Add pins for the sense amp output """
@@ -644,14 +644,14 @@ class multibank(design.design):
driver_in_pos = self.wordline_driver_inst.get_pin("in_{}".format(i)).lc()
mid1 = decoder_out_pos.scale(0.5,1)+driver_in_pos.scale(0.5,0)
mid2 = decoder_out_pos.scale(0.5,0)+driver_in_pos.scale(0.5,1)
self.add_path("metal1", [decoder_out_pos, mid1, mid2, driver_in_pos])
self.add_path("m1", [decoder_out_pos, mid1, mid2, driver_in_pos])
# The mid guarantees we exit the input cell to the right.
driver_wl_pos = self.wordline_driver_inst.get_pin("wl_{}".format(i)).rc()
bitcell_wl_pos = self.bitcell_array_inst.get_pin("wl_{}".format(i)).lc()
mid1 = driver_wl_pos.scale(0.5,1)+bitcell_wl_pos.scale(0.5,0)
mid2 = driver_wl_pos.scale(0.5,0)+bitcell_wl_pos.scale(0.5,1)
self.add_path("metal1", [driver_wl_pos, mid1, mid2, bitcell_wl_pos])
self.add_path("m1", [driver_wl_pos, mid1, mid2, bitcell_wl_pos])
@@ -698,8 +698,8 @@ class multibank(design.design):
else:
mid1_pos = vector(decode_out_pos.x + delta_offset + (self.num_col_addr_lines-i)*self.m2_pitch,decode_out_pos.y)
mid2_pos = vector(mid1_pos.x,mux_addr_pos.y)
#self.add_wire(("metal1","via1","metal2"),[decode_out_pos, mid1_pos, mid2_pos, mux_addr_pos])
self.add_path("metal1",[decode_out_pos, mid1_pos, mid2_pos, mux_addr_pos])
#self.add_wire(self.m1_stack,[decode_out_pos, mid1_pos, mid2_pos, mux_addr_pos])
self.add_path("m1",[decode_out_pos, mid1_pos, mid2_pos, mux_addr_pos])
@@ -715,7 +715,7 @@ class multibank(design.design):
wl_name = "wl_{}".format(i)
wl_pin = self.bitcell_array_inst.get_pin(wl_name)
self.add_label(text=wl_name,
layer="metal1",
layer="m1",
offset=wl_pin.center())
# Add the bitline names
@@ -725,10 +725,10 @@ class multibank(design.design):
bl_pin = self.bitcell_array_inst.get_pin(bl_name)
br_pin = self.bitcell_array_inst.get_pin(br_name)
self.add_label(text=bl_name,
layer="metal2",
layer="m2",
offset=bl_pin.center())
self.add_label(text=br_name,
layer="metal2",
layer="m2",
offset=br_pin.center())
# # Add the data output names to the sense amp output
@@ -736,7 +736,7 @@ class multibank(design.design):
# data_name = "data_{}".format(i)
# data_pin = self.sense_amp_array_inst.get_pin(data_name)
# self.add_label(text="sa_out_{}".format(i),
# layer="metal2",
# layer="m2",
# offset=data_pin.center())
# Add labels on the decoder
@@ -745,7 +745,7 @@ class multibank(design.design):
pin_name = "in_{}".format(i)
data_pin = self.wordline_driver_inst.get_pin(pin_name)
self.add_label(text=data_name,
layer="metal1",
layer="m1",
offset=data_pin.center())
@@ -765,7 +765,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_path("m1", [control_pos, pin_pos])
self.add_via_center(layers=self.m1_stack,
offset=control_pos,
rotate=90)
@@ -776,7 +776,7 @@ class multibank(design.design):
mid_pos = pin_pos + vector(0,self.m1_pitch)
control_x_offset = self.bus_xoffset[control_signal].x
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(self.m1_stack,[pin_pos, mid_pos, control_pos])
control_via_pos = vector(control_x_offset, mid_pos.y)
self.add_via_center(layers=self.m1_stack,
offset=control_via_pos,
@@ -791,13 +791,13 @@ class multibank(design.design):
if self.num_banks > 1:
# it's not an input pin if we have multiple banks
self.add_label_pin(text=ctrl,
layer="metal2",
layer="m2",
offset=vector(x_offset, self.min_y_offset),
width=self.m2_width,
height=self.max_y_offset-self.min_y_offset)
else:
self.add_layout_pin(text=ctrl,
layer="metal2",
layer="m2",
offset=vector(x_offset, self.min_y_offset),
width=self.m2_width,
height=self.max_y_offset-self.min_y_offset)
@@ -807,12 +807,12 @@ class multibank(design.design):
""" Helper routine to connect an unrotated/mirrored oriented instance to the rails """
in_pin = inst.get_pin(pin).lc()
rail_pos = vector(self.rail_1_x_offsets[rail], in_pin.y)
self.add_wire(("metal3","via2","metal2"),[in_pin, rail_pos, rail_pos - vector(0,self.m2_pitch)])
self.add_wire(("m3","via2","m2"),[in_pin, rail_pos, rail_pos - vector(0,self.m2_pitch)])
# Bring it up to M2 for M2/M3 routing
self.add_via(layers=("metal1","via1","metal2"),
self.add_via(layers=self.m1_stack,
offset=in_pin + contact.m1m2.offset,
rotate=90)
self.add_via(layers=("metal2","via2","metal3"),
self.add_via(layers=self.m2_stack,
offset=in_pin + self.m2m3_via_offset,
rotate=90)
@@ -821,10 +821,10 @@ class multibank(design.design):
""" Helper routine to connect an unrotated/mirrored oriented instance to the rails """
in_pin = inst.get_pin(pin).rc()
rail_pos = vector(self.rail_1_x_offsets[rail], in_pin.y)
self.add_wire(("metal3","via2","metal2"),[in_pin, rail_pos, rail_pos - vector(0,self.m2_pitch)])
self.add_via(layers=("metal1","via1","metal2"),
self.add_wire(("m3","via2","m2"),[in_pin, rail_pos, rail_pos - vector(0,self.m2_pitch)])
self.add_via(layers=self.m1_stack,
offset=in_pin + contact.m1m2.offset,
rotate=90)
self.add_via(layers=("metal2","via2","metal3"),
self.add_via(layers=self.m2_stack,
offset=in_pin + self.m2m3_via_offset,
rotate=90)
+2 -2
View File
@@ -92,7 +92,7 @@ class port_address(design.design):
driver_in_pos = self.wordline_driver_inst.get_pin("in_{}".format(row)).lc()
mid1 = decoder_out_pos.scale(0.5,1)+driver_in_pos.scale(0.5,0)
mid2 = decoder_out_pos.scale(0.5,0)+driver_in_pos.scale(0.5,1)
self.add_path("metal1", [decoder_out_pos, mid1, mid2, driver_in_pos])
self.add_path("m1", [decoder_out_pos, mid1, mid2, driver_in_pos])
@@ -149,7 +149,7 @@ class port_address(design.design):
"""
# A space for wells or jogging m2
self.m2_gap = max(2*drc("pwell_to_nwell") + drc("well_enclosure_active"),
self.m2_gap = max(2*drc("pwell_to_nwell") + drc("well_enclose_active"),
3*self.m2_pitch)
row_decoder_offset = vector(0,0)
+4 -4
View File
@@ -212,7 +212,7 @@ class port_data(design.design):
# A space for wells or jogging m2 between modules
self.m2_gap = max(2*drc("pwell_to_nwell") + drc("well_enclosure_active"),
self.m2_gap = max(2*drc("pwell_to_nwell") + drc("well_enclose_active"),
3*self.m2_pitch)
@@ -479,7 +479,7 @@ class port_data(design.design):
offset=end_pos)
# Route between write mask AND array and write driver array
self.add_wire(("metal1","via1","metal2"), [beg_pos, middle_pos, end_pos])
self.add_wire(self.m1_stack, [beg_pos, middle_pos, end_pos])
def route_column_mux_to_precharge_array(self, port):
@@ -655,9 +655,9 @@ class port_data(design.design):
top_br = top_inst.get_pin(top_br_name.format(col+top_start_bit)).bc()
yoffset = 0.5*(top_bl.y+bottom_bl.y)
self.add_path("metal2",[bottom_bl, vector(bottom_bl.x,yoffset),
self.add_path("m2",[bottom_bl, vector(bottom_bl.x,yoffset),
vector(top_bl.x,yoffset), top_bl])
self.add_path("metal2",[bottom_br, vector(bottom_br.x,yoffset),
self.add_path("m2",[bottom_br, vector(bottom_br.x,yoffset),
vector(top_br.x,yoffset), top_br])
def graph_exclude_precharge(self):
+6 -6
View File
@@ -68,10 +68,10 @@ class precharge_array(design.design):
def add_layout_pins(self):
self.add_layout_pin(text="en_bar",
layer="metal1",
layer="m1",
offset=self.pc_cell.get_pin("en_bar").ll(),
width=self.width,
height=drc("minwidth_metal1"))
height=drc("minwidth_m1"))
for inst in self.local_insts:
self.copy_layout_pin(inst, "vdd")
@@ -80,15 +80,15 @@ class precharge_array(design.design):
inst = self.local_insts[i]
bl_pin = inst.get_pin("bl")
self.add_layout_pin(text="bl_{0}".format(i),
layer="metal2",
layer="m2",
offset=bl_pin.ll(),
width=drc("minwidth_metal2"),
width=drc("minwidth_m2"),
height=bl_pin.height())
br_pin = inst.get_pin("br")
self.add_layout_pin(text="br_{0}".format(i),
layer="metal2",
layer="m2",
offset=br_pin.ll(),
width=drc("minwidth_metal2"),
width=drc("minwidth_m2"),
height=bl_pin.height())
+1 -1
View File
@@ -399,7 +399,7 @@ class replica_bitcell_array(design.design):
else:
height = self.height
bl_pos = 0
bl_wire = self.generate_rc_net(int(self.row_size-bl_pos), height, drc("minwidth_metal1"))
bl_wire = self.generate_rc_net(int(self.row_size-bl_pos), height, drc("minwidth_m1"))
bl_wire.wire_c =spice["min_tx_drain_c"] + bl_wire.wire_c # 1 access tx d/s per cell
return bl_wire
+2 -2
View File
@@ -116,7 +116,7 @@ class replica_column(design.design):
for bl_name in self.cell.get_all_bitline_names():
bl_pin = self.cell_inst[0].get_pin(bl_name)
self.add_layout_pin(text=bl_name,
layer="metal2",
layer="m2",
offset=bl_pin.ll(),
width=bl_pin.width(),
height=self.height)
@@ -125,7 +125,7 @@ class replica_column(design.design):
for wl_name in self.cell.get_all_wl_names():
wl_pin = self.cell_inst[row].get_pin(wl_name)
self.add_layout_pin(text="{0}_{1}".format(wl_name,row),
layer="metal1",
layer="m1",
offset=wl_pin.ll().scale(0,1),
width=self.width,
height=wl_pin.height())
+7 -7
View File
@@ -102,13 +102,13 @@ class sense_amp_array(design.design):
self.add_via_center(layers=self.m2_stack,
offset=gnd_pos)
self.add_layout_pin_rect_center(text="gnd",
layer="metal3",
layer="m3",
offset=gnd_pos)
vdd_pos = inst.get_pin("vdd").center()
self.add_via_center(layers=self.m2_stack,
offset=vdd_pos)
self.add_layout_pin_rect_center(text="vdd",
layer="metal3",
layer="m3",
offset=vdd_pos)
bl_pin = inst.get_pin("bl")
@@ -116,18 +116,18 @@ class sense_amp_array(design.design):
dout_pin = inst.get_pin("dout")
self.add_layout_pin(text="bl_{0}".format(i),
layer="metal2",
layer="m2",
offset=bl_pin.ll(),
width=bl_pin.width(),
height=bl_pin.height())
self.add_layout_pin(text="br_{0}".format(i),
layer="metal2",
layer="m2",
offset=br_pin.ll(),
width=br_pin.width(),
height=br_pin.height())
self.add_layout_pin(text="data_{0}".format(i),
layer="metal2",
layer="m2",
offset=dout_pin.ll(),
width=dout_pin.width(),
height=dout_pin.height())
@@ -137,10 +137,10 @@ class sense_amp_array(design.design):
# add sclk rail across entire array
sclk_offset = self.amp.get_pin("en").ll().scale(0,1)
self.add_layout_pin(text="en",
layer="metal1",
layer="m1",
offset=sclk_offset,
width=self.width,
height=drc("minwidth_metal1"))
height=drc("minwidth_m1"))
def input_load(self):
return self.amp.input_load()
@@ -113,13 +113,13 @@ class single_level_column_mux_array(design.design):
mux_inst = self.mux_inst[col_num]
offset = mux_inst.get_pin("bl").ll()
self.add_layout_pin(text="bl_{}".format(col_num),
layer="metal2",
layer="m2",
offset=offset,
height=self.height-offset.y)
offset = mux_inst.get_pin("br").ll()
self.add_layout_pin(text="br_{}".format(col_num),
layer="metal2",
layer="m2",
offset=offset,
height=self.height-offset.y)
@@ -137,7 +137,7 @@ class single_level_column_mux_array(design.design):
for j in range(self.words_per_row):
offset = vector(0, self.route_height + (j-self.words_per_row)*self.m1_pitch)
self.add_layout_pin(text="sel_{}".format(j),
layer="metal1",
layer="m1",
offset=offset,
width=self.mux.width * self.columns)
@@ -155,7 +155,7 @@ class single_level_column_mux_array(design.design):
# use the y offset from the sel pin and the x offset from the gate
offset = vector(gate_offset.x,self.get_pin("sel_{}".format(sel_index)).cy())
# Add the poly contact with a shift to account for the rotation
self.add_via_center(layers=("metal1", "contact", "poly"),
self.add_via_center(layers=("m1", "contact", "poly"),
offset=offset)
self.add_path("poly", [offset, gate_offset])
@@ -176,16 +176,16 @@ class single_level_column_mux_array(design.design):
# These will be located below the select lines. Yes, these are M2 width
# to ensure vias are enclosed and M1 min width rules.
width = self.m2_width + self.mux.width * (self.words_per_row - 1)
self.add_path("metal1", [bl_out_offset, bl_out_offset+vector(width,0)])
self.add_path("metal1", [br_out_offset, br_out_offset+vector(width,0)])
self.add_path("m1", [bl_out_offset, bl_out_offset+vector(width,0)])
self.add_path("m1", [br_out_offset, br_out_offset+vector(width,0)])
# Extend the bitline output rails and gnd downward on the first bit of each n-way mux
self.add_layout_pin_segment_center(text="bl_out_{}".format(int(j/self.words_per_row)),
layer="metal2",
layer="m2",
start=bl_out_offset,
end=bl_out_offset_end)
self.add_layout_pin_segment_center(text="br_out_{}".format(int(j/self.words_per_row)),
layer="metal2",
layer="m2",
start=br_out_offset,
end=br_out_offset_end)
@@ -200,8 +200,8 @@ class single_level_column_mux_array(design.design):
else:
self.add_path("metal2", [ bl_out_offset, bl_out_offset_end])
self.add_path("metal2", [ br_out_offset, br_out_offset_end])
self.add_path("m2", [ bl_out_offset, bl_out_offset_end])
self.add_path("m2", [ br_out_offset, br_out_offset_end])
# This via is on the right of the wire
self.add_via_center(layers=self.m1_stack,
+7 -7
View File
@@ -83,14 +83,14 @@ class tri_gate_array(design.design):
in_pin = self.tri_inst[i].get_pin("in")
self.add_layout_pin(text="in_{0}".format(index),
layer="metal2",
layer="m2",
offset=in_pin.ll(),
width=in_pin.width(),
height=in_pin.height())
out_pin = self.tri_inst[i].get_pin("out")
self.add_layout_pin(text="out_{0}".format(index),
layer="metal2",
layer="m2",
offset=out_pin.ll(),
width=out_pin.width(),
height=out_pin.height())
@@ -103,21 +103,21 @@ class tri_gate_array(design.design):
self.add_via_center(layers=self.m2_stack,
offset=pin_pos)
self.add_layout_pin_rect_center(text=n,
layer="metal3",
layer="m3",
offset=pin_pos)
width = self.tri.width * self.columns - (self.words_per_row - 1) * self.tri.width
en_pin = self.tri_inst[0].get_pin("en")
self.add_layout_pin(text="en",
layer="metal1",
layer="m1",
offset=en_pin.ll().scale(0, 1),
width=width,
height=drc("minwidth_metal1"))
height=drc("minwidth_m1"))
enbar_pin = self.tri_inst[0].get_pin("en_bar")
self.add_layout_pin(text="en_bar",
layer="metal1",
layer="m1",
offset=enbar_pin.ll().scale(0, 1),
width=width,
height=drc("minwidth_metal1"))
height=drc("minwidth_m1"))
+6 -6
View File
@@ -142,7 +142,7 @@ class wordline_driver(design.design):
# Wordline enable connection
en_offset = [self.m1_width + 2 * self.m1_space, 0]
en_pin = self.add_layout_pin(text="en",
layer="metal2",
layer="m2",
offset=en_offset,
width=self.m2_width,
height=self.height)
@@ -155,7 +155,7 @@ class wordline_driver(design.design):
a_pin = nand_inst.get_pin("A")
a_pos = a_pin.lc()
clk_offset = vector(en_pin.bc().x, a_pos.y)
self.add_segment_center(layer="metal1",
self.add_segment_center(layer="m1",
start=clk_offset,
end=a_pos)
self.add_via_center(layers=self.m1_stack,
@@ -167,7 +167,7 @@ class wordline_driver(design.design):
# ensure the bend is in the middle
mid1_pos = vector(0.5*(zr_pos.x+al_pos.x), zr_pos.y)
mid2_pos = vector(0.5*(zr_pos.x+al_pos.x), al_pos.y)
self.add_path("metal1", [zr_pos, mid1_pos, mid2_pos, al_pos])
self.add_path("m1", [zr_pos, mid1_pos, mid2_pos, al_pos])
# connect the decoder input pin to nand2 B
b_pin = nand_inst.get_pin("B")
@@ -182,7 +182,7 @@ class wordline_driver(design.design):
# must under the clk line in M1
self.add_layout_pin_segment_center(text="in_{0}".format(row),
layer="metal1",
layer="m1",
start=input_offset,
end=mid_via_offset)
self.add_via_center(layers=self.m1_stack,
@@ -190,7 +190,7 @@ class wordline_driver(design.design):
directions=("V", "V"))
# now connect to the nand2 B
self.add_path("metal2", [mid_via_offset, b_pos])
self.add_path("m2", [mid_via_offset, b_pos])
contact_offset = b_pos - vector(0.5 * contact.m1m2.height, 0)
self.add_via_center(layers=self.m1_stack,
offset=contact_offset,
@@ -199,7 +199,7 @@ class wordline_driver(design.design):
# output each WL on the right
wl_offset = inv2_inst.get_pin("Z").rc()
self.add_layout_pin_segment_center(text="wl_{0}".format(row),
layer="metal1",
layer="m1",
start=wl_offset,
end=wl_offset - vector(self.m1_width, 0))
+5 -5
View File
@@ -120,20 +120,20 @@ class write_driver_array(design.design):
for i in range(self.word_size):
din_pin = self.driver_insts[i].get_pin("din")
self.add_layout_pin(text="data_{0}".format(i),
layer="metal2",
layer="m2",
offset=din_pin.ll(),
width=din_pin.width(),
height=din_pin.height())
bl_pin = self.driver_insts[i].get_pin("bl")
self.add_layout_pin(text="bl_{0}".format(i),
layer="metal2",
layer="m2",
offset=bl_pin.ll(),
width=bl_pin.width(),
height=bl_pin.height())
br_pin = self.driver_insts[i].get_pin("br")
self.add_layout_pin(text="br_{0}".format(i),
layer="metal2",
layer="m2",
offset=br_pin.ll(),
width=br_pin.width(),
height=br_pin.height())
@@ -146,7 +146,7 @@ class write_driver_array(design.design):
self.add_via_center(layers=self.m2_stack,
offset=pin_pos)
self.add_layout_pin_rect_center(text=n,
layer="metal3",
layer="m3",
offset=pin_pos)
if self.write_size:
for bit in range(self.num_wmasks):
@@ -165,7 +165,7 @@ class write_driver_array(design.design):
height=en_pin.height())
else:
self.add_layout_pin(text="en",
layer="metal1",
layer="m1",
offset=self.driver_insts[0].get_pin("en").ll().scale(0,1),
width=self.width)
+3 -3
View File
@@ -114,7 +114,7 @@ class write_mask_and_array(design.design):
# Extend metal3 to edge of AND array in multiport
en_to_edge = self.and2.width - beg_en_pin.cx()
self.add_layout_pin(text="en",
layer="metal3",
layer="m3",
offset=beg_en_pin.bc(),
width=end_en_pin.cx() - beg_en_pin.cx() + en_to_edge)
self.add_via_center(layers=self.m1_stack,
@@ -123,7 +123,7 @@ class write_mask_and_array(design.design):
offset=vector(end_en_pin.cx() + en_to_edge, end_en_pin.cy()))
else:
self.add_layout_pin(text="en",
layer="metal3",
layer="m3",
offset=beg_en_pin.bc(),
width=end_en_pin.cx() - beg_en_pin.cx())
@@ -146,7 +146,7 @@ class write_mask_and_array(design.design):
for n in ["gnd","vdd"]:
pin = self.and2_insts[i].get_pin(n)
next_pin = self.and2_insts[i+1].get_pin(n)
self.add_path("metal1",[pin.center(),next_pin.center()])
self.add_path("m1",[pin.center(),next_pin.center()])
def get_cin(self):
"""Get the relative capacitance of all the input connections in the bank"""