-
Notifications
You must be signed in to change notification settings - Fork 181
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Vivado: Retry opening device when programming
Vivado 2018.3 is unreliable when opening the hw_device: after connecting a (Nexys Video) FPGA board, the first connection attepmt usually fails. The second attempt is successful. This behavior has been observed with multiple different Nexys Video boards and on different PCs. The GUI behaves identical to the scripted approach: two tries are needed in the GUI as well. To be able to reliably program an FPGA, this commit modifies the programming script to try opening the hw_device for three times before failing. In the process of doing so, I took the liberty to improve the programming approach in a couple more ways: - The script now outputs more helpful information, and less confusing text. The executed commands are not written any more, as is the vivado.log file. This output was confusing, as it wasn't obvious which part of the output was actually executed (e.g. error handlers), and which of it was only in the source code. Instead, handwritten diagnostic messages are output, and a clear indication of success is given at the end of the process. - The call to Vivado to program the device is done through the Makefile (like all other Vivado invocations), and not through edalize directly. This makes it easier to program the FPGA without a full set of core files available. For that purpose, the Makefile now contains a 'pgm' target. - The programming TCL script is now unmodified and gets the part and bitstream arguments through command line arguments. This helps to reuse the programming TCL script for other purposes outside of edalize. New programming output looks like this: ``` vivado -quiet -nolog -notrace -mode batch -source projname_pgm.tcl -tclargs xc7a200tsbg484-1 projname.bit FuseSoC Xilinx FPGA Programming Tool ==================================== INFO: Programming part xc7a200tsbg484-1 with bitstream projname.bit INFO: [Labtools 27-2285] Connecting to hw_server url TCP:localhost:3121 INFO: [Labtools 27-2222] Launching hw_server... INFO: [Labtools 27-2221] Launch Output: ****** Xilinx hw_server v2018.3 **** Build date : Dec 6 2018-23:53:53 ** Copyright 1986-2018 Xilinx, Inc. All Rights Reserved. INFO: Trying to use hardware target localhost:3121/xilinx_tcf/Digilent/210276A79425 INFO: [Labtoolstcl 44-466] Opening hw_target localhost:3121/xilinx_tcf/Digilent/210276A79425 INFO: Opened hardware target localhost:3121/xilinx_tcf/Digilent/210276A79425 on try 1. INFO: Part not found as part of Unknown_Device_0. Trying next device. INFO: [Labtoolstcl 44-464] Closing hw_target localhost:3121/xilinx_tcf/Digilent/210276A79425 INFO: Trying to use hardware target localhost:3121/xilinx_tcf/Digilent/210276A79425B INFO: [Labtoolstcl 44-466] Opening hw_target localhost:3121/xilinx_tcf/Digilent/210276A79425B INFO: Opened hardware target localhost:3121/xilinx_tcf/Digilent/210276A79425B on try 1. INFO: Found xc7a200tsbg484-1 as part of xc7a200t_0. INFO: Programming bitstream to device xc7a200t_0 on target localhost:3121/xilinx_tcf/Digilent/210276A79425B. INFO: [Labtools 27-3164] End of startup status: HIGH program_hw_devices: Time (s): cpu = 00:00:06 ; elapsed = 00:00:06 . Memory (MB): peak = 1418.855 ; gain = 0.000 ; free physical = 3462 ; free virtual = 7136 INFO: [Labtoolstcl 44-464] Closing hw_target localhost:3121/xilinx_tcf/Digilent/210276A79425B INFO: SUCCESS! FPGA xc7a200tsbg484-1 successfully programmed with bitstream projname.bit. ```
- Loading branch information
Showing
7 changed files
with
201 additions
and
70 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,36 +1,73 @@ | ||
# Auto-generated program tcl file | ||
|
||
set bit {{ bitstream_name }} | ||
set part {{ part }} | ||
set part [lindex $argv 0] | ||
set bitstream [lindex $argv 1] | ||
|
||
puts "FuseSoC Xilinx FPGA Programming Tool" | ||
puts "====================================" | ||
puts "" | ||
puts "INFO: Programming part $part with bitstream $bitstream" | ||
|
||
# Connect to Xilinx Hardware Server | ||
open_hw | ||
connect_hw_server | ||
|
||
set found 0 | ||
|
||
# Find the first target and device that contains a FPGA $part. | ||
set hw_device_found 0 | ||
foreach { hw_target } [get_hw_targets] { | ||
puts "INFO: Trying to use hardware target $hw_target" | ||
|
||
current_hw_target $hw_target | ||
if {[catch {open_hw_target} res_open_hw] == 0} { | ||
foreach { hw_device } [get_hw_devices] { | ||
if { [string first [get_property PART $hw_device] $part] == 0 } { | ||
puts "Found hardware target with a ${part} device." | ||
current_hw_device $hw_device | ||
set found 1 | ||
break | ||
} | ||
} | ||
if {$found} {break} | ||
|
||
# Open hardware target | ||
# The Vivado hardware server isn't always able to reliably open a target. | ||
# Try three times before giving up. | ||
set hw_target_opened 0 | ||
for {set open_hw_target_try 1} {$open_hw_target_try <= 3} {incr open_hw_target_try} { | ||
if {[catch {open_hw_target} res_open_hw_target] == 0} { | ||
set hw_target_opened 1 | ||
break | ||
} | ||
} | ||
if { $hw_target_opened == 0 } { | ||
puts "WARNING: Unable to open hardware target $hw_target after " \ | ||
"$open_hw_target_try tries. Skipping." | ||
continue | ||
} | ||
puts "INFO: Opened hardware target $hw_target on try $open_hw_target_try." | ||
|
||
# Iterate through all devices and find one which contains $part | ||
foreach { hw_device } [get_hw_devices] { | ||
if { [string first [get_property PART $hw_device] $part] == 0 } { | ||
puts "INFO: Found $part as part of $hw_device." | ||
current_hw_device $hw_device | ||
set hw_device_found 1 | ||
break | ||
} | ||
} | ||
|
||
if { $hw_device_found == 1 } { | ||
break | ||
} else { | ||
puts "Catched $res_open_hw" | ||
# Close currently tried device, and try with next one. | ||
puts "INFO: Part not found as part of $hw_device. Trying next device." | ||
close_hw_target | ||
} | ||
close_hw_target | ||
} | ||
if { $found == 0 } { | ||
puts "Did not find board with a ${part} device." | ||
if { $hw_device_found == 0 } { | ||
puts "ERROR: None of the hardware targets included a $part FPGA part." | ||
exit 1 | ||
} | ||
puts "INFO: Programming bitstream to device $hw_device on target $hw_target." | ||
|
||
set_property PROGRAM.FILE $bit [current_hw_device] | ||
# Do the programming | ||
current_hw_device $hw_device | ||
set_property PROGRAM.FILE $bitstream [current_hw_device] | ||
program_hw_devices [current_hw_device] | ||
|
||
# Disconnect from Xilinx Hardware Server | ||
close_hw_target | ||
disconnect_hw_server | ||
|
||
puts "" | ||
puts "INFO: SUCCESS! FPGA $part successfully programmed with bitstream $bitstream." |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,36 +1,73 @@ | ||
# Auto-generated program tcl file | ||
|
||
set bit test_vivado_minimal_0.bit | ||
set part xc7a35tcsg324-1 | ||
set part [lindex $argv 0] | ||
set bitstream [lindex $argv 1] | ||
|
||
puts "FuseSoC Xilinx FPGA Programming Tool" | ||
puts "====================================" | ||
puts "" | ||
puts "INFO: Programming part $part with bitstream $bitstream" | ||
|
||
# Connect to Xilinx Hardware Server | ||
open_hw | ||
connect_hw_server | ||
|
||
set found 0 | ||
|
||
# Find the first target and device that contains a FPGA $part. | ||
set hw_device_found 0 | ||
foreach { hw_target } [get_hw_targets] { | ||
puts "INFO: Trying to use hardware target $hw_target" | ||
|
||
current_hw_target $hw_target | ||
if {[catch {open_hw_target} res_open_hw] == 0} { | ||
foreach { hw_device } [get_hw_devices] { | ||
if { [string first [get_property PART $hw_device] $part] == 0 } { | ||
puts "Found hardware target with a ${part} device." | ||
current_hw_device $hw_device | ||
set found 1 | ||
break | ||
} | ||
} | ||
if {$found} {break} | ||
|
||
# Open hardware target | ||
# The Vivado hardware server isn't always able to reliably open a target. | ||
# Try three times before giving up. | ||
set hw_target_opened 0 | ||
for {set open_hw_target_try 1} {$open_hw_target_try <= 3} {incr open_hw_target_try} { | ||
if {[catch {open_hw_target} res_open_hw_target] == 0} { | ||
set hw_target_opened 1 | ||
break | ||
} | ||
} | ||
if { $hw_target_opened == 0 } { | ||
puts "WARNING: Unable to open hardware target $hw_target after " \ | ||
"$open_hw_target_try tries. Skipping." | ||
continue | ||
} | ||
puts "INFO: Opened hardware target $hw_target on try $open_hw_target_try." | ||
|
||
# Iterate through all devices and find one which contains $part | ||
foreach { hw_device } [get_hw_devices] { | ||
if { [string first [get_property PART $hw_device] $part] == 0 } { | ||
puts "INFO: Found $part as part of $hw_device." | ||
current_hw_device $hw_device | ||
set hw_device_found 1 | ||
break | ||
} | ||
} | ||
|
||
if { $hw_device_found == 1 } { | ||
break | ||
} else { | ||
puts "Catched $res_open_hw" | ||
# Close currently tried device, and try with next one. | ||
puts "INFO: Part not found as part of $hw_device. Trying next device." | ||
close_hw_target | ||
} | ||
close_hw_target | ||
} | ||
if { $found == 0 } { | ||
puts "Did not find board with a ${part} device." | ||
if { $hw_device_found == 0 } { | ||
puts "ERROR: None of the hardware targets included a $part FPGA part." | ||
exit 1 | ||
} | ||
puts "INFO: Programming bitstream to device $hw_device on target $hw_target." | ||
|
||
set_property PROGRAM.FILE $bit [current_hw_device] | ||
# Do the programming | ||
current_hw_device $hw_device | ||
set_property PROGRAM.FILE $bitstream [current_hw_device] | ||
program_hw_devices [current_hw_device] | ||
|
||
# Disconnect from Xilinx Hardware Server | ||
close_hw_target | ||
disconnect_hw_server | ||
|
||
puts "" | ||
puts "INFO: SUCCESS! FPGA $part successfully programmed with bitstream $bitstream." |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,36 +1,73 @@ | ||
# Auto-generated program tcl file | ||
|
||
set bit test_vivado_0.bit | ||
set part xc7a35tcsg324-1 | ||
set part [lindex $argv 0] | ||
set bitstream [lindex $argv 1] | ||
|
||
puts "FuseSoC Xilinx FPGA Programming Tool" | ||
puts "====================================" | ||
puts "" | ||
puts "INFO: Programming part $part with bitstream $bitstream" | ||
|
||
# Connect to Xilinx Hardware Server | ||
open_hw | ||
connect_hw_server | ||
|
||
set found 0 | ||
|
||
# Find the first target and device that contains a FPGA $part. | ||
set hw_device_found 0 | ||
foreach { hw_target } [get_hw_targets] { | ||
puts "INFO: Trying to use hardware target $hw_target" | ||
|
||
current_hw_target $hw_target | ||
if {[catch {open_hw_target} res_open_hw] == 0} { | ||
foreach { hw_device } [get_hw_devices] { | ||
if { [string first [get_property PART $hw_device] $part] == 0 } { | ||
puts "Found hardware target with a ${part} device." | ||
current_hw_device $hw_device | ||
set found 1 | ||
break | ||
} | ||
} | ||
if {$found} {break} | ||
|
||
# Open hardware target | ||
# The Vivado hardware server isn't always able to reliably open a target. | ||
# Try three times before giving up. | ||
set hw_target_opened 0 | ||
for {set open_hw_target_try 1} {$open_hw_target_try <= 3} {incr open_hw_target_try} { | ||
if {[catch {open_hw_target} res_open_hw_target] == 0} { | ||
set hw_target_opened 1 | ||
break | ||
} | ||
} | ||
if { $hw_target_opened == 0 } { | ||
puts "WARNING: Unable to open hardware target $hw_target after " \ | ||
"$open_hw_target_try tries. Skipping." | ||
continue | ||
} | ||
puts "INFO: Opened hardware target $hw_target on try $open_hw_target_try." | ||
|
||
# Iterate through all devices and find one which contains $part | ||
foreach { hw_device } [get_hw_devices] { | ||
if { [string first [get_property PART $hw_device] $part] == 0 } { | ||
puts "INFO: Found $part as part of $hw_device." | ||
current_hw_device $hw_device | ||
set hw_device_found 1 | ||
break | ||
} | ||
} | ||
|
||
if { $hw_device_found == 1 } { | ||
break | ||
} else { | ||
puts "Catched $res_open_hw" | ||
# Close currently tried device, and try with next one. | ||
puts "INFO: Part not found as part of $hw_device. Trying next device." | ||
close_hw_target | ||
} | ||
close_hw_target | ||
} | ||
if { $found == 0 } { | ||
puts "Did not find board with a ${part} device." | ||
if { $hw_device_found == 0 } { | ||
puts "ERROR: None of the hardware targets included a $part FPGA part." | ||
exit 1 | ||
} | ||
puts "INFO: Programming bitstream to device $hw_device on target $hw_target." | ||
|
||
set_property PROGRAM.FILE $bit [current_hw_device] | ||
# Do the programming | ||
current_hw_device $hw_device | ||
set_property PROGRAM.FILE $bitstream [current_hw_device] | ||
program_hw_devices [current_hw_device] | ||
|
||
# Disconnect from Xilinx Hardware Server | ||
close_hw_target | ||
disconnect_hw_server | ||
|
||
puts "" | ||
puts "INFO: SUCCESS! FPGA $part successfully programmed with bitstream $bitstream." |