start conversion of ls180 to new niolib
[soclayout.git] / experiments9 / doDesign.py
1 from __future__ import print_function
2
3 import os
4 import json
5 from pprint import pprint
6 import sys
7 import traceback
8 import CRL
9 import helpers
10 from helpers.io import ErrorMessage
11 from helpers.io import WarningMessage
12 from helpers import trace
13 from helpers import l, u, n
14 import plugins
15 from Hurricane import DbU
16 if True: # change this to False to get errors to "go away" so that
17 # print / debug statements in generation of spec can be seen
18 # without the critical dependence of having to run via "cgt"
19 from plugins.alpha.block.configuration import IoPin
20 from plugins.alpha.block.block import Block
21 from plugins.alpha.block.configuration import GaugeConf
22 from plugins.alpha.core2chip.niolib import CoreToChip
23 from plugins.alpha.chip.configuration import ChipConf
24 from plugins.alpha.chip.chip import Chip
25
26
27 af = CRL.AllianceFramework.get()
28
29
30 def _byteify(data, ignore_dicts = False):
31 # if this is a unicode string, return its string representation
32 if isinstance(data, unicode):
33 return data.encode('utf-8')
34 # if this is a list of values, return list of byteified values
35 if isinstance(data, list):
36 return [ _byteify(item, ignore_dicts=True) for item in data ]
37 # if this is a dictionary, return dictionary of byteified keys and values
38 # but only if we haven't already byteified it
39 if isinstance(data, dict) and not ignore_dicts:
40 return dict((_byteify(key, ignore_dicts=True),
41 _byteify(value, ignore_dicts=True))
42 for key, value in data.iteritems())
43 # if it's anything else, return it in its original form
44 return data
45
46 # load JSON-formatted pad info from pinmux
47 pth = os.path.abspath(__file__)
48 pth = os.path.split(pth)[0]
49 print ("path", pth)
50 with open("%s/ls180/litex_pinpads.json" % pth) as f:
51 txt = f.read()
52 chip = json.loads(txt, object_hook=_byteify)
53 chip = _byteify(chip, ignore_dicts=True)
54 print (chip)
55
56 chip.update({ 'pads.ioPadGauge' : 'niolib',
57 # core option (big, time-consuming)
58 #'core.size' : (l(28000), l(28000)),
59 #'chip.size' : (l(30200), l(30200)),
60 # no-core option (test_issuer but no actual core)
61 'core.size' : (l(13000), l(13000)),
62 'chip.size' : (l(14400), l(14400)),
63 'pads.useCoreSize': True,
64 'chip.clockTree' : True,
65 })
66
67 def generate_spec():
68 # convert old ioring format to ioPadsSpec
69 ioPadsSpec = []
70 sd = {'pads.east': IoPin.EAST,
71 'pads.west': IoPin.WEST,
72 'pads.south': IoPin.SOUTH,
73 'pads.north': IoPin.NORTH,
74 }
75 # create lookup dict for resolving pads.instances "side" (NSEW)
76 sides = {}
77 for side in ['pads.east', 'pads.west', 'pads.south', 'pads.north']:
78 io_pin_spec = sd[side]
79 #if side not in sides:
80 # sides[side] = {}
81 for pinname in chip[side]:
82 sides[pinname] = io_pin_spec
83 # now go through pads.instances
84 pprint (sides)
85 for pad in chip['pads.instances']:
86 padname = pad[0]
87 padside = sides[padname]
88 print ("padside", padname, padside)
89 if len(pad) == 4:
90 if pad[-1] == '-':
91 en_sig = 'io_in'
92 if pad[-1] == '+':
93 en_sig = 'io_out'
94 padspec = [padside, None, padname, pad[1], pad[2], en_sig]
95 print("4-long io", pad)
96 elif len(pad) == 6:
97 print("6-long io", pad)
98 padspec = [padside, None, padname] + pad[1:5]
99 else:
100 print("? long io", pad)
101 assert False
102 print ("padspec", padspec)
103 ioPadsSpec.append(tuple(padspec))
104 return ioPadsSpec
105
106 ioPadsSpec = generate_spec()
107
108
109 def scriptMain (**kw):
110 """The mandatory function to be called by Coriolis CGT/Unicorn."""
111 global af
112 rvalue = True
113 try:
114 helpers.setTraceLevel(550)
115 usePadsPosition = True
116 buildChip = True
117 cell, editor = plugins.kwParseMain(**kw)
118 cell = af.getCell('ls180', CRL.Catalog.State.Logical)
119 if cell is None:
120 print(ErrorMessage(2, 'doDesign.scriptMain(): Unable to load '
121 'cell "{}".'.format('ls180')))
122 sys.exit(1)
123 if editor: editor.setCell(cell)
124 ls180Conf = ChipConf(cell, ioPads=ioPadsSpec)
125 ls180Conf.cfg.etesian.bloat = 'nsxlib'
126 ls180Conf.cfg.etesian.uniformDensity = True
127 ls180Conf.cfg.etesian.aspectRatio = 1.0
128 ls180Conf.cfg.etesian.spaceMargin = 0.05
129 ls180Conf.cfg.block.spareSide = l(700)
130 ls180Conf.cfg.chip.padCoreSide = 'North'
131 ls180Conf.editor = editor
132 ls180Conf.useSpares = True
133 ls180Conf.useClockTree = True
134 ls180Conf.bColumns = 2
135 ls180Conf.bRows = 2
136 ls180Conf.chipConf.name = 'chip'
137 ls180Conf.chipConf.ioPadGauge = 'niolib'
138 ls180Conf.coreSize = (l(13000), l(13000))
139 ls180Conf.chipSize = (l(14400), l(14400))
140 ls180ToChip = CoreToChip(ls180Conf)
141 ls180ToChip.buildChip()
142 chipBuilder = Chip(ls180Conf)
143 rvalue = chipBuilder.doPnR()
144 chipBuilder.save()
145 except Exception, e:
146 helpers.io.catch(e)
147 rvalue = False
148 sys.stdout.flush()
149 sys.stderr.flush()
150 return rvalue