waf

FORK: waf with some random patches
git clone https://git.neptards.moe/neptards/waf.git
Log | Files | Refs | README

wscript (6407B)


      1 #!/usr/bin/env python
      2 # encoding: utf-8
      3 # waf example, builds a Xilinx FPGA bitstream
      4 
      5 __copyright__  = '(c) Jérôme Carretero <cJ-waf@zougloub.eu> 2012'
      6 
      7 """
      8 This script builds an FPGA bitstream in an automated fashion.
      9 The Xilinx ISE IDE does the same thing, but needs mouse interaction.
     10 
     11 Notes:
     12 
     13 - this is quite sad, but the Xilinx toolchain tools want to operate
     14   in the source folder, so top==out
     15 
     16 - Xilinx toolchain tools generate file with timestamps,
     17   so an unsignificant change can still trigger domino cascade
     18   of compilations.
     19 
     20 - a "xilinx" wrapper is used; this file performs set up of the
     21   PATH for Xilinx tools (not done yet by the wscript)
     22 
     23 TODO:
     24 
     25 - make a tool
     26 - remove hard-coded .xst / .ut data (ISE generates that from the .xise)
     27 - CPLD toolchain (only works for FPGA)
     28 
     29 """
     30 
     31 top = out = "." # mandatory
     32 
     33 import os
     34 import shutil
     35 import waflib
     36 from lxml import etree
     37 
     38 def options(opt):
     39 	pass
     40 
     41 def configure(cfg):
     42 	pass
     43 
     44 def build(bld):
     45 
     46 	if not os.path.exists("xst/projnav.tmp"):
     47 		os.makedirs("xst/projnav.tmp")
     48 	
     49 	nsmap={"pn": "http://www.xilinx.com/XMLSchema"}
     50 
     51 	xise = "waf_demo.xise"
     52 	fn = "waf_demo"
     53 	xml = etree.parse(xise)
     54 
     55 	def get(txt):
     56 		try: return xml.xpath('//pn:property[@pn:name = "%s"]/@pn:value' % txt, namespaces=nsmap)[0]
     57 		except: pass
     58 
     59 	device = get("Device") # or "xc3s1500"
     60 	package = get("Package") # or "fg456"
     61 	speed = get("Speed Grade") # or "-4"
     62 
     63 	# Set .prj file contents and collect HDL sources
     64 	hdl = []
     65 	prj = []
     66 	for x in xml.xpath('//pn:files/pn:file[@pn:type = "FILE_VHDL"]/@pn:name', namespaces=nsmap):
     67 		prj.append('vhdl work "%s"' % x)
     68 		hdl.append(x)
     69 	for x in xml.xpath('//pn:files/pn:file[@pn:type = "FILE_VERILOG"]/@pn:name', namespaces=nsmap):
     70 		prj.append('verilog work "%s"' % x)
     71 		hdl.append(x)
     72 	
     73 	ucf = xml.xpath('//pn:files/pn:file[@pn:type = "FILE_UCF"]/@pn:name', namespaces=nsmap)[0] or "src/pci_7seg.ucf"
     74 
     75 	def make_prj(self):
     76 		self.outputs[0].write("\n".join(prj))
     77 	
     78 	def make_xst(self):
     79 		self.outputs[0].write("""
     80 set -tmpdir "xst/projnav.tmp"
     81 set -xsthdpdir "xst"
     82 run
     83 -ifn %(fn)s.prj
     84 -ifmt mixed
     85 -ofn %(fn)s
     86 -ofmt NGC
     87 -p %(device)s%(speed)s-%(package)s
     88 -top %(fn)s
     89 -opt_mode Speed
     90 -opt_level 1
     91 -iuc NO
     92 -keep_hierarchy No
     93 -netlist_hierarchy As_Optimized
     94 -rtlview Yes
     95 -glob_opt AllClockNets
     96 -read_cores YES
     97 -write_timing_constraints NO
     98 -cross_clock_analysis NO
     99 -hierarchy_separator /
    100 -bus_delimiter <>
    101 -case Maintain
    102 -slice_utilization_ratio 100
    103 -bram_utilization_ratio 100
    104 -verilog2001 YES
    105 -fsm_extract YES -fsm_encoding Auto
    106 -safe_implementation No
    107 -fsm_style LUT
    108 -ram_extract Yes
    109 -ram_style Auto
    110 -rom_extract Yes
    111 -mux_style Auto
    112 -decoder_extract YES
    113 -priority_extract Yes
    114 -shreg_extract YES
    115 -shift_extract YES
    116 -xor_collapse YES
    117 -rom_style Auto
    118 -auto_bram_packing NO
    119 -mux_extract Yes
    120 -resource_sharing YES
    121 -async_to_sync NO
    122 -mult_style Auto
    123 -iobuf YES
    124 -max_fanout 500
    125 -bufg 8
    126 -register_duplication YES
    127 -register_balancing No
    128 -slice_packing YES
    129 -optimize_primitives NO
    130 -use_clock_enable Yes
    131 -use_sync_set Yes
    132 -use_sync_reset Yes
    133 -iob Auto
    134 -equivalent_register_removal YES
    135 -slice_utilization_ratio_maxmargin 5
    136 """ % locals())
    137 
    138 
    139 
    140 	def make_ut(self):
    141 		self.outputs[0].write("""
    142 -w
    143 -g DebugBitstream:No
    144 -g Binary:no
    145 -g CRC:Enable
    146 -g ConfigRate:6
    147 -g CclkPin:PullUp
    148 -g M0Pin:PullUp
    149 -g M1Pin:PullUp
    150 -g M2Pin:PullUp
    151 -g ProgPin:PullUp
    152 -g DonePin:PullUp
    153 -g HswapenPin:PullUp
    154 -g TckPin:PullUp
    155 -g TdiPin:PullUp
    156 -g TdoPin:PullUp
    157 -g TmsPin:PullUp
    158 -g UnusedPin:PullDown
    159 -g UserID:0xFFFFFFFF
    160 -g DCMShutdown:Disable
    161 -g DCIUpdateMode:AsRequired
    162 -g StartUpClk:CClk
    163 -g DONE_cycle:4
    164 -g GTS_cycle:5
    165 -g GWE_cycle:6
    166 -g LCK_cycle:NoWait
    167 -g Match_cycle:Auto
    168 -g Security:None
    169 -g DonePipe:No
    170 -g DriveDone:No""")
    171 
    172 
    173 	bld(
    174 	 name='prj',
    175 	 target="%s.prj" % fn,
    176 	 rule=make_prj,
    177 	 source=[xise],
    178 	)
    179 
    180 	bld(
    181 	 name='xst',
    182 	 target='%s.xst' % fn,
    183 	 rule=make_xst,
    184 	 source=[xise],
    185 	)
    186 	bld(
    187 	 name='ut',
    188 	 target='%s.ut' % fn,
    189 	 rule=make_ut,
    190 	 source=[xise],
    191 	)
    192 
    193 	bld(
    194 	 name='synth',
    195 	 target=['%s%s' % (fn, ext) for ext in ('.syr', '.ngc', '.ngr', '.lso', '_xst.xrpt') ],
    196 	 rule='xilinx xst -intstyle ise -ifn ${SRC[0].abspath()} -ofn ${TGT[0].abspath()}; true',
    197 	 source=['%s.xst' % fn, '%s.prj' % fn] + hdl,
    198 	)
    199 
    200 	bld(
    201 	 name='ngdbuild',
    202 	 target=['%s%s' % (fn, ext) for ext in ('.ngd', '_ngdbuild.xrpt') ],
    203 	 rule='xilinx ngdbuild -intstyle ise -dd _ngo -nt timestamp -uc ${SRC[1].abspath()} -p %(device)s-%(package)s%(speed)s ${SRC[0].bldpath()} ${TGT[0].bldpath()}' % locals(),
    204 	 source=['%s.ngc' % fn, ucf],
    205 	)
    206 
    207 	bld(
    208 	 name='map',
    209 	 target=['%s%s' % (fn, ext) for ext in ('_map.ncd', '.pcf', '_map.map', '_map.mrp', '_map.ngm', '_map.xrpt', '.bld') ],
    210 	 rule='xilinx map -intstyle ise -p %(device)s-%(package)s%(speed)s -cm area -ir off -pr b -c 100 -o ${TGT[0].bldpath()} ${SRC[0].bldpath()} ${TGT[1].bldpath()}' % locals(),
    211 	 source=['%s.ngd' % fn],
    212 	)
    213 
    214 	bld(
    215 	 name='par',
    216 	 target=['%s%s' % (fn, ext) for ext in ('.ncd', '.pad', '.par', '.ptwx', '.unroutes', '.xpi', '_pad.csv', '_pad.txt', '_par.xrpt') ],
    217 	 rule='xilinx par -w -intstyle ise -ol high -t 1 ${SRC[0].bldpath()} ${TGT[0].bldpath()} ${SRC[1].bldpath()}',
    218 	 source=['%s_map.ncd' % fn, '%s.pcf' % fn],
    219 	)
    220 
    221 	bld(
    222 	 name='trce',
    223 	 target=['%s%s' % (fn, ext) for ext in ('.twx', '.twr') ],
    224 	 rule='xilinx trce -intstyle ise -e 3 -s 4 -n 3 -xml ${TGT[0].bldpath()} ${SRC[0].bldpath()} -o ${TGT[1].bldpath()} ${SRC[1].bldpath()}; true',
    225 	 source=['%s_map.ncd' % fn, '%s.pcf' % fn],
    226 	)
    227 
    228 	bld(
    229 	 name='bitgen',
    230 	 target=['%s%s' % (fn, ext) for ext in ('.bit', '.bgn', '.drc', '_bitgen.xwbt', '_summary.xml', '_usage.xml') ],
    231 	 rule='xilinx bitgen -intstyle ise -f ${SRC[1].bldpath()} ${SRC[0].bldpath()} ${TGT[0].bldpath()}',
    232 	 source=['%s.ncd' % fn, '%s.ut' % fn],
    233 	)
    234 
    235 	if bld.cmd == 'clean':
    236 		for tgen in bld.get_all_task_gen():
    237 			for tgt in waflib.Utils.to_list(tgen.target):
    238 				if os.path.exists(tgt):
    239 					os.remove(tgt)
    240 		for x in (
    241 		 'usage_statistics_webtalk.html',
    242 		 'webtalk_pn.xml',
    243 		 'webtalk.log',
    244 		 ):
    245 			if os.path.exists(x):
    246 				os.remove(x)
    247 
    248 		for x in (
    249 		 '_ngo',
    250 		 '_xmsgs',
    251 		 'iseconfig',
    252 		 'xlnx_auto_0_xdb',
    253 		 'xst',
    254 		 ):
    255 			try:
    256 				shutil.rmtree(x)
    257 			except:
    258 				pass
    259 
    260 def distclean(ctx):
    261 	import os, shutil
    262 	from waflib import Context
    263 
    264 	for fn in os.listdir('.'):
    265 		if fn.startswith(('.conf_check_', ".lock-w")) \
    266 		 or fn in (Context.DBFILE, 'config.log') \
    267 		 or fn == 'c4che':
    268 			if os.path.isdir(fn):
    269 				shutil.rmtree(fn)
    270 			else:
    271 				os.remove(fn)
    272 
    273