2011年11月8日火曜日

コマンドラインで配置配線のススメ

XILINXのFPGA合成ツールの話です。

ここではise12を使う事を前提に記事を書いてます。
すでにise13.3がリリースされている今なぜise12なの?と思うかもしれませんが、諸事情でise12を使い続けているから仕方がないのです。

これから書く内容はise13ではPlanAhedが使えるツールに進化していて、もう必要ないよって事かもしれませんが、僕の個人的な予想ではise13でもまだコマンドラインを使い続ける必要があるかなと思ってます



通常の開発ではWindowsなりLinuxなりの ISE上でGUIベースのツールを使って開発しますが、あえてCUIベースで論理合成から配置配線までを行います。

コマンドラインで開発を行う目的は以下の3点です

1. 論理合成処理時間短縮
2. 複数の配置配線を同時に行う
3. 完了の通知を行いたい

1) 一番大きなメリットは論理合成の処理時間短縮ですが、大規模な設計で合成処理に1時間近くかかるような場合に、モジュール別の合成を行うことで1/5から1/10の時間短縮ができる可能性があります。
ISEではモジュール別の合成がサポートされていないので、大規模なプロジェクトの場合ちょっとしたソースの変更でも論理合成にかなりの時間が必要になります。
そこで、ソースを大きなブロックで分けて論理合成をすることで、変更の無いモジュールの合成を完全に防ぐ事にします。
PlanAheadのパーティションを使用して配置配線もモジュール毎に固定して行えば時間短縮になりそうですが、試したところあまりよい結果は出ていません。配置配線はスマートガイドを利用するのが一番効果が出ています

2) ISEではワンボタンクリックで全ての処理が自動で出来ますが、処理中は殆どの処理が禁止状態になります。コマンドラインではファイルの競合に気をつけさえすれば、配置配線を同時に実行したり、配置配線中にチップスコープのプローブ作成や、論理合成の実行も自由に行えます。
配置配線中にHDLソースのバグを見つけたときに今の処理を中止して最初からやり直すか、とりあえず結果を見てから論理合成をするか...悩む事が結構ありますが、迷わず別のスレッドで論理合成を実行できます。

コマンドラインだと出力するファイル名を直接指定するので、Makeファイルさえ作っておけば、埋め込むチップスコープのファイル毎に別のbitファイル名にする事等が簡単にできます。逆にGUIではファイルの名前をかえるのは手間がかかります

3)一回の論理合成から配置配線完了まで2時間も3時間もかかる場合に処理が完了したことに気がつかないでいたり、途中でエラー終了していたことに気がつかないで時間を無駄にしてしまうことがあります。
そこで処理の終了時に指定アドレスにメールを送るようにスクリプトを組み込むことで、配置配線完了と同時にメールで通知を受け取ることが出来ます。

そのほかにスクリプトさえ作っておけばバージョン番号をソースに埋め込んだり、bitファイルに埋め込んだりが自動でできたりします


コマンドラインで開発するデメリットは
1. 準備が面倒
2. 構成の変更が面倒
3. 合成エラーとエディタの連携が出来ない
3. サマリーの出力が出来ない?合成結果のタイミング解析等が面倒

デメリットは実行環境を作るのにはGUIでの操作に比べるとかなり手間がかかるといったところです。実際HDLの依存関係をリストするなんて事はGUIでやったほうが早いので、一旦ISEでプロジェクトを作成して必要な設定をコピペする事にします。
ソースを解析してソースツリーを作るようなスクリプトを書くという手もあります

僕はiseでプロジェクトを作って、GUIが便利なところはiseを使って、デバック時の合成をコマンドラインで行うような運用をしています

topの論理合成makefile例。
モジュール毎の階層ディレクトリを作って論理合成は階層毎のmakefileで行います。チップスコープを使いした場合は
make cps_bit CPS_PROJ=cps_test
と実行すると最終的には
top_module_cps_test_download.bit ファイルが出来上がります


  1. TOPHDL      = top_module  
  2. CURRENT_DIR = ../module  
  3. CPS_PROJ    = test  
  4. SRC_DIR     = ../iseproject/hdl  
  5. UCS_FLAG    =  -uc $(SRC_DIR)/top/top_module.ucf   
  6. CORE_FLAG   = -sd $(SRC_DIR)/coregen_v6  
  7. EDK_DIR     = $(SRC_DIR)/../system  
  8. DEVICE_TYPE = xc6vlx130t  
  9. DEVICE_NAME = $(DEVICE_TYPE)-1-ff784  
  10. SMARTGUIDE  = no  
  11. MTFLAG      = -mt off  
  12. MAPFLAG     = -w -logic_opt off -ol high -t 1 -xt 0 -register_duplication off -global_opt off $(MTFLAG) -ir off -pr off -lc off -power off  
  13.   
  14. NGCS = \  
  15.   system.ngc \  
  16.   module1.ngc \  
  17.   module2.ngc \  
  18.   top_module.ngc  
  19.   
  20. export SRC_DIR  
  21.   
  22. ifeq ($(SMARTGUIDE),yes)  
  23.  SMART_OPT= -smartguide $(TOPHDL)_guide.ncd  
  24. else  
  25. ifeq ($(SMARTGUIDE),no)  
  26.  SMART_OPT=  
  27. else  
  28.  SMART_OPT= -smartguide $(TOPHDL)_$(SMARTGUIDE)_guide.ncd  
  29. endif  
  30. endif  
  31.   
  32. .PHONY: all clean synthesize bit par cps_edit cps_build cps_bit  
  33.   
  34. all: synthesize bit  
  35.   
  36. clean:  
  37.  $(MAKE) -C module1 TARGET=$@  
  38.  $(MAKE) -C module2 TARGET=$@  
  39.  $(MAKE) -C top_module TARGET=$@  
  40.  del /Q *.ngc  
  41.   
  42. synthesize:   
  43.  $(MAKE) -C module1  
  44.  $(MAKE) -C module2  
  45.  $(MAKE) -C top_module  
  46.  cp -a $(EDK_DIR)/implementation/system.ngc ./  
  47.   
  48. bit: $(TOPHDL).bit  
  49.   
  50. par: $(TOPHDL).twx  
  51.   
  52. $(TOPHDL).ngd : $(NGCS) synthesize  
  53.  cp -a $(EDK_DIR)/implementation/system_bd.bmm ./edkBmmFile.bmm  
  54.  cp -a $(EDK_DIR)/implementation/system.ngc ./  
  55.  ngdbuild -intstyle silent -dd _ngo -sd ipcore_dir -nt timestamp $(UCS_FLAG) $(CORE_FLAG) -bm edkBmmFile.bmm -p $(DEVICE_NAME) $(TOPHDL).ngc $(TOPHDL).ngd    
  56.   
  57. $(TOPHDL)_map.ncd : $(TOPHDL).ngd  
  58.  map -intstyle silent -p $(DEVICE_NAME) $(MAPFLAG) $(SMART_OPT) -o $(TOPHDL)_map.ncd $(TOPHDL).ngd $(TOPHDL).pcf   
  59.   
  60. $(TOPHDL).ncd : $(TOPHDL)_map.ncd  
  61.  par -w -intstyle silent -ol high $(MTFLAG) $(SMART_OPT) $(TOPHDL)_map.ncd $(TOPHDL).ncd $(TOPHDL).pcf   
  62.   
  63. $(TOPHDL).twx : $(TOPHDL).ncd  
  64.  trce -intstyle silent -v 3 -s 1 -n 3 -fastpaths -xml $(TOPHDL).twx $(TOPHDL).ncd -o $(TOPHDL).twr $(TOPHDL).pcf   
  65.   
  66. $(TOPHDL).bit : $(TOPHDL).ncd  
  67.  bitgen -intstyle silent -f $(TOPHDL).ut $(TOPHDL).ncd   
  68.   
  69. $(TOPHDL)_download.bit : $(TOPHDL)_top.bit  
  70.  bitinit -bm edkBmmFile_bd.bmm -p $(DEVICE_NAME) $(EDK_DIR)/system.mhs -pe microblaze_0 $(EDK_DIR)/hrboot/hrboot.elf -bt $(TOPHDL).bit -o $(TOPHDL)_download.bit -log bitinit.log  
  71.   
  72. update_bit: $(TOPHDL)_download.bit  
  73.   
  74. ## Chip scope inserter ##  
  75. $(CPS_PROJ).cdc :  
  76.  inserter -intstyle ise -mode initial -proj $(CPS_PROJ).cdc -p $(DEVICE_TYPE) -output_dir $(CURRENT_DIR)/_ngo -ise_project_dir $(CURRENT_DIR)  
  77.   
  78. cps_edit: $(CPS_PROJ).cdc  
  79.  inserter -intstyle ise -mode setup -proj $(CPS_PROJ).cdc -ise_project_dir $(CURRENT_DIR) -dd _ngo -p $(DEVICE_NAME) $(TOPHDL).ngc $(TOPHDL)_$(CPS_PROJ)_cs.ngc  
  80.  inserter -intstyle ise -mode insert -ise_project_dir $(CURRENT_DIR) -proj $(CURRENT_DIR)/$(CPS_PROJ).cdc -intstyle ise -dd $(CURRENT_DIR)/_ngo -uc $(CURRENT_DIR)/example_top.ucf -uc $(CURRENT_DIR)/gtx_right_top.ucf -uc $(CURRENT_DIR)/vp8408_peripheral_cpu_side.ucf  -sd $(CURRENT_DIR)/../ipcore_dir -p xc6vhx380t-ff1924-1 $(CURRENT_DIR)/$(TOPHDL).ngc $(TOPHDL)_$(CPS_PROJ)_cs.ngc  
  81.   
  82. $(TOPHDL)_$(CPS_PROJ)_cs.ngc: $(CPS_PROJ).cdc $(NGCS)  
  83.  inserter -intstyle ise -mode insert -ise_project_dir $(CURRENT_DIR) -proj $(CURRENT_DIR)/$(CPS_PROJ).cdc -intstyle ise -dd $(CURRENT_DIR)/_ngo -uc $(CURRENT_DIR)/$(TOPHDL).ucf -sd $(CURRENT_DIR)/../ipcore_dir -p xc6vhx380t-ff1924-1 $(CURRENT_DIR)/$(TOPHDL).ngc $(TOPHDL)_$(CPS_PROJ)_cs.ngc  
  84.   
  85. $(TOPHDL)_$(CPS_PROJ).ngd: synthesize $(TOPHDL)_$(CPS_PROJ)_cs.ngc  
  86.  cp -a $(EDK_DIR)/implementation/system_bd.bmm ./edkBmmFile.bmm  
  87.  cp -a $(EDK_DIR)/implementation/system.ngc ./  
  88.  ngdbuild -intstyle silent -dd _ngo -sd ipcore_dir -nt timestamp $(UCS_FLAG) $(CORE_FLAG) -bm edkBmmFile.bmm -p $(DEVICE_NAME) $(TOPHDL)_$(CPS_PROJ)_cs.ngc $(TOPHDL)_$(CPS_PROJ).ngd    
  89.   
  90.   
  91. $(TOPHDL)_map_$(CPS_PROJ).ncd : $(TOPHDL)_$(CPS_PROJ).ngd  
  92.  map -intstyle silent -p $(DEVICE_NAME) $(MAPFLAG) $(SMART_OPT) -o $(TOPHDL)_map_$(CPS_PROJ).ncd $(TOPHDL)_$(CPS_PROJ).ngd $(TOPHDL)_$(CPS_PROJ).pcf   
  93.  cat $(TOPHDL)_map_$(CPS_PROJ).mrp | grep Total  
  94.   
  95. $(TOPHDL)_$(CPS_PROJ).ncd : $(TOPHDL)_map_$(CPS_PROJ).ncd  
  96.  par -w -intstyle silent -ol high $(MTFLAG) $(SMART_OPT) $(TOPHDL)_map_$(CPS_PROJ).ncd $(TOPHDL)_$(CPS_PROJ).ncd $(TOPHDL)_$(CPS_PROJ).pcf   
  97.  cat $(TOPHDL)_$(CPS_PROJ).par | grep Total  
  98.   
  99. $(TOPHDL)_$(CPS_PROJ).twx : $(TOPHDL)_$(CPS_PROJ).ncd  
  100.  trce -intstyle silent -v 3 -s 1 -n 3 -fastpaths -xml $(TOPHDL)_$(CPS_PROJ).twx $(TOPHDL)_$(CPS_PROJ).ncd -o $(TOPHDL)_$(CPS_PROJ).twr $(TOPHDL)_$(CPS_PROJ).pcf   
  101.   
  102. $(TOPHDL)_$(CPS_PROJ).bit : $(TOPHDL)_$(CPS_PROJ).ncd  
  103.  bitgen -intstyle silent -f $(TOPHDL).ut $(TOPHDL)_$(CPS_PROJ).ncd   
  104.   
  105. $(TOPHDL)_$(CPS_PROJ)_download.bit : $(TOPHDL)_$(CPS_PROJ).bit  
  106.  bitinit -bm edkBmmFile_bd.bmm -p $(DEVICE_NAME) $(EDK_DIR)/system.mhs -pe microblaze_0 $(EDK_DIR)/hrboot/hrboot.elf -bt $(TOPHDL)_$(CPS_PROJ).bit -o $(TOPHDL)_$(CPS_PROJ)_download.bit -log bitinit.log  
  107.   
  108. cps_bit: $(TOPHDL)_$(CPS_PROJ)_download.bit  
  109.   
  110. cps_update_bit: $(TOPHDL)_$(CPS_PROJ)_download.bit  

