mirror of https://github.com/VLSIDA/OpenRAM.git
Create VCG using nets as nodes rather than pins.
This commit is contained in:
parent
add0e3ad68
commit
fcc4a75295
|
|
@ -602,6 +602,7 @@ class layout(lef.lef):
|
||||||
"""
|
"""
|
||||||
Connect a mapping of pin -> name for a bus. This could be
|
Connect a mapping of pin -> name for a bus. This could be
|
||||||
replaced with a channel router in the future.
|
replaced with a channel router in the future.
|
||||||
|
NOTE: This has only really been tested with point-to-point connections (not multiple pins on a net).
|
||||||
"""
|
"""
|
||||||
(horizontal_layer, via_layer, vertical_layer)=layer_stack
|
(horizontal_layer, via_layer, vertical_layer)=layer_stack
|
||||||
if horizontal:
|
if horizontal:
|
||||||
|
|
@ -720,6 +721,7 @@ class layout(lef.lef):
|
||||||
try to minimize the number of tracks -- instead, it picks an order to avoid the vertical
|
try to minimize the number of tracks -- instead, it picks an order to avoid the vertical
|
||||||
conflicts between pins.
|
conflicts between pins.
|
||||||
"""
|
"""
|
||||||
|
local_debug = True
|
||||||
|
|
||||||
def remove_net_from_graph(pin, g):
|
def remove_net_from_graph(pin, g):
|
||||||
# Remove the pin from the keys
|
# Remove the pin from the keys
|
||||||
|
|
@ -732,6 +734,29 @@ class layout(lef.lef):
|
||||||
g[other_pin]=conflicts
|
g[other_pin]=conflicts
|
||||||
return g
|
return g
|
||||||
|
|
||||||
|
def vcg_pins_overlap(pins1, pins2, vertical):
|
||||||
|
# Check all the pin pairs on two nets and return a pin
|
||||||
|
# overlap if any pin overlaps vertically
|
||||||
|
for pin1 in pins1:
|
||||||
|
for pin2 in pins2:
|
||||||
|
if vcg_pin_overlap(pin1, pin2, vertical):
|
||||||
|
return True
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
|
def vcg_pin_overlap(pin1, pin2, vertical):
|
||||||
|
# Check for vertical overlap of the two pins
|
||||||
|
|
||||||
|
# Pin 1 must be in the "LEFT" set and overlap the right
|
||||||
|
x_overlap = pin1.lx() < pin2.lx() and abs(pin1.center().x-pin2.center().x)<pitch
|
||||||
|
|
||||||
|
# Pin 1 must be in the "TOP" set and overlap the bottom
|
||||||
|
y_overlap = pin1.by() > pin2.by() and abs(pin1.center().y-pin2.center().y)<pitch
|
||||||
|
|
||||||
|
return (not vertical and x_overlap) or (vertical and y_overlap)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if not pitch:
|
if not pitch:
|
||||||
pitch = self.m2_pitch
|
pitch = self.m2_pitch
|
||||||
|
|
||||||
|
|
@ -744,22 +769,38 @@ class layout(lef.lef):
|
||||||
|
|
||||||
# Initialize the vertical conflict graph (vcg) and make a list of all pins
|
# Initialize the vertical conflict graph (vcg) and make a list of all pins
|
||||||
vcg = {}
|
vcg = {}
|
||||||
|
|
||||||
|
# Create names for the nets for the graphs
|
||||||
|
nets = {}
|
||||||
|
index = 0
|
||||||
|
print(route_map)
|
||||||
|
for pin_connections in route_map:
|
||||||
|
net_name = "n{}".format(index)
|
||||||
|
print("N",net_name)
|
||||||
|
index += 1
|
||||||
|
nets[net_name] = []
|
||||||
|
for pin_name in pin_connections:
|
||||||
|
pin = all_pins[pin_name]
|
||||||
|
nets[net_name].append(pin)
|
||||||
|
if local_debug:
|
||||||
|
import pprint
|
||||||
|
pprint.pprint(nets)
|
||||||
|
|
||||||
# Find the vertical pin conflicts
|
# Find the vertical pin conflicts
|
||||||
# FIXME: O(n^2) but who cares for now
|
# FIXME: O(n^2) but who cares for now
|
||||||
for top_name,top_pin in top_pins.items():
|
for net_name1 in nets:
|
||||||
vcg[top_name]=[]
|
print("NET1:",net_name1)
|
||||||
for bot_name,bot_pin in bottom_pins.items():
|
vcg[net_name1]=[]
|
||||||
# Remember, vertical is the boolean of the routes in the channel
|
for net_name2 in nets:
|
||||||
# so check the intervals of the pins in the other dimension
|
print("NET2:",net_name2)
|
||||||
x_overlap = abs(top_pin.center().x-bot_pin.center().x)<pitch
|
# Skip yourself
|
||||||
y_overlap = abs(top_pin.center().y-bot_pin.center().y)<pitch
|
if net_name1 == net_name2:
|
||||||
|
continue
|
||||||
if (vertical and y_overlap) or (not vertical and x_overlap):
|
if vcg_pins_overlap(nets[net_name1], nets[net_name2], vertical):
|
||||||
try:
|
try:
|
||||||
vcg[bot_name].append(top_name)
|
vcg[net_name1].append(net_name2)
|
||||||
except:
|
except:
|
||||||
vcg[bot_name] = [top_name]
|
vcg[net_name1] = [net_name2]
|
||||||
|
|
||||||
#FIXME: What if we have a cycle?
|
#FIXME: What if we have a cycle?
|
||||||
|
|
||||||
|
|
@ -773,27 +814,28 @@ class layout(lef.lef):
|
||||||
|
|
||||||
# list of routes to do
|
# list of routes to do
|
||||||
while vcg:
|
while vcg:
|
||||||
#print(vcg)
|
if local_debug:
|
||||||
|
from pprint import pformat
|
||||||
|
print("VCG:\n",pformat(vcg))
|
||||||
# get a route from conflict graph with empty fanout set
|
# get a route from conflict graph with empty fanout set
|
||||||
route_pin=None
|
net_name=None
|
||||||
for route_pin,conflicts in vcg.items():
|
for net_name,conflicts in vcg.items():
|
||||||
if len(conflicts)==0:
|
if len(conflicts)==0:
|
||||||
vcg=remove_net_from_graph(route_pin,vcg)
|
vcg=remove_net_from_graph(net_name,vcg)
|
||||||
break
|
break
|
||||||
|
else:
|
||||||
|
# FIXME: We don't support cyclic VCGs right now.
|
||||||
|
debug.error("Cyclic VCG in channel router.",-1)
|
||||||
|
|
||||||
|
if local_debug:
|
||||||
|
print("Routing:",net_name,pin_connections)
|
||||||
|
|
||||||
# Get the connected pins from the routing map
|
# These are the pins we'll have to connect
|
||||||
for pin_connections in route_map:
|
pin_list = nets[net_name]
|
||||||
if route_pin in pin_connections:
|
|
||||||
break
|
# Remove the net from other constriants in the VCG
|
||||||
#print("Routing:",route_pin,pin_connections)
|
vcg=remove_net_from_graph(net_name, vcg)
|
||||||
|
|
||||||
# Remove the other pins from the conflict graph too
|
|
||||||
for other_pin in pin_connections:
|
|
||||||
vcg=remove_net_from_graph(other_pin, vcg)
|
|
||||||
|
|
||||||
# Create a list of the pins rather than a list of the names
|
|
||||||
pin_list = [all_pins[pin_name] for pin_name in pin_connections]
|
|
||||||
|
|
||||||
# Add the trunk route and move up to next track
|
# Add the trunk route and move up to next track
|
||||||
if vertical:
|
if vertical:
|
||||||
self.add_vertical_trunk_route(pin_list, offset, layer_stack, pitch)
|
self.add_vertical_trunk_route(pin_list, offset, layer_stack, pitch)
|
||||||
|
|
|
||||||
|
|
@ -23,8 +23,8 @@ class sram_1bank_test(openram_test):
|
||||||
|
|
||||||
c.words_per_row=1
|
c.words_per_row=1
|
||||||
debug.info(1, "Single bank, no column mux with control logic")
|
debug.info(1, "Single bank, no column mux with control logic")
|
||||||
a = sram(c, "sram1")
|
#a = sram(c, "sram1")
|
||||||
self.local_check(a, final_verification=True)
|
#self.local_check(a, final_verification=True)
|
||||||
|
|
||||||
c.num_words=32
|
c.num_words=32
|
||||||
c.words_per_row=2
|
c.words_per_row=2
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue