FC2カウンター FPGAの部屋 Chipscope

FPGAやCPLDの話題やFPGA用のツールの話題などです。 マニアックです。 日記も書きます。

FPGAの部屋

FPGAの部屋の有用と思われるコンテンツのまとめサイトを作りました。Xilinx ISEの初心者の方には、FPGAリテラシーおよびチュートリアルのページをお勧めいたします。

ISE14.5以降の ISE で SDK と ChipScope Pro の協調デバックをする方法

ZedBoard AXI4 Lite Slave 演習3(実機テスト)”でSDKとChipScope Pro(以下、ChipScope)を同時に使えなかった。以前は同時に使えたと思ったのだが。。。(ISE14.7を使用している)

そこで、検索してみたところ、Xilinx User Community Forums の”[14.6] SDK and Chipscope do not work together”がヒットした。
それによると、ISE14.4にロールバックして使っているとか。。。どうやらISE14.5からダメになったようだ。
そのページからリンクされたWordファイル、”Launch SDK and Chipscope.docx ‏”にやり方が書いてあったので、実際に確かめてみることにした。

SDK起動

・SDKを立ち上げる、もしくはSDKが立ち上がった状態のとき。

・ZedBoardをJTAGモードで立ち上げる。(MI2~MI6の設定ピンをすべてGNDにする)

・SDKのXilinx Tools -> Program FPGA を選択して、Program FPGAダイアログを出す。

・ビットストリームを選択し、Program ボタンをクリックして、Zynqにビットストリームをダウンロードする。
SDK_ChipScope_1_131221.png

・ZedBoard の青い Done LEDが点灯する。

・SDKで、プロジェクトを選択し、右クリックメニューから Debug As -> Launch on Hardware (System Debuger) を選択する。
SDK_ChipScope_2_131221.png

・SDKをデバック・パースペクティブにするというダイアログが出る。Yesボタンをクリックする。
SDK_ChipScope_3_131221.png

・SDKがデバック・パースペクティブに変更された。
SDK_ChipScope_8_131221.png

ChipScope起動

・Project Navigator に戻って、ChipScope を起動する。
SDK_ChipScope_4_131221.png

・ChipScope が起動する。
SDK_ChipScope_5_131221.png

・JTAG Chain メニューから Open Plug-in... を選択する。
SDK_ChipScope_6_131221.png

・Plug-in Parameters に、xilinx_tcf URL =tcp::3121 と入力して、了解ボタンをクリックする。
SDK_ChipScope_7_131221.png

・FPGAが認識されるので、OKボタンをクリックする。
SDK_ChipScope_9_131221.png

・Dataportが表示されるが、まだ信号名が入っていない。
SDK_ChipScope_10_131221.png

CDCファイルのインポート

・ChipScope の File メニューから Import... を選択する。
SDK_ChipScope_11_131221.png

・system\implementation\chipscope_axi_monitor_0_wapper\chipscope_axi_monitor_0.cdc を選択する。
SDK_ChipScope_12_131221.png

・OKボタンをクリックする。

・信号名が表示された。
SDK_ChipScope_13_131221.png

・これで、SDK, ChipScope協調デバックができた。下の図は、SDKでブレークポイントを設定しながら、AXI4 Lite Slave の応答を ChipScope で確認しているところだ。操作は Tera Term で行っている。
SDK_ChipScope_14_131221.png

(業務連絡)hw_server はすでに立ち上がっていました。
  1. 2013年12月21日 19:24 |
  2. Chipscope
  3. | トラックバック:0
  4. | コメント:2

ChipScope Analyzer でステートマシンのステートを表示する方法

ChipScope Analyzer でステートマシンのステートを表示させると通常は16進数しか表示しない。私は通常VHDLでは、ステートマシンのステートをtype で列挙するだけで値を割り当てていない。それで、XSTのレポートファイル (***.syr) を見てステートを判断していた。それだととても面倒だ。VerilogでもOne Hotに値を指定していると、XSTでグレーコードに変更されたりするので、やはり、XSTのレポートファイル (***.syr) を見る必要がある。いちいち見ながらステートを判断するのは面倒なので、ChipScope Analyzer でステートマシンのステート名を表示する方法を試してみる。なお、参考にさせて頂いたのは、Xilinxのアンサー、”ChipScope Pro : Analyzer に FSM のステート名を表示させる方法”、”ChipScope Pro Software and Cores User Guide UG029 (v14.2) July 25, 2012”の55ページToken、そしてブログでは、徒然日記さんの”ChipScope™ Proの使い方 Lab. 5”を参考にさせて頂いた。

VHDLの場合
最初にVHDLのステートマシンのステート名を表示してみよう。まずは私の様にVHDLでtypeで宣言して、ステートの値を与えていない場合(たぶんステートの値を割り当てていてもXSTで変更されることがあるので、確認しておくことをお勧めする)は、XSTのレポートファイル(今回は、char_write_axi_master.syr)でステートマシンのステート値を確認する。まずは、VHDLの記述から下に示す。

type write_transaction_state is (idle_wr, awvalid_assert, data_write, bready_assert, wr_tran_end);
signal wrt_cs : write_transaction_state;


char_write_axi_master.syr には、こう記述されたていた。

Optimizing FSM <FSM_1> on signal <wrt_cs[1:3]> with user encoding.
----------------------------
 State          | Encoding
----------------------------
 idle_wr        | 000
 awvalid_assert | 001
 data_write     | 010
 bready_assert  | 011
 wr_tran_end    | 100
----------------------------


ここからToken ファイルを作成した。”ChipScope Pro Software and Cores User Guide UG029 (v14.2) July 25, 2012”の55ページToken の項を参照した。”@DEFAULT_TOKEN=ERROR”と記述しておくとデフォルトのステート値を定義できるようだ。つまりステートのリストにないステートということでERRORと記述しているようだ。下に、ChipScpe Analyzer 用 Token ファイル、wrt_cs.tok ファイルを示す。

#Optimizing FSM on signal with user encoding.

@DEFAULT_TOKEN=ERROR

idle_wr=000\b
awvalid_assert=001\b
data_write=010\b
bready_assert=011\b
wr_tran_end=100\b


なお、\b は2進数だが、\u の符号なし10進数、\h の16進数が使えるようだ。
ChipScope Analyzer の標準の表示を見てみる。なお、上にも書いてあるが、ステートマシンのステートの割り当ては、wrt_cs[1:3]なので、通常にバスにしているのだったら、逆順にしておく必要が有る。
下に、wrt_cs のChipScope Analyzer での16進数表示を示す。
ChipScopeA_sm_disp_1_121019.png

これに wrt_cs.tok ファイルを読みこませるには、wrt_cs_FSM_FFd の右クリックメニューから Bus Radix -> Token... を選択する。
ChipScopeA_sm_disp_2_121019.png

ダイアログが表示されるので、Select New File ボタンをクリックしてwrt_cs.tok を選択して、OKボタンをクリックする。
ChipScopeA_sm_disp_3_121019.png

すると、wrt_cs_FSM_FFd にステート値が表示された。
ChipScopeA_sm_disp_4_121019.png

ちなみに、wrt_cs_FSM_FFd3, 2, 1は通常ではバスになっていないので、バスにまとめてある。上図で、wrt_cs_FSM_FFd を展開してあるが、wrt_cs_FSM_FFd3, 2, 1 という順番になっているのがわかると思う。これは、XSTの論理合成の定義が、wrt_cs[1:3]となっているためである。wrt_cs_FSM_FFd1, 2, 3をバスにした当初は、通常 wrt_cs_FSM_FFd1, 2, 3の順番に並んでいるので、バス (wrt_cs_FSM_FFd) の右クリックメニューからReverse Bus Order をクリックしてバスの順序を逆にする必要がある。


Verilogの場合
Verilog で記述したステートマシンの定義を下に示す。

    parameter [2:0]    IDLE_MAIN =            3'b000,
                    CHAR_ROM_READ =        3'b001,
                    CHAR_ROM_VALID =    3'b011,
                    CONVERT_FORMAT =    3'b010,
                    NEXT_LINE_ST =        3'b110,
                    RASTER_VALID_WAIT =    3'b111,
                    RASTER_VALID_ST =    3'b101;
                    
    reg        [2:0]    mainsm_cs;


XSTで論理合成すると、グレーコードになってしまっていたので、今回はワンホットにせずにグレーコードで記述している。こう記述すると、XSTのレポートファイル(今回は、char_write_axi_master.syr)では、そのままのステート値になっていた。

Optimizing FSM <char_gen_8raster_i/FSM_2> on signal <mainsm_cs[1:3]> with user encoding.
-------------------
 State | Encoding
-------------------
 000   | 000
 001   | 001
 011   | 011
 110   | 110
 111   | 111
 010   | 010
 101   | 101
-------------------


これを元に、mainsm_cs.tok を記述した。

#Optimizing FSM on signal with user encoding.

@DEFAULT_TOKEN=ERROR

IDLE_MAIN=000\b
CHAR_ROM_READ=001\b
CHAR_ROM_VALID=011\b
CONVERT_FORMAT=010\b
NEXT_LINE_ST=110\b
RASTER_VALID_WAIT=111\b
RASTER_VALID_ST=101\b


なお、言うまでもないかもしれないが、”#”はコメントを表す。
この Token ファイルで、main_cs_FSM_FFd のステート値を表示させたのが、下の図になる。
ChipScopeA_sm_disp_5_121019.png

これで、ChipScope Analyzer でステーマシンのステート値を表示することが出来た。ちょっとステートを見れば良い時は、Token ファイルを作るのが面倒だが、しっかりステートマシンを解析したい時は便利だと思う。
  1. 2012年10月19日 04:06 |
  2. Chipscope
  3. | トラックバック:0
  4. | コメント:4

ChipScope AXI Monitor を試してみた

今回もどのカテゴリに入れて良いか迷う話題。IP Core なんだけどChipScope Pro のコアだし、EDKで使うんだし、困ったがChipScope Analyzer も使うので、ChipScope のカテゴリに入れておいた。

今回は、ChipScope AXI Monitor を試してみることにした。常々、AXIバスの負荷について解析できたら良いと思っている。例えば、DDR2 SDRAMを画像のフレームバッファとして使っている。時間方向に演算するために何画面分フレームバッファとして使えるかを計算する場合がある。その場合には、現在のバス負荷を計算やシミュレーションで求め、それを検証する必要がある。その検証のためにバス負荷を計算できるAXIバスのモニタを使ってみたいと思っている。ChipScope AXI Monitor は結論として、そうしたバスモニタではなかったが、備忘録として書いておこうと思う。

使用したマニュアルは、”LogiCORE IP ChipScope AXI Monitor (v3.03.a)”だ。ここには、AXI Protocol Checkerという項目があって、HDLで合成可能なARM system verilogアサーションを生成するものだそうだ。これもやってみたい。

使用するプロジェクトは、PlanAheadのプロジェクトで、”PlanAhead14.1で、XPS入りのISE14.1のプロジェクトをインポートしてみた2(解決編)”で使用した。AXI4バス・スレーブIP、AXI4バス・マスタIPを使用したキャラクタ・ディスプレイ・コントローラの回路を使用する。

・PlanAheadプロジェクトからXPSプロジェクトをダブルクリックして立ち上げる。ChipScope AXI Monitor IPコアはIP CatalogウインドウのDebugの下にある。
ChipScope_0_120527.png

・今回はこれをAdd IPせずに、DebugメニューからDebug Configuration を選択する。

・Debug Configurationダイアログで、Add ChipScope Peripheral...ボタンをクリックする。
ChipScope_1_120527.png

・Add New ChisScope Peripheralダイアログで、To monitor AXI Interconnect signal(adding AXI Monitor) のラジオボタンをクリックして、OKボタンをクリックする。
ChipScope_2_120527.png

・Debug Configurationダイアログが開く。SystemウインドウのMonitor Hardware Signals で、chipscope_axi_monitor_0 が選択されていると思う。右のMonitor Bus Signals でcdctest_axi_master_0.M_AXI を選択した。
ChipScope_3_120527.png

・Advanced タブをクリックした。Protocol Checker Setting で下の図のようにセットした。
ChipScope_3_5_120527.png

・上の図では表示しきれない部分があったので、もう一度、下図に示す。
ChipScope_3_6_120527.png

・OKボタンをクリックして、Debug Configurationダイアログを閉じると、XPSにchipscope_axi_monitor_0が入っていた。下の方にchipscope_icon_0 も入っている。ChipScopeでは、これが入っている必要がある。
ChipScope_4_120527.png

・XPSのPortタブでのchipscope_axi_monitor_0の設定の状況を下に示す。なお、Addressタブでは、特にアドレスは設定されていなかった。
ChipScope_5_120527.png

・XPSを閉じて、PlanAheadに戻り論理合成、インプリメント、ビットストリームの生成を行った。Critical Warning が出てしまった。
ChipScope_6_120527.png

・PlanAheadからChipScope Pro を立ち上げた。

・Trigger Setupウインドウを開いて、M3を展開し、MON_AXI_AWVALID に1を設定して1の時にトリガが掛かるように設定した。
ChipScope_6_5_120527.png

・Waveformウインドウの波形を示す。まずはWriteから。すべてのAXIバスの信号を見ることが出来る。
ChipScope_7_120527.png

・次はRead。やはり、すべてのAXIバスの信号を見ることが出来る。
ChipScope_8_120527.png

・上の図で、下の方にPC_ERROR_BUS[78}_c4、error_bus_i という信号があるが、これがどうやらAXI Protocol Checkerの信号らしい? error_bus_i を展開するとたくさんの信号が入っているが、これが何を意味するかが良く分からない?
ChipScope_8_6__120527.png

・Trigger Setupウインドウにも、AXI Protocol Checker信号が入っている。試しにRを入れてみてやってみたが、どこでトリガが掛かるか良くわからない。PC_ERROR_BUS[78}_c4、error_bus_i の値も0になっている。
ChipScope_8_5_120527.png

AXI Protocol Checkerについてはよく分からなかった。残念だ。AXI Protocol Checkerに関しての情報をお持ちの方がいらっしゃったら、教えて下さい。

最後にChipScope AXI Monitor を入れた時と入れない時のリソースの比較をしてみようと思う。
最初は、ChipScope AXI Monitor を入れた時のリソースを下に示す。
ChipScope_9_120527.png

次に、ChipScope AXI Monitor を入れない時のリソースを下に示す。
ChipScope_10_120527.png

やはり、かなりの本数のモニタしているので、かなり増えている。LUTは19%から26%に増えている。RAMB16BWER は25%から37%に増えている。

  1. 2012年05月28日 05:25 |
  2. Chipscope
  3. | トラックバック:0
  4. | コメント:0

XPSでChipScope Proコアを追加してデバック2

XPSでChipScope Proコアを追加してデバック1”の続き。

Project Navigator のAnalyze Design Using Chipscope をダブルクリックして、ChipScope Pro Analyzer を立ち上げた。
左上のOpen Cable/Search JTAG Chainアイコンをクリックして、FPGAを捜す。
EDK_Debug_10_111022.png

FPGAとコンフィグROMが見つかった。OKボタンをクリックする。
EDK_Debug_11_111022.png

左上のウインドウにXC3S700AとXCF04Sが表示された。XC3S700Aを選択して、右クリックメニューからConfigure...を選択する。
EDK_Debug_12_111022.png

ChipScope Pro Analyzerのダイアログが表示された。OKボタンをクリックする。
EDK_Debug_13_111022.png

ChipScope Pro Analyzerは下のような状態になった。
EDK_Debug_14_111022.png

これでは信号名が入っていないので、信号名をインポートする。
FileメニューからImport...を選択する。Signal Importダイアログが表示されるので、system\implementation\chipscope_ila_0_wrapper\chipscope_ila_0.cdcを選択する。
EDK_Debug_15_111022.png

Auto-create Buses Warningダイアログが表示される。了解ボタンをクリックする。
そうすると、WaveformにSignal名が表示された。
EDK_Debug_16_111022.png

これで通常にChipScope Proでデバックをすることができる。
なお、今回はトリガ信号とデータ信号が同一だが、トリガ信号とデータ信号を異なる信号を入れる場合は、”11.1 EDK - ChipScope Pro ILA コアのデータ ポートに信号を接続する方法”を参照のこと。
  1. 2011年10月22日 06:15 |
  2. Chipscope
  3. | トラックバック:0
  4. | コメント:0

XPSでChipScope Proコアを追加してデバック1

Spartan3シリーズでは、BSCANユニットが1個しか入っていないため、MicroBlazeでMDMユニットが入っているとChipScope Pro Inserter でChipScope Proを挿入することができなかった。(”The Simple MicroBlaze Microcontroller 17 (ChipScope Proによるデバックの問題点)”参照)

EDKでは、XPS上でChipScope ProのコアをAdd IPすることによって、ChipScope Proを使用することができるようだ。それをやってみようと思う。この場合にはBSCANユニットをMDMとChipScope Proで共有すると思われる。

XPSでDebugメニューからDebug Configuration...を選択する。
EDK_Debug_1_111020.png

Debug Configurationダイアログが表示された。Moniter Hardware Signalsを選択されていた。左下のAdd ChipScope Peripheral...ボタンをクリックする。
EDK_Debug_2_111021.png

Add New ChipScope Peripheralダイアログが表示された。To monitior arbitrary system level signals (adding ILA) のラジオボタンをクリックする。今回はrotary_encoder のデバックなので、ILAを選択した。
EDK_Debug_3_111021.png

Debug Configuraitonダイアログが表示された。BasicタブでAvailable Ports on InstanceからExternal Portsを選択し、rot_a, rot_b, rot_centerを選択して、Add >>ボタンをクリックし、Signals Monitored by:に入れる。
Select the clock to be used monitoring: をclk_62_5000MHzに変更した。
EDK_Debug_4_111021.png

Advancedタブをクリックして、UserタブのMiscを選択し、Use The ILA Trigger Signals As The ILA Data Signal のチェックを外す。これを外すと編集できるようになるので、Width of ILA Data Input Signalを32から16に変更した。これはデータサンプル数が1024で、データ幅が32ビットだと、1つのBRAMに収まらないからだ。
EDK_Debug_6_111022.png

次に、Trigger Uinitをクリックして、Match Type for Trigger Unit0をbasicからbasic with edges に変更した。
EDK_Debug_7_111022.png

もう一度、Miscをクリックして、Use The ILA Trigger Signals As The ILA Data Signal のチェックを入れた。これでOKボタンをクリックした。
EDK_Debug_8_111022.png

XPSに戻ると、chipscope_icon_0とchipscope_ila_0が追加されていた。
EDK_Debug_5_111021.png

これでXPSを終了して、Project Navigator でインプリメントした。
インプリメントが終了した。やはり、BRAMは100%の使用率になった。
EDK_Debug_9_111022.png
  1. 2011年10月22日 05:37 |
  2. Chipscope
  3. | トラックバック:0
  4. | コメント:0

ChipScope ProのVIOをtclスクリプトで制御

ChipScope ProのVIOを使う1”と”ChipScope ProのVIOを使う2”で、ChipScopeのVIOを使って、アドレスを入力してデータをChipScope Analyzer上に表示する方法を書いた。
今回は、ChipScopeのVIOをtclスクリプトから制御して、プログラムでアドレスを連続に入力しながら、出力されたデータをファイルに書き出す方法を書こうと思う。使用したISEのバージョンは12.1。

今回、参照したマニュアルや文献は、最初に、”ChipScope Pro 12.1 ソフトウェアおよびコア ユーザー ガイド (英語版)"の171ページ、”ChipScope Engine Tcl Interface”と”ChipScope Engine Tcl interface”。日本語の情報は検索で出てこなかった。このブログがChipScope ProのVIOをtclで使う方法の最初の日本語の情報かも?

さて、tclスクリプトでのVIOを使うサンプルが、ISE12.1のインストールフォルダのXilinx\12.1\ISE_DS\ISE\cse\tcl の下にある。csevio_example1.tcl がそれだ。これを、ユーザーガイドに書いてあるように、コマンド・プロンプトから下のコマンドを入力すると起動できる。(Platform Cable USBなどのUSB接続のダウンロード・ケーブルの場合)

<XILINX_ISE_INSTALL>\bin\nt\xtclsh csevio_example1.tcl -usb


起動すると、FPGAのVIOのいろいろな情報が表示される。
このサンプルを元に、”ChipScope ProのVIOを使う1”と”ChipScope ProのVIOを使う2”で、使用したサンプルで、VIOでアドレスを回路に出力して、データを連続的に取得して、ファイルに書き出す。作るデータ・ファイルは、a.txt, h.txt, v.txt, d.txt。csevio_example1.tcl を参考にして、csevio_example1.tcl を書き換えて作ってあるため、全部を載せることは出来ない。
下に、書き換えたあたりのソースを示す(あくまでイメージとしてみてください。全ソースではないです)。

proc scanDevice {handle deviceIndex} {
...
    global str_a
    global str_h
    global str_v
    global str_d
...
    if {$deviceIndex == 0 } {
        # scanDeviceの前にa, h, v, dのデータを格納するファイルをオープンする
        set file_a [open a.txt w]
        set file_h [open h.txt w]
        set file_v [open v.txt w]
        set file_d [open d.txt w]
        
        set VIOSyncInputLimit 0x7f
        
        for {set VIOSyncInputVal 0} {$VIOSyncInputVal <= $VIOSyncInputLimit} {incr VIOSyncInputVal} {
...
            }
            puts $file_a $str_a
            puts $file_h $str_h
            puts $file_v $str_v
            puts $file_d $str_d
        }
            
        #file closed
        puts "File Closed"
        close $file_a
        close $file_h
        close $file_v
        close $file_d
    } else {
...
proc scanVIOCore { handle coreRef } {
    csevio_define_bus $handle $coreRef "status" $CSEVIO_SYNC_INPUT [list 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75]
    
    if {[lindex $coreRef 2] == 0} { # coreIndex
        csevio_define_bus $handle $coreRef "address" $CSEVIO_SYNC_OUTPUT [list 0 1 2 3 4 5 6]
        set str [format "%.2x" $VIOSyncInputVal]
        set outputTclArray(address) $str
        puts "outputTclArray(address) = $str"
        csevio_write_values $handle $coreRef outputTclArray
        after 100
    }
    csevio_read_values $handle $coreRef inputTclArray
    set str $inputTclArray(status.value)
    puts "VIOSyncInputVal = $VIOSyncInputVal"
    if {[lindex $coreRef 2] == 0} { # coreIndex    
        set str_a $str
    } elseif {[lindex $coreRef 2] == 1} { # coreIndex
        set str_h $str
    } elseif {[lindex $coreRef 2] == 2} { # coreIndex
        set str_v $str
    } elseif {[lindex $coreRef 2] == 3} { # coreIndex
        set str_d $str
    }
...


下に、このtclスクリプトを起動した時の表示を示す。
VIO_tcl_1_100723.png

これで、a.txt, h.txt, v.txt, d.txtにデータが書き込まれた。ちなみにh.txtの最初の10行を下に示す。

021160A6D8191B84B5B
003B600E40022980A1F
0011C00348007780197
0008A001A4002B80092
0005A000F8001C8003E
00052000D800128002D
000420008C000D0002D
0001600034000400021
0000000008000080000
0000C00024000100005


ChipScopeのVIOをtclスクリプトから制御して、プログラムでアドレスを連続に入力しながら、出力されたデータをファイルに書き出すことができた。これで、いろいろとデータを便利に取得することができると思う。
#どうだろうか?情報が少なくて、1週間悩んだ、取って置きの情報を開示した(つもり)。もし使っていらっしゃる方がいらしたら、情報交換しましょう。と言うか、教えてください。
  1. 2010年07月23日 14:14 |
  2. Chipscope
  3. | トラックバック:0
  4. | コメント:2

ChipScope ProのVIOを使う2

ChipScope ProのVIOを使う1”の続き。

今度は、生成したICON, VIO, ILAコアを接続していく。前回のvio_aをクリックして、View HDL Instantiaion Template をダブルクリックすると、component文とインスタンスの例が出るので、それを参考にする。
cs_vio_13_100618.png

こんな感じで接続した。

    vio_icon_inst : vio_icon port map (
        CONTROL0 => CONTROL0,
        CONTROL1 => CONTROL1,
        CONTROL2 => CONTROL2,
        CONTROL3 => CONTROL3,
        CONTROL4 => CONTROL4
    );
    
    vio_a_inst : vio_a port map(
        CONTROL => CONTROL0,
        CLK => mclk,
        SYNC_IN => a_sync_in,
        SYNC_OUT => a_sync_out
    );
    select_sig <= a_sync_out;
    a_sync_in(18 downto 0) <= a_sig0;
    a_sync_in(37 downto 19) <= a_sig1;
    a_sync_in(56 downto 38) <= a_sig2;
    a_sync_in(75 downto 57) <= a_sig3;
    
    vio_h_inst : vio_h port map(
        CONTROL => CONTROL1,
        CLK => mclk,
        SYNC_IN => h_sync_in
    );
    h_sync_in(18 downto 0) <= h_sig0;
    h_sync_in(37 downto 19) <= h_sig1;
    h_sync_in(56 downto 38) <= h_sig2;
    h_sync_in(75 downto 57) <= h_sig3;
    
    vio_v_inst : vio_v port map(
        CONTROL => CONTROL2,
        CLK => mclk,
        SYNC_IN => v_sync_in
    );
    v_sync_in(18 downto 0) <= v_sig0;
    v_sync_in(37 downto 19) <= v_sig1;
    v_sync_in(56 downto 38) <= v_sig2;
    v_sync_in(75 downto 57) <= v_sig3;
    
    vio_d_inst : vio_d port map(
        CONTROL => CONTROL3,
        CLK => mclk,
        SYNC_IN => v_sync_in
    );
    d_sync_in(18 downto 0) <= d_sig0;
    d_sync_in(37 downto 19) <= d_sig1;
    d_sync_in(56 downto 38) <= d_sig2;
    d_sync_in(75 downto 57) <= d_sig3;
    
    vio_ila_inst : vio_ila port map(
        CONTROL => CONTROL4,
        CLK => mclk,
        DATA => ila_data,
        TRIG0 => ila_trig0
    );
    ila_trig0(0) <= cam_vsync_2d_rpulse;
    ila_trig0(1) <= cam_vsync_2d;
    ila_trig0(2) <= cam_href_2d;
    ila_trig0(3) <= master_sync;
    ila_data(18 downto 0) <= a_sig0;
    ila_data(37 downto 19) <= h_sig0;
    ila_data(56 downto 38) <= v_sig0;
    ila_data(75 downto 57) <= d_sig0;
    ila_data(76) <= cam_vsync_2d_rpulse;
    ila_data(77) <= cam_vsync_2d;
    ila_data(78) <= cam_href_2d;
    ila_data(79) <= r_w;
    ila_data(80) <= master_sync;
    ila_data(81) <= mem_uwe;
    ila_data(82) <= mem_lwe;
    ila_data(98 downto 83) <= mem_data_out;


これはトップモジュールだが、その下のモジュールで、select_sig (vio_aのSYNC_OUT), a_sig0, 1, 2, 3 をどう使っているかという例を示す。

    process(clk) begin
        if clk'event and clk='1' then
            if reset='1' then
                a_sig_node0 <= (others => '0');
                a_sig_node1 <= (others => '0');
                a_sig_node2 <= (others => '0');
                a_sig_node3 <= (others => '0');
            else
                if cam_vsync_2d_fpulse='1' then -- cam_vsync_2d の立ち下がりなので、クリア
                    a_sig_node0 <= (others => '0');
                    a_sig_node1 <= (others => '0');
                    a_sig_node2 <= (others => '0');
                    a_sig_node3 <= (others => '0');
                elsif vd_read_line_write_2d='1' and current_line_is_even='0' and sub_count(1 downto 0)="11" then -- 奇数ライン
                    if (select_sig(5 downto 0) & "00")=a_data_th then 
                        a_sig_node0 <= a_sig_node0 + 1;
                    end if;
                    if (select_sig(5 downto 0) & "01")=a_data_th then
                        a_sig_node1 <= a_sig_node1 + 1;
                    end if;
                    if (select_sig(5 downto 0) & "10")=a_data_th then 
                        a_sig_node2 <= a_sig_node2 + 1;
                    end if;
                    if (select_sig(5 downto 0) & "11")=a_data_th then
                        a_sig_node3 <= a_sig_node3 + 1;
                    end if;
                end if;
            end if;
        end if;
    end process;


上の例で、a_sig_node0がa_sig0に接続されている(1フレーム間、値が変動しないように順序回路が入っている)。a_sig1, 2, 3も同様だ。select_sig (vio_aのSYNC_OUT)の値によって、その値のあるデータの1フレームあたりの数をカウントしている。select_sigをVIOコンソールから入力することによって、色々な値の積算値をVIOコンソールの出力で見ることができる。
実際に、ChipScope Analyzerを立ち上げて、VIOコンソールを表示したのが、下の図だ。現在のJTAG Scan Rateは1secにしてある。これは、サンプル間隔で250ms~5secとマニュアルサンプルがある。
cs_vio_14_100629.png

これで、VIOコンソールから、値を入れて、その値に対応するデータをVIOコンソールで見ることができた。
スイッチや表示器が何も無い基板でも、お手軽にデータを収集できるので、とても良いと思う。
  1. 2010年07月02日 05:09 |
  2. Chipscope
  3. | トラックバック:0
  4. | コメント:0
»