2 from __future__
import print_function
11 from helpers
import trace
, l
, u
, n
12 from helpers
.io
import ErrorMessage
, WarningMessage
13 from helpers
.overlay
import UpdateSession
15 from Hurricane
import Breakpoint
, DataBase
, DbU
, Transformation
, Box
, Instance
16 from plugins
.alpha
.macro
.macro
import Macro
17 from plugins
.alpha
.block
.iospecs
import IoSpecs
18 from plugins
.alpha
.block
.block
import Block
19 from plugins
.alpha
.block
.configuration
import IoPin
, GaugeConf
20 from plugins
.alpha
.core2chip
.libresocio
import CoreToChip
21 from plugins
.alpha
.chip
.configuration
import ChipConf
22 from plugins
.alpha
.chip
.chip
import Chip
25 af
= CRL
.AllianceFramework
.get()
29 def isiterable ( pyobj
):
30 if isinstance(pyobj
,collections
.Iterable
): return True
34 def doIoPowerCap ( flags
):
36 side
= flags
& IoPin
.SIDE_MASK
37 if flags
& IoPin
.A_BEGIN
:
38 ioPadPower
= [ (side
, None, 'power_{}'.format(powerCount
), 'vdd' )
39 , (side
, None, 'ground_{}'.format(powerCount
), 'vss' )
40 , (side
, None, 'ioground_{}'.format(powerCount
), 'iovss' )
41 , (side
, None, 'iopower_{}'.format(powerCount
), 'iovdd' )
44 ioPadPower
= [ (side
, None, 'iopower_{}'.format(powerCount
), 'iovdd' )
45 , (side
, None, 'ioground_{}'.format(powerCount
), 'iovss' )
46 , (side
, None, 'ground_{}'.format(powerCount
), 'vss' )
47 , (side
, None, 'power_{}'.format(powerCount
), 'vdd' )
53 def doIoPinVector ( ioSpec
, bits
):
55 if not isiterable(bits
): bits
= range(bits
)
57 raise ErrorMessage( 1, [ 'doIoPinVector(): Argument "bits" is neither a width nor an iterable.'
58 , '(bits={})'.format(bits
)
64 , ioSpec
[2].format(bit
)
65 , ioSpec
[3].format(bit
)
66 , ioSpec
[4].format(bit
) ))
67 elif len(ioSpec
) == 6:
71 , ioSpec
[2].format(bit
)
72 , ioSpec
[3].format(bit
)
73 , ioSpec
[4].format(bit
)
74 , ioSpec
[5].format(bit
) ))
75 elif len(ioSpec
) == 7:
79 , ioSpec
[2].format(bit
)
80 , ioSpec
[3].format(bit
)
81 , ioSpec
[4].format(bit
)
82 , ioSpec
[5].format(bit
)
83 , ioSpec
[6].format(bit
) ))
85 raise ErrorMessage( 1, [ 'doIoPinVector(): Argument "ioSpec" must have between 5 and 7 fields ({})'.format(len(ioSpec
))
86 , '(ioSpec={})'.format(ioSpec
)
91 def rgetInstance ( cell
, path
):
93 Get the instance designated by path (recursively). The path argument can be
94 either a string of instance names separated by dots or directly a list of
97 if isinstance(path
,str):
98 path
= path
.split( '.' )
99 elif not isinstance(path
,list):
100 raise ErrorMessage( 1, 'rgetInstance(): "path" argument is neither a string or a list ({})"' \
102 instance
= cell
.getInstance( path
[0] )
104 raise ErrorMessage( 1, 'rgetInstance(): no instance "{}" in cell "{}"' \
105 .format(path
[0],cell
.getName()) )
108 return rgetInstance( instance
.getMasterCell(), path
[1:] )
111 def rsetAbutmentBox ( cell
, ab
):
112 for occurrence
in cell
.getNonTerminalNetlistInstanceOccurrences():
113 masterCell
= occurrence
.getEntity().getMasterCell()
114 masterCell
.setAbutmentBox( ab
)
117 def scriptMain (**kw
):
118 """The mandatory function to be called by Coriolis CGT/Unicorn."""
120 #helpers.setTraceLevel( 550 )
121 #Breakpoint.setStopLevel( 99 )
124 chipBorder
= u(2*214.0 + 10*13.0)
126 #pinmuxFile = './non_generated/litex_pinpads.json'
127 #pinmuxFile = './coriolis2/ls180/litex_pinpads.json'
128 #ioSpecs.loadFromPinmux( pinmuxFile )
129 # I/O pads, East side.
131 ioPadsSpec
+= doIoPowerCap( IoPin
.EAST|IoPin
.A_BEGIN
)
132 ioPadsSpec
+= doIoPinVector( (IoPin
.EAST
, None, 'sdram_a_{}', 'sdram_a({})', 'sdram_a({})'), 13 )
133 ioPadsSpec
+= doIoPinVector( (IoPin
.EAST
, None, 'gpio_{}', 'gpio({})', 'gpio_i({})', 'gpio_oe({})', 'gpio_o({})'), range(8,16) )
134 ioPadsSpec
+= [ (IoPin
.EAST
, None, 'jtag_tms', 'jtag_tms', 'jtag_tms' )
135 , (IoPin
.EAST
, None, 'jtag_tdi', 'jtag_tdi', 'jtag_tdi' )
136 , (IoPin
.EAST
, None, 'jtag_tdo', 'jtag_tdo', 'jtag_tdo' )
137 , (IoPin
.EAST
, None, 'jtag_tck', 'jtag_tck', 'jtag_tck' )
139 ioPadsSpec
+= doIoPinVector( (IoPin
.EAST
, None, 'nc_{}', 'nc({})', 'nc({})'), range(4) )
140 ioPadsSpec
+= doIoPowerCap( IoPin
.EAST|IoPin
.A_END
)
141 # I/O pads, West side.
142 ioPadsSpec
+= doIoPowerCap( IoPin
.WEST|IoPin
.A_BEGIN
)
143 ioPadsSpec
+= [ (IoPin
.WEST
, None, 'pwm_1', 'pwm(1)', 'pwm(1)' ) ]
144 ioPadsSpec
+= doIoPinVector( (IoPin
.WEST
, None, 'eint_{}', 'eint({})', 'eint({})'), 3 )
145 ioPadsSpec
+= [ (IoPin
.WEST
, None, 'spimaster_clk' , 'spimaster_clk' , 'spimaster_clk' )
146 , (IoPin
.WEST
, None, 'spimaster_cs_n', 'spimaster_cs_n', 'spimaster_cs_n' )
147 , (IoPin
.WEST
, None, 'spimaster_mosi', 'spimaster_mosi', 'spimaster_mosi' )
148 , (IoPin
.WEST
, None, 'spimaster_miso', 'spimaster_miso', 'spimaster_miso' )
149 , (IoPin
.WEST
, None, 'sdcard_cmd' , 'sdcard_cmd' , 'sdcard_cmd_i', 'sdcard_cmd_oe', 'sdcard_cmd_o' )
150 , (IoPin
.WEST
, None, 'sdcard_clk' , 'sdcard_clk' , 'sdcard_clk' )
152 ioPadsSpec
+= doIoPinVector( (IoPin
.WEST
, None, 'sdcard_data_{}', 'sdcard_data({})', 'sdcard_data_i({})', 'sdcard_data_oe', 'sdcard_data_o({})'), 4 )
153 ioPadsSpec
+= doIoPinVector( (IoPin
.WEST
, None, 'nc_{}', 'nc({})', 'nc({})'), range(4,16) )
154 ioPadsSpec
+= doIoPowerCap( IoPin
.WEST|IoPin
.A_END
)
155 # I/O pads, North side.
156 ioPadsSpec
+= doIoPowerCap( IoPin
.NORTH|IoPin
.A_BEGIN
)
157 ioPadsSpec
+= doIoPinVector( (IoPin
.NORTH
, None, 'sdram_dm_{}', 'sdram_dm({})', 'sdram_dm({})'), 2 )
158 ioPadsSpec
+= doIoPinVector( (IoPin
.NORTH
, None, 'sdram_dq_{}', 'sdram_dq({})', 'sdram_dq_i({})', 'sdram_dq_oe', 'sdram_dq_o({})'), range(0,16) )
159 ioPadsSpec
+= doIoPinVector( (IoPin
.NORTH
, None, 'sdram_ba_{}', 'sdram_ba({})', 'sdram_ba({})'), 2 )
160 ioPadsSpec
+= [ (IoPin
.NORTH
, None, 'sdram_clock' , 'sdram_clock' , 'sdram_clock' )
161 , (IoPin
.NORTH
, None, 'sdram_cke' , 'sdram_cke' , 'sdram_cke' )
162 , (IoPin
.NORTH
, None, 'sdram_ras_n' , 'sdram_ras_n' , 'sdram_ras_n' )
163 , (IoPin
.NORTH
, None, 'sdram_cas_n' , 'sdram_cas_n' , 'sdram_cas_n' )
164 , (IoPin
.NORTH
, None, 'sdram_we_n' , 'sdram_we_n' , 'sdram_we_n' )
165 , (IoPin
.NORTH
, None, 'sdram_cs_n' , 'sdram_cs_n' , 'sdram_cs_n' )
167 ioPadsSpec
+= doIoPinVector( (IoPin
.NORTH
, None, 'nc_{}', 'nc({})', 'nc({})'), range(16,18) )
168 ioPadsSpec
+= doIoPowerCap( IoPin
.NORTH|IoPin
.A_END
)
169 # I/O pads, South side.
170 ioPadsSpec
+= doIoPowerCap( IoPin
.SOUTH|IoPin
.A_BEGIN
)
171 ioPadsSpec
+= [ (IoPin
.SOUTH
, None, 'i2c_sda_i' , 'i2c_sda_i' , 'i2c_sda_i' ) ]
172 ioPadsSpec
+= doIoPinVector( (IoPin
.SOUTH
, None, 'nc_{}', 'nc({})', 'nc({})'), range(18,22) )
173 ioPadsSpec
+= [ (IoPin
.SOUTH
, None, 'spisdcard_clk' , 'spisdcard_clk' , 'spisdcard_clk' )
174 , (IoPin
.SOUTH
, None, 'spisdcard_cs_n', 'spisdcard_cs_n', 'spisdcard_cs_n' )
175 , (IoPin
.SOUTH
, None, 'spisdcard_mosi', 'spisdcard_mosi', 'spisdcard_mosi' )
176 , (IoPin
.SOUTH
, None, 'spisdcard_miso', 'spisdcard_miso', 'spisdcard_miso' )
178 ioPadsSpec
+= doIoPinVector( (IoPin
.SOUTH
, None, 'nc_{}', 'nc({})', 'nc({})'), range(22,23) )
179 ioPadsSpec
+= [ (IoPin
.SOUTH
, None, 'uart_tx', 'uart_tx', 'uart_tx' )
180 , (IoPin
.SOUTH
, None, 'uart_rx', 'uart_rx', 'uart_rx' )
182 ioPadsSpec
+= doIoPinVector( (IoPin
.SOUTH
, None, 'gpio_{}', 'gpio({})', 'gpio_i({})', 'gpio_oe({})', 'gpio_o({})'), range(0,8) )
183 ioPadsSpec
+= [ (IoPin
.SOUTH
, None, 'sys_clk', 'sys_clk', 'sys_clk' )
184 , (IoPin
.SOUTH
, None, 'sys_rst', 'sys_rst', 'sys_rst' )
186 ioPadsSpec
+= doIoPinVector( (IoPin
.SOUTH
, None, 'nc_{}', 'nc({})', 'nc({})'), range(23,24) )
187 ioPadsSpec
+= [ (IoPin
.SOUTH
, None, 'sys_pll_18_o' , 'sys_pll_18_o' , 'sys_pll_18_o' ) ]
188 ioPadsSpec
+= doIoPinVector( (IoPin
.SOUTH
, None, 'sys_clksel_i{}', 'sys_clksel_i({})', 'sys_clksel_i({})'), 2 )
189 ioPadsSpec
+= [ (IoPin
.SOUTH
, None, 'sys_pll_lck_o' , 'sys_pll_lck_o' , 'sys_pll_lck_o' ) ]
190 ioPadsSpec
+= doIoPowerCap( IoPin
.SOUTH|IoPin
.A_END
)
192 cell
, editor
= plugins
.kwParseMain( **kw
)
193 cell
= af
.getCell( 'ls180', CRL
.Catalog
.State
.Logical
)
195 print( ErrorMessage( 2, 'doDesign.scriptMain(): Unable to load cell "{}".' \
198 if editor
: editor
.setCell( cell
)
199 #ls180Conf = ChipConf( cell, ioPads=ioSpecs.ioPadsSpec )
200 ls180Conf
= ChipConf( cell
, ioPads
=ioPadsSpec
)
201 ls180Conf
.cfg
.etesian
.bloat
= 'nsxlib'
202 ls180Conf
.cfg
.etesian
.uniformDensity
= True
203 ls180Conf
.cfg
.etesian
.aspectRatio
= 1.0
204 ls180Conf
.cfg
.etesian
.spaceMargin
= 0.05
205 ls180Conf
.cfg
.anabatic
.searchHalo
= 2
206 ls180Conf
.cfg
.anabatic
.globalIterations
= 20
207 ls180Conf
.cfg
.anabatic
.topRoutingLayer
= 'METAL5'
208 ls180Conf
.cfg
.katana
.hTracksReservedLocal
= 6
209 ls180Conf
.cfg
.katana
.vTracksReservedLocal
= 3
210 ls180Conf
.cfg
.katana
.hTracksReservedMin
= 3
211 ls180Conf
.cfg
.katana
.vTracksReservedMin
= 1
212 ls180Conf
.cfg
.block
.spareSide
= u(100)
213 ls180Conf
.cfg
.chip
.supplyRailWidth
= u(35)
214 ls180Conf
.cfg
.chip
.supplyRailPitch
= u(90)
215 ls180Conf
.editor
= editor
216 ls180Conf
.useSpares
= True
217 ls180Conf
.useClockTree
= True
218 ls180Conf
.useHFNS
= False
219 ls180Conf
.bColumns
= 2
221 ls180Conf
.chipConf
.name
= 'chip'
222 ls180Conf
.chipConf
.ioPadGauge
= 'LibreSOCIO'
223 ls180Conf
.coreSize
= (coreSize
, coreSize
)
224 ls180Conf
.chipSize
= (coreSize
+ chipBorder
, coreSize
+ chipBorder
)
226 with
UpdateSession():
227 sliceHeight
= ls180Conf
.sliceHeight
228 coreAb
= Box( 0, 0, coreSize
, coreSize
)
229 rsetAbutmentBox( cell
, coreAb
)
231 ls180ToChip
= CoreToChip( ls180Conf
)
232 ls180ToChip
.buildChip()
233 chipBuilder
= Chip( ls180Conf
)
234 chipBuilder
.doChipFloorplan()
236 with
UpdateSession():
237 tiPath
= 'subckt_38695_test_issuer.subckt_1_ti.'
238 sramPaths
= [ tiPath
+'subckt_3695_sram4k_0.subckt_144_SPBlock_512W64B8W'
239 , tiPath
+'subckt_3696_sram4k_1.subckt_144_SPBlock_512W64B8W'
240 , tiPath
+'subckt_3697_sram4k_2.subckt_144_SPBlock_512W64B8W'
241 , tiPath
+'subckt_3698_sram4k_3.subckt_144_SPBlock_512W64B8W'
243 sram
= DataBase
.getDB().getCell( 'SPBlock_512W64B8W' )
245 raise ErrorMessage( 1, 'SRAM instance "{}" not found.'.format(sramPaths
[i
]) )
246 sramAb
= sram
.getAbutmentBox()
247 coreAb
= cell
.getAbutmentBox()
248 sliceHeight
= chipBuilder
.conf
.sliceHeight
250 sram
= rgetInstance( cell
, sramPaths
[i
] )
251 chipBuilder
.placeMacro \
253 , Transformation( coreAb
.getXMin() + (sramAb
.getWidth () + 2*sliceHeight
)*i
254 , coreAb
.getYMax() - sramAb
.getHeight() - 2*sliceHeight
255 , Transformation
.Orientation
.ID
)
257 ls180Conf
.placeArea
= Box( coreAb
.getXMin()
260 , coreAb
.getYMax() - sramAb
.getHeight() - 2*sliceHeight
262 Breakpoint
.stop( 99, 'After core placement.' )
264 rvalue
= chipBuilder
.doPnR()
266 CRL
.Gds
.save( ls180Conf
.chip
)