2016-11-17 00:02:07 +01:00
|
|
|
import numpy as np
|
2017-04-24 19:27:04 +02:00
|
|
|
import string
|
2016-11-17 00:02:07 +01:00
|
|
|
import debug
|
2016-11-17 01:47:31 +01:00
|
|
|
from vector3d import vector3d
|
2018-09-07 23:46:58 +02:00
|
|
|
from grid_cell import grid_cell
|
2017-04-24 19:27:04 +02:00
|
|
|
|
2016-11-17 00:02:07 +01:00
|
|
|
class grid:
|
2018-08-23 00:56:19 +02:00
|
|
|
"""
|
|
|
|
|
A two layer routing map. Each cell can be blocked in the vertical
|
2016-11-17 00:02:07 +01:00
|
|
|
or horizontal layer.
|
|
|
|
|
"""
|
2018-09-07 23:46:58 +02:00
|
|
|
# costs are relative to a unit grid
|
|
|
|
|
# non-preferred cost allows an off-direction jog of 1 grid
|
|
|
|
|
# rather than 2 vias + preferred direction (cost 5)
|
|
|
|
|
VIA_COST = 2
|
|
|
|
|
NONPREFERRED_COST = 4
|
|
|
|
|
PREFERRED_COST = 1
|
|
|
|
|
|
2016-11-17 00:02:07 +01:00
|
|
|
|
2018-09-06 20:54:14 +02:00
|
|
|
def __init__(self, ll, ur, track_width):
|
2018-08-23 00:56:19 +02:00
|
|
|
""" Initialize the map and define the costs. """
|
2017-04-24 19:27:04 +02:00
|
|
|
|
2018-09-06 20:54:14 +02:00
|
|
|
# list of the source/target grid coordinates
|
2019-01-30 20:15:47 +01:00
|
|
|
self.source = set()
|
|
|
|
|
self.target = set()
|
2018-09-06 20:54:14 +02:00
|
|
|
|
|
|
|
|
self.track_width = track_width
|
|
|
|
|
self.track_widths = [self.track_width, self.track_width, 1.0]
|
|
|
|
|
self.track_factor = [1/self.track_width, 1/self.track_width, 1.0]
|
|
|
|
|
|
|
|
|
|
# The bounds are in grids for this
|
|
|
|
|
# This is really lower left bottom layer and upper right top layer in 3D.
|
|
|
|
|
self.ll = vector3d(ll.x,ll.y,0).scale(self.track_factor).round()
|
|
|
|
|
self.ur = vector3d(ur.x,ur.y,1).scale(self.track_factor).round()
|
|
|
|
|
|
2017-04-24 19:27:04 +02:00
|
|
|
# let's leave the map sparse, cells are created on demand to reduce memory
|
2017-04-14 22:56:09 +02:00
|
|
|
self.map={}
|
2016-11-17 01:47:31 +01:00
|
|
|
|
2018-10-19 23:21:03 +02:00
|
|
|
def add_all_grids(self):
|
|
|
|
|
for x in range(self.ll.x, self.ur.x, 1):
|
|
|
|
|
for y in range(self.ll.y, self.ur.y, 1):
|
|
|
|
|
self.add_map(vector3d(x,y,0))
|
|
|
|
|
self.add_map(vector3d(x,y,1))
|
|
|
|
|
|
2018-09-06 20:54:14 +02:00
|
|
|
def set_blocked(self,n,value=True):
|
2018-09-13 18:10:29 +02:00
|
|
|
if isinstance(n, (list,tuple,set,frozenset)):
|
2018-09-06 20:54:14 +02:00
|
|
|
for item in n:
|
|
|
|
|
self.set_blocked(item,value)
|
|
|
|
|
else:
|
|
|
|
|
self.add_map(n)
|
|
|
|
|
self.map[n].blocked=value
|
2017-06-05 23:42:56 +02:00
|
|
|
|
2017-06-07 02:12:19 +02:00
|
|
|
def is_blocked(self,n):
|
2018-09-13 18:10:29 +02:00
|
|
|
if isinstance(n, (list,tuple,set,frozenset)):
|
2018-09-07 23:46:58 +02:00
|
|
|
for item in n:
|
|
|
|
|
if self.is_blocked(item):
|
|
|
|
|
return True
|
|
|
|
|
else:
|
|
|
|
|
return False
|
|
|
|
|
else:
|
|
|
|
|
self.add_map(n)
|
|
|
|
|
return self.map[n].blocked
|
|
|
|
|
|
2017-06-07 02:12:19 +02:00
|
|
|
|
2018-09-06 20:54:14 +02:00
|
|
|
def set_path(self,n,value=True):
|
2018-09-13 18:10:29 +02:00
|
|
|
if isinstance(n, (list,tuple,set,frozenset)):
|
2018-09-06 20:54:14 +02:00
|
|
|
for item in n:
|
|
|
|
|
self.set_path(item,value)
|
|
|
|
|
else:
|
|
|
|
|
self.add_map(n)
|
|
|
|
|
self.map[n].path=value
|
|
|
|
|
|
2018-09-08 19:05:48 +02:00
|
|
|
def clear_blockages(self):
|
2019-01-30 22:02:34 +01:00
|
|
|
for k in self.map:
|
|
|
|
|
self.map[k].blocked=False
|
2018-09-08 19:05:48 +02:00
|
|
|
|
2018-09-13 18:10:29 +02:00
|
|
|
def set_source(self,n,value=True):
|
|
|
|
|
if isinstance(n, (list,tuple,set,frozenset)):
|
2018-09-06 20:54:14 +02:00
|
|
|
for item in n:
|
2018-09-13 18:10:29 +02:00
|
|
|
self.set_source(item,value)
|
2018-09-06 20:54:14 +02:00
|
|
|
else:
|
|
|
|
|
self.add_map(n)
|
2018-09-13 18:10:29 +02:00
|
|
|
self.map[n].source=value
|
2019-01-30 20:15:47 +01:00
|
|
|
self.source.add(n)
|
2018-09-06 20:54:14 +02:00
|
|
|
|
2018-09-13 18:10:29 +02:00
|
|
|
def set_target(self,n,value=True):
|
|
|
|
|
if isinstance(n, (list,tuple,set,frozenset)):
|
2018-09-06 20:54:14 +02:00
|
|
|
for item in n:
|
2018-09-13 18:10:29 +02:00
|
|
|
self.set_target(item,value)
|
2018-09-06 20:54:14 +02:00
|
|
|
else:
|
|
|
|
|
self.add_map(n)
|
2018-09-13 18:10:29 +02:00
|
|
|
self.map[n].target=value
|
2019-01-30 20:15:47 +01:00
|
|
|
self.target.add(n)
|
2018-09-06 20:54:14 +02:00
|
|
|
|
|
|
|
|
|
2018-09-18 21:57:39 +02:00
|
|
|
def add_source(self,track_list,value=True):
|
2018-09-09 03:55:36 +02:00
|
|
|
debug.info(3,"Adding source list={0}".format(str(track_list)))
|
2018-09-06 20:54:14 +02:00
|
|
|
for n in track_list:
|
2018-09-09 03:55:36 +02:00
|
|
|
debug.info(4,"Adding source ={0}".format(str(n)))
|
2018-09-18 21:57:39 +02:00
|
|
|
self.set_source(n,value)
|
2018-09-07 23:46:58 +02:00
|
|
|
self.set_blocked(n,False)
|
2018-09-06 20:54:14 +02:00
|
|
|
|
|
|
|
|
|
2018-09-18 21:57:39 +02:00
|
|
|
def add_target(self,track_list,value=True):
|
2018-09-09 03:55:36 +02:00
|
|
|
debug.info(3,"Adding target list={0}".format(str(track_list)))
|
2018-09-06 20:54:14 +02:00
|
|
|
for n in track_list:
|
2018-09-09 03:55:36 +02:00
|
|
|
debug.info(4,"Adding target ={0}".format(str(n)))
|
2018-09-13 18:10:29 +02:00
|
|
|
self.set_target(n,value)
|
2018-09-07 23:46:58 +02:00
|
|
|
self.set_blocked(n,False)
|
2018-09-06 20:54:14 +02:00
|
|
|
|
|
|
|
|
def is_target(self,point):
|
|
|
|
|
"""
|
|
|
|
|
Point is in the target set, so we are done.
|
|
|
|
|
"""
|
|
|
|
|
return point in self.target
|
|
|
|
|
|
|
|
|
|
def add_map(self,n):
|
2017-04-14 22:18:35 +02:00
|
|
|
"""
|
|
|
|
|
Add a point to the map if it doesn't exist.
|
|
|
|
|
"""
|
2018-09-13 18:10:29 +02:00
|
|
|
if isinstance(n, (list,tuple,set,frozenset)):
|
2018-09-06 20:54:14 +02:00
|
|
|
for item in n:
|
|
|
|
|
self.add_map(item)
|
|
|
|
|
else:
|
2019-01-30 22:02:34 +01:00
|
|
|
if n not in self.map:
|
2018-09-07 23:46:58 +02:00
|
|
|
self.map[n]=grid_cell()
|
2016-11-17 01:47:31 +01:00
|
|
|
|
2017-04-14 22:18:35 +02:00
|
|
|
|
2018-09-06 01:01:11 +02:00
|
|
|
def block_path(self,path):
|
|
|
|
|
"""
|
|
|
|
|
Mark the path in the routing grid as blocked.
|
|
|
|
|
Also unsets the path flag.
|
|
|
|
|
"""
|
2018-09-07 23:46:58 +02:00
|
|
|
path.set_path(False)
|
|
|
|
|
path.set_blocked(True)
|
2018-09-06 01:01:11 +02:00
|
|
|
|
2016-11-18 18:17:59 +01:00
|
|
|
|
2018-08-23 00:56:19 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|