モジュール別のmakefile
*.prj ファイルを生成したり、*.xstファイルをテンプレートファイルから改編したりします。
この例には記述していませんが、topモジュールはi/oポートのインサートを許可してサブモジュールはi/oポートのインサートを禁止したりする必要があります

  1. TOPHDL      = module1  
  2.   
  3. SRC = \  
  4.   ../$(SRC_DIR)/module1/source1.vhd \  
  5.   ../$(SRC_DIR)/module1/source2.vhd \  
  6.   ../$(SRC_DIR)/module1/module1.vhd  
  7.   
  8. .PHONY: all clean  
  9. all: xst/projnav.tmp $(TOPHDL).prj $(TOPHDL).xst $(TOPHDL).ngc   
  10.   
  11. clean:  
  12.  del *.ngc  
  13.   
  14. xst/projnav.tmp:  
  15.  mkdir -p xst/projnav.tmp  
  16.   
  17. $(TOPHDL).prj :  
  18.  echo #$(TOPHDL) > $(TOPHDL).prj  
  19.  @for SRC_ in $(SRC); do \  
  20.   (echo vhdl work $$SRC_ >> $(TOPHDL).prj) ;\  
  21.  done  
  22.   
  23. $(TOPHDL).xst :  
  24.  sed -e s/%TARGET%/$(TOPHDL)/g ../template.xst > $(TOPHDL).xst  
  25.   
  26. $(TOPHDL).ngc : $(SRC)  
  27.  xst -intstyle silent -ifn "$(TOPHDL).xst" -ofn "$(TOPHDL).syr"  
  28.  cp -a $(TOPHDL).ngc ..\  

0 件のコメント: