Add brain-dead router pins to perimeter

This commit is contained in:
mrg 2020-06-14 15:52:09 -07:00
parent 9930b5f3f6
commit 78be9f367a
3 changed files with 123 additions and 31 deletions

View File

@ -1354,7 +1354,7 @@ class layout():
# Hack for min area
if OPTS.tech_name == "sky130":
width = round_to_grid(sqrt(drc["minarea_m3"]))
height = round_to_grid(drc["minarea_m3"]/width)
height = round_to_grid(drc["minarea_m3"] / width)
else:
width = via.width
height = via.height
@ -1364,6 +1364,46 @@ class layout():
width=width,
height=height)
def add_perimeter_pin(self, name, pin, side, bbox):
"""
Add a pin along the perimeter side specified by the bbox with
the given name and layer from the pin starting location.
"""
(ll, ur) = bbox
left = ll.x
bottom = ll.y
right = ur.x
top = ur.y
pin_loc = pin.center()
if side == "left":
peri_pin_loc = vector(left, pin_loc.y)
layer = "m3"
elif side == "right":
layer = "m3"
peri_pin_loc = vector(right, pin_loc.x)
elif side == "top":
layer = "m4"
peri_pin_loc = vector(pin_loc.x, top)
elif side == "bottom":
layer = "m4"
peri_pin_loc = vector(pin_loc.x, bottom)
self.add_via_stack_center(from_layer=pin.layer,
to_layer=layer,
offset=pin_loc)
self.add_path(layer,
[pin_loc, peri_pin_loc])
self.add_via_stack_center(from_layer=layer,
to_layer="m4",
offset=peri_pin_loc)
self.add_layout_pin_rect_center(text=name,
layer="m4",
offset=peri_pin_loc)
def add_power_ring(self, bbox):
"""
Create vdd and gnd power rings around an area of the bounding box

View File

@ -1005,7 +1005,7 @@ class control_logic(design.design):
def route_output_to_bus_jogged(self, inst, name):
# Connect this at the bottom of the buffer
out_pos = inst.get_pin("Z").center()
mid1 = vector(out_pos.x, out_pos.y - 0.25 * inst.mod.height)
mid1 = vector(out_pos.x, out_pos.y - 0.4 * inst.mod.height)
mid2 = vector(self.input_bus[name].cx(), mid1.y)
bus_pos = self.input_bus[name].center()
self.add_wire(self.m2_stack[::-1], [out_pos, mid1, mid2, bus_pos])

View File

@ -246,46 +246,100 @@ class sram_1bank(sram_base):
"""
Add the top-level pins for a single bank SRAM with control.
"""
for port in self.all_ports:
# Connect the control pins as inputs
for signal in self.control_logic_inputs[port] + ["clk"]:
self.copy_layout_pin(self.control_logic_insts[port],
signal,
signal + "{}".format(port))
highest_coord = self.find_highest_coords()
lowest_coord = self.find_lowest_coords()
bbox = [lowest_coord, highest_coord]
for port in self.all_ports:
# Depending on the port, use the bottom/top or left/right sides
# Port 0 is left/bottom
# Port 1 is right/top
bottom_or_top = "bottom" if port==0 else "top"
left_or_right = "left" if port==0 else "right"
# Connect the control pins as inputs
for signal in self.control_logic_inputs[port]:
if signal == "clk":
continue
self.add_perimeter_pin(name=signal + "{}".format(port),
pin=self.control_logic_insts[port].get_pin(signal),
side=left_or_right,
bbox=bbox)
# self.copy_layout_pin(self.control_logic_insts[port],
# signal,
# signal + "{}".format(port))
self.add_perimeter_pin(name="clk{}".format(port),
pin=self.control_logic_insts[port].get_pin("clk"),
side=bottom_or_top,
bbox=bbox)
# Data output pins go to BOTTOM/TOP
if port in self.read_ports:
for bit in range(self.word_size + self.num_spare_cols):
self.copy_layout_pin(self.bank_inst,
"dout{0}_{1}".format(port, bit),
"dout{0}[{1}]".format(port, bit))
self.add_perimeter_pin(name="dout{0}[{1}]".format(port, bit),
pin=self.bank_inst.get_pin("dout{0}_{1}".format(port, bit)),
side=bottom_or_top,
bbox=bbox)
# self.copy_layout_pin(self.bank_inst,
# "dout{0}_{1}".format(port, bit),
# "dout{0}[{1}]".format(port, bit))
# Lower address bits
# Lower address bits go to BOTTOM/TOP
for bit in range(self.col_addr_size):
self.copy_layout_pin(self.col_addr_dff_insts[port],
"din_{}".format(bit),
"addr{0}[{1}]".format(port, bit))
# Upper address bits
self.add_perimeter_pin(name="addr{0}[{1}]".format(port, bit),
pin=self.col_addr_dff_insts[port].get_pin("din_{}".format(bit)),
side=bottom_or_top,
bbox=bbox)
# self.copy_layout_pin(self.col_addr_dff_insts[port],
# "din_{}".format(bit),
# "addr{0}[{1}]".format(port, bit))
# Upper address bits go to LEFT/RIGHT
for bit in range(self.row_addr_size):
self.copy_layout_pin(self.row_addr_dff_insts[port],
"din_{}".format(bit),
"addr{0}[{1}]".format(port, bit + self.col_addr_size))
self.add_perimeter_pin(name="addr{0}[{1}]".format(port, bit + self.col_addr_size),
pin=self.row_addr_dff_insts[port].get_pin("din_{}".format(bit)),
side=left_or_right,
bbox=bbox)
# self.copy_layout_pin(self.row_addr_dff_insts[port],
# "din_{}".format(bit),
# "addr{0}[{1}]".format(port, bit + self.col_addr_size))
# Data input pins go to BOTTOM/TOP
if port in self.write_ports:
for bit in range(self.word_size + self.num_spare_cols):
self.copy_layout_pin(self.data_dff_insts[port],
"din_{}".format(bit),
"din{0}[{1}]".format(port, bit))
self.add_perimeter_pin(name="din{0}[{1}]".format(port, bit),
pin=self.data_dff_insts[port].get_pin("din_{}".format(bit)),
side=bottom_or_top,
bbox=bbox)
# self.copy_layout_pin(self.data_dff_insts[port],
# "din_{}".format(bit),
# "din{0}[{1}]".format(port, bit))
# Write mask pins go to BOTTOM/TOP
if port in self.write_ports:
if self.write_size:
for bit in range(self.num_wmasks):
self.copy_layout_pin(self.wmask_dff_insts[port],
"din_{}".format(bit),
"wmask{0}[{1}]".format(port, bit))
self.add_perimeter_pin(name="wmask{0}[{1}]".format(port, bit),
pin=self.wmask_dff_insts[port].get_pin("din_{}".format(bit)),
side=bottom_or_top,
bbox=bbox)
# self.copy_layout_pin(self.wmask_dff_insts[port],
# "din_{}".format(bit),
# "wmask{0}[{1}]".format(port, bit))
# Spare wen pins go to BOTTOM/TOP
if port in self.write_ports:
for bit in range(self.num_spare_cols):
self.copy_layout_pin(self.spare_wen_dff_insts[port],
"din_{}".format(bit),
"spare_wen{0}[{1}]".format(port, bit))
self.add_perimeter_pin(name="spare_wen{0}[{1}]".format(port, bit),
pin=self.spare_wen_dff_insts[port].get_pin("din_{}".format(bit)),
side=left_or_right,
bbox=bbox)
# self.copy_layout_pin(self.spare_wen_dff_insts[port],
# "din_{}".format(bit),
# "spare_wen{0}[{1}]".format(port, bit))
def route_layout(self):
""" Route a single bank SRAM """
@ -314,8 +368,6 @@ class sram_1bank(sram_base):
# This is the actual input to the SRAM
for port in self.all_ports:
self.copy_layout_pin(self.control_logic_insts[port], "clk", "clk{}".format(port))
# Connect all of these clock pins to the clock in the central bus
# This is something like a "spine" clock distribution. The two spines
# are clk_buf and clk_buf_bar