mirror of https://github.com/VLSIDA/OpenRAM.git
deleting spacing, add ci test, fixing merge error
This commit is contained in:
parent
74cab87782
commit
70ed2a506e
|
|
@ -0,0 +1,20 @@
|
||||||
|
default:
|
||||||
|
image: ubuntu:latest
|
||||||
|
before_script:
|
||||||
|
- apt-get update && apt-get install -y git wget make gcc curl
|
||||||
|
- git checkout ci_test
|
||||||
|
- git pull origin ci_test
|
||||||
|
- chmod +x ./install_conda.sh
|
||||||
|
- ./install_conda.sh
|
||||||
|
- echo "export OPENRAM_HOME="/builds/asic_non_nda/openramenhanced/compiler"" >> ~/.bashrc
|
||||||
|
- echo "export OPENRAM_TECH="/builds/asic_non_nda/openramenhance/technology"" >> ~/.bashrc
|
||||||
|
- echo "export PYTHONPATH=$OPENRAM_HOME" >> ~/.bashrc
|
||||||
|
- source ~/.bashrc
|
||||||
|
- source miniconda/bin/activate
|
||||||
|
- make sky130-pdk
|
||||||
|
- make sky130-install
|
||||||
|
script:
|
||||||
|
- pwd
|
||||||
|
- cd ./macros
|
||||||
|
- make sky130_sram_1rw_tiny
|
||||||
|
|
||||||
|
|
@ -1947,7 +1947,7 @@ class layout():
|
||||||
width=width,
|
width=width,
|
||||||
height=height)
|
height=height)
|
||||||
|
|
||||||
return pin
|
return pin
|
||||||
|
|
||||||
def add_power_pin(self, name, loc, directions=None, start_layer="m1"):
|
def add_power_pin(self, name, loc, directions=None, start_layer="m1"):
|
||||||
# Hack for min area
|
# Hack for min area
|
||||||
|
|
@ -2087,12 +2087,12 @@ class layout():
|
||||||
|
|
||||||
# Hack for sky130 klayout drc rule nwell.6
|
# Hack for sky130 klayout drc rule nwell.6
|
||||||
if OPTS.tech_name == "sky130":
|
if OPTS.tech_name == "sky130":
|
||||||
# Apply the drc rule
|
# Apply the drc rule
|
||||||
# Add the dnwell
|
# Add the dnwell
|
||||||
self.add_rect("dnwell",
|
self.add_rect("dnwell",
|
||||||
offset=ll - vector(0.5 * self.nwell_width, 0.5 * self.nwell_width) - vector(drc["minclosure_nwell_by_dnwell"], drc["minclosure_nwell_by_dnwell"]),
|
offset=ll - vector(0.5 * self.nwell_width, 0.5 * self.nwell_width) - vector(drc["minclosure_nwell_by_dnwell"], drc["minclosure_nwell_by_dnwell"]),
|
||||||
height=ur.y - ll.y + self.nwell_width + 2 * drc["minclosure_nwell_by_dnwell"],
|
height=ur.y - ll.y + self.nwell_width + 2 * drc["minclosure_nwell_by_dnwell"],
|
||||||
width=ur.x - ll.x + self.nwell_width + 2 * drc["minclosure_nwell_by_dnwell"])
|
width=ur.x - ll.x + self.nwell_width + 2 * drc["minclosure_nwell_by_dnwell"])
|
||||||
else: # other tech
|
else: # other tech
|
||||||
# Add the dnwell
|
# Add the dnwell
|
||||||
self.add_rect("dnwell",
|
self.add_rect("dnwell",
|
||||||
|
|
@ -2171,11 +2171,11 @@ class layout():
|
||||||
pin = self.add_power_pin(name="vdd",
|
pin = self.add_power_pin(name="vdd",
|
||||||
loc=loc,
|
loc=loc,
|
||||||
start_layer="li")
|
start_layer="li")
|
||||||
elif route_option == "fast":
|
elif route_option == "quality":
|
||||||
pin = self.add_power_pin_m2(name="vdd",
|
pin = self.add_power_pin_m2(name="vdd",
|
||||||
loc=loc,
|
loc=loc,
|
||||||
start_layer="li")
|
start_layer="li")
|
||||||
moat_pins.append(pin)
|
moat_pins.append(pin)
|
||||||
count += 1
|
count += 1
|
||||||
loc += nwell_offset.scale(0, tap_spacing)
|
loc += nwell_offset.scale(0, tap_spacing)
|
||||||
|
|
||||||
|
|
@ -2197,7 +2197,7 @@ class layout():
|
||||||
pin = self.add_power_pin(name="vdd",
|
pin = self.add_power_pin(name="vdd",
|
||||||
loc=loc,
|
loc=loc,
|
||||||
start_layer="li")
|
start_layer="li")
|
||||||
elif route_option == "fast":
|
elif route_option == "quality":
|
||||||
pin = self.add_power_pin_m2(name="vdd",
|
pin = self.add_power_pin_m2(name="vdd",
|
||||||
loc=loc,
|
loc=loc,
|
||||||
start_layer="li")
|
start_layer="li")
|
||||||
|
|
|
||||||
|
|
@ -1135,7 +1135,7 @@ class sram_1bank(design, verilog, lef):
|
||||||
if OPTS.route_supplies:
|
if OPTS.route_supplies:
|
||||||
if route_option == "classic":
|
if route_option == "classic":
|
||||||
self.route_supplies(init_bbox)
|
self.route_supplies(init_bbox)
|
||||||
else: # quality
|
elif route_option == "quality": # quality
|
||||||
self.route_supplies_constructive(init_bbox)
|
self.route_supplies_constructive(init_bbox)
|
||||||
|
|
||||||
def route_dffs(self, add_routes=True):
|
def route_dffs(self, add_routes=True):
|
||||||
|
|
@ -1264,7 +1264,7 @@ class sram_1bank(design, verilog, lef):
|
||||||
dff_right_x = self.data_dff_insts[0].rx()
|
dff_right_x = self.data_dff_insts[0].rx()
|
||||||
# check if row address dffs are overlaped with dff area, bank position as reference
|
# check if row address dffs are overlaped with dff area, bank position as reference
|
||||||
if self.bank_inst.rx() < (dff_right_x + 2 * self.m4_pitch):
|
if self.bank_inst.rx() < (dff_right_x + 2 * self.m4_pitch):
|
||||||
debug.warning("m4 pitch ----> {0}".format(self.m4_pitch))
|
debug.warning("m4 pitch ----> {0}".format(self.m4_pitch))
|
||||||
debug.warning("m3 pitch ----> {0}".format(self.m3_pitch))
|
debug.warning("m3 pitch ----> {0}".format(self.m3_pitch))
|
||||||
debug.warning("m4_non_pref pitch ----> {0}".format(self.m4_nonpref_pitch))
|
debug.warning("m4_non_pref pitch ----> {0}".format(self.m4_nonpref_pitch))
|
||||||
debug.warning("lower row addr dff: {0}".format(self.row_addr_dff_insts[1].by()))
|
debug.warning("lower row addr dff: {0}".format(self.row_addr_dff_insts[1].by()))
|
||||||
|
|
@ -1273,7 +1273,7 @@ class sram_1bank(design, verilog, lef):
|
||||||
if y_bottom < self.row_addr_dff_insts[1].by():
|
if y_bottom < self.row_addr_dff_insts[1].by():
|
||||||
y_bottom_most = y_bottom
|
y_bottom_most = y_bottom
|
||||||
else:
|
else:
|
||||||
y_bottom_most = self.row_addr_dff_insts[1].by()
|
y_bottom_most = self.row_addr_dff_insts[1].by()
|
||||||
# the upper track should below the lower one
|
# the upper track should below the lower one
|
||||||
extra_offset = 6 * self.m3_pitch + (self.bank_inst.by() - (y_bottom_most - self.m4_nonpref_pitch))
|
extra_offset = 6 * self.m3_pitch + (self.bank_inst.by() - (y_bottom_most - self.m4_nonpref_pitch))
|
||||||
else: # do not need take care of address dff 1, since it's far away
|
else: # do not need take care of address dff 1, since it's far away
|
||||||
|
|
@ -1301,7 +1301,7 @@ class sram_1bank(design, verilog, lef):
|
||||||
dff_left_x = self.data_dff_insts[1].lx()
|
dff_left_x = self.data_dff_insts[1].lx()
|
||||||
# check if row address dffs are overlaped with dff area
|
# check if row address dffs are overlaped with dff area
|
||||||
if self.bank_inst.lx() > (dff_left_x - 2 * self.m4_pitch):
|
if self.bank_inst.lx() > (dff_left_x - 2 * self.m4_pitch):
|
||||||
debug.warning("m4 pitch ----> {0}".format(self.m4_pitch))
|
debug.warning("m4 pitch ----> {0}".format(self.m4_pitch))
|
||||||
debug.warning("m3 pitch ----> {0}".format(self.m3_pitch))
|
debug.warning("m3 pitch ----> {0}".format(self.m3_pitch))
|
||||||
debug.warning("m4_non_pref pitch ----> {0}".format(self.m4_nonpref_pitch))
|
debug.warning("m4_non_pref pitch ----> {0}".format(self.m4_nonpref_pitch))
|
||||||
# the bottom track should also above row address decoder
|
# the bottom track should also above row address decoder
|
||||||
|
|
@ -1309,7 +1309,7 @@ class sram_1bank(design, verilog, lef):
|
||||||
# do not need change since first track is high enough
|
# do not need change since first track is high enough
|
||||||
extra_offset = y_offset - self.bank.height # height could be use since bank at 0,0
|
extra_offset = y_offset - self.bank.height # height could be use since bank at 0,0
|
||||||
else: # make it higher tham row address decoder
|
else: # make it higher tham row address decoder
|
||||||
extra_offset = self.row_addr_dff_insts[0].uy() + self.m4_nonpref_pitch - self.bank_inst.height
|
extra_offset = self.row_addr_dff_insts[0].uy() + self.m4_nonpref_pitch - self.bank_inst.height
|
||||||
# update the new y_offset
|
# update the new y_offset
|
||||||
y_offset = self.row_addr_dff_insts[0].uy() + self.m4_nonpref_pitch
|
y_offset = self.row_addr_dff_insts[0].uy() + self.m4_nonpref_pitch
|
||||||
else: # do not need to take care address dff0, since it's far away
|
else: # do not need to take care address dff0, since it's far away
|
||||||
|
|
|
||||||
|
|
@ -111,7 +111,7 @@ class router(router_tech):
|
||||||
self.all_pins.update(pin_set)
|
self.all_pins.update(pin_set)
|
||||||
|
|
||||||
|
|
||||||
def find_pins_inside(self, pin_name):
|
def find_pins_inside(self, pin_name):
|
||||||
# find pins except moat, power ring, the moat pins will be store as set and return
|
# find pins except moat, power ring, the moat pins will be store as set and return
|
||||||
""" Find the pins with the given name. """
|
""" Find the pins with the given name. """
|
||||||
debug.info(4, "Finding all pins for {}".format(pin_name))
|
debug.info(4, "Finding all pins for {}".format(pin_name))
|
||||||
|
|
|
||||||
|
|
@ -107,7 +107,7 @@ class supply_placer(router):
|
||||||
# Report routed count
|
# Report routed count
|
||||||
routed_count += 1
|
routed_count += 1
|
||||||
debug.info(2, "Routed {} of {} supply pins".format(routed_count, routed_max))
|
debug.info(2, "Routed {} of {} supply pins".format(routed_count, routed_max))
|
||||||
# finsih
|
# finsih
|
||||||
self.replace_layout_pins()
|
self.replace_layout_pins()
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -163,14 +163,14 @@ class supply_placer(router):
|
||||||
# Report routed count
|
# Report routed count
|
||||||
routed_count += 1
|
routed_count += 1
|
||||||
debug.info(2, "Routed {} of {} supply pins".format(routed_count, routed_max))
|
debug.info(2, "Routed {} of {} supply pins".format(routed_count, routed_max))
|
||||||
# finsih
|
# finsih
|
||||||
self.replace_layout_pins()
|
self.replace_layout_pins()
|
||||||
|
|
||||||
|
|
||||||
def route_moat(self, io_pin_names):
|
def route_moat(self, io_pin_names):
|
||||||
# route the vdd pins at the moat
|
# route the vdd pins at the moat
|
||||||
# io_pin_names is a list
|
# io_pin_names is a list
|
||||||
# the moat vdd shape will also be created and stored in the list
|
# the moat vdd shape will also be created and stored in the list
|
||||||
for moat_pin in self.moat_pins:
|
for moat_pin in self.moat_pins:
|
||||||
self.check_overlap(moat_pin, io_pin_names)
|
self.check_overlap(moat_pin, io_pin_names)
|
||||||
|
|
||||||
|
|
@ -188,7 +188,7 @@ class supply_placer(router):
|
||||||
|
|
||||||
# Remove the pin shape(s)
|
# Remove the pin shape(s)
|
||||||
self.design.remove_layout_pin(pin_name)
|
self.design.remove_layout_pin(pin_name)
|
||||||
|
|
||||||
# Get new pins, change the name of ring to extern supply name
|
# Get new pins, change the name of ring to extern supply name
|
||||||
# vccd1 ring
|
# vccd1 ring
|
||||||
pins = self.get_new_pins("vdd")
|
pins = self.get_new_pins("vdd")
|
||||||
|
|
@ -205,7 +205,7 @@ class supply_placer(router):
|
||||||
pin.layer,
|
pin.layer,
|
||||||
pin.ll(),
|
pin.ll(),
|
||||||
pin.width(),
|
pin.width(),
|
||||||
pin.height())
|
pin.height())
|
||||||
|
|
||||||
|
|
||||||
def prepare_selected_moat_pins(self):
|
def prepare_selected_moat_pins(self):
|
||||||
|
|
@ -236,7 +236,7 @@ class supply_placer(router):
|
||||||
selected_moat_pins.extend(filtered_moat_pins_right)
|
selected_moat_pins.extend(filtered_moat_pins_right)
|
||||||
selected_moat_pins.extend(self.moat_pins_top)
|
selected_moat_pins.extend(self.moat_pins_top)
|
||||||
return selected_moat_pins
|
return selected_moat_pins
|
||||||
|
|
||||||
else: # only 1 port
|
else: # only 1 port
|
||||||
# in order to save runtime
|
# in order to save runtime
|
||||||
# top -> moat pins all
|
# top -> moat pins all
|
||||||
|
|
@ -256,7 +256,7 @@ class supply_placer(router):
|
||||||
return selected_moat_pins
|
return selected_moat_pins
|
||||||
|
|
||||||
|
|
||||||
def check_overlap(self, moat_pin, io_pin_names):
|
def check_overlap(self, moat_pin, io_pin_names):
|
||||||
# use all the IO pins(at correspoding edge) to check overlap, check 1 moat vdd pin, give the corresponding target/source position as list, and connect them
|
# use all the IO pins(at correspoding edge) to check overlap, check 1 moat vdd pin, give the corresponding target/source position as list, and connect them
|
||||||
add_distance = 0
|
add_distance = 0
|
||||||
direction = 1
|
direction = 1
|
||||||
|
|
@ -281,7 +281,7 @@ class supply_placer(router):
|
||||||
vdd_ring = self.new_pins["vdd"][1] # order in list -> "top", "bottom", "right", "left"]
|
vdd_ring = self.new_pins["vdd"][1] # order in list -> "top", "bottom", "right", "left"]
|
||||||
# bottom ring's y position at it's top
|
# bottom ring's y position at it's top
|
||||||
target_egde_y = vdd_ring.center().y + 0.5 * vdd_ring.height()
|
target_egde_y = vdd_ring.center().y + 0.5 * vdd_ring.height()
|
||||||
if tmp_center == source_center: # no overlap
|
if tmp_center == source_center: # no overlap
|
||||||
# no jog, direct return the source/target center position
|
# no jog, direct return the source/target center position
|
||||||
# the target center position, should consider enought space for via
|
# the target center position, should consider enought space for via
|
||||||
target_point = vector(tmp_center.x, (target_egde_y - 0.5 * self.track_wire))
|
target_point = vector(tmp_center.x, (target_egde_y - 0.5 * self.track_wire))
|
||||||
|
|
@ -292,13 +292,13 @@ class supply_placer(router):
|
||||||
ll = vector(source_point.x - 0.5 * self.track_wire, source_point.y - 0.5 * self.track_wire)
|
ll = vector(source_point.x - 0.5 * self.track_wire, source_point.y - 0.5 * self.track_wire)
|
||||||
ur = vector(source_point.x + 0.5 * self.track_wire, source_point.y + 0.5 * self.track_wire)
|
ur = vector(source_point.x + 0.5 * self.track_wire, source_point.y + 0.5 * self.track_wire)
|
||||||
rect = [ll, ur]
|
rect = [ll, ur]
|
||||||
moat_pin_route = graph_shape("vdd", rect, "m4")
|
moat_pin_route = graph_shape("vdd", rect, "m4")
|
||||||
self.moat_pins_bottom.append(moat_pin_route)
|
self.moat_pins_bottom.append(moat_pin_route)
|
||||||
else: # need jog
|
else: # need jog
|
||||||
# shift the center
|
# shift the center
|
||||||
# add rectangle at same layer (original)
|
# add rectangle at same layer (original)
|
||||||
intermediate_point = vector(tmp_center.x, tmp_center.y)
|
intermediate_point = vector(tmp_center.x, tmp_center.y)
|
||||||
source_point = vector(source_center.x, source_center.y)
|
source_point = vector(source_center.x, source_center.y)
|
||||||
target_point = vector(tmp_center.x, (target_egde_y - 0.5 * self.track_wire))
|
target_point = vector(tmp_center.x, (target_egde_y - 0.5 * self.track_wire))
|
||||||
point_list = [source_point, intermediate_point, target_point]
|
point_list = [source_point, intermediate_point, target_point]
|
||||||
self.add_wire(point_list, vertical=True)
|
self.add_wire(point_list, vertical=True)
|
||||||
|
|
@ -306,8 +306,8 @@ class supply_placer(router):
|
||||||
ll = vector(intermediate_point.x - 0.5 * self.track_wire, intermediate_point.y - 0.5 * self.track_wire)
|
ll = vector(intermediate_point.x - 0.5 * self.track_wire, intermediate_point.y - 0.5 * self.track_wire)
|
||||||
ur = vector(intermediate_point.x + 0.5 * self.track_wire, intermediate_point.y + 0.5 * self.track_wire)
|
ur = vector(intermediate_point.x + 0.5 * self.track_wire, intermediate_point.y + 0.5 * self.track_wire)
|
||||||
rect = [ll, ur]
|
rect = [ll, ur]
|
||||||
moat_pin_route = graph_shape("vdd", rect, "m4")
|
moat_pin_route = graph_shape("vdd", rect, "m4")
|
||||||
self.moat_pins_bottom.append(moat_pin_route)
|
self.moat_pins_bottom.append(moat_pin_route)
|
||||||
elif edge == "top":
|
elif edge == "top":
|
||||||
add_distance = self.via2_via3_pitch # if shift, need to fulfill via2-via3 spacing, top/bottom only
|
add_distance = self.via2_via3_pitch # if shift, need to fulfill via2-via3 spacing, top/bottom only
|
||||||
pin_too_close = any(abs(io_pin.center().x - source_center.x) < (self.track_width + 0.1) for io_pin in self.io_pins_top)
|
pin_too_close = any(abs(io_pin.center().x - source_center.x) < (self.track_width + 0.1) for io_pin in self.io_pins_top)
|
||||||
|
|
@ -325,7 +325,7 @@ class supply_placer(router):
|
||||||
vdd_ring = self.new_pins["vdd"][0] # order in list -> "top", "bottom", "right", "left"]
|
vdd_ring = self.new_pins["vdd"][0] # order in list -> "top", "bottom", "right", "left"]
|
||||||
# top ring's y position at it's bottom
|
# top ring's y position at it's bottom
|
||||||
target_egde_y = vdd_ring.center().y - 0.5 * vdd_ring.height()
|
target_egde_y = vdd_ring.center().y - 0.5 * vdd_ring.height()
|
||||||
if tmp_center == source_center: # no overlap
|
if tmp_center == source_center: # no overlap
|
||||||
# no jog, direct return the source/target center position
|
# no jog, direct return the source/target center position
|
||||||
# the target center position, should consider enought space for via
|
# the target center position, should consider enought space for via
|
||||||
target_point = vector(tmp_center.x, (target_egde_y + 0.5 * self.track_wire))
|
target_point = vector(tmp_center.x, (target_egde_y + 0.5 * self.track_wire))
|
||||||
|
|
@ -336,13 +336,13 @@ class supply_placer(router):
|
||||||
ll = vector(source_point.x - 0.5 * self.track_wire, source_point.y - 0.5 * self.track_wire)
|
ll = vector(source_point.x - 0.5 * self.track_wire, source_point.y - 0.5 * self.track_wire)
|
||||||
ur = vector(source_point.x + 0.5 * self.track_wire, source_point.y + 0.5 * self.track_wire)
|
ur = vector(source_point.x + 0.5 * self.track_wire, source_point.y + 0.5 * self.track_wire)
|
||||||
rect = [ll, ur]
|
rect = [ll, ur]
|
||||||
moat_pin_route = graph_shape("vdd", rect, "m4")
|
moat_pin_route = graph_shape("vdd", rect, "m4")
|
||||||
self.moat_pins_top.append(moat_pin_route)
|
self.moat_pins_top.append(moat_pin_route)
|
||||||
else: # need jog
|
else: # need jog
|
||||||
# shift the center
|
# shift the center
|
||||||
# add rectangle at same layer (original)
|
# add rectangle at same layer (original)
|
||||||
intermediate_point = vector(tmp_center.x, tmp_center.y)
|
intermediate_point = vector(tmp_center.x, tmp_center.y)
|
||||||
source_point = vector(source_center.x, source_center.y)
|
source_point = vector(source_center.x, source_center.y)
|
||||||
target_point = vector(tmp_center.x, (target_egde_y + 0.5 * self.track_wire))
|
target_point = vector(tmp_center.x, (target_egde_y + 0.5 * self.track_wire))
|
||||||
point_list = [source_point, intermediate_point, target_point]
|
point_list = [source_point, intermediate_point, target_point]
|
||||||
self.add_wire(point_list, vertical=True)
|
self.add_wire(point_list, vertical=True)
|
||||||
|
|
@ -350,8 +350,8 @@ class supply_placer(router):
|
||||||
ll = vector(intermediate_point.x - 0.5 * self.track_wire, intermediate_point.y - 0.5 * self.track_wire)
|
ll = vector(intermediate_point.x - 0.5 * self.track_wire, intermediate_point.y - 0.5 * self.track_wire)
|
||||||
ur = vector(intermediate_point.x + 0.5 * self.track_wire, intermediate_point.y + 0.5 * self.track_wire)
|
ur = vector(intermediate_point.x + 0.5 * self.track_wire, intermediate_point.y + 0.5 * self.track_wire)
|
||||||
rect = [ll, ur]
|
rect = [ll, ur]
|
||||||
moat_pin_route = graph_shape("vdd", rect, "m4")
|
moat_pin_route = graph_shape("vdd", rect, "m4")
|
||||||
self.moat_pins_top.append(moat_pin_route)
|
self.moat_pins_top.append(moat_pin_route)
|
||||||
elif edge == "left":
|
elif edge == "left":
|
||||||
pin_too_close = any(abs(io_pin.center().y - source_center.y) < self.track_width for io_pin in self.io_pins_left)
|
pin_too_close = any(abs(io_pin.center().y - source_center.y) < self.track_width for io_pin in self.io_pins_left)
|
||||||
tmp_center = vector(source_center.x, source_center.y)
|
tmp_center = vector(source_center.x, source_center.y)
|
||||||
|
|
@ -368,7 +368,7 @@ class supply_placer(router):
|
||||||
vdd_ring = self.new_pins["vdd"][3] # order in list -> "top", "bottom", "right", "left"]
|
vdd_ring = self.new_pins["vdd"][3] # order in list -> "top", "bottom", "right", "left"]
|
||||||
# left ring's x position at it's right
|
# left ring's x position at it's right
|
||||||
target_egde_x = vdd_ring.center().x + 0.5 * vdd_ring.width()
|
target_egde_x = vdd_ring.center().x + 0.5 * vdd_ring.width()
|
||||||
if tmp_center == source_center: # no overlap
|
if tmp_center == source_center: # no overlap
|
||||||
# no jog, direct return the source/target center position
|
# no jog, direct return the source/target center position
|
||||||
# the target center position, should consider enought space for via
|
# the target center position, should consider enought space for via
|
||||||
target_point = vector((target_egde_x - 0.5 * self.track_wire), tmp_center.y)
|
target_point = vector((target_egde_x - 0.5 * self.track_wire), tmp_center.y)
|
||||||
|
|
@ -379,13 +379,13 @@ class supply_placer(router):
|
||||||
ll = vector(source_point.x - 0.5 * self.track_wire, source_point.y - 0.5 * self.track_wire)
|
ll = vector(source_point.x - 0.5 * self.track_wire, source_point.y - 0.5 * self.track_wire)
|
||||||
ur = vector(source_point.x + 0.5 * self.track_wire, source_point.y + 0.5 * self.track_wire)
|
ur = vector(source_point.x + 0.5 * self.track_wire, source_point.y + 0.5 * self.track_wire)
|
||||||
rect = [ll, ur]
|
rect = [ll, ur]
|
||||||
moat_pin_route = graph_shape("vdd", rect, "m3")
|
moat_pin_route = graph_shape("vdd", rect, "m3")
|
||||||
self.moat_pins_left.append(moat_pin_route)
|
self.moat_pins_left.append(moat_pin_route)
|
||||||
else: # need jog
|
else: # need jog
|
||||||
# shift the center
|
# shift the center
|
||||||
# add rectangle at same layer (original)
|
# add rectangle at same layer (original)
|
||||||
intermediate_point = vector(tmp_center.x, tmp_center.y)
|
intermediate_point = vector(tmp_center.x, tmp_center.y)
|
||||||
source_point = vector(source_center.x, source_center.y)
|
source_point = vector(source_center.x, source_center.y)
|
||||||
target_point = vector((target_egde_x - 0.5 * self.track_wire), tmp_center.y)
|
target_point = vector((target_egde_x - 0.5 * self.track_wire), tmp_center.y)
|
||||||
point_list = [source_point, intermediate_point, target_point]
|
point_list = [source_point, intermediate_point, target_point]
|
||||||
self.add_wire(point_list, vertical=False)
|
self.add_wire(point_list, vertical=False)
|
||||||
|
|
@ -393,7 +393,7 @@ class supply_placer(router):
|
||||||
ll = vector(intermediate_point.x - 0.5 * self.track_wire, intermediate_point.y - 0.5 * self.track_wire)
|
ll = vector(intermediate_point.x - 0.5 * self.track_wire, intermediate_point.y - 0.5 * self.track_wire)
|
||||||
ur = vector(intermediate_point.x + 0.5 * self.track_wire, intermediate_point.y + 0.5 * self.track_wire)
|
ur = vector(intermediate_point.x + 0.5 * self.track_wire, intermediate_point.y + 0.5 * self.track_wire)
|
||||||
rect = [ll, ur]
|
rect = [ll, ur]
|
||||||
moat_pin_route = graph_shape("vdd", rect, "m3")
|
moat_pin_route = graph_shape("vdd", rect, "m3")
|
||||||
self.moat_pins_left.append(moat_pin_route)
|
self.moat_pins_left.append(moat_pin_route)
|
||||||
else: #right
|
else: #right
|
||||||
pin_too_close = any(abs(io_pin.center().y - source_center.y) < self.track_width for io_pin in self.io_pins_right)
|
pin_too_close = any(abs(io_pin.center().y - source_center.y) < self.track_width for io_pin in self.io_pins_right)
|
||||||
|
|
@ -411,7 +411,7 @@ class supply_placer(router):
|
||||||
vdd_ring = self.new_pins["vdd"][2] # order in list -> "top", "bottom", "right", "left"]
|
vdd_ring = self.new_pins["vdd"][2] # order in list -> "top", "bottom", "right", "left"]
|
||||||
# right ring's y position at it's left
|
# right ring's y position at it's left
|
||||||
target_egde_x = vdd_ring.center().x - 0.5 * vdd_ring.width()
|
target_egde_x = vdd_ring.center().x - 0.5 * vdd_ring.width()
|
||||||
if tmp_center == source_center: # no overlap
|
if tmp_center == source_center: # no overlap
|
||||||
# no jog, direct return the source/target center position
|
# no jog, direct return the source/target center position
|
||||||
# the target center position, should consider enought space for via
|
# the target center position, should consider enought space for via
|
||||||
target_point = vector((target_egde_x + 0.5 * self.track_wire), tmp_center.y)
|
target_point = vector((target_egde_x + 0.5 * self.track_wire), tmp_center.y)
|
||||||
|
|
@ -422,13 +422,13 @@ class supply_placer(router):
|
||||||
ll = vector(source_point.x - 0.5 * self.track_wire, source_point.y - 0.5 * self.track_wire)
|
ll = vector(source_point.x - 0.5 * self.track_wire, source_point.y - 0.5 * self.track_wire)
|
||||||
ur = vector(source_point.x + 0.5 * self.track_wire, source_point.y + 0.5 * self.track_wire)
|
ur = vector(source_point.x + 0.5 * self.track_wire, source_point.y + 0.5 * self.track_wire)
|
||||||
rect = [ll, ur]
|
rect = [ll, ur]
|
||||||
moat_pin_route = graph_shape("vdd", rect, "m3")
|
moat_pin_route = graph_shape("vdd", rect, "m3")
|
||||||
self.moat_pins_right.append(moat_pin_route)
|
self.moat_pins_right.append(moat_pin_route)
|
||||||
else: # need jog
|
else: # need jog
|
||||||
# shift the center
|
# shift the center
|
||||||
# add rectangle at same layer (original)
|
# add rectangle at same layer (original)
|
||||||
intermediate_point = vector(tmp_center.x, tmp_center.y)
|
intermediate_point = vector(tmp_center.x, tmp_center.y)
|
||||||
source_point = vector(source_center.x, source_center.y)
|
source_point = vector(source_center.x, source_center.y)
|
||||||
target_point = vector((target_egde_x + 0.5 * self.track_wire) ,tmp_center.y)
|
target_point = vector((target_egde_x + 0.5 * self.track_wire) ,tmp_center.y)
|
||||||
point_list = [source_point, intermediate_point, target_point]
|
point_list = [source_point, intermediate_point, target_point]
|
||||||
self.add_wire(point_list, vertical=False)
|
self.add_wire(point_list, vertical=False)
|
||||||
|
|
@ -436,15 +436,15 @@ class supply_placer(router):
|
||||||
ll = vector(intermediate_point.x - 0.5 * self.track_wire, intermediate_point.y - 0.5 * self.track_wire)
|
ll = vector(intermediate_point.x - 0.5 * self.track_wire, intermediate_point.y - 0.5 * self.track_wire)
|
||||||
ur = vector(intermediate_point.x + 0.5 * self.track_wire, intermediate_point.y + 0.5 * self.track_wire)
|
ur = vector(intermediate_point.x + 0.5 * self.track_wire, intermediate_point.y + 0.5 * self.track_wire)
|
||||||
rect = [ll, ur]
|
rect = [ll, ur]
|
||||||
moat_pin_route = graph_shape("vdd", rect, "m3")
|
moat_pin_route = graph_shape("vdd", rect, "m3")
|
||||||
self.moat_pins_right.append(moat_pin_route)
|
self.moat_pins_right.append(moat_pin_route)
|
||||||
|
|
||||||
|
|
||||||
def add_wire(self, point_list, vertical=False):
|
def add_wire(self, point_list, vertical=False):
|
||||||
if vertical == True: # m4 line, need start via3(m3 -> m4), end via3(m3 -> m4)
|
if vertical == True: # m4 line, need start via3(m3 -> m4), end via3(m3 -> m4)
|
||||||
if len(point_list) == 2: # direct connect
|
if len(point_list) == 2: # direct connect
|
||||||
# start via
|
# start via
|
||||||
self.add_via(point=point_list[0],
|
self.add_via(point=point_list[0],
|
||||||
from_layer="m3",
|
from_layer="m3",
|
||||||
to_layer="m4")
|
to_layer="m4")
|
||||||
self.add_via(point=point_list[0],
|
self.add_via(point=point_list[0],
|
||||||
|
|
@ -484,10 +484,10 @@ class supply_placer(router):
|
||||||
self.add_via(point=point_list[2],
|
self.add_via(point=point_list[2],
|
||||||
from_layer="m4",
|
from_layer="m4",
|
||||||
to_layer="m4") # shape
|
to_layer="m4") # shape
|
||||||
else: # m3 line, need start via2(m2 -> m3), end via3(m3 -> m4)
|
else: # m3 line, need start via2(m2 -> m3), end via3(m3 -> m4)
|
||||||
if len(point_list) == 2: # direct connect
|
if len(point_list) == 2: # direct connect
|
||||||
# start via
|
# start via
|
||||||
self.add_via(point=point_list[0],
|
self.add_via(point=point_list[0],
|
||||||
from_layer="m2",
|
from_layer="m2",
|
||||||
to_layer="m3")
|
to_layer="m3")
|
||||||
self.add_via(point=point_list[0],
|
self.add_via(point=point_list[0],
|
||||||
|
|
@ -500,11 +500,11 @@ class supply_placer(router):
|
||||||
# end via
|
# end via
|
||||||
self.add_via(point=point_list[1],
|
self.add_via(point=point_list[1],
|
||||||
from_layer="m3",
|
from_layer="m3",
|
||||||
to_layer="m4")
|
to_layer="m4")
|
||||||
self.add_via(point=point_list[1],
|
self.add_via(point=point_list[1],
|
||||||
from_layer="m3",
|
from_layer="m3",
|
||||||
to_layer="m3") # shape
|
to_layer="m3") # shape
|
||||||
elif len(point_list) == 3: # need intermediate point
|
elif len(point_list) == 3: # need intermediate point
|
||||||
# jog
|
# jog
|
||||||
self.add_line(point_1=point_list[0],
|
self.add_line(point_1=point_list[0],
|
||||||
point_2=point_list[1],
|
point_2=point_list[1],
|
||||||
|
|
@ -537,9 +537,9 @@ class supply_placer(router):
|
||||||
# via could be via2(m2 -> m3), via3(m3 -> m4)
|
# via could be via2(m2 -> m3), via3(m3 -> m4)
|
||||||
# or a shape at same layer
|
# or a shape at same layer
|
||||||
if from_layer == to_layer:
|
if from_layer == to_layer:
|
||||||
self.design.add_rect_center(layer=from_layer,
|
self.design.add_rect_center(layer=from_layer,
|
||||||
offset=point,
|
offset=point,
|
||||||
width=self.track_wire,
|
width=self.track_wire,
|
||||||
height=self.track_wire)
|
height=self.track_wire)
|
||||||
else:
|
else:
|
||||||
self.design.add_via_stack_center(from_layer=from_layer,
|
self.design.add_via_stack_center(from_layer=from_layer,
|
||||||
|
|
@ -598,7 +598,7 @@ class supply_placer(router):
|
||||||
elif min_diff == ur_diff_x:
|
elif min_diff == ur_diff_x:
|
||||||
self.io_pins_right.append(pin)
|
self.io_pins_right.append(pin)
|
||||||
else:
|
else:
|
||||||
self.io_pins_top.append(pin)
|
self.io_pins_top.append(pin)
|
||||||
|
|
||||||
|
|
||||||
def add_side_pin(self, pin_name, side, num_vias=3, num_fake_pins=4):
|
def add_side_pin(self, pin_name, side, num_vias=3, num_fake_pins=4):
|
||||||
|
|
@ -742,7 +742,7 @@ class supply_placer(router):
|
||||||
"""
|
"""
|
||||||
Extend the MST logic to connect internal pins to the nearest external ring pins.
|
Extend the MST logic to connect internal pins to the nearest external ring pins.
|
||||||
"""
|
"""
|
||||||
# Prepare the pins that are allowed to connect to the moat pins.
|
# Prepare the pins that are allowed to connect to the moat pins.
|
||||||
# Specical handle gnd ring
|
# Specical handle gnd ring
|
||||||
candidate_pins = []
|
candidate_pins = []
|
||||||
max_distance = 20#13
|
max_distance = 20#13
|
||||||
|
|
@ -755,7 +755,7 @@ class supply_placer(router):
|
||||||
if max_distance is None or dist <= max_distance:
|
if max_distance is None or dist <= max_distance:
|
||||||
candidate_pins.append(pin)
|
candidate_pins.append(pin)
|
||||||
break
|
break
|
||||||
|
|
||||||
# Compute the MST for internal pins
|
# Compute the MST for internal pins
|
||||||
mst_pairs = self.get_mst_pairs(pins)
|
mst_pairs = self.get_mst_pairs(pins)
|
||||||
|
|
||||||
|
|
@ -780,7 +780,7 @@ class supply_placer(router):
|
||||||
internal_to_ring_pairs.append((pin, nearest_ring_pin))
|
internal_to_ring_pairs.append((pin, nearest_ring_pin))
|
||||||
# Mark the ring pin as used if the pin is VDD
|
# Mark the ring pin as used if the pin is VDD
|
||||||
if pin_name == "vdd":
|
if pin_name == "vdd":
|
||||||
used_ring_pins.add(nearest_ring_pin)
|
used_ring_pins.add(nearest_ring_pin)
|
||||||
|
|
||||||
# Combine internal MST pairs and external connections
|
# Combine internal MST pairs and external connections
|
||||||
full_connections = mst_pairs + internal_to_ring_pairs
|
full_connections = mst_pairs + internal_to_ring_pairs
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue