Hog v9.9.0
post-bitstream.tcl
Go to the documentation of this file.
1 #!/usr/bin/env tclsh
2 # Copyright 2018-2024 The University of Birmingham
3 #
4 # Licensed under the Apache License, Version 2.0 (the "License");
5 # you may not use this file except in compliance with the License.
6 # You may obtain a copy of the License at
7 #
8 # http://www.apache.org/licenses/LICENSE-2.0
9 #
10 # Unless required by applicable law or agreed to in writing, software
11 # distributed under the License is distributed on an "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
15 
16 # @file
17 # The post bitstream script copies binary files, reports and other files to the bin directory in your repository.
18 # This script is automatically integrated into the Vivado/Quartus workflow by the Create Project script.
19 
20 set old_path [pwd]
21 set tcl_path [file normalize "[file dirname [info script]]/.."]
22 source $tcl_path/hog.tcl
23 set repo_path [file normalize "$tcl_path/../../"]
24 
25 # Import tcllib
26 if {[IsLibero]} {
27  if {[info exists env(HOG_TCLLIB_PATH)]} {
28  lappend auto_path $env(HOG_TCLLIB_PATH)
29  } else {
30  puts "ERROR: To run Hog with Microsemi Libero SoC, you need to define the HOG_TCLLIB_PATH variable."
31  return
32  }
33 }
34 
35 if {[info exists env(HOG_EXTERNAL_PATH)]} {
36  set ext_path $env(HOG_EXTERNAL_PATH)
37  Msg Info "Found environment variable HOG_EXTERNAL_PATH, setting path for external files to $ext_path..."
38 } else {
39  set ext_path ""
40 }
41 
42 set bin_dir [file normalize "$repo_path/bin"]
43 
44 if {[IsXilinx]} {
45  # Binary files are called .bit for ISE and for Vivado unless the chip is a Versal
46  set fw_file_ext "bit"
47 
48  # Vivado + PlanAhead
49  if {[IsISE]} {
50  # planAhead
51  set work_path [get_property DIRECTORY [get_runs impl_1]]
52  } else {
53  # Vivado
54  set work_path $old_path
55  if {[IsVersal [get_property PART [current_design]]]} {
56  #In Vivado if a Versal chip is used, the main binary file is called .bif
57  set fw_file_ext "bif"
58  }
59  }
60 
61  set main_file [file normalize [lindex [glob -nocomplain "$work_path/*.$fw_file_ext"] 0]]
62  set proj_name [file tail [file normalize $work_path/../../]]
63  set proj_dir [file normalize "$work_path/../.."]
64 
65  set top_name [file rootname [file tail $main_file]]
66 
67  set additional_ext "bin ltx pdi"
68 
69  set xml_dir [file normalize "$work_path/../xml"]
70  set run_dir [file normalize "$work_path/.."]
71 
72 } elseif {[IsQuartus]} {
73  # Quartus
74  ##nagelfar ignore Unknown variable
75  set proj_name [lindex $quartus(args) 1]
76  set proj_dir [pwd]
77  set xml_dir [file normalize "$repo_path/xml"]
78  set run_dir [file normalize "$proj_dir"]
79  set name [file rootname [file tail [file normalize [pwd]]]]
80  # programming object file
81  set pof_file [file normalize "$proj_dir/output_files/$proj_name.pof"]
82  # SRAM Object File
83  set sof_file [file normalize "$proj_dir/output_files/$proj_name.sof"]
84  # raw binary file
85  set rbf_file [file normalize "$proj_dir/output_files/$proj_name.rbf"]
86  #raw programming file
87  set rpd_file [file normalize "$proj_dir/output_files/$proj_name.rpd"]
88  # signal tap file
89  set stp_file [file normalize "$proj_dir/output_files/$proj_name.stp"]
90  #source and probes file
91  set spf_file [file normalize "$proj_dir/output_files/$proj_name.spf"]
92 
93 } elseif {[IsLibero]} {
94  # Libero
95  ##nagelfar ignore Unknown variable
96  set proj_name $project
97  ##nagelfar ignore Unknown variable
98  set proj_dir $main_folder
99  set map_file [file normalize [lindex [glob -nocomplain "$proj_dir/synthesis/*.map"] 0]]
100  set sap_file [file normalize [lindex [glob -nocomplain "$proj_dir/synthesis/*.sap"] 0]]
101  set srd_file [file normalize [lindex [glob -nocomplain "$proj_dir/synthesis/*.srd"] 0]]
102  set srm_file [file normalize [lindex [glob -nocomplain "$proj_dir/synthesis/*.srm"] 0]]
103  set srs_file [file normalize [lindex [glob -nocomplain "$proj_dir/synthesis/*.srs"] 0]]
104  set srr_file [file normalize [lindex [glob -nocomplain "$proj_dir/synthesis/*.srr"] 0]]
105  set top_name [file rootname [file tail $srr_file]]
106  set stxt_files [glob -nocomplain "$proj_dir/synthesis/*.txt"]
107  set scsv_files [glob -nocomplain "$proj_dir/synthesis/*.csv"]
108  set slog_files [glob -nocomplain "$proj_dir/synthesis/*.log"]
109  set srpt_files [glob -nocomplain "$proj_dir/synthesis/*.rpt"]
110  set dtxt_files [glob -nocomplain "$proj_dir/designer/$top_name/*.txt"]
111  set dcsv_files [glob -nocomplain "$proj_dir/designer/$top_name/*.csv"]
112  set dlog_files [glob -nocomplain "$proj_dir/designer/$top_name/*.log"]
113  set drpt_files [glob -nocomplain "$proj_dir/designer/$top_name/*.rpt"]
114  set xml_dir [file normalize "$repo_path/xml"]
115 
116 } else {
117  #tcl shell
118  set work_path $old_path
119  set fw_file [file normalize [lindex [glob -nocomplain "$work_path/*.bit"] 0]]
120  set proj_name [file tail [file normalize $work_path/../../]]
121  set proj_dir [file normalize "$work_path/../.."]
122 
123  set top_name [file rootname [file tail $fw_file]]
124 
125  set main_file [file normalize "$work_path/$top_name.bit"]
126  set bin_file [file normalize "$work_path/$top_name.bin"]
127  set ltx_file [file normalize "$work_path/$top_name.ltx"]
128 
129  set xml_dir [file normalize "$work_path/../xml"]
130  set run_dir [file normalize "$work_path/.."]
131 }
132 
133 set group_name [GetGroupName $proj_dir "$tcl_path/../.."]
134 
135 # Vivado
136 if {[IsXilinx] && [file exists $main_file]} {
137 
138  # Go to repository path
139  cd $tcl_path/../../
140 
141  Msg Info "Evaluating Git sha for $proj_name..."
142  lassign [GetRepoVersions [file normalize ./Top/$group_name/$proj_name] $repo_path] sha
143 
144  set describe [GetHogDescribe $sha $repo_path]
145  Msg Info "Hog describe set to: $describe"
146 
147  set ts [clock format [clock seconds] -format {%Y-%m-%d-%H-%M}]
148 
149  set dst_dir [file normalize "$bin_dir/$group_name/$proj_name\-$describe"]
150  set dst_main [file normalize "$dst_dir/$proj_name\-$describe.$fw_file_ext"]
151  set dst_xml [file normalize "$dst_dir/xml"]
152 
153  Msg Info "Creating $dst_dir..."
154  file mkdir $dst_dir
155 
156  Msg Info "Copying main binary file $main_file into $dst_main..."
157  file copy -force $main_file $dst_main
158 
159  # LTX file for ILA, needs a special treatment...
160  set ltx_file "$work_path/$top_name.ltx"
161  write_debug_probes -quiet $ltx_file
162 
163  # Additional files
164  foreach e $additional_ext {
165  set orig [file normalize "$work_path/$top_name.$e"]
166  set dst [file normalize "$dst_dir/$proj_name\-$describe.$e"]
167  if {[file exists $orig]} {
168  Msg Info "Copying $orig file into $dst..."
169  file copy -force $orig $dst
170  } else {
171  Msg Debug "File: $orig not found."
172  }
173 
174  }
175 
176 
177 
178 } elseif {[IsQuartus]} {
179  #Quartus
180  # Go to repository path
181  cd $repo_path
182 
183  Msg Info "Evaluating Git sha for $name... repo_path: $repo_path"
184  puts "$repo_path repo_path"
185  lassign [GetRepoVersions "$repo_path/Top/$group_name/$name" "$repo_path"] sha
186 
187  set describe [GetHogDescribe $sha $repo_path]
188  Msg Info "Git describe set to: $describe"
189 
190  set ts [clock format [clock seconds] -format {%Y-%m-%d-%H-%M}]
191 
192  set dst_dir [file normalize "$bin_dir/$group_name/$proj_name\-$describe"]
193  set dst_pof [file normalize "$dst_dir/$name\-$describe.pof"]
194  set dst_sof [file normalize "$dst_dir/$name\-$describe.sof"]
195  set dst_rbf [file normalize "$dst_dir/$name\-$describe.rbf"]
196  set dst_rpd [file normalize "$dst_dir/$name\-$describe.rpd"]
197  set dst_stp [file normalize "$dst_dir/$name\-$describe.stp"]
198  set dst_spf [file normalize "$dst_dir/$name\-$describe.spf"]
199  set dst_xml [file normalize "$dst_dir/xml"]
200 
201  Msg Info "Creating $dst_dir..."
202  file mkdir $dst_dir
203  Msg Info "Evaluating differences with last commit..."
204  set found_uncommitted 0
205  set diff [Git diff]
206  if {$diff != ""} {
207  set found_uncommitted 1
208  Msg Warning "Found non committed changes:"
209  Msg Status "$diff"
210  set fp [open "$dst_dir/diff_postbistream.txt" w+]
211  puts $fp "$diff"
212  close $fp
213  }
214 
215  if {$found_uncommitted == 0} {
216  Msg Info "No uncommitted changes found."
217  }
218 
219  #pof file
220  if {[file exists $pof_file]} {
221  Msg Info "Copying pof file $pof_file into $dst_pof..."
222  file copy -force $pof_file $dst_pof
223  } else {
224  Msg Info "No pof file found: $pof_file, that is not a problem"
225  }
226 
227  #Reports
228  file mkdir $dst_dir/reports
229  set reps [glob -nocomplain "$proj_dir/output_files/*.rpt"]
230 
231  if {[file exists [lindex $reps 0]]} {
232  file copy -force {*}$reps $dst_dir/reports
233  } else {
234  Msg Warning "No reports found in $proj_dir/output_files subfolders"
235  }
236 
237  # sof File
238  if {[file exists $sof_file]} {
239  Msg Info "Copying sof file $sof_file into $dst_sof..."
240  file copy -force $sof_file $dst_sof
241  } else {
242  Msg Info "No sof file found: $sof_file, that is not a problem"
243  }
244 
245 
246  #rbf rpd
247  if { [file exists $rbf_file] || [file exists $rpd_file] } {
248  if {[file exists $rbf_file]} {
249  file copy -force $rbf_file $dst_rbf
250  }
251  if {[file exists $rpd_file]} {
252  file copy -force $rpd_file $dst_rpd
253  }
254  } else {
255  Msg Info "No rbf or rpd file found: this is not a problem"
256  }
257 
258  # stp and spf File
259  if {[file exists $stp_file] || [file exists $spf_file]} {
260  if {[file exists $stp_file]} {
261  file copy -force $stp_file $dst_stp
262  }
263  if {[file exists $spf_file]} {
264  file copy -force $spf_file $dst_spf
265  }
266  } else {
267  Msg Info "No stp or spf file found: that is not a problem"
268  }
269 
270 } elseif {[IsLibero] } {
271  # Go to repository path
272  cd $tcl_path/../../
273  ##nagelfar variable project
274  Msg Info "Evaluating git SHA for $project..."
275  lassign [GetRepoVersions [file normalize ./Top/$group_name/$project] $repo_path] sha
276  set describe [GetHogDescribe $sha $repo_path]
277  Msg Info "Git describe set to: $describe"
278 
279  set ts [clock format [clock seconds] -format {%Y-%m-%d-%H-%M}]
280 
281  set dst_dir [file normalize "$bin_dir/$group_name/$project\-$describe"]
282  set dst_map [file normalize "$dst_dir/$project\-$describe.map"]
283  set dst_sap [file normalize "$dst_dir/$project\-$describe.sap"]
284  set dst_srd [file normalize "$dst_dir/$project\-$describe.srd"]
285  set dst_srm [file normalize "$dst_dir/$project\-$describe.srm"]
286  set dst_srs [file normalize "$dst_dir/$project\-$describe.srs"]
287  set dst_srr [file normalize "$dst_dir/$project\-$describe.srr"]
288  set dst_rpt [file normalize "$dst_dir/reports"]
289  set dst_xml [file normalize "$dst_dir/xml"]
290 
291  Msg Info "Creating $dst_dir..."
292  file mkdir $dst_dir/reports
293 
294  if {[file exists $map_file]} {
295  Msg Info "Copying map file $map_file into $dst_map..."
296  file copy -force $map_file $dst_map
297  }
298 
299  if {[file exists $sap_file]} {
300  Msg Info "Copying sap file $sap_file into $dst_sap..."
301  file copy -force $sap_file $dst_sap
302  }
303 
304  if {[file exists $srd_file]} {
305  Msg Info "Copying srd file $srd_file into $dst_srd..."
306  file copy -force $srd_file $dst_srd
307  }
308 
309  if {[file exists $srm_file]} {
310  Msg Info "Copying srm file $srm_file into $dst_srm..."
311  file copy -force $srm_file $dst_map
312  }
313 
314  if {[file exists $srs_file]} {
315  Msg Info "Copying srs file $srs_file into $dst_srs..."
316  file copy -force $srs_file $dst_srs
317  }
318 
319  if {[file exists $srr_file]} {
320  Msg Info "Copying srr file $srr_file into $dst_srr..."
321  file copy -force $srr_file $dst_srr
322  }
323 
324 
325  Msg Info "Copying synth txt files $stxt_files into $dst_rpt..."
326  file copy -force {*}$stxt_files $dst_rpt
327  Msg Info "Copying synth csv files $scsv_files into $dst_rpt..."
328  file copy -force {*}$scsv_files $dst_rpt
329  Msg Info "Copying synth log files $slog_files into $dst_rpt..."
330  file copy -force {*}$slog_files $dst_rpt
331  Msg Info "Copying synth rpt files $srpt_files into $dst_rpt..."
332  file copy -force {*}$srpt_files $dst_rpt
333 
334  Msg Info "Copying impl txt files $dtxt_files into $dst_rpt..."
335  file copy -force {*}$dtxt_files $dst_rpt
336  Msg Info "Copying impl csv files $dcsv_files into $dst_rpt..."
337  file copy -force {*}$dcsv_files $dst_rpt
338  Msg Info "Copying impl log files $dlog_files into $dst_rpt..."
339  file copy -force {*}$dlog_files $dst_rpt
340  Msg Info "Copying impl rpt files $drpt_files into $dst_rpt..."
341  file copy -force {*}$drpt_files $dst_rpt
342 
343 } else {
344  Msg CriticalWarning "Firmware binary file not found."
345 }
346 
347 
348 # IPbus XML
349 if {[file exists $xml_dir]} {
350  Msg Info "XML directory found, copying xml files from $xml_dir to $dst_xml..."
351  if {[file exists $dst_xml]} {
352  Msg Info "Directory $dst_xml exists, deleting it..."
353  file delete -force $dst_xml
354  }
355  file copy -force $xml_dir $dst_xml
356 }
357 
358 # Zynq XSA Export
359 if {[IsXilinx]} {
360  # Vivado
361  # automatically export for zynqs (checking via regex)
362  set export_xsa false
363  set part [get_property part [current_project]]
364 
365  if { [IsZynq $part] || [IsVersal $part]} {
366  Msg Info "SoC FPGA detected (Zynq or Versal), automatically enabling XSA file creation. To disable it, add 'EXPORT_XSA = false' in the \[hog\] section of hog.conf."
367  set export_xsa true
368  }
369 
370  # check for explicit EXPORT_XSA flag in hog.conf
371  set properties [ReadConf [lindex [GetConfFiles $repo_path/Top/$group_name/$proj_name] 0]]
372  if {[dict exists $properties "hog"]} {
373  set propDict [dict get $properties "hog"]
374  if {[dict exists $propDict "EXPORT_XSA"]} {
375  set export_xsa [dict get $propDict "EXPORT_XSA"]
376  }
377  }
378 
379  if {[string compare [string tolower $export_xsa] "true"]==0} {
380  # there is a bug in Vivado 2020.1, check for that version and warn
381  # that we can't export XSAs
382  regexp -- {Vivado v([0-9]{4}\.[0-9,A-z,_,\.]*) } [version] -> VIVADO_VERSION
383  if {[string compare "2020.1" $VIVADO_VERSION]==0} {
384  Msg Warning "Vivado 2020.1, a patch must be applied to Vivado to export XSA Files, c.f. https://www.xilinx.com/support/answers/75210.html"
385  } else {
386 
387  set dst_xsa [file normalize "$dst_dir/${proj_name}\-$describe.xsa"]
388  Msg Info "Generating XSA File at $dst_xsa"
389  if { [IsVersal $part] } {
390  # Run user pre-platform file
391  set user_pre_platform_file "./Top/$group_name/$proj_name/pre-platform.tcl"
392  if {[file exists $user_pre_platform_file]} {
393  Msg Info "Sourcing user pre-platform file $user_pre_platform_file"
394  source $user_pre_platform_file
395  }
396  set pdi_post_imp [file normalize "$work_path/$top_name.pdi"]
397  set_property platform.full_pdi_file $pdi_post_imp [current_project]
398  Msg Info "XSA file will be generated for Versal with this PDI: $pdi_post_imp"
399  write_hw_platform -fixed -force -file "$dst_xsa"
400  } else {
401  write_hw_platform -include_bit -fixed -force -file "$dst_xsa"
402  }
403  }
404  }
405 }
406 
407 
408 # Run user post-bitstream file
409 set user_post_bitstream_file "./Top/$group_name/$proj_name/post-bitstream.tcl"
410 if {[file exists $user_post_bitstream_file]} {
411  Msg Info "Sourcing user post-bitstream file $user_post_bitstream_file"
412  source $user_post_bitstream_file
413 }
414 
415 cd $old_path
416 Msg Info "All done."