FC2カウンター FPGAの部屋 2010年07月

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

FPGAの部屋

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

Spartan-3A Starter KitでCMOSカメラ・ディスプレイ回路5(シミュレーション)

Spartan-3A Starter KitでCMOSカメラ・ディスプレイ回路4(Verilogコーディング中)”の続き

CMOSカメラ・ディスプレイ回路のコーディングも終了し、OV7640のモデルをVerilogで作ったので、シミュレーションを行っている。DDR2 SDRAMのモデルはいつものMicron社のモデルを使用している。Veritakでシミュレーションを行っている。
VeritakのScope Tree Viewダイアログを見ると、テストベンチ(CamDispCntrler_DDR2_tb.v) の下に、CMOSカメラ・ディスプレイ回路(CamDispCntrler_DDR2.v) とCMOSカメラのモデル(OV7670) 、DDR2 SDRAMのモデル(MT47H16M16_inst) が入っているのが見えると思う。
CamDispCntrler_DDR2_10_100730.png

シミュレーションしているところを下図に示す。
CamDispCntrler_DDR2_11_100730.png

今はシミュレーションで接続されていない信号を修正したりしている段階だ。この回路のシミュレーションは面倒だ。
DDR2 SDRAMは133.33MHz, 7.5nsec で動作していて、CMOSカメラの1フレームは16.7msec とタイムスケールが違いすぎるのが問題だと思う。かなり長くシミュレーションする必要がある。
まだ、Camere ControllerがDDR2 SDRAMにデータを書いていないので、VGA_Display_Controllerで受け取るデータはXになってしまう。
もしくはモデルを修正して、なるべく早くデータを書き込める用に修正するかな?検討してみよう。
  1. 2010年07月30日 05:55 |
  2. 画像処理
  3. | トラックバック:0
  4. | コメント:0

ブラックベリー・ヨーグルト

昨日は朝収穫してきたブラックベリーをヨーグルトにたっぷり入れて、砂糖をかけて食べました。美味しかったです。ヨーグルトはいつも自分で作っているカスピ海ヨーグルトです。ヨーグルトメーカーも購入して作っています。美味しいですよ。。。朝はパン食なので、パンとヨーグルト、今はカモミールのハーブティーのラインナップです。
yoghurt_100730.jpg

冷凍して貯めておいたブルーベリーは、子供たちのおやつとして、殆ど食べられてしまいました。冷凍ブルーベリーは美味しいそうですが、冷凍ブラックベリーはまずいそうです。まあ、暑いですから冷菓として食べたんだったら良いでしょう。。。ブラックベリー・ジャムのみにします。
  1. 2010年07月30日 03:59 |
  2. 日記
  3. | トラックバック:0
  4. | コメント:0

ISE Design Suite 12.2

XilinxのダウンロードページにISE Design Suite 12.2が出ています。アップデートではなく、フルインストールみたいです。Alteraと同じようになったんですね。 (勘違い、以前からそうでしたね。)まだ、ダウンロードしていませんが、後でダウンロードしてみようと思います。
ISE122_100728.jpg

(追加)
ダウンロードしました。インストール中です。
インストール終了して、起動してみましたが、Application VersionがM.63cになっている(ISE12.1はM.53d)のが、新しいですが、ISE12.1と変わらない外観です。インプリメントしてみた結果も変化がありません。(Spartan-3Aで小さい回路ですが)
PlanAheadも外観は変わらないです。今のところ違いがわかりませんが、Partial Reconfiguration に対応しているはずですよね?そのうちに、機能を確かめてみたいと思います。
もしかして、ModelSim XEⅢは無くなってしまったのでしょうか?Xilinxのデザインツールのページそのキャッシュ。キャッシュの右真ん中のロジックデザインツールにリアル タイムのオンチップ検証 ModelSim Xilinx Edition-III (MXE-III) の項目があったのですが、現在のページにはないです。
(また追記)
12.1用のModelSim XEⅢはここにありました12.2用はまだ出ていないだけなのかもしれません。マイナーアップデートの時には、出ないそうです。
#でも、ModelSim XEのライブラリ・アップデートはあっても良い気がしますが?今後に期待します。

(2010/07/29:追記)
astrayさんに教えていただいたのですが、今日Xilinx社のダウンロードのページにModelSim XEのライブラリが追加されていました。astaryさん、ありがとうございました。

  1. 2010年07月28日 05:15 |
  2. Xilinx ISEについて
  3. | トラックバック:0
  4. | コメント:2

ブルーベリー、ブラックベリー収穫、でも虫刺され

今日は、娘のオープンキャンパスで休暇だったので、帰ってきてからブルーベリーとブラックベリーを収穫しました。
ブルーベリーを収穫していたら、毛虫に刺されて痛いのなんの。。。痛かったです。刺したのはコイツです。
iraga_100727.jpg

調べてみると、クロシタアオイラガというそうです。いかにも凶悪な感じ。毒の棘を持っているそうです。ハンパなく痛いです。キンカンつけましたが、まだ痛いです。
指を犠牲にした今日の収穫です。結構取れました。これは冷凍しておいてジャムにします。今度からはゴム手袋をして収穫します。
syukaku_100727.jpg

ちなみに、ブルーベリーもブラックベリーも生で食べて美味しいです。ブラックベリーは、濃厚なぶどうジュースの味がします。

(追加)
ブラックベリーはこんなふうに実をつけています

ブルーベリーの実のつけ方はこんな感じです。(下図)この葉の裏に、例の毛虫がいます。
blueberry_100729.jpg
  1. 2010年07月27日 18:02 |
  2. 日記
  3. | トラックバック:0
  4. | コメント:0

Spartan-3A Starter KitでCMOSカメラ・ディスプレイ回路5(テストベンチをコーディング中)

いやー、暑い夏ですね。。。日曜日にエアコンなしで過ごしていたら、マジにクラクラして熱中症になりそうになりました。室温は約36度でした。皆さんはいかがお過ごしですか?暑いのでご注意ください

さて、Spartan-3A Starter KitでCMOSカメラ・ディスプレイ回路もインプリメンテーション用のVerilogファイルは書き終えて、一応、XSTで論理合成はできるようになった。(熱中症になりそうになりながらも頑張りました)
CamDispCntrler_DDR2_8_100727.png

次はシミュレーション用のテストベンチを作成している。DDR2 SDRAMのモデルと以前作成してあったCMOSカメラのモデルを一部修正して使う予定だ。
私は、Notepad++を2つのビューにして左を見ながら右のビューを書いている。下の図のような感じでテストベンチを作っている。
CamDispCntrler_DDR2_9_100727.png

もっと便利にテストベンチを作れないかと思う。Project Navigatorからテストベンチをつくるとテンプレートを作ってくれるが、いまいち自分のスタイルではないので、簡易的には利用するが、どうもテストベンチを書くときは自分で書いてしまう。やはりSystemVerilogに移行したいが、XSTは対応していないな。。。
  1. 2010年07月27日 05:15 |
  2. 画像処理
  3. | トラックバック:0
  4. | コメント:4

祗園祭

いつもこの時期にはこの話題なのですが、うちの地元でも祗園祭が行われました。家の小6の娘も子供神輿を担ぎました。うちの地元の子供神輿は3機ありまして、小学生低学年向け、小学生高学年向け、中学生向けの3機です。
下の写真が中学生用神輿です。
gionsai_1_100726.jpg

下の写真の前が小学校高学年向け神輿で、家の娘も神輿を担いでいます。後ろが小学校低学年向けの神輿です。
gionsai_2_100726.jpg

昨日はすごい雷で、バケツをひっくり返したような雨でかわいそうでした。びしょぬれになっちゃいました。神事ですので、雨での中断はあっても、中止はありません。来年は中学生ですので、後3年は御みこし担ぎです。
  1. 2010年07月26日 04:21 |
  2. 日記
  3. | トラックバック:0
  4. | コメント:2

FILCO Majestouchテンキーレス 茶軸キーボードを買いました

昨日、アマゾンに注文してあったFILCO Majestouchテンキーレス メカニカルキーボードUSB&PS2両対応 日本語91キー・かな印字あり Nキーロールオーバー 独CherryMX茶軸スイッチ ブラック FKBN91M/JBが届きました。
職場では、東プレ NG0100 REALFORCE91Uを使っています。最初はこの東プレのキーボードをアマゾンで注文したのですが、14,800円で買おうとすると、かなり待たされました。それで、キャンセルして、キーが軽いと評判がよく、しかも在庫のあるMajestouchの茶軸を注文しました。(キーがとても軽いのが好みです)
昨日来たのですが、東プレよりもカチャカチャ音はうるさい気がしますが、キーも軽く、こっちの方が好みかもしれません。REALFORCE91Uは可変荷重ですし、全部押し下げて使っていると少し重い気がします。長く入力していると人差し指と中指が特に疲れます。茶軸はみんな同じ軽さなので良い感じです。クリック感は余りありません。茶軸はクリック感があると説明にも書いてありましたが、余り感じません。クリック感はあまりすきじゃないので、とても気に入りました。買って良かったです。
keyboard_100724.jpg

  1. 2010年07月24日 05:37 |
  2. パソコン関連
  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

Spartan-3A Starter KitでCMOSカメラ・ディスプレイ回路4(Verilogコーディング中)

さて、Spartan-3A Starter KitでCMOSカメラ・ディスプレイ回路のVerilogコーディング中だ。暑いので、やる気が失せている。ほんとうに暑い。今朝は少し涼しく部屋の温度計は28.0度だが、昨日は29.8度だった。昨日、夏休みで家にいた息子が室温が36度になって流石にエアコンを点けたと言っていた。皆さん、夏バテしないようにご注意ください。私も夏の予定が目白押しなので、気をつけようと思います。
さて、VerilogコーディングはVGA_Display_Controller.vをコーディング中だ。一部を下に示す。
CamDispCntrler_DDR2_6_100722.png
(2010/07/22 修正:Verilogコードが間違っていたので修正しました)

暑いけど頑張って作ろうと思う。今回はOVLを使用してアサーションをする予定だ。VGA_Display_Controller.vにはOVL_NEVERを使って、非同期FIFOがoverflow, underflow しないかを監視させることにする。OVLに関しては、”アサーション事始め”や”ISimでOVLのVHDL, Verilog混在シミュレーション(OVLライブラリのコンパイルと登録)”、”ISimでOVLのVHDL, Verilog混在シミュレーション(ISimでシミュレーション)”を参照のこと。
下が取り敢えず書いてみたOVL_NEVERのVerilogコード。下のその様子を示す。
CamDispCntrler_DDR2_7_100722.png

いろいろ次の企画も考えているが、今のところVerilogコーディングが忙しく手がついていない。なかなか忙しい。
  1. 2010年07月22日 05:39 |
  2. 画像処理
  3. | トラックバック:0
  4. | コメント:8

借りぐらしのアリエッティを見てきた、日記

先週のトイ・ストーリー3に続いて、今日は借りぐらしアリエッティを見てきた。画面は綺麗だったが、ストーリーとしてはトイ・ストーリー3の方が良いと思った。やはりジブリ作品は千と千尋の神隠しまでの宮崎駿のシリーズが面白かった。。。
その後は、奥さんの実家に行った。行くと梅干がほしてあった。梅干は塩で漬けた後、天日干しするのだ。干した後、裏を干すためにひっくり返す。ひっくり返した下の方は青いのだ。日が当たっている上は赤っぽい梅干しの色だが、ひっくり返すと日があたっていないので青い。ひっくり返すのを手伝ってきた。
nikki_3_100719.jpg

田植えをした田んぼに行ってみると、丈夫に稲が育っていた。まだ穂は出ていないみたい。
nikki_1_100719.jpg

ネギやシソの葉、ニラ、トウモロコシをもらってきた。下の写真で左はネギ、右がトウモロコシだ。
nikki_2_100719.jpg

トウモロコシをその場で茹でてもらって食べたら、とても甘かった。採りたて、茹でたてトウモロコシ、最高に美味しい!!!

  1. 2010年07月19日 21:35 |
  2. 日記
  3. | トラックバック:0
  4. | コメント:0

Write側とRead側のデータ幅の異なるFIFOのシミュレーション3

非同期FIFOの話題をもう1つ。
今度は前とは逆で、Writeのデータ幅が16ビットで、Readのデータ幅が32ビットの非同期FIFOの入出力フォーマットを検証してみた。
まずは、Write側で16ビット幅で書く場合のシミュレーション波形を下に示す。
def_width_fifo_15_100718.png

wr_enが1の時のwr_clkの立ち上がりで、FIFOにdin[15:0]のデータがWriteされる。Writeした値は、0006, 0007, 0008,0009, 000a, 000b, 000c, 000d だ。
これでRead側で32ビット幅で読んだときのシミュレーション波形を見てみる。
def_width_fifo_16_100718.png

FWFTなFIFOなので、rd_enが1の時に、rd_clkの立ち上がりでdout[15:0]に出てくるデータがそうだ。00060007, 00080009, 000a000b, 000c000d と出てくる。32ビットのうちの最初に入れた16ビットが上位、次の16ビットが下位になっている。これで、”Write側とRead側のデータ幅の異なるFIFOのシミュレーション2”と対称に成っていることがわかった。普通に使えば使えるので安心した。
  1. 2010年07月18日 10:02 |
  2. Core Generator
  3. | トラックバック:0
  4. | コメント:0

Write側とRead側のデータ幅の異なるFIFOのシミュレーション2

そういえば、本来何やりたいたいかという目的を忘れていた。幅が違うFIFOの出力のフォーマットを見たかったのだった。
Writeのデータ幅が32ビットで、Readのデータ幅が16ビットの非同期FIFOの入出力フォーマットを検証してみた。
まずは、Write側で32ビット幅で書く場合のシミュレーション波形を下に示す。
def_width_fifo_13_100717.png

wr_enが1の時のwr_clkの立ち上がりで、FIFOにdin[31:0]のデータがWriteされる。Writeした値は0000000b, 0000000c, 0000000d だ。
これでRead側で16ビット幅で読んだときのシミュレーション波形を見てみる。
def_width_fifo_14_100717.png

FWFTなFIFOなので、rd_enが1の時に、rd_clkの立ち上がりでdout[15:0]に出てくるデータがそうだ。0000, 000b, 0000, 000c, 0000, 000d と出てくるので、32ビットで書いたときの上位16ビット、下位16ビットの順で出てくる。

これで、Writeのデータ幅が32ビットで、Readのデータ幅が16ビットの非同期FIFOの入出力フォーマットを検証することができた。
  1. 2010年07月17日 19:08 |
  2. Core Generator
  3. | トラックバック:0
  4. | コメント:0

Write側とRead側のデータ幅の異なるFIFOのシミュレーション

Spartan-3A Starter KitでCMOSカメラ・ディスプレイ回路3(FIFOの深度)”でFIFOの深度を考察した際に、Write側とRead側のデータ幅の異なるFIFOを使用することにした。実は前回も使っているのだが、単体でシミュレーションしたことがないため、シミュレーションをやってみることにした。(ISE12.1)

Writeのデータ幅が32ビットで深度64、Readのデータ幅が16ビットで深度128の非同期FIFO、fifo32_16をCORE Generator のFIFO Generatorで生成した。下に生成した時の図を示す。
def_width_fifo_1_100716.png

def_width_fifo_2_100716.png

def_width_fifo_3_100716.png

def_width_fifo_4_100716.png

def_width_fifo_5_100716.png

def_width_fifo_6_100716.png

次にテストベンチfifo32_16_tb.v をVerilogで書いた。下にVerilog ソースを示す。

`timescale 10ps / 1ps
`default_nettype none

module fifo32_16_tb;

    // Inputs
    reg rst;
    reg wr_clk = 0'b0;
    reg rd_clk = 0'b0;
    reg [31:0] din;
    reg wr_en;
    reg rd_en;

    // Outputs
    wire [15:0] dout;
    wire full;
    wire overflow;
    wire empty;
    wire underflow;
    wire [5:0] wr_data_count;
    
    parameter WR_CLK_PERIOD = 750; // 7.5nsec
    parameter RD_CLK_PERIOD = 4000; // 40nsec

    // Instantiate the Unit Under Test (UUT)
    fifo32_16 uut (
        .rst(rst), 
        .wr_clk(wr_clk), 
        .rd_clk(rd_clk), 
        .din(din), 
        .wr_en(wr_en), 
        .rd_en(rd_en), 
        .dout(dout), 
        .full(full), 
        .overflow(overflow), 
        .empty(empty), 
        .underflow(underflow), 
        .wr_data_count(wr_data_count)
    );
    
    // wr_clk
    always begin
       #(WR_CLK_PERIOD/2)    wr_clk = 1'b1 ;
       #(WR_CLK_PERIOD/2)    wr_clk = 1'b0 ;
    end
    
    // rd_clk
    always begin
       #(RD_CLK_PERIOD/2)    rd_clk = 1'b1 ;
       #(RD_CLK_PERIOD/2)    rd_clk = 1'b0 ;
    end
    
    always @(posedge wr_clk, posedge rst) begin
        if (rst)
            din <= 32'd0;
        else
            din <= din + 32'd1;
    end
    
    // wr_clk domain
    initial begin
        // Initialize Inputs
        rst = 1'b1;
        wr_en = 0;

        // Wait 100 ns for global reset to finish
        #10000;
      rst = 1'b0;  
        // Add stimulus here
        @(posedge wr_clk); #100; // 次のクロックの後1nsec wait
        wr_en = 1'b1;
        @(posedge wr_clk); #100; // 次のクロックの後1nsec wait
        @(posedge wr_clk); #100; // 次のクロックの後1nsec wait
        @(posedge wr_clk); #100; // 次のクロックの後1nsec wait
        @(posedge wr_clk); #100; // 次のクロックの後1nsec wait
        @(posedge wr_clk); #100; // 次のクロックの後1nsec wait
        @(posedge wr_clk); #100; // 次のクロックの後1nsec wait
        @(posedge wr_clk); #100; // 次のクロックの後1nsec wait
        @(posedge wr_clk); #100; // 次のクロックの後1nsec wait
        @(posedge wr_clk); #100; // 次のクロックの後1nsec wait
        @(posedge wr_clk); #100; // 次のクロックの後1nsec wait
//        wr_en = 1'b1;
        @(posedge wr_clk); #100; // 次のクロックの後1nsec wait
        @(posedge wr_clk); #100; // 次のクロックの後1nsec wait
        @(posedge wr_clk); #100; // 次のクロックの後1nsec wait
        wr_en = 1'b0;
    end
    
    // rd_clk domain
   initial begin
        rd_en = 0;
        #10000; // rstの分をwait
        @(negedge empty); #100; // emptyがデアサートされるまで待つ
        @(posedge rd_clk); #100; // 次のクロックの後1nsec wait
        rd_en = 1'b1;
        @(posedge rd_clk); #100; // 次のクロックの後1nsec wait
        @(posedge rd_clk); #100; // 次のクロックの後1nsec wait
        @(posedge rd_clk); #100; // 次のクロックの後1nsec wait
        @(posedge rd_clk); #100; // 次のクロックの後1nsec wait
        @(posedge rd_clk); #100; // 次のクロックの後1nsec wait
        @(posedge rd_clk); #100; // 次のクロックの後1nsec wait
        rd_en = 1'b0;
    end
endmodule
`default_nettype wire



ここで時間がなくなったので、また帰ってきてから書きます。衝撃の事実が。。。ご期待ください???
(大げさすぎですね。。。)書いてみたかったので。。。

続きです。いよいよ衝撃の事実が明らかに。(ネタです。本気にしないでください。)

Project NavigatorのDesignウインドウでSimulationモードにしてISE Simulatorでシミュレーションをしてみた。
シミュレーションが出来ました。(ここから文体をですます調に変更)あれ?なんかoverflowが立っている???なんででしょうか?
def_width_fifo_7_100716.png

その部分を拡大してみます。
def_width_fifo_8_100716.png

非同期リセットのrstを1にしてもfullは1のままで、rstを0にした次のwr_clkの立ち上がり(黄色いカーソルのところ)でwr_enがサンプルされて、overflowが1になってしまっています。なぜfullはリセットしても0にならないのでしょうか?wr_data_countはリセットされて初期値は00ですので、fullを見ていないと最初はoverflowしてしまうことになります。これが衝撃の事実です。本当かな?

rstが1の長さを1usecにしてみましたが同様でした。
今度はどうなっているか見るために、wr_en = 1'b1;にするところをコメントアウトしている位置に移動して、従来のwr_en = 1'b1;はコメントアウトしました。
def_width_fifo_9_100716.png

今度は大丈夫です。問題の部分を拡大してみましょう。
def_width_fifo_10_100716.png

rstが0になってから、fullが3クロックかかって0になっています。どうしてでしょうか?
気になって、Veritakでもシミュレーションしてみたが同様の結果でした。なぜ?(シミュレーションを中止させるために、$stopをソースに追加しました)
def_width_fifo_11_100716.png

その時にワーニングに気がついた。(ですます調が苦痛になってきたので、である調に戻します)

WARNING: Behavioral models for independent clock FIFO configurations are not cycle-accurate. You may wish to choose the structural simulation model instead of the behavioral model. This will ensure accurate behavior and latencies during simulation. You can enable this from CORE Generator by selecting Project -> Project Options -> Generation tab -> Structural Simulation. See the FIFO Generator User Guide for more information.


あれ?behavioral modelからstructural simulation modelにしろって?早速アンサーをサーチ。これだろうか?

20414 - LogiCORE 非同期 FIFO および FIFO Generator - ビヘイビア モデルの限界


非同期FIFOだから、シミュレーションと実際の動作に違いが出るのは、よく分かるが、それでリセットでfullが落ちない理由になるのかな?
Project NavigatorからCORE Generatorを立ち上げて、早速、structural simulation modelにモデル生成を切り替えたんだけど、やはり結果は同じだった。
def_width_fifo_12_100716.png

もう少しFIFOの構成をいじってやってみよう。

(追記)この動作は正常だそうです。

AR #23659 - FIFO Generator - Why is there a latency in the deassertion of the FULL, ALMOST_FULL, and PROG_FULL signals after the release of RST?


内部は同期ロジックなので、FULL関連の信号をディアサートするのに時間がかかるとのことでした。知りませんでした。以前からそうでしたか?まずいっすね。カウントだけで制御しているものはなかったかな?
”FULLは絶対見ること”という教訓を心に誓います。。。
#結局、ネタになってしまった。。。

(2012/04/02:追記)
非同期FIFOでFWFTモードの場合は、Use Extra Logic For More Accurate Data Countsのチェックボックスにチェックを入れる必要があるそうです。詳しくは”FWFTモードのBlock RAM使用した非同期FIFOのrd_data_countについて”を参照してください。
  1. 2010年07月16日 05:49 |
  2. Core Generator
  3. | トラックバック:0
  4. | コメント:4

Spartan-3A Starter KitでCMOSカメラ・ディスプレイ回路3(FIFOの深度)

今、CMOSカメラ・ディスプレイ回路のVerilog ソースを作製中だ。
VGA DISPLAY CONTROLLERやCAMERA_CONTROLLERの非同期FIFOの深度についてまとめておこうと思う。
VGA DISPLAY CONTROLLERはBRAM使用の非同期FIFOを使用して、Writeのビット幅は32ビットの64深度、Readビット幅は16ビットの128深度の入り口と出口のビット幅が異なる非同期FIFOにする。(”Spartan-3A Starter KitでCMOSカメラ・ディスプレイ回路2(レイテンシの測定)”を参照。)
VGA DISPLAY CONTROLLERの非同期FIFOの動作は最初にFULLまでDDR2 SDRAMから画像データを読み込んで、その後、VGAに出力するためにデータを吐き出していって、1/2の容量になったら、1/2分の画像データをDDR2 SDRAMから読み出すという構成になる。
CAMERA_CONTROLLERの非同期FIFOは、通常はCMOSカメラから出てくるデータは25MHz2クロック分で1画素であるため、12.5MHzで16ビットデータを書き込めれば良い。これは、133.33MHzで32ビットのデータを書き込む(133.33MHzクロックの立ち上がり、立ち下がりエッジで16ビットずつ書き込む)DDR2 SDRAMに対して十分に遅いため、通常の状態では非同期FIFOにデータは貯まることはない。ただし、VGA DISPLAY CONTROLLERがその容量の1/2の画像データをフィルしているときは、VGA DISPLAY CONTROLLERのアクセスが優先であるため待たされる。その待たされる時間の推測値を計算してみる。”Spartan-3A Starter KitでCMOSカメラ・ディスプレイ回路2(レイテンシの測定)”を参照。

CAMERA_CONTROLLERの非同期FIFOが待たされる時間(最悪値) = Readのレイテンシ(165nsec) + リフレッシュのレイテンシ(203nsec) + 画像データの転送時間(7.5nsec * 32 = 240nsec) = 603nsec


608nsecを12.5MHzの周期80nsecで割ると7.6になる。8深度あれば十分だが、16深度とする。こちらはWriteのビット幅を16ビット、Readのビット幅を32ビットにしたいところだ。しかし、Fifo GeneratorでWriteのビット幅よりもRead伸びット幅の大きいFIFOにすると、最小深度が16であるため、Writeの16ビット幅で32深度、Readの32ビット幅で16深度のFIFOをBRAMで生成するしかない。これで行くことにする。
次は、WriteとReadでビット幅の異なるFIFOの動作をシミュレーションしてみたい。
  1. 2010年07月15日 05:39 |
  2. 画像処理
  3. | トラックバック:0
  4. | コメント:0

SP605でキャラクタ・ディスプレイ・コントローラ4(CH7301C用のラッパー・ソースファイル)

一応、”SP605でキャラクタ・ディスプレイ・コントローラ3(実機でテスト)”の続き。
Yahooグループの方でリクエストがあったので、SP605でキャラクタ・ディスプレイ・コントローラのCH7301C用のラッパー・ソースファイルを貼っておく。

Clocking WizardのDCM_CLKGEN_S6は、下のように差動入力に設定して、200MHzから25MHzに落としてクロックとして、使っている。CLK_OUT2はCLK_OUT1より位相を90度ずらしている。
SP605_DVI_7_100623.png

SP605_DVI_9_100713.png

CharDispCtrlerTestは、”キャラクタ・ディスプレイ・コントローラのまとめ”からDCMを除いて、25MHzクロックで動作するようにしたものだ。display_enableは画像表示期間を示す信号だ。2つ下の階層のCharDispCtrler.vから、下のように引き出している。

assign display_enable = display_on_d2;


それ以外に変更はしていない(はず)。

CH7301Cのマニュアルを読むと分かるのだが、I2Cをいじらないデフォルト状態ではDouble Data Rateでデータを入れてやれば良い。DVIデジタルでも表示出来ている。

なお、いつも通りに、ソースファイルについて、一切の保証はしないので、ご承知おきください。

// CharDispCtrlerTest_SP605.v
// CharDispCtrlerTest.vのSP605用のラッパー、CH7301Cを使用する
//
// 2012/07/26 : ODDR2 のDDR_ALIGNMENTとSRTYPEを修正
//

`default_nettype none

module CharDispCtrlerTest_SP605 (
    input    wire            sysclk_p, sysclk_n,
    input    wire            reset_sw,
    output    wire            dvi_xclk_p, dvi_xclk_n,
    output    reg                dvi_de, dvi_h, dvi_v,
    output    wire    [11:0]    dvi_d,
    output    wire            dvi_reset_b,
    output    wire            dvi_sda,
    output    wire            dvi_scl
);
    wire clk, clkb;
    wire clk90, clk90b;
    wire clkdv;
    wire reset;
    wire locked;
    wire vga_red, vga_green, vga_blue;
    wire vga_hsync, vga_vsync;
    wire display_enable;
    
    DCM_CLKGEN_S6 clk200_DCM (
        .CLK_IN1_P          (sysclk_p),    // IN
        .CLK_IN1_N          (sysclk_n),    // IN
        // Clock out ports
        .CLK_OUT1           (clk),     // OUT
        .CLK_OUT2           (clk90),     // OUT
        // Status and control signals
        .RESET              (reset_sw),        // IN
        .LOCKED             (locked)      // OUT
    );
    assign reset = !locked;
    assign clkb = !clk;
    assign clk90b = !clk90;
//    assign dvi_reset_b = locked;
    assign dvi_reset_b = 1'b1;
    
    CharDispCtrlerTest CharDispCtrlerTest_inst (
        .clk(clk),
        .reset(reset),
        .VGA_RED(vga_red),
        .VGA_GREEN(vga_green),
        .VGA_BLUE(vga_blue),
        .VGA_HSYNC(vga_hsync),
        .VGA_VSYNC(vga_vsync),
        .display_enable(display_enable)
    );
    
    always @(posedge clk) begin
        if (reset) begin
            dvi_de <= 1'b0;
            dvi_h <= 1'b1;
            dvi_v <= 1'b1;
        end else begin
            dvi_de <= display_enable;
            dvi_h <= vga_hsync;
            dvi_v <= vga_vsync;
        end
    end
    
    // dvi_xclk_p : clkbと同位相
    ODDR2  #(
        .DDR_ALIGNMENT("C0"),    //  Sets  output  alignment  to  "NONE",  "C0"  or  "C1"
        .INIT(1'b0),            //  Sets  initial  state  of  the  Q  output  to  1’b0  or  1’b1
        .SRTYPE("ASYNC")            //  Specifies  "SYNC"  or  "ASYNC"  set/reset
    )  ODDR2_xclk_p  (
        .Q(dvi_xclk_p),            //  1-bit  DDR  output  data
        .C0(clk90),                //  1-bit  clock  input
        .C1(clk90b),                //  1-bit  clock  input
        .CE(1'b1),                //  1-bit  clock  enable  input
        .D0(1'b1),                //  1-bit  data  input  (associated  with  C0)    
        .D1(1'b0),                //  1-bit  data  input  (associated  with  C1)
        .R(reset),                //  1-bit  reset  input
        .S(1'b0)                //  1-bit  set  input
    );    
    
    // dvi_xclk_n : clkと同位相
    ODDR2  #(
        .DDR_ALIGNMENT("C0"),    //  Sets  output  alignment  to  "NONE",  "C0"  or  "C1"
        .INIT(1'b1),            //  Sets  initial  state  of  the  Q  output  to  1’b0  or  1’b1
        .SRTYPE("ASYNC")            //  Specifies  "SYNC"  or  "ASYNC"  set/reset
    )  ODDR2_xclk_n  (
        .Q(dvi_xclk_n),            //  1-bit  DDR  output  data
        .C0(clk90),                //  1-bit  clock  input
        .C1(clk90b),                //  1-bit  clock  input
        .CE(1'b1),                //  1-bit  clock  enable  input
        .D0(1'b0),                //  1-bit  data  input  (associated  with  C0)    
        .D1(1'b1),                //  1-bit  data  input  (associated  with  C1)
        .R(reset),                //  1-bit  reset  input
        .S(1'b0)                //  1-bit  set  input
    );    
    
    // DVI_D// DVI_D[0]
    ODDR2  #( 
        .DDR_ALIGNMENT("C0"),    //  Sets  output  alignment  to  "NONE",  "C0"  or  "C1"
        .INIT(1'b0),            //  Sets  initial  state  of  the  Q  output  to  1’b0  or  1’b1
        .SRTYPE("ASYNC")            //  Specifies  "SYNC"  or  "ASYNC"  set/reset
    )  ODDR2_D0  (
        .Q(dvi_d[0]),            //  1-bit  DDR  output  data
        .C0(clk),                //  1-bit  clock  input
        .C1(clkb),                //  1-bit  clock  input
        .CE(1'b1),                //  1-bit  clock  enable  input
        .D0(vga_blue),            //  B0[0], 1-bit  data  input  (associated  with  C0)    
        .D1(vga_green),            //  G0[4], 1-bit  data  input  (associated  with  C1)
        .R(reset),                //  1-bit  reset  input
        .S(1'b0)                //  1-bit  set  input
    );    
    
    ODDR2  #( // DVI_D[1]
        .DDR_ALIGNMENT("C0"),    //  Sets  output  alignment  to  "NONE",  "C0"  or  "C1"
        .INIT(1'b0),            //  Sets  initial  state  of  the  Q  output  to  1’b0  or  1’b1
        .SRTYPE("ASYNC")            //  Specifies  "SYNC"  or  "ASYNC"  set/reset
    )  ODDR2_D1  (
        .Q(dvi_d[1]),            //  1-bit  DDR  output  data
        .C0(clk),                //  1-bit  clock  input
        .C1(clkb),                //  1-bit  clock  input
        .CE(1'b1),                //  1-bit  clock  enable  input
        .D0(vga_blue),            //  B0[1], 1-bit  data  input  (associated  with  C0)    
        .D1(vga_green),            //  G0[5], 1-bit  data  input  (associated  with  C1)
        .R(reset),                //  1-bit  reset  input
        .S(1'b0)                //  1-bit  set  input
    );    
    
    ODDR2  #( // DVI_D[2]
        .DDR_ALIGNMENT("C0"),    //  Sets  output  alignment  to  "NONE",  "C0"  or  "C1"
        .INIT(1'b0),            //  Sets  initial  state  of  the  Q  output  to  1’b0  or  1’b1
        .SRTYPE("ASYNC")            //  Specifies  "SYNC"  or  "ASYNC"  set/reset
    )  ODDR2_D2  (
        .Q(dvi_d[2]),            //  1-bit  DDR  output  data
        .C0(clk),                //  1-bit  clock  input
        .C1(clkb),                //  1-bit  clock  input
        .CE(1'b1),                //  1-bit  clock  enable  input
        .D0(vga_blue),            //  B0[2], 1-bit  data  input  (associated  with  C0)    
        .D1(vga_green),            //  G0[6], 1-bit  data  input  (associated  with  C1)
        .R(reset),                //  1-bit  reset  input
        .S(1'b0)                //  1-bit  set  input
    );    
    
    ODDR2  #( // DVI_D[3]
        .DDR_ALIGNMENT("C0"),    //  Sets  output  alignment  to  "NONE",  "C0"  or  "C1"
        .INIT(1'b0),            //  Sets  initial  state  of  the  Q  output  to  1’b0  or  1’b1
        .SRTYPE("ASYNC")            //  Specifies  "SYNC"  or  "ASYNC"  set/reset
    )  ODDR2_D3  (
        .Q(dvi_d[3]),            //  1-bit  DDR  output  data
        .C0(clk),                //  1-bit  clock  input
        .C1(clkb),                //  1-bit  clock  input
        .CE(1'b1),                //  1-bit  clock  enable  input
        .D0(vga_blue),            //  B0[3], 1-bit  data  input  (associated  with  C0)    
        .D1(vga_green),            //  G0[7], 1-bit  data  input  (associated  with  C1)
        .R(reset),                //  1-bit  reset  input
        .S(1'b0)                //  1-bit  set  input
    );    
    
    ODDR2  #( // DVI_D[4]
        .DDR_ALIGNMENT("C0"),    //  Sets  output  alignment  to  "NONE",  "C0"  or  "C1"
        .INIT(1'b0),            //  Sets  initial  state  of  the  Q  output  to  1’b0  or  1’b1
        .SRTYPE("ASYNC")            //  Specifies  "SYNC"  or  "ASYNC"  set/reset
    )  ODDR2_D4  (
        .Q(dvi_d[4]),            //  1-bit  DDR  output  data
        .C0(clk),                //  1-bit  clock  input
        .C1(clkb),                //  1-bit  clock  input
        .CE(1'b1),                //  1-bit  clock  enable  input
        .D0(vga_blue),            //  B0[4], 1-bit  data  input  (associated  with  C0)    
        .D1(vga_red),            //  R0[0], 1-bit  data  input  (associated  with  C1)
        .R(reset),                //  1-bit  reset  input
        .S(1'b0)                //  1-bit  set  input
    );    
    
    ODDR2  #( // DVI_D[5]
        .DDR_ALIGNMENT("C0"),    //  Sets  output  alignment  to  "NONE",  "C0"  or  "C1"
        .INIT(1'b0),            //  Sets  initial  state  of  the  Q  output  to  1’b0  or  1’b1
        .SRTYPE("ASYNC")            //  Specifies  "SYNC"  or  "ASYNC"  set/reset
    )  ODDR2_D5  (
        .Q(dvi_d[5]),            //  1-bit  DDR  output  data
        .C0(clk),                //  1-bit  clock  input
        .C1(clkb),                //  1-bit  clock  input
        .CE(1'b1),                //  1-bit  clock  enable  input
        .D0(vga_blue),            //  B0[5], 1-bit  data  input  (associated  with  C0)    
        .D1(vga_red),            //  R0[1], 1-bit  data  input  (associated  with  C1)
        .R(reset),                //  1-bit  reset  input
        .S(1'b0)                //  1-bit  set  input
    );    
    
    ODDR2  #( // DVI_D[6]
        .DDR_ALIGNMENT("C0"),    //  Sets  output  alignment  to  "NONE",  "C0"  or  "C1"
        .INIT(1'b0),            //  Sets  initial  state  of  the  Q  output  to  1’b0  or  1’b1
        .SRTYPE("ASYNC")            //  Specifies  "SYNC"  or  "ASYNC"  set/reset
    )  ODDR2_D6  (
        .Q(dvi_d[6]),            //  1-bit  DDR  output  data
        .C0(clk),                //  1-bit  clock  input
        .C1(clkb),                //  1-bit  clock  input
        .CE(1'b1),                //  1-bit  clock  enable  input
        .D0(vga_blue),            //  B0[6], 1-bit  data  input  (associated  with  C0)    
        .D1(vga_red),            //  R0[2], 1-bit  data  input  (associated  with  C1)
        .R(reset),                //  1-bit  reset  input
        .S(1'b0)                //  1-bit  set  input
    );    
    
    ODDR2  #( // DVI_D[7]
        .DDR_ALIGNMENT("C0"),    //  Sets  output  alignment  to  "NONE",  "C0"  or  "C1"
        .INIT(1'b0),            //  Sets  initial  state  of  the  Q  output  to  1’b0  or  1’b1
        .SRTYPE("ASYNC")            //  Specifies  "SYNC"  or  "ASYNC"  set/reset
    )  ODDR2_D7  (
        .Q(dvi_d[7]),            //  1-bit  DDR  output  data
        .C0(clk),                //  1-bit  clock  input
        .C1(clkb),                //  1-bit  clock  input
        .CE(1'b1),                //  1-bit  clock  enable  input
        .D0(vga_blue),            //  B0[7], 1-bit  data  input  (associated  with  C0)    
        .D1(vga_red),            //  R0[3], 1-bit  data  input  (associated  with  C1)
        .R(reset),                //  1-bit  reset  input
        .S(1'b0)                //  1-bit  set  input
    );    
    
    ODDR2  #( // DVI_D[8]
        .DDR_ALIGNMENT("C0"),    //  Sets  output  alignment  to  "NONE",  "C0"  or  "C1"
        .INIT(1'b0),            //  Sets  initial  state  of  the  Q  output  to  1’b0  or  1’b1
        .SRTYPE("ASYNC")            //  Specifies  "SYNC"  or  "ASYNC"  set/reset
    )  ODDR2_D8  (
        .Q(dvi_d[8]),            //  1-bit  DDR  output  data
        .C0(clk),                //  1-bit  clock  input
        .C1(clkb),                //  1-bit  clock  input
        .CE(1'b1),                //  1-bit  clock  enable  input
        .D0(vga_green),            //  G0[0], 1-bit  data  input  (associated  with  C0)    
        .D1(vga_red),            //  R0[4], 1-bit  data  input  (associated  with  C1)
        .R(reset),                //  1-bit  reset  input
        .S(1'b0)                //  1-bit  set  input
    );    
    
    ODDR2  #( // DVI_D[9]
        .DDR_ALIGNMENT("C0"),    //  Sets  output  alignment  to  "NONE",  "C0"  or  "C1"
        .INIT(1'b0),            //  Sets  initial  state  of  the  Q  output  to  1’b0  or  1’b1
        .SRTYPE("ASYNC")            //  Specifies  "SYNC"  or  "ASYNC"  set/reset
    )  ODDR2_D9  (
        .Q(dvi_d[9]),            //  1-bit  DDR  output  data
        .C0(clk),                //  1-bit  clock  input
        .C1(clkb),                //  1-bit  clock  input
        .CE(1'b1),                //  1-bit  clock  enable  input
        .D0(vga_green),            //  G0[1], 1-bit  data  input  (associated  with  C0)    
        .D1(vga_red),            //  R0[5], 1-bit  data  input  (associated  with  C1)
        .R(reset),                //  1-bit  reset  input
        .S(1'b0)                //  1-bit  set  input
    );    
    
    ODDR2  #( // DVI_D[10]
        .DDR_ALIGNMENT("C0"),    //  Sets  output  alignment  to  "NONE",  "C0"  or  "C1"
        .INIT(1'b0),            //  Sets  initial  state  of  the  Q  output  to  1’b0  or  1’b1
        .SRTYPE("ASYNC")            //  Specifies  "SYNC"  or  "ASYNC"  set/reset
    )  ODDR2_D10  (
        .Q(dvi_d[10]),            //  1-bit  DDR  output  data
        .C0(clk),                //  1-bit  clock  input
        .C1(clkb),                //  1-bit  clock  input
        .CE(1'b1),                //  1-bit  clock  enable  input
        .D0(vga_green),            //  G0[2], 1-bit  data  input  (associated  with  C0)    
        .D1(vga_red),            //  R0[6], 1-bit  data  input  (associated  with  C1)
        .R(reset),                //  1-bit  reset  input
        .S(1'b0)                //  1-bit  set  input
    );    
    
    ODDR2  #( // DVI_D[11]
        .DDR_ALIGNMENT("C0"),    //  Sets  output  alignment  to  "NONE",  "C0"  or  "C1"
        .INIT(1'b0),            //  Sets  initial  state  of  the  Q  output  to  1’b0  or  1’b1
        .SRTYPE("ASYNC")            //  Specifies  "SYNC"  or  "ASYNC"  set/reset
    )  ODDR2_D11  (
        .Q(dvi_d[11]),            //  1-bit  DDR  output  data
        .C0(clk),                //  1-bit  clock  input
        .C1(clkb),                //  1-bit  clock  input
        .CE(1'b1),                //  1-bit  clock  enable  input
        .D0(vga_green),            //  G0[3], 1-bit  data  input  (associated  with  C0)    
        .D1(vga_red),            //  R0[7], 1-bit  data  input  (associated  with  C1)
        .R(reset),                //  1-bit  reset  input
        .S(1'b0)                //  1-bit  set  input
    );
    
    SCCB_Reg_Controller I2C_Setting_inst (
        .clk(clk),
        .reset(reset),
        .SCL(dvi_scl),
        .SDA(dvi_sda)
    );
    
endmodule    


(2012/07/26:Verilogソースを修正)
ただし、Virtex-6では、ODDR2プリミティブではなく、ODDRプリミティブだったはずだ。

(2011/04/25:追記)
SP605では、CH7301Cの設定レジスタがコンフィグROMで初期化されていたようです。初期化されていないXUPV5-LX110Tでは、CH7301Cの設定レジスタを設定しないとディスプレイに表示できなかったです。
CH7301Cの設定レジスタを設定する必要があります。

(2011/04/26:追記)
現在使用しているCH7301Cの設定レジスタの設定値は、”XPS Thin Film Transistor(TFT) Controller (v2.00a)”の6ページの”Table 2: Chrontel CH-7301 Configuration Register Description”と同一の設定値を使用している。Table 2: Chrontel CH-7301 Configuration Register Descriptionを下に引用する。
XUPV5-LX110T_CDispC_1_110426.png

CH7301Cの設定レジスタを設定する回路は、OV7670のSCCB設定レジスタの設定回路のID_ADDRESSを0xECに変更して使用した。
SCCB設定レジスタ設定回路の資料。
SCCBインタフェース回路の実装1(タイミングチャート)
SCCBインタフェース回路の実装2(ブロック図の作成)
SCCBインタフェース回路の実装3(シミュレーション)
SCCBインターフェース回路の説明1(SCCB_Reg_Controller.vhd)
SCCBインターフェース回路の説明2(freqdiv.vhd、SCCB_reg_values_ROM.vhd)
SCCBインターフェース回路の説明3(One_Transaction_SCCB.vhd)

更に、OV9655のID_ADDRESSに書き換えたときの参考資料がここにある。

(2011/06/02:追記)
dvi_de, dvi_h, dvi_v の出力用FFがIOBにマップされないと画面が表示されないので、Verilogソースに(* IOB = "FORCE" *)制約を追加した。
  1. 2010年07月13日 20:45 |
  2. Spartan-6 FPGA SP605 評価キット
  3. | トラックバック:0
  4. | コメント:0

トイ・ストーリー3を見てきました

今日は9時10分からイーアスで、トイ・ストーリー3を見てきました。トイ・ストーリーは1,2と見てきたので、ぜひ3も見てみたいと思っていました。期待に違わず、大人が見ても面白かったです。最後には泣かされました。おもちゃには遊んでもらうのが良いのでしょうね?トトロも出てましたよ。
お昼はフードコートで幸楽苑の煮玉子いりラーメンを食べてきました。煮玉子が黄身だけとろとろで、絶品でしたね。
その後は、高校の娘の英検2級の面接試験だったので、土浦第3中学校に送って行きました。車は、ジョイフル本田に置いて歩いて行きました。試験が終わるまで、ジョイフル本田でお買い物です。木材を色々みたり、工具をみたりしました。以前から欲しかった小さい差金とよく切れる3Mの紙やすりを買いました。木材は桐の板があって、今度作ろうと思っている家具にぴったりのようでした。今度は木のトランクをつくろうと思っています。軽い木で作らないと重すぎて持ち歩けません。
案外早く娘が帰ってきたので、家に帰って投票に行きました。投票した人が当選するかや、自分が投票した党が議席を伸ばすかが楽しみですね。
どうでしょう?明日の朝には情勢が決まっているでしょう。
  1. 2010年07月11日 20:35 |
  2. 日記
  3. | トラックバック:0
  4. | コメント:2

Spartan-3A Starter KitでCMOSカメラ・ディスプレイ回路2(レイテンシの測定)

Spartan3A Starter KitのビットマップVGAコントローラの仕様3(レイテンシの測定)”と”Spartan3A Starter KitのビットマップVGAコントローラの仕様3(レイテンシの測定2)”でDDR2 SDRAMのレイテンシを測定して、VGAコントローラの非同期FIFOの深度を決定した。
今度もDDR2 SDRAMコントローラのレイテンシ込みのDDR2 SDRAMのレイテンシを測定してみる。以前のDDR2 SDRAMの動作周波数は150MHzだったが、今回は133MHzに変更してある。

DDR2 SDRAMの動作周波数が150MHzの場合のinitialize_end が1(初期化が終了)してから最初のWriteアクセスを見てみる。
BitMaped_VGA_Controller_4_090108.gif

この場合のWriteレイテンシは約87nsec となった。(黒いカーソルから赤いカーソルまで)上図で説明すると、read_writeが0の時がWriteなので、addr_fifo_wrenが1の時にアドレスの書き込みとなって、ここでDDR2 SDRAMへのWriteを要求している(同時にWriteデータもFIFOに書き込んでいるはず)。そこからDDR2 SDRAMのWriteした時点までをWriteレイテンシとしている。
次に、DDR2 SDRAMの動作周波数が133MHzの場合のinitialize_end が1(初期化が終了)してから最初のWriteアクセスを見てみる。
CamDispCntrler_DDR2_5_100710.png

レイテンシは97.5nsecとなった。87nsec * 150MHz / 133.33MHz = 97.9nsecとなって、大体、97.5nsecと同一となった。これは、動作周波数のみ変更しているので、当たり前といえば当たり前だ。
後は全部計算してみる。
READ要求を入れてからデータがREADできるまでのレイテンシは150MHzの時に147nsec だったので、133MHzでは165nsec。下の図は150MHzの例。
BitMaped_VGA_Controller_5_090108.gif

次にリフレッシュによるレイテンシについて検証する。次のバーストのためにプリチャージしてACTコマンドを入れたときにリフレッシュが起きて、また同じACTコマンドを入れ直している例だ。以前の150MHzの例を下図に示す。
150MHzの時に、180nsec のレイテンシが増加しているので、133MHzでは約203nsecとなる。
BitMaped_VGA_Controller_6_090109.gif

ROWアドレスやバンクが異なる(つまりプリチャージ、ACTコマンドを入れなければならない)Write, ReadコマンドがFIFOに詰まっている場合のレイテンシについて検討してみる。下図に150MHzの場合を示す。
BitMaped_VGA_Controller_7_090110.gif

上図は、DDR2 SDRAMコントローラへのWrite, Read要求用のFIFOがFULLになったところのRead要求を入力してから、Readされた値がoutput_data に出てくるまでの時間を測定している。測定した時間は1340nsec という情けないような値だ。これを133MHzに変換すると1507nsecとなる。これをCMOSカメラの入出力周波数25MHzの周期40nsecで割ると、約38となる。これは、DDR2 SDRAMコントローラがフルに使われている状態からVGA DISPLAY CONTROLLERが読み出しそうとして、表示するデータがロストしない表示データの最小バッファ値を表す。つまり、ARBITERがVGA DISPLAY CONTROLLERを最優先にするときに38データをVGA DISPLAY CONTROLLERで貯めておけば、表示するデータはなくならないことになる。ということで非同期FIFOの深度は64で十分ということになる。非同期FIFOが半分の容量になったときに、VGA DISPLAY CONTROLLERはARBITERに表示データの要求を出すので、非同期FIFOの容量は64ではなく、倍の128深度ということになる。(あくまで、25MHzのUYかVYの1画素(16ビット)単位での値)(2010/07/14:訂正)
この構成では、DDR2 SDRAMに各モジュールはCMOSカメラのみで、DDR2 SDRAMコントローラのコマンド用FIFOがフルに書かれる状態はないので、(CMOSカメラの書き込みスピードは25MHzだが、書き込みのビット幅がDDR2 SDRAMの1/4、動作周波数の差も0.19倍なので、コマンド用FIFOがフルになるはずがないからだ)十分すぎる余裕がある。
IPとして使用するときに、別に接続した他のモジュールからどんどんDDR2 SDRAMがアクセスされても大丈夫だ(ARBITERがVGA DISPLAY CONTROLLERを最優先するという条件は必要)。

これで、DDR2 SDRAMのレイテンシに関する検討は終了とする。
  1. 2010年07月11日 05:26 |
  2. 画像処理
  3. | トラックバック:0
  4. | コメント:0

Spartan-3A Starter KitでCMOSカメラ・ディスプレイ回路1(ブロック図)

Spartan-3A Starter KitでCMOSカメラ・ディスプレイ回路を組んでみようと思っている。

(仕様)
CMOSカメラはaitendoのOV7670とする。このOV7670に25MHzクロックを入力することにする。標準は24MHzだが、Spartan-3A Starter Kitのクロックは50MHzなので、25MHzだと2分周で作ることができる。
Spartan-3A Starter KitのCMOSカメラのデータ入力は、受信ヘッダ(J2)か、送信ヘッダ(J15)を使う。受信ヘッダの法を優先して使おうと思っているが、使えない場合は送信ヘッダを使う。1つのヘッダの入出力ピンの数が2本足りないので、SCCBは使わないことにする。接続する信号ピンの位置が不規則なので、aitendoのピンヘッダ用接続ケーブ[CB-PH10P-250] を使って、CMOSカメラとSpartan-3A Starter Kitを接続することとする。

全体のブロック図を下に示す。
CamDispCntrler_DDR2_1_100708.png

以前のSRAMをDDR2 SDRAMに変更した。それに伴って、DDR2 SDRAMコントローラを付けるようにした。以前はクロックごとにSRAMへRead, Writeを繰り返していた。今回は、以前に作成してバグがあってお蔵入りのSpartan3A Starter KitのビットマップVGAコントローラの仕様をいただいて、AERBITERを付けて、VGA DISPLAY CONTROLLERからのRead要求とCAMERA CONTROLLERからのWrite要求をアービトレーションしようと思っている。前回作ったキャラクタ描画テスト回路よりはアービタの構造が簡単なので、でバックしやすいと思う。前回作ったが、途中で挫折したキャラクタ描画テスト回路の概要はVGAコントローラのカテゴリの”Spartan3A Starter KitのビットマップVGAコントローラの仕様1”以降を参照のこと。(キャラクタ描画テスト回路は、途中まで、それなりに動いているが時間が経つとおかしくなってしまっている。デバックするのは大変なので、ペンディングになっている)

・データの粒度も考慮する必要がある。DDR2 SDRAMのWriteの粒度は16ビット幅で4バーストとなっていて、つまり8バイト単位でRead, Writeする必要がある。CAMERA CONTROLLERもVGA DISPLAY CONTROLLERも8バイト単位でWrite, Readすることとする。
・DDR2 SDRAMコントローラは前回は150MHz動作だったが、今回は133MHz動作に落として使用することにする。150MHzだとどうしてもタイミングエラーを消すのが難しい。
・VGA DISPLAY CONTROLLERのタイミングの検証は、ビットマップVGAコントローラで行ったものを流用する。”Spartan3A Starter KitのビットマップVGAコントローラの仕様2”、”Spartan3A Starter KitのビットマップVGAコントローラの仕様3(レイテンシの測定)”、”Spartan3A Starter KitのビットマップVGAコントローラの仕様3(レイテンシの測定2)”などに詳しく書いてあるので、それを流用する。ただし、動作周波数が変更になっている。DDR2 SDRAMコントローラが133MHz、入出力回路は25MHz動作となる。前回は150MHz, 65MHzだったので、前回よりも条件は緩くなる。
・VGA DISPLAY CONTROLLERのRGB出力は8ビットだが、Spartan-3A Starter Kitには、抵抗分割のRGBそれぞれ4ビット分しかないので、上位4ビットを使用する。(追記、忘れてました)

・CAMERA CONTROLLER
CAMERA CONTROLLERは、Address生成回路と非同期FIFOを主に持っている。Address生成回路はHREFやVSYNCからアドレスを生成する。アドレスのビット幅は19ビットとなる。
非同期FIFOは、32ビット幅のデータ(2つの画像ビットの情報UYVY)と19ビットのアドレスの幅を持つ。深度は取り敢えず256深度とするが、VGA DISPLAY CONTROLLERのバス占有時間によっては見直すこととする。
下にCAMERA CONTROLLERのブロック図を示す。
CamDispCntrler_DDR2_2_100709.png

・VGA DISPLAY CONTROLLER
VGA DISPLAY CONTROLLERは、前述した以前のビットマップVGAコントローラと同様の構成を取るが、DDR2 SDRAMコントローラからReadされるデータはRGBではなく、UYVYなので、非同期FIFOの後にYUV-RGB変換回路を付けてRGBに変換し、抵抗ラダー回路に送る。
下にVGA DISPLAY CONTROLLERのブロック図を示す。
CamDispCntrler_DDR2_3_100709.png

下にピクセルデータ管理モジュールのブロック図を示す。
CamDispCntrler_DDR2_4_100709.png

・ARBITER
ARBITERは、VGA DISPLAY CONTROLLERの要求を優先して処理する。VGA DISPLAY CONTROLLERの非同期FIFOがFULLになってから、CAMERA CONTROLLERのWrite要求を処理する。CAMERA CONTROLLERがWrite出来る状態を示すためEnable信号を用意する。VGA DISPLAY CONTROLLERの制御信号としてはREQとGNTを使用する。
ARBITERは、CAMERA CONTROLLERとVGA DISPLAY CONTROLLERからアドレスと32ビット幅のデータを受け取って、DDR2 SDRAMコントローラにRead, Write処理を投げる。

・DDR2 SDRAMコントローラ
DDR2 SDRAMコントローラは、Spartan3A Starter KitのDDR2 SDRAMコントローラを流用するが、150MHz動作ではタイミングを満たすことが難しいので、133MHz動作に変更する。もう一度タイミングを検証するか?検証するのが面倒なときは動作周波数のみ133MHzとする。(それでも大丈夫なはず?)

(2010/7/12追記:133MHzでのDDR2 SDRAMコントローラの動作を確認しました。ISE12.1でインプリメントした際にもタイミングの収束が150MHzよりもスムーズのような気がします)
  1. 2010年07月08日 05:57 |
  2. 画像処理
  3. | トラックバック:0
  4. | コメント:0

Verilog HDLでの初期化の推論

Xilinx社で行われたSpartan-6ファミリ デザイン セミナで、XSTのみHDLでの初期化の推論ができると聞いてきた。Synplfyではどうかと思ってやってみた。使用したのは訳あってISE10.1.03とSynplify Pro 9.6.2。使用したFPGAはSpartan-3E1200(xc3s1200e-fg320)。
下のソースを使用した。

`default_nettype none
`timescale 1ns / 1ps

module init_test(
    input clk,
    input enable,
    output [15:0] cnt_out
    );
    
    reg [15:0] cnt = 16'd1; // 初期化(ここの値がFFの初期値になっていればOK)
    
    always @(posedge clk) begin
        if (enable)
            cnt <= cnt + 1;
    end
    assign cnt_out = cnt;
        
endmodule


まずはSynplify Proで論理合成、インプリメントした。
Verilog_RST_1_100706.png

FPGA Editorでcnt[0], cnt[1]を見てみたが、ちゃんとcnt[0]のFFがINIT1, cnt[1]のFFがINIT0になっている。
Verilog_RST_2_100706.png

Synplify ProでもVerilogでの初期化の推論が出来ているようだ。
次に論理合成ツールをXSTに変えてやってみた。
同様に、FPGA Editorでcnt<0>, cnt<1>を見てみたが、ちゃんとcnt<0>のFFがINIT1, cnt<1>のFFがINIT0になっている。
Verilog_RST_3_100706.png

XSTでもSynplify ProでもVerilog HDLでの初期化の推論が出来ていた。
  1. 2010年07月06日 17:31 |
  2. FPGAチップ内の配線方法
  3. | トラックバック:0
  4. | コメント:0

開発効率を引き上げるディジタル・ハードウェアの検証技法セミナに申し込み

8月19日に行われるCQ出版社のセミナ、”開発効率を引き上げるディジタル・ハードウェアの検証技法”に申し込む予定です。
本当は7月9日の同じセミナに申し込んだんですが、参加人数が足りなくて中止になってしまいました。がっくり。
8月20日には、大事な仕事があるんですが、大丈夫だろう?ということで、今日、申し込むことにしました。
SystemVerilogの基本や検証用ライブラリ「VMM」の基本について学んでこうと思います。楽しみです。

SystemVerilogの勉強もしようと思って、買ってあった本も引っ張り出してきました。どれか今までつくってきた回路をSystemVerilogで書きなおしてみたいと思います。

やりたいことは目白押しなんですよね。
1. aitendoさんのカメラモジュール(OV7670)をSpartan-3A Starter KitとDE0につないでみようと思っています。SP605にもつなぎたいです(こっちはカメラモジュールの改造が必要?)。
2. Auroraをやってみたいという計画も進行中ですが、これは合間を見てということになります。
3. SP605でせっかく色々なモジュールやSpartan-6の勉強をしてきたので、システムとして1つ作ってみたいです。
4. カメラモジュールを搭載したカメラ基板を設計してみたいです。
5. SystemVerilogの勉強。回路の書き直し。

今年52歳になりますが、色々やってみたいという欲は限りがない感じがします。どうしよう?
  1. 2010年07月06日 04:07 |
  2. その他のFPGAの話題
  3. | トラックバック:0
  4. | コメント:4

XUP USB-JTAG Programming Cable

職場で買ったXUP USB-JTAG Programming Cableが届きました。箱が小さいです。
XUP_ProgCable_1_100705.jpg

箱の中の物をすべて出すと。。。
XUP_ProgCable_2_100705.jpg

下にシャープペンシルを置いてみました。
早速、Spartan-3 Starter Kitをコンフィギュレーションしてみました。フライングワイヤと2mmピッチヘッダの両方からやってみましたが、私の環境では問題なくiMPACTからコンフィギュレーションできます(OSはWindows7 32bit版、ISE11.5)。
XUP_ProgCable_3_100705.jpg

ChipScope Proも試してみましたが、問題なく動作しました。
MIPSプロセッサの実験に使用します。
  1. 2010年07月05日 04:43 |
  2. その他のFPGAの話題
  3. | トラックバック:0
  4. | コメント:2

メガネを購入した

昨日は、メガネをかけている下の娘が目が悪くなったということで眼科に行ってきたのだが、私も視力を測定しもらってメガネを作ることにした。今までのメガネは10年以上使っていて、レンズに大分傷が入ってきた。
さて、眼鏡のレンズの度数を測ってもらうと、今までのよりも弱い度数の方が良いとのこと、今までの度数は左右5.25だったが、右4.75, 左5.00の方が良いとのことだった。若いうちは、どんどん眼鏡のレンズの度数が進んでいったが、年を取ってくると、眼鏡の度数が減ってきた。老眼になっていくということかもしれない。
メガネの処方箋を娘と共にもらったので、早速メガネ屋へ行った。イーアスのJINSというメガネ屋に行った。ここは以前、息子のメガネを作ったことがあり、眼鏡の度数にかかわらずに表示された価格で購入ができる。
私は、今まで色々メガネを作ったが、とても嫌な思いをしてきた。例えば、レンズ込みで1万円というメガネを買っても、眼が悪いので、追加2万円ね!というように、レンズの追加料金の方が高い時が多かった。なんかボッタくられたみたいな気がしてしょうがなかった。”あなたの目が悪いから、お金がかかるんですよ”と言われているような感じがしてしょうがなかった。メガネを買うのが嫌だったが、今度は安心して買うことができる。
以前かけていたメガネはパリミキで確か5万5千円程度だったが、今回買ったメガネは5千円だった。最近、薄利多売のメガネ屋が増えているみたいだ。うれしい。。。
下の写真が持っているメガネ。左上が今回買ったメガネ。グリーンを買ってしまった。右上が以前のメガネ。左下が読書用のメガネ。右下がパソコン用のメガネ。老眼なので、各シチュエーションで一番良く見える度数に合わせてある。遠近両用は3面ディスプレイを見るときに歪んでしまうので却下。
#娘のメガネも買いましたよ。こちらは6千円でした。
mengane_100704.jpg
  1. 2010年07月04日 05:33 |
  2. 日記
  3. | トラックバック:0
  4. | コメント:3

SP605のIBRETデザイン

SP605 GTP IBERT デザインの生成 (XTP066)”を見ながら、IBRETデザインを試してみた。
SP605 GTP IBERT デザインの生成 (XTP066)の11ページで紹介されていたSMAケーブルは、秋月電子から両端SMAケーブル RG-316(1.5m)を購入した。1本700円でとても安かった。多分、普通の値段の1/10くらいじゃないだろうか?これでも(と行っては失礼か?)ケーブルの特性的には3GHzまで通るそうだ。ということは6GbpsまでOKということか?
取り敢えず、12、13ページの用にSP605のSMAコネクタのJ32とJ34、J33とJ35をSMAケーブルで接続した。
14ページのOptical Loopback Adapterは買っていないので、このままやることにした。
IBERT_4_100703.jpg

ChipScope Pro (以下ChipScope)から、sp605_ibert.bitをコンフィギュレーションして、sp650_ibert.cpjのプロジェクトをロードする。
20ページで、GTPA1_DUAL_X0Y0_0とGTPA1_DUAL_X1Y0_1に近端PMAループバックを設定したつもりだったが、プロジェクトのデフォルト設定のままにしたら、近端PCSループバックだった。それで出たのが下の画像だ。
SP605_IBERT_1_100701.png

GTPA1_DUAL_X1Y0_0がNo Linkになっている。どうやらここが、SPFコネクタ/ケージのGTPトランシーバのようだ。GTPA1_DUAL_X0Y0_1がSMAケーブルで接続したGTPトランシーバらしいが、安いケーブルでも無事に2.5Gbpsでエラーなしに通信ができている。
あれ、やっているときは気がつかなかったが、両端の2つのGTPトランシーバは近端PCSループバックになっている。近端PMAループバックにするのを忘れてしまった。でも両端ともエラーはない。
さて、GTPA1_DUAL_X1Y0_0を近端PCSループバックにしてみた。だが、他のGTPトランシーバに比べて、RX Bit ErrorRatioが悪く、RX Received Bit Countもかなり出ている。(下図)どうしてだろうか?
SP605_IBERT_2_100701.png

GTPA1_DUAL_X1Y0_0を近端PMAループバックにしてみた。(下図)エラーはなくなってしまった。
SP605_IBERT_3_100701.png

どうしてだろうか?そこで、Spartan-6 FPGA GTPトランシーバ・ユーザーズガイド Ver.2.0 で調べてみた。67ページのループバックによると、近端PCSループバックが一番浅い所のループバック①で近端PMAループバックがそのつぎ②、遠端は通信相手のGTPトランシーバでループバック③、④する。下に英語版のFigure 2-14: Loopback Testing Overviewを引用する。
SP605_IBERT_4_100703.png

しかし、近端PCSループバックでエラーが出て、近端PMAループバックでエラーなしというのはどういう訳だろう?ループバックの部分が悪いのか?謎だ?でも近端PMAループバックでエラーなしなので、取り敢えずGTPトランシーバの動作には問題ないだろう?と思う。良かった。

(2010/07/13追記)
Xilinxのアンサーに”34203 - 11.x ChipScope - IBERT - Spartan-6、Virtex-5、Virtex-6 - PCS ループバックでエラー レートが増加する”というアンサーがあった。やはり、既知のバグのようです。
  1. 2010年07月03日 05:45 |
  2. Spartan-6 FPGA SP605 評価キット
  3. | トラックバック:0
  4. | コメント:0

2010年の”FPGAの部屋”の月別アクセス数、半年分

今年も半分終わってしまったが、2010年の”FPGAの部屋”の月別アクセス数は半年分で264,894アクセスだった。皆さん、見ていただいてありがとうございました。
Access_100702.png
  1. 2010年07月02日 19:12 |
  2. その他のFPGAの話題
  3. | トラックバック:0
  4. | コメント:0

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

ChipScope ProのVIOを使う1

ChipScope ProのVIO (Virtual Input/Output core)について書いておこうと思う。VIOは、ChipScopeで、VirtualなI/Oを実現できる。基板にスイッチやLCD,LEDがなくても、値を入力できたり、値を出力して目で見ることができる。スイッチや表示器が実装されていない基板で、便利に使用することができる。Spartan-6ファミリ デザイン セミナで実習をしてきたので、何時か使ってみたいと思っていた。
今回は、CMOSカメラ画像出力回路(これよりは、研究用にいろいろな回路を追加してある)の各値の1フレームあたりの出現数を見るのに使用する。

さて、最初にICONコアをプロジェクトに追加する。このへんも参照のこと
Hierarchyウインドウで右クリックメニューからNew Source...を選択して、New Source Wizardを表示させる。Select Source TypeからIP(CORE Generator & Architecture Wizard) を選択する。File Nameにvio_iconと入力して、Nextボタンをクリックする。
cs_vio_1_100618.png

New Source WizardのView by FunctionのDebug & Verification からChipScope Pro を選択し、その下のICON (ChipScope Pro - Integrated Controller) を選択する。Nextボタンをクリックする。
cs_vio_2_100618.png

Summaryが表示される。Finishボタンをクリックする。
cs_vio_3_100618.png

ICON (ChipScope Pro - Integrated Controller) のWizardが表示される。今回は4つのVIO+1つのILAコアを使用するので、Number of Control Portsを5にしてGenerateボタンをクリックして、ICONコアを生成する。
cs_vio_4_100618.png

Project Navigatorにvio_iconが追加された。
cs_vio_5_100618.png

次にVIOコアを追加する。
同様に、Hierarchyウインドウで右クリックメニューからNew Source...を選択して、New Source Wizardを表示させる。Select Source TypeからIP(CORE Generator & Architecture Wizard) を選択する。File Nameにvio_a と入力して、Nextボタンをクリックする。
cs_vio_6_100618.png

New Source WizardのView by FunctionのDebug & Verification からChipScope Pro を選択し、その下のVIO (ChipScope Pro- Virtual Input/Output) を選択する。Nextボタンをクリックする。
cs_vio_7_100618.png

Summaryが表示される。Finishボタンをクリックする。
cs_vio_8_100618.png

VIO (ChipScope Pro- Virtual Input/Output) のWizardが開く。vio_aは、Synchronous Inputを152ポートとSynchronous Outputを6ポート使用する。Enable のチェックをチェックして、それぞれの値を入力し、Generateボタンをクリックする。
cs_vio_9_100618.png

vio_aが生成された。
cs_vio_10_100618.png

今度は、次のVIOコアを生成する。vio_hと名前をつけて、Synchronous Outputは無しで、Synchronous Inputを152ポート使用する。
cs_vio_11_100618.png

vio_hと同様に、vio_v, vio_dを作成した。
cs_vio_12_100618.png

次にilaコアも入れてコアを完成させた。
cs_vio_13_100618.png

第1回目終了。

ChipScope ProのVIOを使う2”へ続く。
  1. 2010年07月01日 18:59 |
  2. Chipscope
  3. | トラックバック:0
  4. | コメント:0