1 from __future__
import print_function
5 from pprint
import pprint
10 from helpers
.io
import ErrorMessage
11 from helpers
.io
import WarningMessage
12 from helpers
import trace
13 from helpers
import l
, u
, n
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 hard 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
27 af
= CRL
.AllianceFramework
.get()
29 # converts unicode strings to utf-8 because coriolis2 python code is expecting
31 def _byteify(data
, ignore_dicts
= False):
32 # if this is a unicode string, return its string representation
33 if isinstance(data
, unicode):
34 return data
.encode('utf-8')
35 # if this is a list of values, return list of byteified values
36 if isinstance(data
, list):
37 return [ _byteify(item
, ignore_dicts
=True) for item
in data
]
38 # if this is a dictionary, return dictionary of byteified keys and values
39 # but only if we haven't already byteified it
40 if isinstance(data
, dict) and not ignore_dicts
:
41 return dict((_byteify(key
, ignore_dicts
=True),
42 _byteify(value
, ignore_dicts
=True))
43 for key
, value
in data
.iteritems())
44 # if it's anything else, return it in its original form
47 # load JSON-formatted pad info from pinmux
48 pth
= os
.path
.abspath(__file__
)
49 pth
= os
.path
.split(pth
)[0]
51 with
open("%s/ls180/litex_pinpads.json" % pth
) as f
:
53 chip
= json
.loads(txt
, object_hook
=_byteify
)
54 chip
= _byteify(chip
, ignore_dicts
=True)
57 chip
.update({ 'pads.ioPadGauge' : 'niolib',
58 # core option (big, time-consuming)
59 #'core.size' : (l(28000), l(28000)),
60 #'chip.size' : (l(30200), l(30200)),
61 # no-core option (test_issuer but no actual core)
62 'core.size' : (l(13000), l(13000)),
63 'chip.size' : (l(14400), l(14400)),
64 'pads.useCoreSize': True,
65 'chip.clockTree' : True,
68 # this function is the equivalent of statically-declared io pad specs.
69 # it is not ok to have io declared manually, duplicated in (literally) 5
70 # different places, too many mistakes can be made and changes are a
73 # therefore the pinmux code takes responsibility for declaring the pinouts,
74 # generates a JSON file which is read (above) and *creates* the list from
75 # that auto-generated file. the core, litex peripheral code, *and* the C4M
76 # JTAG Boundary Scan code do *EXACTLY* the same thing and in this way they
79 # here we do some weirdness to convert from the ioring.py pads list format over
80 # to the new niolib format.
83 # convert old ioring format to ioPadsSpec
85 sd
= {'pads.east': IoPin
.EAST
,
86 'pads.west': IoPin
.WEST
,
87 'pads.south': IoPin
.SOUTH
,
88 'pads.north': IoPin
.NORTH
,
90 # create lookup dict for resolving pads.instances "side" (NSEW)
92 for side
in ['pads.east', 'pads.west', 'pads.south', 'pads.north']:
93 io_pin_spec
= sd
[side
]
94 #if side not in sides:
96 for pinname
in chip
[side
]:
97 sides
[pinname
] = io_pin_spec
99 # now go through pads.instances
101 for pad
in chip
['pads.instances']:
103 padside
= sides
[padname
]
104 print ("padside", padname
, padside
)
106 # format here is ['padname', 'to core', 'from core', 'direction']
107 # where direction is "+" for out, "-" for in, "*" for bi-directionaly
109 print("4-long io", pad
)
110 padspec
= [padside
, None, padname
, pad
[1], pad
[2]]
113 # ['padname', 'something', 'to core', 'from core', 'en', 'direction']
115 print("6-long io", pad
)
116 padspec
= [padside
, None, padname
] + pad
[1:5]
118 # format here is power/gnd (io)vss/vdd
120 print("2-long io", pad
)
121 padspec
= [padside
, None] + pad
123 print("? long io", pad
)
125 print ("padspec", padspec
)
126 ioPadsSpec
.append(tuple(padspec
))
130 ioPadsSpec
= generate_spec()
133 def scriptMain (**kw
):
134 """The mandatory function to be called by Coriolis CGT/Unicorn."""
138 helpers
.setTraceLevel(550)
139 usePadsPosition
= True
141 cell
, editor
= plugins
.kwParseMain(**kw
)
142 cell
= af
.getCell('ls180', CRL
.Catalog
.State
.Logical
)
144 print(ErrorMessage(2, 'doDesign.scriptMain(): Unable to load '
145 'cell "{}".'.format('ls180')))
147 if editor
: editor
.setCell(cell
)
148 ls180Conf
= ChipConf(cell
, ioPads
=ioPadsSpec
)
149 ls180Conf
.cfg
.etesian
.bloat
= 'nsxlib'
150 ls180Conf
.cfg
.etesian
.uniformDensity
= True
151 ls180Conf
.cfg
.etesian
.aspectRatio
= 1.0
152 ls180Conf
.cfg
.etesian
.spaceMargin
= 0.05
153 ls180Conf
.cfg
.block
.spareSide
= l(700)
154 ls180Conf
.cfg
.chip
.padCoreSide
= 'North'
155 ls180Conf
.editor
= editor
156 ls180Conf
.useSpares
= True
157 ls180Conf
.useClockTree
= True
158 ls180Conf
.bColumns
= 2
160 ls180Conf
.chipConf
.name
= 'chip'
161 ls180Conf
.chipConf
.ioPadGauge
= 'niolib'
162 ls180Conf
.coreSize
= (l(15000), l(15000))
163 ls180Conf
.chipSize
= (l(19000), l(19000))
164 ls180ToChip
= CoreToChip(ls180Conf
)
165 ls180ToChip
.buildChip()
166 chipBuilder
= Chip(ls180Conf
)
167 rvalue
= chipBuilder
.doPnR()