|
@@ -1,114 +0,0 @@
|
|
-#!/usr/bin/env python
|
|
|
|
-
|
|
|
|
-from collections import namedtuple
|
|
|
|
-import re
|
|
|
|
-
|
|
|
|
-BEL = namedtuple('BEL', 'x y z')
|
|
|
|
-
|
|
|
|
-def to_int(s):
|
|
|
|
- return int(re.sub(r'[^\d-]+', '', s))
|
|
|
|
-
|
|
|
|
-def split_bel(b):
|
|
|
|
- return BEL(*[to_int(x) for x in b.split('/', 3)])
|
|
|
|
-
|
|
|
|
-def find_io_site(lc):
|
|
|
|
- # Check in/out ports
|
|
|
|
- for pn in [ 'I0', 'I1', 'I2', 'I3', 'O' ]:
|
|
|
|
- n = lc.ports[pn].net
|
|
|
|
- if (n is None) or n.name.startswith('$PACKER_'):
|
|
|
|
- continue
|
|
|
|
- pl = [ n.driver ] + list(n.users)
|
|
|
|
- for p in pl:
|
|
|
|
- if (p.cell.type == 'SB_IO') and ('BEL' in p.cell.attrs):
|
|
|
|
- return split_bel(p.cell.attrs['BEL'])
|
|
|
|
- return None
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-# Find all groups and all LCs
|
|
|
|
-serdes_lcs = {}
|
|
|
|
-serdes_site = {}
|
|
|
|
-
|
|
|
|
-for n,c in ctx.cells:
|
|
|
|
- if 'SERDES_GRP' in c.attrs:
|
|
|
|
- # Get group ID
|
|
|
|
- grp = int(c.attrs['SERDES_GRP'],2)
|
|
|
|
-
|
|
|
|
- # Append to LCs list and IO site list
|
|
|
|
- serdes_lcs.setdefault(grp, []).append(c)
|
|
|
|
-
|
|
|
|
- io_site = find_io_site(c)
|
|
|
|
- if io_site is not None:
|
|
|
|
- if (grp in serdes_site) and (serdes_site[grp] != io_site):
|
|
|
|
- raise RuntimeError('IO site conflict for SERDES group %d (%s vs %s)' % (grp, io_site, serdes_site[grp]))
|
|
|
|
- serdes_site[grp] = io_site
|
|
|
|
-
|
|
|
|
-# Split into top / bottmon IO banks
|
|
|
|
-serdes_top = {}
|
|
|
|
-serdes_bot = {}
|
|
|
|
-
|
|
|
|
-for grp, site in serdes_site.items():
|
|
|
|
- if site.y == 31:
|
|
|
|
- serdes_top[grp] = site
|
|
|
|
- else:
|
|
|
|
- serdes_bot[grp] = site
|
|
|
|
-
|
|
|
|
-# Place them
|
|
|
|
-# (super dumb algo ...)
|
|
|
|
-def place(sites):
|
|
|
|
- # Init set
|
|
|
|
- toplace = sorted(sites.items(), key=lambda x:-x[1].x)
|
|
|
|
- placed = {}
|
|
|
|
-
|
|
|
|
- # Scan each possible site in order and place ASAP
|
|
|
|
- for x in range(1,26):
|
|
|
|
- # Skip invalid (SPRAM columns)
|
|
|
|
- if x in [6, 19]:
|
|
|
|
- continue
|
|
|
|
-
|
|
|
|
- # Place next one ?
|
|
|
|
- if x >= (toplace[-1][1].x - 1):
|
|
|
|
- placed[toplace.pop()[0]] = x
|
|
|
|
-
|
|
|
|
- # Done ?
|
|
|
|
- if not toplace:
|
|
|
|
- break
|
|
|
|
-
|
|
|
|
- # Cleanup pass
|
|
|
|
- while True:
|
|
|
|
- # Find a group that could be moved to its preferred X
|
|
|
|
- used = set(placed.values())
|
|
|
|
- for grp, pos in placed.items():
|
|
|
|
- px = sites[grp].x
|
|
|
|
- if (pos != px) and (px not in used) and (px not in [6, 19]):
|
|
|
|
- placed[grp] = sites[grp].x
|
|
|
|
- break
|
|
|
|
- else:
|
|
|
|
- break
|
|
|
|
-
|
|
|
|
- # Done
|
|
|
|
- return placed
|
|
|
|
-
|
|
|
|
-serdes_top_place = place(serdes_top)
|
|
|
|
-serdes_bot_place = place(serdes_bot)
|
|
|
|
-
|
|
|
|
-# Merge results
|
|
|
|
-serdes_place = dict()
|
|
|
|
-serdes_place.update(serdes_top_place)
|
|
|
|
-serdes_place.update(serdes_bot_place)
|
|
|
|
-
|
|
|
|
-# Add the final BEL attribute to all LCs
|
|
|
|
-for grp in serdes_place.keys():
|
|
|
|
- x = serdes_place[grp]
|
|
|
|
- for lc in serdes_lcs[grp]:
|
|
|
|
- # Grab attributes
|
|
|
|
- yofs = int(lc.attrs['SERDES_YOFS'], 2)
|
|
|
|
- y = (30-yofs) if serdes_site[grp].y == 31 else (1+yofs)
|
|
|
|
- z = int(lc.attrs['SERDES_Z'], 2)
|
|
|
|
-
|
|
|
|
- # Set attribute
|
|
|
|
- lc.setAttr('BEL', 'X%d/Y%d/lc%d' % (x, y, z))
|
|
|
|
-
|
|
|
|
- # Clear out
|
|
|
|
- lc.unsetAttr('SERDES_GRP')
|
|
|
|
- lc.unsetAttr('SERDES_YOFS')
|
|
|
|
- lc.unsetAttr('SERDES_Z')
|
|
|