mirror of https://github.com/VLSIDA/OpenRAM.git
Merge branch 'dev' into multiport_characterization
This commit is contained in:
commit
6f6d45f025
|
|
@ -754,36 +754,42 @@ class layout(lef.lef):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
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 graph and all conflicts
|
||||||
|
"""
|
||||||
g.pop(pin,None)
|
g.pop(pin,None)
|
||||||
|
|
||||||
# Remove the pin from all conflicts
|
# Remove the pin from all conflicts
|
||||||
# This is O(n^2), so maybe optimize it.
|
# FIXME: This is O(n^2), so maybe optimize it.
|
||||||
for other_pin,conflicts in g.items():
|
for other_pin,conflicts in g.items():
|
||||||
if pin in conflicts:
|
if pin in conflicts:
|
||||||
conflicts.remove(pin)
|
conflicts.remove(pin)
|
||||||
g[other_pin]=conflicts
|
g[other_pin]=conflicts
|
||||||
return g
|
return g
|
||||||
|
|
||||||
def vcg_pins_overlap(pins1, pins2, vertical):
|
def vcg_nets_overlap(net1, net2, vertical):
|
||||||
# Check all the pin pairs on two nets and return a pin
|
"""
|
||||||
# overlap if any pin overlaps vertically
|
Check all the pin pairs on two nets and return a pin
|
||||||
for pin1 in pins1:
|
overlap if any pin overlaps
|
||||||
for pin2 in pins2:
|
"""
|
||||||
|
|
||||||
|
for pin1 in net1:
|
||||||
|
for pin2 in net2:
|
||||||
if vcg_pin_overlap(pin1, pin2, vertical):
|
if vcg_pin_overlap(pin1, pin2, vertical):
|
||||||
return True
|
return True
|
||||||
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def vcg_pin_overlap(pin1, pin2, vertical):
|
def vcg_pin_overlap(pin1, pin2, vertical):
|
||||||
# Check for vertical overlap of the two pins
|
""" Check for vertical or horizontal overlap of the two pins """
|
||||||
|
|
||||||
# Pin 1 must be in the "TOP" set
|
# Pin 1 must be in the "BOTTOM" set
|
||||||
x_overlap = pin1.by() > pin2.by() and abs(pin1.center().x-pin2.center().x)<pitch
|
x_overlap = pin1.by() < pin2.by() and abs(pin1.center().x-pin2.center().x)<pitch
|
||||||
|
|
||||||
# Pin 1 must be in the "LET" set
|
# Pin 1 must be in the "LEFT" set
|
||||||
y_overlap = pin1.lx() < pin2.lx() and abs(pin1.center().y-pin2.center().y)<pitch
|
y_overlap = pin1.lx() < pin2.lx() and abs(pin1.center().y-pin2.center().y)<pitch
|
||||||
|
overlaps = (not vertical and x_overlap) or (vertical and y_overlap)
|
||||||
return (not vertical and x_overlap) or (vertical and y_overlap)
|
return overlaps
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -813,26 +819,19 @@ class layout(lef.lef):
|
||||||
# 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 net_name1 in nets:
|
for net_name1 in nets:
|
||||||
|
if net_name1 not in vcg.keys():
|
||||||
vcg[net_name1]=[]
|
vcg[net_name1]=[]
|
||||||
for net_name2 in nets:
|
for net_name2 in nets:
|
||||||
|
if net_name2 not in vcg.keys():
|
||||||
|
vcg[net_name2]=[]
|
||||||
# Skip yourself
|
# Skip yourself
|
||||||
if net_name1 == net_name2:
|
if net_name1 == net_name2:
|
||||||
continue
|
continue
|
||||||
if vcg_pins_overlap(nets[net_name1], nets[net_name2], vertical):
|
if vcg_nets_overlap(nets[net_name1], nets[net_name2], vertical):
|
||||||
try:
|
|
||||||
vcg[net_name2].append(net_name1)
|
vcg[net_name2].append(net_name1)
|
||||||
except:
|
|
||||||
vcg[net_name2] = [net_name1]
|
|
||||||
|
|
||||||
#FIXME: What if we have a cycle?
|
#FIXME: What if we have a cycle?
|
||||||
|
|
||||||
# The starting offset is the first trunk at the top or left
|
|
||||||
# so we must offset from the lower left of the channel placement
|
|
||||||
# in the case of vertical tracks
|
|
||||||
if not vertical:
|
|
||||||
# This will start from top down
|
|
||||||
offset = offset + vector(0,len(nets)*pitch)
|
|
||||||
|
|
||||||
# list of routes to do
|
# list of routes to do
|
||||||
while vcg:
|
while vcg:
|
||||||
#from pprint import pformat
|
#from pprint import pformat
|
||||||
|
|
@ -856,13 +855,13 @@ class layout(lef.lef):
|
||||||
# Remove the net from other constriants in the VCG
|
# Remove the net from other constriants in the VCG
|
||||||
vcg=remove_net_from_graph(net_name, vcg)
|
vcg=remove_net_from_graph(net_name, vcg)
|
||||||
|
|
||||||
# Add the trunk routes from the bottom up or the left to right
|
# Add the trunk routes from the bottom up for horizontal or the left to right for vertical
|
||||||
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)
|
||||||
offset += vector(pitch,0)
|
offset += vector(pitch,0)
|
||||||
else:
|
else:
|
||||||
self.add_horizontal_trunk_route(pin_list, offset, layer_stack, pitch)
|
self.add_horizontal_trunk_route(pin_list, offset, layer_stack, pitch)
|
||||||
offset -= vector(0,pitch)
|
offset += vector(0,pitch)
|
||||||
|
|
||||||
|
|
||||||
def create_vertical_channel_route(self, netlist, pins, offset,
|
def create_vertical_channel_route(self, netlist, pins, offset,
|
||||||
|
|
|
||||||
|
|
@ -223,7 +223,7 @@ class sram_1bank(sram_base):
|
||||||
""" Connect the output of the data flops to the write driver """
|
""" Connect the output of the data flops to the write driver """
|
||||||
# This is where the channel will start (y-dimension at least)
|
# This is where the channel will start (y-dimension at least)
|
||||||
for port in self.write_ports:
|
for port in self.write_ports:
|
||||||
offset = self.data_dff_inst[port].ul() + vector(0, self.m1_pitch)
|
offset = self.data_dff_inst[port].ul() + vector(0, 2*self.m1_pitch)
|
||||||
|
|
||||||
dff_names = ["dout_{}".format(x) for x in range(self.word_size)]
|
dff_names = ["dout_{}".format(x) for x in range(self.word_size)]
|
||||||
bank_names = ["din{0}_{1}".format(port,x) for x in range(self.word_size)]
|
bank_names = ["din{0}_{1}".format(port,x) for x in range(self.word_size)]
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
import unittest,warnings
|
import unittest,warnings
|
||||||
import sys,os,glob,copy
|
import sys,os,glob,copy
|
||||||
|
import shutil
|
||||||
sys.path.append(os.path.join(sys.path[0],".."))
|
sys.path.append(os.path.join(sys.path[0],".."))
|
||||||
from globals import OPTS
|
from globals import OPTS
|
||||||
import debug
|
import debug
|
||||||
|
|
@ -7,6 +8,7 @@ import debug
|
||||||
class openram_test(unittest.TestCase):
|
class openram_test(unittest.TestCase):
|
||||||
""" Base unit test that we have some shared classes in. """
|
""" Base unit test that we have some shared classes in. """
|
||||||
|
|
||||||
|
|
||||||
def local_drc_check(self, w):
|
def local_drc_check(self, w):
|
||||||
|
|
||||||
self.reset()
|
self.reset()
|
||||||
|
|
@ -36,11 +38,17 @@ class openram_test(unittest.TestCase):
|
||||||
import verify
|
import verify
|
||||||
result=verify.run_drc(a.name, tempgds)
|
result=verify.run_drc(a.name, tempgds)
|
||||||
if result != 0:
|
if result != 0:
|
||||||
|
#zip_file = "/tmp/{0}_{1}".format(a.name,os.getpid())
|
||||||
|
#debug.info(0,"Archiving failed files to {}.zip".format(zip_file))
|
||||||
|
#shutil.make_archive(zip_file, 'zip', OPTS.openram_temp)
|
||||||
self.fail("DRC failed: {}".format(a.name))
|
self.fail("DRC failed: {}".format(a.name))
|
||||||
|
|
||||||
|
|
||||||
result=verify.run_lvs(a.name, tempgds, tempspice, final_verification)
|
result=verify.run_lvs(a.name, tempgds, tempspice, final_verification)
|
||||||
if result != 0:
|
if result != 0:
|
||||||
|
#zip_file = "/tmp/{0}_{1}".format(a.name,os.getpid())
|
||||||
|
#debug.info(0,"Archiving failed files to {}.zip".format(zip_file))
|
||||||
|
#shutil.make_archive(zip_file, 'zip', OPTS.openram_temp)
|
||||||
self.fail("LVS mismatch: {}".format(a.name))
|
self.fail("LVS mismatch: {}".format(a.name))
|
||||||
|
|
||||||
if OPTS.purge_temp:
|
if OPTS.purge_temp:
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue