mirror of https://github.com/VLSIDA/OpenRAM.git
Add brain-dead router pins to perimeter
This commit is contained in:
parent
9930b5f3f6
commit
78be9f367a
|
|
@ -1354,7 +1354,7 @@ class layout():
|
||||||
# Hack for min area
|
# Hack for min area
|
||||||
if OPTS.tech_name == "sky130":
|
if OPTS.tech_name == "sky130":
|
||||||
width = round_to_grid(sqrt(drc["minarea_m3"]))
|
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:
|
else:
|
||||||
width = via.width
|
width = via.width
|
||||||
height = via.height
|
height = via.height
|
||||||
|
|
@ -1364,6 +1364,46 @@ class layout():
|
||||||
width=width,
|
width=width,
|
||||||
height=height)
|
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):
|
def add_power_ring(self, bbox):
|
||||||
"""
|
"""
|
||||||
Create vdd and gnd power rings around an area of the bounding box
|
Create vdd and gnd power rings around an area of the bounding box
|
||||||
|
|
|
||||||
|
|
@ -1005,7 +1005,7 @@ class control_logic(design.design):
|
||||||
def route_output_to_bus_jogged(self, inst, name):
|
def route_output_to_bus_jogged(self, inst, name):
|
||||||
# Connect this at the bottom of the buffer
|
# Connect this at the bottom of the buffer
|
||||||
out_pos = inst.get_pin("Z").center()
|
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)
|
mid2 = vector(self.input_bus[name].cx(), mid1.y)
|
||||||
bus_pos = self.input_bus[name].center()
|
bus_pos = self.input_bus[name].center()
|
||||||
self.add_wire(self.m2_stack[::-1], [out_pos, mid1, mid2, bus_pos])
|
self.add_wire(self.m2_stack[::-1], [out_pos, mid1, mid2, bus_pos])
|
||||||
|
|
|
||||||
|
|
@ -246,46 +246,100 @@ class sram_1bank(sram_base):
|
||||||
"""
|
"""
|
||||||
Add the top-level pins for a single bank SRAM with control.
|
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:
|
if port in self.read_ports:
|
||||||
for bit in range(self.word_size + self.num_spare_cols):
|
for bit in range(self.word_size + self.num_spare_cols):
|
||||||
self.copy_layout_pin(self.bank_inst,
|
self.add_perimeter_pin(name="dout{0}[{1}]".format(port, bit),
|
||||||
"dout{0}_{1}".format(port, bit),
|
pin=self.bank_inst.get_pin("dout{0}_{1}".format(port, bit)),
|
||||||
"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):
|
for bit in range(self.col_addr_size):
|
||||||
self.copy_layout_pin(self.col_addr_dff_insts[port],
|
self.add_perimeter_pin(name="addr{0}[{1}]".format(port, bit),
|
||||||
"din_{}".format(bit),
|
pin=self.col_addr_dff_insts[port].get_pin("din_{}".format(bit)),
|
||||||
"addr{0}[{1}]".format(port, bit))
|
side=bottom_or_top,
|
||||||
# Upper address bits
|
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):
|
for bit in range(self.row_addr_size):
|
||||||
self.copy_layout_pin(self.row_addr_dff_insts[port],
|
self.add_perimeter_pin(name="addr{0}[{1}]".format(port, bit + self.col_addr_size),
|
||||||
"din_{}".format(bit),
|
pin=self.row_addr_dff_insts[port].get_pin("din_{}".format(bit)),
|
||||||
"addr{0}[{1}]".format(port, bit + self.col_addr_size))
|
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:
|
if port in self.write_ports:
|
||||||
for bit in range(self.word_size + self.num_spare_cols):
|
for bit in range(self.word_size + self.num_spare_cols):
|
||||||
self.copy_layout_pin(self.data_dff_insts[port],
|
self.add_perimeter_pin(name="din{0}[{1}]".format(port, bit),
|
||||||
"din_{}".format(bit),
|
pin=self.data_dff_insts[port].get_pin("din_{}".format(bit)),
|
||||||
"din{0}[{1}]".format(port, 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:
|
if self.write_size:
|
||||||
for bit in range(self.num_wmasks):
|
for bit in range(self.num_wmasks):
|
||||||
self.copy_layout_pin(self.wmask_dff_insts[port],
|
self.add_perimeter_pin(name="wmask{0}[{1}]".format(port, bit),
|
||||||
"din_{}".format(bit),
|
pin=self.wmask_dff_insts[port].get_pin("din_{}".format(bit)),
|
||||||
"wmask{0}[{1}]".format(port, 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):
|
for bit in range(self.num_spare_cols):
|
||||||
self.copy_layout_pin(self.spare_wen_dff_insts[port],
|
self.add_perimeter_pin(name="spare_wen{0}[{1}]".format(port, bit),
|
||||||
"din_{}".format(bit),
|
pin=self.spare_wen_dff_insts[port].get_pin("din_{}".format(bit)),
|
||||||
"spare_wen{0}[{1}]".format(port, 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):
|
def route_layout(self):
|
||||||
""" Route a single bank SRAM """
|
""" Route a single bank SRAM """
|
||||||
|
|
@ -314,8 +368,6 @@ class sram_1bank(sram_base):
|
||||||
|
|
||||||
# This is the actual input to the SRAM
|
# This is the actual input to the SRAM
|
||||||
for port in self.all_ports:
|
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
|
# Connect all of these clock pins to the clock in the central bus
|
||||||
# This is something like a "spine" clock distribution. The two spines
|
# This is something like a "spine" clock distribution. The two spines
|
||||||
# are clk_buf and clk_buf_bar
|
# are clk_buf and clk_buf_bar
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue