1 |
44 |
wzab |
# Script prepared by Wojciech M. Zabolotny (wzab<at>ise.pw.edu.pl) to
|
2 |
|
|
# create a Vivado project from the hierarchical list of files
|
3 |
|
|
# (extended project files).
|
4 |
|
|
# This file is published as PUBLIC DOMAIN
|
5 |
|
|
#
|
6 |
|
|
# Set the reference directory for source file relative paths (by default the value is script directory path)
|
7 |
|
|
set origin_dir "."
|
8 |
|
|
|
9 |
|
|
# Check the Vivado version
|
10 |
|
|
set viv_version [ version -short ]
|
11 |
|
|
set ver_cmp_res [ string compare $viv_version $eprj_vivado_version ]
|
12 |
|
|
if { $eprj_vivado_version_allow_upgrade } {
|
13 |
|
|
if [ expr $ver_cmp_res < 0 ] {
|
14 |
|
|
error "Wrong Vivado version. Expected: $eprj_vivado_version or higher, found $viv_version"
|
15 |
|
|
}
|
16 |
|
|
} else {
|
17 |
|
|
if [ expr $ver_cmp_res != 0 ] {
|
18 |
|
|
error "Wrong Vivado version. Expected: $eprj_vivado_version , found $viv_version"
|
19 |
|
|
}
|
20 |
|
|
}
|
21 |
|
|
# Create project
|
22 |
|
|
create_project $eprj_proj_name ./$eprj_proj_name
|
23 |
|
|
|
24 |
|
|
# Set the directory path for the new project
|
25 |
|
|
set proj_dir [get_property directory [current_project]]
|
26 |
|
|
|
27 |
|
|
# Set project properties
|
28 |
|
|
set obj [get_projects $eprj_proj_name]
|
29 |
|
|
set_property "board_part" $eprj_board_part $obj
|
30 |
|
|
set_property "part" $eprj_part $obj
|
31 |
|
|
set_property "default_lib" $eprj_default_lib $obj
|
32 |
|
|
set_property "simulator_language" $eprj_simulator_language $obj
|
33 |
|
|
set_property "target_language" $eprj_target_language $obj
|
34 |
|
|
|
35 |
|
|
# Create the global variable which will keep the list of the OOC synthesis runs
|
36 |
|
|
global vextproj_ooc_synth_runs
|
37 |
|
|
set vextproj_ooc_synth_runs [list ]
|
38 |
|
|
|
39 |
|
|
# The procedure below changes the library "work" to "xil_defaultlib"
|
40 |
|
|
# to avoid problems with simulation in Vivado
|
41 |
|
|
# (see https://forums.xilinx.com/t5/Simulation-and-Verification/ERROR-XSIM-43-3225-Cannot-find-design-unit-xil-defaultlib-glbl/m-p/703641 )
|
42 |
|
|
proc fix_library { lib } {
|
43 |
|
|
global eprj_default_lib
|
44 |
|
|
if [ string match $eprj_default_lib "xil_defaultlib"] {
|
45 |
|
|
if [ string match "work" $lib ] {
|
46 |
|
|
set lib "xil_defaultlib"
|
47 |
|
|
}
|
48 |
|
|
}
|
49 |
|
|
return $lib
|
50 |
|
|
}
|
51 |
|
|
|
52 |
|
|
# The project reading procedure operates on objects storing the files
|
53 |
|
|
proc eprj_create_block {ablock mode setname } {
|
54 |
|
|
upvar $ablock block
|
55 |
|
|
#Set the last file_obj initially to "none"
|
56 |
|
|
set block(last_file_obj) "error"
|
57 |
|
|
#Set the mode of the block
|
58 |
|
|
#may be either IC - in context or OOC - out of context
|
59 |
|
|
set block(mode) $mode
|
60 |
|
|
if [string match -nocase $mode "IC"] {
|
61 |
|
|
# Create 'sources_1' fileset (if not found)
|
62 |
|
|
if {[string equal [get_filesets -quiet sources_1] ""]} {
|
63 |
|
|
create_fileset -srcset sources_1
|
64 |
|
|
}
|
65 |
|
|
set block(srcset) [get_filesets sources_1]
|
66 |
|
|
# Create 'constrs_1' fileset (if not found)
|
67 |
|
|
if {[string equal [get_filesets -quiet constrs_1] ""]} {
|
68 |
|
|
create_fileset -constrset constrs_1
|
69 |
|
|
}
|
70 |
|
|
set block(cnstrset) [get_filesets constrs_1]
|
71 |
|
|
} elseif [string match -nocase $mode "OOC"] {
|
72 |
|
|
# We create only a single blkset
|
73 |
|
|
# Create 'setname' fileset (if not found)
|
74 |
|
|
if {[string equal [get_filesets -quiet $setname] ""]} {
|
75 |
|
|
create_fileset -blockset $setname
|
76 |
|
|
}
|
77 |
|
|
# Both constraints and XDC should be added to the same set
|
78 |
|
|
set block(srcset) [get_filesets $setname]
|
79 |
|
|
set block(cnstrset) [get_filesets $setname]
|
80 |
|
|
} else {
|
81 |
|
|
eprj_error block "The block mode must be either IC - in context, or OOC - out of context. The $mode value is unacceptable"
|
82 |
|
|
}
|
83 |
|
|
}
|
84 |
|
|
|
85 |
|
|
#Add file to the sources fileset
|
86 |
|
|
proc add_file_sources {ablock args pdir fname} {
|
87 |
|
|
upvar $ablock block
|
88 |
|
|
set nfile [file normalize "$pdir/$fname"]
|
89 |
|
|
if {! [file exists $nfile]} {
|
90 |
|
|
eprj_error block "Requested file $nfile is not available!"
|
91 |
|
|
}
|
92 |
|
|
add_files -norecurse -fileset $block(srcset) $nfile
|
93 |
|
|
set file_obj [get_files -of_objects $block(srcset) $nfile]
|
94 |
|
|
set block(last_file_obj) $file_obj
|
95 |
|
|
#Check if the arguments contain "sim" and set the "simulation" properties if necessary
|
96 |
|
|
if [expr [lsearch $args "sim"] >= 0] {
|
97 |
|
|
set_property "used_in" "simulation" $file_obj
|
98 |
|
|
set_property "used_in_synthesis" "0" $file_obj
|
99 |
|
|
}
|
100 |
|
|
return $file_obj
|
101 |
|
|
}
|
102 |
|
|
|
103 |
|
|
proc handle_xci {ablock args pdir line} {
|
104 |
|
|
upvar $ablock block
|
105 |
|
|
#Handle XCI file
|
106 |
|
|
lassign $line lib fname
|
107 |
|
|
set file_obj [add_file_sources block $args $pdir $fname]
|
108 |
|
|
#set_property "synth_checkpoint_mode" "Singular" $file_obj
|
109 |
|
|
set_property "library" [ fix_library $lib ] $file_obj
|
110 |
|
|
}
|
111 |
|
|
|
112 |
|
|
proc handle_xcix {ablock args pdir line} {
|
113 |
|
|
upvar $ablock block
|
114 |
|
|
#Handle XCIX file
|
115 |
|
|
lassign $line lib fname
|
116 |
|
|
set file_obj [add_file_sources block $args $pdir $fname]
|
117 |
|
|
#set_property "synth_checkpoint_mode" "Singular" $file_obj
|
118 |
|
|
set_property "library" [ fix_library $lib ] $file_obj
|
119 |
|
|
export_ip_user_files -of_objects $file_obj -force -quiet
|
120 |
|
|
}
|
121 |
|
|
|
122 |
|
|
proc handle_vhdl {ablock args pdir line} {
|
123 |
|
|
upvar $ablock block
|
124 |
|
|
#Handle VHDL file
|
125 |
|
|
lassign $line lib fname
|
126 |
|
|
set file_obj [add_file_sources block $args $pdir $fname]
|
127 |
|
|
set_property "file_type" "VHDL" $file_obj
|
128 |
|
|
set_property "library" [ fix_library $lib ] $file_obj
|
129 |
|
|
}
|
130 |
|
|
|
131 |
|
|
proc handle_verilog {ablock args pdir line} {
|
132 |
|
|
upvar $ablock block
|
133 |
|
|
#Handle Verilog file
|
134 |
|
|
lassign $line fname
|
135 |
|
|
set file_obj [add_file_sources block $args $pdir $fname]
|
136 |
|
|
set_property "file_type" "Verilog" $file_obj
|
137 |
|
|
}
|
138 |
|
|
|
139 |
|
|
proc handle_sys_verilog {ablock args pdir line} {
|
140 |
|
|
upvar $ablock block
|
141 |
|
|
#Handle SystemVerilog file
|
142 |
|
|
lassign $line fname
|
143 |
|
|
set file_obj [add_file_sources block $args $pdir $fname]
|
144 |
|
|
set_property "file_type" "SystemVerilog" $file_obj
|
145 |
|
|
}
|
146 |
|
|
|
147 |
|
|
proc handle_verilog_header {ablock args pdir line} {
|
148 |
|
|
upvar $ablock block
|
149 |
|
|
#Handle SystemVerilog file
|
150 |
|
|
lassign $line fname
|
151 |
|
|
set file_obj [add_file_sources block $args $pdir $fname]
|
152 |
|
|
set_property "file_type" "Verilog Header" $file_obj
|
153 |
|
|
}
|
154 |
|
|
|
155 |
|
|
proc handle_global_verilog_header {ablock args pdir line} {
|
156 |
|
|
upvar $ablock block
|
157 |
|
|
#Handle Global Verilog Header file
|
158 |
|
|
lassign $line fname
|
159 |
|
|
set file_obj [add_file_sources block $args $pdir $fname]
|
160 |
|
|
set_property "file_type" "Verilog Header" $file_obj
|
161 |
|
|
set_property is_global_include true $file_obj
|
162 |
|
|
}
|
163 |
|
|
|
164 |
|
|
proc handle_bd {ablock args pdir line} {
|
165 |
|
|
upvar $ablock block
|
166 |
|
|
#Handle BD file
|
167 |
|
|
lassign $line fname
|
168 |
|
|
set file_obj [add_file_sources block $args $pdir $fname]
|
169 |
|
|
if { ![get_property "is_locked" $file_obj] } {
|
170 |
|
|
set_property "generate_synth_checkpoint" "0" $file_obj
|
171 |
|
|
}
|
172 |
|
|
}
|
173 |
|
|
|
174 |
|
|
proc handle_mif {ablock args pdir line} {
|
175 |
|
|
upvar $ablock block
|
176 |
|
|
#Handle MIF file
|
177 |
|
|
lassign $line lib fname
|
178 |
|
|
set file_obj [add_file_sources block $args $pdir $fname]
|
179 |
|
|
set_property "file_type" "Memory Initialization Files" $file_obj
|
180 |
|
|
set_property "library" [ fix_library $lib ] $file_obj
|
181 |
|
|
#set_property "synth_checkpoint_mode" "Singular" $file_obj
|
182 |
|
|
}
|
183 |
|
|
|
184 |
|
|
proc handle_xdc {ablock args pdir line} {
|
185 |
|
|
upvar $ablock block
|
186 |
|
|
#Handle XDC file
|
187 |
|
|
lassign $line fname
|
188 |
|
|
set nfile [file normalize "$pdir/$fname"]
|
189 |
|
|
if {![file exists $nfile]} {
|
190 |
|
|
eprj_error block "Requested file $nfile is not available!"
|
191 |
|
|
}
|
192 |
|
|
add_files -norecurse -fileset $block(cnstrset) $nfile
|
193 |
|
|
set file_obj [get_files -of_objects $block(cnstrset) $nfile]
|
194 |
|
|
set_property "file_type" "XDC" $file_obj
|
195 |
|
|
}
|
196 |
|
|
|
197 |
|
|
proc handle_xdc_ooc {ablock args pdir line} {
|
198 |
|
|
upvar $ablock block
|
199 |
|
|
#Handle XDC_OOC file
|
200 |
|
|
lassign $line fname
|
201 |
|
|
set nfile [file normalize "$pdir/$fname"]
|
202 |
|
|
if {![file exists $nfile]} {
|
203 |
|
|
eprj_error block "Requested file $nfile is not available!"
|
204 |
|
|
}
|
205 |
|
|
if {![string match -nocase $block(mode) "OOC"]} {
|
206 |
|
|
puts "Ignored file $nfile in IC mode"
|
207 |
|
|
#Clear "last file object" in the block array
|
208 |
|
|
set block(last_file_obj) "none"
|
209 |
|
|
} else {
|
210 |
|
|
add_files -norecurse -fileset $block(cnstrset) $nfile
|
211 |
|
|
set file_obj [get_files -of_objects $block(cnstrset) $nfile]
|
212 |
|
|
set_property "file_type" "XDC" $file_obj
|
213 |
|
|
set_property USED_IN {out_of_context synthesis implementation} $file_obj
|
214 |
|
|
}
|
215 |
|
|
}
|
216 |
|
|
|
217 |
|
|
proc handle_prop {ablock args pdir line} {
|
218 |
|
|
upvar $ablock block
|
219 |
|
|
if [string match $block(last_file_obj) "error"] {
|
220 |
|
|
eprj_error block "I don't know to which file apply the property $line"
|
221 |
|
|
} elseif [string match $block(last_file_obj) "none"] {
|
222 |
|
|
puts "Property ignored $line"
|
223 |
|
|
} else {
|
224 |
|
|
lassign $line property value
|
225 |
|
|
set_property $property $value $block(last_file_obj)
|
226 |
|
|
}
|
227 |
|
|
}
|
228 |
|
|
|
229 |
|
|
proc handle_propadd {ablock args pdir line} {
|
230 |
|
|
upvar $ablock block
|
231 |
|
|
if [string match $block(last_file_obj) "error"] {
|
232 |
|
|
eprj_error block "I don't know to which file apply the property $line"
|
233 |
|
|
} elseif [string match $block(last_file_obj) "none"] {
|
234 |
|
|
puts "Property ignored $line"
|
235 |
|
|
} else {
|
236 |
|
|
lassign $line property value
|
237 |
|
|
set old_val [ get_property $property $block(last_file_obj) ]
|
238 |
|
|
lappend old_val $value
|
239 |
|
|
set_property $property $old_val $block(last_file_obj)
|
240 |
|
|
}
|
241 |
|
|
}
|
242 |
|
|
|
243 |
|
|
proc handle_exec {ablock args pdir line} {
|
244 |
|
|
upvar $ablock block
|
245 |
|
|
#Handle EXEC line
|
246 |
|
|
lassign $line fname
|
247 |
|
|
set nfile [file normalize "$pdir/$fname"]
|
248 |
|
|
if {![file exists $nfile]} {
|
249 |
|
|
eprj_error block "Requested file $nfile is not available!"
|
250 |
|
|
}
|
251 |
|
|
#Execute the program in its directory
|
252 |
|
|
set old_dir [ pwd ]
|
253 |
|
|
cd $pdir
|
254 |
|
|
exec "./$fname"
|
255 |
|
|
cd $old_dir
|
256 |
|
|
}
|
257 |
|
|
|
258 |
|
|
# Handlers for VCS systems
|
259 |
|
|
proc handle_git_local {ablock args pdir line} {
|
260 |
|
|
upvar $ablock block
|
261 |
|
|
lassign $line clone_dir commit_or_tag_id exported_dir strip_num
|
262 |
|
|
set old_dir [ pwd ]
|
263 |
|
|
cd $pdir
|
264 |
|
|
file delete -force -- "ext_src"
|
265 |
|
|
file mkdir "ext_src"
|
266 |
|
|
#Prepare the git command
|
267 |
|
|
set strip_cmd ""
|
268 |
|
|
if { $strip_num ne ""} {
|
269 |
|
|
append strip_cmd " --strip-components=$strip_num"
|
270 |
|
|
}
|
271 |
|
|
set git_cmd "( cd $clone_dir ; git archive --format tar $commit_or_tag_id $exported_dir ) | ( cd ext_src ; tar -xf - $strip_cmd )"
|
272 |
|
|
exec bash -c "$git_cmd"
|
273 |
|
|
cd $old_dir
|
274 |
|
|
}
|
275 |
|
|
|
276 |
|
|
proc handle_git_remote {ablock args pdir line} {
|
277 |
|
|
upvar $ablock block
|
278 |
|
|
lassign $line repository_url tag_id exported_dir strip_num
|
279 |
|
|
set old_dir [ pwd ]
|
280 |
|
|
cd $pdir
|
281 |
|
|
file delete -force -- "ext_src"
|
282 |
|
|
file mkdir "ext_src"
|
283 |
|
|
#Prepare the git command
|
284 |
|
|
set strip_cmd ""
|
285 |
|
|
if { $strip_num ne ""} {
|
286 |
|
|
append strip_cmd " --strip-components=$strip_num"
|
287 |
|
|
}
|
288 |
|
|
set git_cmd "( git archive --format tar --remote $repository_url $tag_id $exported_dir ) | ( cd ext_src ; tar -xf - $strip_cmd )"
|
289 |
|
|
exec bash -c "$git_cmd"
|
290 |
|
|
cd $old_dir
|
291 |
|
|
}
|
292 |
|
|
|
293 |
|
|
proc handle_svn {ablock args pdir line} {
|
294 |
|
|
upvar $ablock block
|
295 |
|
|
lassign $line repository_with_path revision
|
296 |
|
|
set old_dir [ pwd ]
|
297 |
|
|
cd $pdir
|
298 |
|
|
file delete -force -- "ext_src"
|
299 |
|
|
file mkdir "ext_src"
|
300 |
|
|
#Prepare the SVN command
|
301 |
|
|
set rev_cmd ""
|
302 |
|
|
if { $revision ne ""} {
|
303 |
|
|
append rev_cmd " -r $revision"
|
304 |
|
|
}
|
305 |
|
|
set svn_cmd "( cd ext_src ; svn export $rev_cmd $repository_with_path )"
|
306 |
|
|
exec bash -c "$svn_cmd"
|
307 |
|
|
cd $old_dir
|
308 |
|
|
}
|
309 |
|
|
|
310 |
|
|
#Procedure exctracting the args from the text: "type[arg1,arg2,arg3]"
|
311 |
|
|
#Returns the two-element list {type args}, where args is the list" {arg1 arg2 arg3}
|
312 |
|
|
proc type_parse_args { type_args } {
|
313 |
|
|
regexp {([^\[]*)(\[(.*)\])*} $type_args whole_type type arg_part arg_list
|
314 |
|
|
if [string match arg_list ""] {
|
315 |
|
|
set args {}
|
316 |
|
|
} else {
|
317 |
|
|
set args [split $arg_list ","]
|
318 |
|
|
}
|
319 |
|
|
return [list $type $args]
|
320 |
|
|
}
|
321 |
|
|
|
322 |
|
|
|
323 |
|
|
# Array with line handlers, used by the line handling procedure
|
324 |
|
|
array set line_handlers {
|
325 |
|
|
xci handle_xci
|
326 |
|
|
xcix handle_xcix
|
327 |
|
|
header handle_verilog_header
|
328 |
|
|
global_header handle_global_verilog_header
|
329 |
|
|
sys_verilog handle_sys_verilog
|
330 |
|
|
verilog handle_verilog
|
331 |
|
|
mif handle_mif
|
332 |
|
|
bd handle_bd
|
333 |
|
|
vhdl handle_vhdl
|
334 |
|
|
|
335 |
|
|
prop handle_prop
|
336 |
|
|
propadd handle_propadd
|
337 |
|
|
ooc handle_ooc
|
338 |
|
|
xdc handle_xdc
|
339 |
|
|
xdc_ooc handle_xdc_ooc
|
340 |
|
|
exec handle_exec
|
341 |
|
|
git_local handle_git_local
|
342 |
|
|
git_remote handle_git_remote
|
343 |
|
|
svn handle_svn
|
344 |
|
|
}
|
345 |
|
|
|
346 |
|
|
#Line handling procedure
|
347 |
|
|
proc handle_line { ablock pdir line } {
|
348 |
|
|
upvar $ablock block
|
349 |
|
|
global line_handlers
|
350 |
|
|
set rest [lassign $line type_args]
|
351 |
|
|
#First we attempt to separate possible arguments from type
|
352 |
|
|
lassign [type_parse_args $type_args] type args
|
353 |
|
|
#Find the procedure to be called depending on the type of the line
|
354 |
|
|
set ptc [lindex [array get line_handlers [string tolower $type]] 1]
|
355 |
|
|
if [ string equal $ptc "" ] {
|
356 |
|
|
eprj_error block "Unknown line of type: $type"
|
357 |
|
|
} else {
|
358 |
|
|
$ptc block $args $pdir $rest
|
359 |
|
|
}
|
360 |
|
|
}
|
361 |
|
|
|
362 |
|
|
proc handle_ooc { ablock args pdir line } {
|
363 |
|
|
global eprj_impl_strategy
|
364 |
|
|
global eprj_impl_flow
|
365 |
|
|
global eprj_synth_strategy
|
366 |
|
|
global eprj_synth_flow
|
367 |
|
|
global eprj_flow
|
368 |
|
|
global eprj_part
|
369 |
|
|
global vextproj_ooc_synth_runs
|
370 |
|
|
|
371 |
|
|
upvar $ablock block
|
372 |
|
|
#The OOC blocks can't be nested
|
373 |
|
|
#detect the attempt to nest the block and return an error
|
374 |
|
|
if {[string match -nocase $block(mode) "OOC"]} {
|
375 |
|
|
eprj_error block "The OOC blocks can't be nested: $line"
|
376 |
|
|
}
|
377 |
|
|
lassign $line stub fname blksetname
|
378 |
|
|
#Create the new block of type OOC and continue parsing in it
|
379 |
|
|
array set ooc_block {}
|
380 |
|
|
eprj_create_block ooc_block "OOC" $blksetname
|
381 |
|
|
if {[string match -nocase $stub "noauto"]} {
|
382 |
|
|
set_property "use_blackbox_stub" "0" [get_filesets $blksetname]
|
383 |
|
|
} elseif {![string match -nocase $stub "auto"]} {
|
384 |
|
|
eprj_error block "OOC stub creation mode must be either 'auto' or 'noauto' not: $stub"
|
385 |
|
|
}
|
386 |
|
|
read_prj ooc_block $pdir/$fname
|
387 |
|
|
set_property TOP $blksetname [get_filesets $blksetname]
|
388 |
|
|
update_compile_order -fileset $blksetname
|
389 |
|
|
#Create synthesis run for the blockset (if not found)
|
390 |
|
|
set ooc_synth_run_name ${blksetname}_synth_1
|
391 |
|
|
if {[string equal [get_runs -quiet ${ooc_synth_run_name}] ""]} {
|
392 |
|
|
create_run -name ${ooc_synth_run_name} -part $eprj_part -flow {$eprj_flow} -strategy $eprj_synth_strategy -constrset $blksetname
|
393 |
|
|
} else {
|
394 |
|
|
set_property strategy $eprj_synth_strategy [get_runs ${ooc_synth_run_name}]
|
395 |
|
|
set_property flow $eprj_synth_flow [get_runs ${ooc_synth_run_name}]
|
396 |
|
|
}
|
397 |
|
|
lappend vextproj_ooc_synth_runs ${ooc_synth_run_name}
|
398 |
|
|
set_property constrset $blksetname [get_runs ${ooc_synth_run_name}]
|
399 |
|
|
set_property part $eprj_part [get_runs ${ooc_synth_run_name}]
|
400 |
|
|
# Create implementation run for the blockset (if not found)
|
401 |
|
|
set ooc_impl_run_name ${blksetname}_impl_1
|
402 |
|
|
if {[string equal [get_runs -quiet ${ooc_impl_run_name}] ""]} {
|
403 |
|
|
create_run -name impl_1 -part $eprj_part -flow {$eprj_flow} -strategy $eprj_impl_strategy -constrset $blksetname -parent_run ${ooc_synth_run_name}
|
404 |
|
|
} else {
|
405 |
|
|
set_property strategy $eprj_impl_strategy [get_runs ${ooc_impl_run_name}]
|
406 |
|
|
set_property flow $eprj_impl_flow [get_runs ${ooc_impl_run_name}]
|
407 |
|
|
}
|
408 |
|
|
set_property constrset $blksetname [get_runs ${ooc_impl_run_name}]
|
409 |
|
|
set_property part $eprj_part [get_runs ${ooc_impl_run_name}]
|
410 |
|
|
set_property include_in_archive "0" [get_runs ${ooc_impl_run_name}]
|
411 |
|
|
}
|
412 |
|
|
|
413 |
|
|
# Prepare the main block
|
414 |
|
|
array set main_block {}
|
415 |
|
|
eprj_create_block main_block "IC" ""
|
416 |
|
|
|
417 |
|
|
# Procedure reporting the errors
|
418 |
|
|
proc eprj_error { ablock message } {
|
419 |
|
|
upvar $ablock block
|
420 |
|
|
puts "ERROR in file: $block(file_name), line: $block(line_count)"
|
421 |
|
|
error $message
|
422 |
|
|
}
|
423 |
|
|
|
424 |
|
|
# Procedure below reads the source files from PRJ files, extended with
|
425 |
|
|
# the "include file" statement
|
426 |
|
|
#Important thing - path to the source files should be given relatively
|
427 |
|
|
#to the location of the PRJ file.
|
428 |
|
|
proc read_prj { ablock prj } {
|
429 |
|
|
upvar $ablock block
|
430 |
|
|
#parray block
|
431 |
|
|
#Clear information about the "last file_obj" to avoid wrong assignment of properties
|
432 |
|
|
set block(last_file_obj) "error"
|
433 |
|
|
#allow to use just the directory names. In this case add
|
434 |
|
|
#the "/main.eprj" to it
|
435 |
|
|
if {[file isdirectory $prj]} {
|
436 |
|
|
append prj "/main.eprj"
|
437 |
|
|
puts "Added default main.eprj to the directory name: $prj"
|
438 |
|
|
}
|
439 |
|
|
if {[file exists $prj]} {
|
440 |
|
|
puts "\tReading PRJ file: $prj"
|
441 |
|
|
set source [open $prj r]
|
442 |
|
|
set source_data [read $source]
|
443 |
|
|
close $source
|
444 |
|
|
#Extract the directory of the PRJ file, as all paths to the
|
445 |
|
|
#source files must be given relatively to that directory
|
446 |
|
|
set prj_dir [ file dirname $prj ]
|
447 |
|
|
regsub -all {\"} $source_data {} source_data
|
448 |
|
|
set prj_lines [split $source_data "\n" ]
|
449 |
|
|
#Set line counter and file name for error reporting function
|
450 |
|
|
set block(line_count) 0
|
451 |
|
|
set block(file_name) $prj
|
452 |
|
|
foreach line $prj_lines {
|
453 |
|
|
incr block(line_count)
|
454 |
|
|
#Ignore empty and commented lines
|
455 |
|
|
if {[llength $line] > 0 && ![string match -nocase "#*" $line]} {
|
456 |
|
|
#Detect the inlude line and ooc line
|
457 |
|
|
lassign $line type fname
|
458 |
|
|
if {[string match -nocase $type "include"]} {
|
459 |
|
|
puts "\tIncluding PRJ file: $prj_dir/$fname"
|
460 |
|
|
read_prj block $prj_dir/$fname
|
461 |
|
|
# Clear information about the last file_obj to avoid wrong assignment of properties
|
462 |
|
|
set block(last_file_obj) "error"
|
463 |
|
|
} else {
|
464 |
|
|
handle_line block $prj_dir $line
|
465 |
|
|
}
|
466 |
|
|
}
|
467 |
|
|
}
|
468 |
|
|
} else {
|
469 |
|
|
eprj_error block "Requested file $prj is not available!"
|
470 |
|
|
}
|
471 |
|
|
}
|
472 |
|
|
|
473 |
|
|
|
474 |
|
|
# Read project definitions
|
475 |
|
|
set main_block(file_name) ""
|
476 |
|
|
set main_block(line_count) 0
|
477 |
|
|
read_prj main_block $eprj_def_root
|
478 |
|
|
|
479 |
|
|
set_property "top" $eprj_top_entity $main_block(srcset)
|
480 |
|
|
update_compile_order -fileset sources_1
|
481 |
|
|
# Create 'synth_1' run (if not found)
|
482 |
|
|
if {[string equal [get_runs -quiet synth_1] ""]} {
|
483 |
|
|
create_run -name synth_1 -part $eprj_part -flow {$eprj_flow} -strategy $eprj_synth_strategy -constrset constrs_1
|
484 |
|
|
} else {
|
485 |
|
|
set_property strategy $eprj_synth_strategy [get_runs synth_1]
|
486 |
|
|
set_property flow $eprj_synth_flow [get_runs synth_1]
|
487 |
|
|
}
|
488 |
|
|
set obj [get_runs synth_1]
|
489 |
|
|
|
490 |
|
|
# set the current synth run
|
491 |
|
|
current_run -synthesis [get_runs synth_1]
|
492 |
|
|
|
493 |
|
|
# Create 'impl_1' run (if not found)
|
494 |
|
|
if {[string equal [get_runs -quiet impl_1] ""]} {
|
495 |
|
|
create_run -name impl_1 -part $eprj_part -flow {$eprj_flow} -strategy $eprj_impl_strategy -constrset constrs_1 -parent_run synth_1
|
496 |
|
|
} else {
|
497 |
|
|
set_property strategy $eprj_impl_strategy [get_runs impl_1]
|
498 |
|
|
set_property flow $eprj_impl_flow [get_runs impl_1]
|
499 |
|
|
}
|
500 |
|
|
set obj [get_runs impl_1]
|
501 |
|
|
|
502 |
|
|
# set the current impl run
|
503 |
|
|
current_run -implementation [get_runs impl_1]
|
504 |
|
|
|
505 |
|
|
# Write the list of the OOC synthesis runs to the file
|
506 |
|
|
set file_ooc_runs [open "ooc_synth_runs.txt" "w"]
|
507 |
|
|
puts $file_ooc_runs $vextproj_ooc_synth_runs
|
508 |
|
|
close $file_ooc_runs
|
509 |
|
|
|
510 |
|
|
puts "INFO: Project created:$eprj_proj_name"
|
511 |
|
|
|
512 |
|
|
# Create the Tcl file with the initial state of the project
|
513 |
|
|
# In theory it should be enough to write it now:
|
514 |
|
|
# write_project_tcl -force -no_copy_sources {initial_state.tcl}
|
515 |
|
|
# But unfortunately it will differ significantly from the Tcl file created after opening of the saved
|
516 |
|
|
# XPR file.
|
517 |
|
|
# Therefore we delegate it to the another script...
|
518 |
|
|
|
519 |
|
|
#launch_runs synth_1
|
520 |
|
|
#wait_on_run synth_1
|
521 |
|
|
#launch_runs impl_1
|
522 |
|
|
#wait_on_run impl_1
|
523 |
|
|
#launch_runs impl_1 -to_step write_bitstream
|
524 |
|
|
#wait_on_run impl_1
|
525 |
|
|
|