[opentitan-pgm-fpga] Add ability to choose HW server

Add the ability to choose a running Xilinx HW server instead of starting
a new one on localhost (the default behavior, which is unchanged). This
is mainly useful for remote/CI setups where the FPGA board is connected
to another machine.

Signed-off-by: Philipp Wagner <phw@lowrisc.org>
diff --git a/util/opentitan-pgm-fpga/opentitan-pgm-fpga b/util/opentitan-pgm-fpga/opentitan-pgm-fpga
index fbefd4e..cb8a091 100755
--- a/util/opentitan-pgm-fpga/opentitan-pgm-fpga
+++ b/util/opentitan-pgm-fpga/opentitan-pgm-fpga
@@ -10,12 +10,14 @@
 import sys
 
 
-def program_bitstream_with_vivado(part, bitstream, hw_target, jtag_freq):
+def program_bitstream_with_vivado(part, bitstream, hw_server_url, hw_target, jtag_freq):
     tcl_file = os.path.join(os.path.dirname(__file__), 'vivado_pgm.tcl')
     if not os.path.isfile(tcl_file):
         raise FileNotFoundError('{} not found.'.format(tcl_file))
 
     cmd_env = os.environ.copy()
+    if hw_server_url is not None:
+        cmd_env['HW_SERVER_URL'] = hw_server_url
     if hw_target is not None:
         cmd_env['HW_TARGET'] = hw_target
     if jtag_freq is not None:
@@ -38,6 +40,12 @@
 
 def main():
     parser = argparse.ArgumentParser()
+    parser.add_argument('--hw-server-url',
+                        required=False,
+                        default=None,
+                        help='The URL of a running Xilinx hardware server to '
+                        'connect to. If not specified, a hardware server will '
+                        'be started automatically on localhost.')
     parser.add_argument('--hw-target',
                         '-t',
                         required=False,
@@ -56,6 +64,7 @@
 
     return program_bitstream_with_vivado(args.part,
                                          args.bitstream,
+                                         hw_server_url=args.hw_server_url,
                                          hw_target=args.hw_target,
                                          jtag_freq=args.jtag_freq)
 
diff --git a/util/opentitan-pgm-fpga/vivado_pgm.tcl b/util/opentitan-pgm-fpga/vivado_pgm.tcl
index e10ab6e..fdd3756 100644
--- a/util/opentitan-pgm-fpga/vivado_pgm.tcl
+++ b/util/opentitan-pgm-fpga/vivado_pgm.tcl
@@ -29,9 +29,18 @@
   puts "INFO: Programming target $explicit_hw_target"
 }
 
-# Connect to Xilinx Hardware Server
+# Connect to Xilinx Hardware Server. A new instance of the hardware server is
+# started on localhost if HW_SERVER_URL is not given, and if no hardware server
+# is already running on localhost.
 if { [ catch { open_hw_manager } ] } { open_hw }
-connect_hw_server
+
+if {[info exists env(HW_SERVER_URL)]} {
+  set hw_server_url $env(HW_SERVER_URL)
+  puts "INFO: Connecting to hardware server at $hw_server_url"
+  connect_hw_server -url $hw_server_url
+} else {
+  connect_hw_server
+}
 
 if { $explicit_hw_target == "" } {
   set hw_targets [get_hw_targets]