mirror of
				https://github.com/YosysHQ/sby.git
				synced 2025-10-31 13:02:28 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			96 lines
		
	
	
	
		
			2.6 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			96 lines
		
	
	
	
		
			2.6 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| from collections import defaultdict
 | |
| import inspect
 | |
| 
 | |
| N = 32
 | |
| f = lambda x: (2*x-1) ^ (x&7)
 | |
| 
 | |
| table = [f(i) & (N-1) for i in range(N)]
 | |
| rtable = [table.count(i) for i in range(N)]
 | |
| 
 | |
| def getPath(v):
 | |
|     if table[v] is None:
 | |
|         return [v]
 | |
|     bak = table[v]
 | |
|     table[v] = None
 | |
|     r = [v] + getPath(bak)
 | |
|     table[v] = bak
 | |
|     return r
 | |
| 
 | |
| def getPaths():
 | |
|     visited = set()
 | |
|     paths = list()
 | |
|     for i in range(N):
 | |
|         if rtable[i] == 0:
 | |
|             paths.append(getPath(i))
 | |
|     for path in paths:
 | |
|         for i in path:
 | |
|             visited.add(i)
 | |
|     for i in range(N):
 | |
|         if i not in visited:
 | |
|             paths.append(getPath(i))
 | |
|             for j in paths[-1]:
 | |
|                 visited.add(j)
 | |
|     return paths
 | |
| 
 | |
| pathsByLidx = defaultdict(set)
 | |
| loopsByIdx = dict()
 | |
| loopsByLidx = dict()
 | |
| 
 | |
| for path in getPaths():
 | |
|     i = path.index(path[-1])+1
 | |
|     head, loop, lidx = tuple(path[:i]), tuple(path[i:]), max(path[i:])
 | |
|     pathsByLidx[lidx].add((head, loop))
 | |
| 
 | |
| print()
 | |
| print("The %d-bit function f(x) produces %d loops:" % (N.bit_length()-1, len(pathsByLidx)))
 | |
| print("  ", inspect.getsource(f).strip())
 | |
| 
 | |
| for lidx, paths in pathsByLidx.items():
 | |
|     loop = None
 | |
|     for path in paths:
 | |
|         for i in path[0] + path[1]:
 | |
|             loopsByIdx[i] = lidx
 | |
|         if loop is None or path[1][0] > loop[0]:
 | |
|             loop = path[1]
 | |
| 
 | |
|     loopsByLidx[lidx] = loop
 | |
|     
 | |
|     print()
 | |
|     print("%d-Element Loop:" % len(loop))
 | |
|     print("  ", " ->- ".join(["%2d" % i for i in loop + (loop[0],)]))
 | |
| 
 | |
|     lines = []
 | |
|     lastPath = []
 | |
|     for path in sorted([tuple(reversed(p[0])) for p in paths]):
 | |
|         line = ""
 | |
|         for i in range(len(path)):
 | |
|             if i < len(lastPath) and lastPath[i] == path[i]:
 | |
|                 line += " %s   " % (" " if i == 0 else "|  ")
 | |
|             else:
 | |
|                 line += " %s %2d" % (" " if i == 0 else "`<-" if len(lastPath) else "-<-", path[i])
 | |
|                 lastPath = []
 | |
|         lastPath = path
 | |
|         lines.append(line)
 | |
| 
 | |
|     for i in range(len(lines)-1, -1, -1):
 | |
|         line, nextline = list(lines[i]), "" if i == len(lines)-1 else lines[i+1]
 | |
|         if len(nextline) < len(line): nextline = nextline.ljust(len(line))
 | |
| 
 | |
|         for k in range(len(line)):
 | |
|             if line[k] == "|" and nextline[k] in " -":
 | |
|                 line[k] = " "
 | |
| 
 | |
|         lines[i] = "".join(line)
 | |
| 
 | |
|     print("%d Lead-Ins:" % len(lines))
 | |
|     for line in lines:
 | |
|         print(line)
 | |
| 
 | |
| print()
 | |
| print("Loop Membership:")
 | |
| for lidx in pathsByLidx:
 | |
|     print("%18s |" % (loopsByLidx[lidx],), end="")
 | |
|     for i in range(N):
 | |
|         print("*" if loopsByIdx[i] == lidx else ".", end="")
 | |
|     print("|")
 | |
| print()
 |