Merge branch 'dev' into multiport_characterization

This commit is contained in:
Hunter Nichols 2018-11-11 23:47:49 -08:00
commit 6f6d45f025
3 changed files with 37 additions and 30 deletions

View File

@ -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:
vcg[net_name1]=[] if net_name1 not in vcg.keys():
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,

View File

@ -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)]

View File

@ -1,12 +1,14 @@
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
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: