Running Vivado TCL as a script

Vivado で TCLファイルを、シェルスクリプトのように実行することができます。

TL;DR

スクリプトの先頭を以下のようにしておくと、 vivado で TCLスクリプトを簡単に実行することができます。

#!/bin/sh
# Make the next line a comment line for TCL \
exec vivado -mode batch -nolog -nojournal -notrace -tempDir $(mktemp -d /tmp/vivado.XXXXXXXXXX) -source "$0" -tclargs ${1+"$@"}

Details

たとえば、

puts "hello world"

というファイルを tclsh で実行する場合は、

#!/bin/sh
# the next line restarts using tclsh \
exec tclsh "$0" ${1+"$@"}

puts "hello world"

と、します。 実際には シェルスクリプトとして起動されますが、 exec コマンドによって自分を tclsh に置き換えます。このとき、 tclsh には実行しているファイルが第一引数 ($0) として渡され、それ以外の引数があれば、それら (${1+"$@"}) も渡されます。
tclsh としてこのファイルを読みだした場合、 2行目の \ によって 3行目も tclsh にとってはコメント行の扱いとなります。 3行目以降には TCLが書かれているので tclsh はいつも通り TCL を解釈します。
この Hackは tchshmanページに記載されています。

長々説明しましたが、実は Linux の場合 puts "hello world" くらいであれば、こんな Hack は不要です。

#!/usr/bin/tclsh
puts "hello world"

これで正しく実行できます。

では、なぜこんな面倒な説明をしているのかというと #! ではいくつか制限があるためです。最大の問題は $PATH 環境変数からコマンドを探してくれないという問題です。

現実的には、この問題は env を使うことでほとんどの場合は解決します。 python3 を使う人は よく
#! /usr/bin/env python3 という shebang を見るはずです。 env は歴史的に /usr/bin/env に install されているので、これをつかって python3 を探します。

この解決方法によって、 さらに問題が発生します。 env は (こちらも歴史的に) 引数をまとめて渡すという仕様になっています。最近の GNU coreutils に含まれる env では -S オプションがあるので問題ないのですが、逆に古い env を使っているシステムとの互換性がなくなります。このへんは Wikipedia に詳細がかかれているので、興味がある人は確認してみてください。

で、 env -S に依存しない方法として、一度 shell script として実行し、置き換えるという手法がとられるのでした。

vivado を利用する場合は、以下の通りです。

#!/bin/sh
# Make the next line a comment line for TCL \
exec vivado -mode batch -nolog -nojournal -notrace -tempDir $(mktemp -d /tmp/vivado.XXXXXXXXXX) -source "$0" -tclargs ${1+"$@"}
puts "hello world"
  • -mode: vivado には 3つのモード(gui, tcl, batch)があります。 script のときは batchを指定
  • nolog: vivado.log ファイルの生成を抑制
  • nojournal: vivado.jou ファイルの生成を抑制
  • notrace: TCLの実行トレースの表示を抑制 (指定しても表示されるものはある)
  • tempDir: vivado が使用する temporary directory を指定。これを指定しないと、複数の vivado コマンドが同じディレクトリを使って、想定外の挙動をすることがある
  • source: スクリプトのソースファイルの指定
  • -tclargs: スクリプトファイルへの引数の指定