FC2カウンター FPGAの部屋 2009年03月

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

FPGAの部屋

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

Spartan3A Starter KitのDDR2 SDRAMコントローラの途中経過5(ロジックセルの固定の微調整)

”Spartan3A Starter KitのDDR2 SDRAMコントローラの途中経過4(ロジックセルを固定する)”でロジックセルを固定したが、微妙な遅延差が残った。今回は微妙な遅延差の解消を目指す。

まずはIOBから非同期FIFOまでのネットが約0.4ns のDQ0と同じく0.7ns のDQ1の違いを考察することにする。まずはDQ0から下の図にFPGA Editorで見たIOBから非同期FIFOまでのネットを示す。
Spa3A_DDR2_25_090325.png

DQ0はIOBと非同期FIFOのロジックが同じ行にある。IOBから最初につながっているスライス(フロアプランの位置で言うとX0Y62)と次のスライス(X2Y63)はX方向(行方向)が異なっているが、遅延の差は5ps だった(0.405ns と0.410ns)。
次にDQ1を見てみよう。下にDQ1のにFPGA Editorで見たIOBから非同期FIFOまでのネットを示す。
Spa3A_DDR2_26_090325.png

これはIOBとスライスの列方向の位置が違っている。この遅延はどちらのスライスも0.700ns と大きい。やはり列方向に配線するのに遅延が大きくなっているのだろうか?なるべく、列方向が異なる配置にならないようにもう一度Floorplannerで配置をやり直すことにする。
もう一度、Floorplannerを立ち上げてよく見てみると、IOBとスライスの間が2重線でつながれているところがある。そこが列が違うところのようだった。
Spa3A_DDR2_27_090325.png

2重線をネットがまたがないように位置を並べ替えた。そして、この状態でインプリメントし、Timinig Analyzerで見たところ、IOBから非同期FIFOまでのネットの遅延が0.7ns程度のものがある。どうやら区画の上側のIOパッドから、その区画のSLICEM(分散RAMになるのはSLICEMのみです)に行くネットの遅延が大きいようだ。下にDQ1のネットを示す。0.7ns程度の遅延だ(ピンクの四角の部分)。
Spa3A_DDR2_28_090330.png

これは困った。スイッチファブリックのスイッチルートが悪いのだろうか?
更に、区画内の上側のIOパッドから少ない遅延時間で接続できるSLICEM(非同期FIFOの入り口のロジックセル)を探してみることにした。その結果、上の区画のX0の位置の2つのSLICEMに接続すれば0.481ns の遅延で接続できることがわかった。
Spa3A_DDR2_29_090330.png

この結果、区画の下側のIOパッドは同じ区画のSLICEMに接続すれば遅延が少なく、区画の上側のIOパッドは上の区画のX0の2つのSLICEMに接続すればやはり遅延が少ないことがわかった。
上の法則にしたがって、さらにもう一度Floorplannerで配置をやり直す。
これでインプリメントしたら失敗してしまった。FPGA Editorで見たIOパッドの位置とFloorplannerで見た区画内のIOパッドの位置は逆のようだ。それを考慮して、Floorplannerで逆に配置する。
実際には下の図のように配置した。
Spa3A_DDR2_30_090330.png

これでIOパッド(IOB)から非同期FIFOまでのネットの遅延は0.401ns、0.411ns と0.481ns になったが、DQ7のネットのみ、ロングライン配線の通っている(横切っている)数が多いようで、間が広いようだった?そのため遅延が0.543ns と多くなってしまった。それでも、最大遅延と最小遅延の差は142ps になった。これはこの辺でいいだろうというか、これ以上改善は難しいと思う。
  1. 2009年03月30日 22:00 |
  2. Spartan3A Starter Kit
  3. | トラックバック:0
  4. | コメント:0

2009年のF1初戦

2009年のF1初戦は、オーストラリアから開幕だった。昨日の午後4時からのTV放映があったので、テレビの前でどうなるかわくわくしながら見ていた。
結果はブラウンGPの1,2フィニッシュ。ホンダが撤退してしまって、もったいないと思った。撤退していなければ、今頃ホンダ優勝でお祭り騒ぎだったのではないか?本当に残念だけど。ブラウンGPには心からおめでとうと言いたい。
それとも、ホンダエンジンじゃなくてメルセデスになったのが良かったのかな?
その後は、録画してあった激走GTを見た。近藤真彦監督、国内初優勝おめでとう。
夕方はレース観戦漬けだった。
  1. 2009年03月30日 05:45 |
  2. 日記
  3. | トラックバック:0
  4. | コメント:0

Spartan3A Starter KitのDDR2 SDRAMコントローラの途中経過4(ロジックセルを固定する)

”Spartan3A Starter KitのDDR2 SDRAMコントローラの途中経過3(フロアプランを試す)”でフロアプランのエリア制約をかけてみたところ、IOパッドから分散RAM使用のFIFOの入り口までのネットの遅延がばらばらという問題があった。これを入り口のロジックセルを狙い撃ちして位置を固定することで遅延の短縮ならびに、平均化を図ることにする。

現在のISEのバージョンは10.1SP3。
まずはProject Navigater のProcessesウインドウのImplement Design -> Place & Route -> View/Edit Placed Design (Floorplanner) をダブルクリックする。
Spa3A_DDR2_16_090325.png

Floorplannerが立ち上がる。エラーの嵐。どうやらRISINGやFALLINGなどの新しいキーワードが入った制約はエラーになるようだ。どうもXilinxのツールはツール同士の互換性が取れていない場合が多い気がする。本当はこの辺は無料版でないISEにバンドルされているPlanAheadでやるという予定になっているのかもしれない?
Spa3A_DDR2_15_090325.png

とりあえずエラーをすべて無視すれば、Floorplannerが使えるようになった。
Spa3A_DDR2_17_090325.png

Floorplannerはエラーがでるので、FPGA Ediotrとかでロジックセルを固定してもいいのだが、どのロジックセルがIOパッドからつながっているかが良くわからない。Timing Analyzerのインスタンス名とFPGA Editorのコンポーネント名が微妙に違っている見たいなので、エラーがでても、わかりやすいFloorplannerからやることにした。インプリメントが終了した時点でFloorplannerを起動すると、インプリメントされたロジックセルの位置を表示するウインドウ(上の図ですでに開いている右側のウインドウ)と、制約ファイルに反映させるためにロジックセルをフロアプランし固定するためのUCF Flowのウインドウが開く(いずれも右側のウインドウで、右側のウインドウの上にウインドウの上の部分だけが表示されている)
この辺は、私のブログの”Floorplannerの使い方”を参照。
昔のISEでは、Timing AnalyzerからFloorplannerを呼べて、選択したルートはFloorplanner上で選択され、どのように接続されているかがわかったのだけれど(Crossprobeができた)、しょうがない。あれれ、もしかしてTiming Analyzerを単体で立ち上げると、まだそれができたりするのかな?
やってみることにする。Floorplannerを閉じて、Windowsメニューから、Xilinx Design Suite 10.1 -> ISE-> Timing Analyzer を選択して、Timing Analyzer を立ち上げる。そうするとダイアログが出てくる。
Spa3A_DDR2_18_090325.png

ここで、一度、ISE project file に現在のプロジェクトを入力したらISEごともう1つ立ち上がってしまった。失敗。。。ダイアログの項目は何も入力しないでOKボタンをクリックすると、以前のTiming Analyzerが立ち上がる。
Spa3A_DDR2_19_090325.png

FileメニューからOpen Design... を選択して、Open Design ダイアログを開いて、Designファイルを選択するとPhysical Constraints Fileも選択されるはず。これでOKボタンをクリックしよう。
Spa3A_DDR2_20_090325.png

Analyze against Timing Constraints アイコンをクリックして、タイミング制約を解析する。
Spa3A_DDR2_21_090325.png

解析できたら、”Floorplannerの使い方覚書1”を参考にFloorplannerでCrossprobingしよう。CrossprobingするとFloorplannerが立ち上がる。パスを選択するとインスタンスとネットが選択された状態でFloorplannerで見えるんだけど、なぜか制約で位置を固定したIOBが見えないので、この方法は使えない。その代わり、分散RAMを使用したFIFOの入り口のインスタンスをTiming Analyzerでクリックし、Floorplanner上でも選択させて、UCF Flow にコピーする。
Spa3A_DDR2_22_090325.png

UCF Flow を見ると今選択したインスタンスがコピーされている。
Spa3A_DDR2_23_090325.png

このロジックセルは近くに配置されていて、これで良いような気もするが、ドラックアンドドロップで更に近くに配置する。これをすべてのDQに対して行っていく。下がDQ15までに行った結果。
Spa3A_DDR2_24_090325.png

これでセーブしたところ、また大量にエラーが出てしまった。エラーがでたRISING, FALLINGなどのキーワードが入った制約はなくなってしまったので、あらかじめセーブしておいたバックアップを戻して、Floorplannerで書き加えた以下のような制約を追加した。

INST "rddata_afifo_inst/RDDATA_AFIFO_FALL[3].DQS2intclk_FIFO_FALL/BU2/U0/grf.rf/mem/gdm.dm/Mram_RAM8" LOC = "SLICE_X2Y78" ;


これでもう一度インプリメントしてみた。Timing Analyzerの結果を見ると、IOBから分散RAM使用、非同期FIFOまでのネットの遅延は0.401ns ~ 0.969ns となった。その差、0.568ns と少なくなったが、もう少し調整する必要がありそうだ。もう少し追い込んでみたい。

2009/03/30 追記:
3つのロジックセルを配置するのを忘れていた。全部配置したら、IOBから非同期FIFOまでのネットが0.4ns ~ 0.7ns に収まった。約300ps 位の差、もう少し調整してみたい。
  1. 2009年03月29日 15:58 |
  2. Spartan3A Starter Kit
  3. | トラックバック:0
  4. | コメント:0

NT京都のニコニコ動画

ニコニコ動画でNT京都の撮影できますPさんとアルテラマスターPさんのプレゼンの動画があった。
撮影できますPさんのほうはFPGAでオールハードウェアの実装。アルテラマスターPさんのほうはNiosで動画用の命令をカスタマイズしての実装。どちらもすばらしい。。。
私も静止画だけど、画像関係をやるので、参考にさせていただこうと思う。
アルテラマスターPさんの”FPGAは己を映す鏡”という言葉が印象に残った。確かにFPGAは真っ白なキャンバスに自分の考えを描いていくので、自分を写しているのかもしれない。(IPとかはありますけどね。。。)
私はあまり何を作りたいという強い欲求がない。。。年を取ったということかな???
まあ、FPGAを良く知りたいという欲求が強いし、FPGA1チップでマイコンシステムを作ってみたいという欲求もある。
FPGAを知って、いろんなものをFPGAで作る仲間が増えてくれれば良いな?と思っている。今回の動画のように自分の知らないことを教えて欲しい。その代わりといっては何だが、細々とFPGAの情報を発信して行こうと思う。





撮影できますPさんのブログには、今回のプレゼンのスライドへのリンクもあった。
  1. 2009年03月28日 07:50 |
  2. その他のFPGAの話題
  3. | トラックバック:0
  4. | コメント:6

Spartan3A Starter KitのDDR2 SDRAMコントローラの途中経過3(フロアプランを試す)

しかし、ブログを書きながらやっているので、なかなかSpartan3A Starter KitのDDR2 SDRAMコントローラも進まないが、記録を残しておくことに意義があると思っている。

前回、”Spartan3A Starter KitのDDR2 SDRAMコントローラの途中経過2(DQSからBUFGをまわしたクロック)”で、お任せでインプリメントをしてみたが、遅延がばらついてしまった。それで今回はFloorplan Editorでエリア制約を試してみることにした。
まずは”ISE10.1iのFloorplan Editorでエリア制約”を参考にPrpcessesウインドウのUser Constrains -> Floorplan Area / IO / Logic - Post-Synthesis をダブルクリックしてフロアプランする。下図の赤いエリアにrddata_afifo_instを配置した。その下のRDDATA_AFIFO_FALL[2].DQS2intclk_FIFO_FALLなどを配置しようとしたが配置できなかった。
Spa3A_DDR2_7_090325.png

フロアプランをセーブすると、制約(UCF)ファイルに以下のフロアプラン(エリア制約)が追加された。
I

INST "rddata_afifo_inst" AREA_GROUP = "AG_rddata_afifo_inst";
AREA_GROUP "AG_rddata_afifo_inst" RANGE = SLICE_X9Y48:SLICE_X0Y79;


これで、もう一度インプリメントして、Timing Analyzerの結果を見てみよう。下がDQ0の入力の結果だ。
Spa3A_DDR2_8_090325.png

その結果、FIFOに行くまでのデータのネット(dq_data<0>) は、7.774ns から0.761ns となり劇的に短くなった。下がそのFloorplan Editorでの配線ルートの図だ。
Spa3A_DDR2_9_090325.png

緑の始点から赤の終点まで配線が非常に短いことがわかる。更に、上でフロアプランされた範囲にロジックが配置されていることがわかる。
次にDQSのクロックのパスだが、上のTiming Analyzer の画面を見ると、3.139ns から2.223ns に短縮されている。クロックのパスを同様にFloorplan Editorでの配線ルートの図を下に示す。
Spa3A_DDR2_10_090325.png

チップの上側のBUFGを使っている。こちらの方がBUFGに入るまでの遅延が少ないようだ。DQの上半分のBUFGに入るまでのクロックパスの遅延は1.998ns なので、DQの下半分のBUFGに入るまでのクロックパスの遅延との差は0.225nsとなった。この辺でBUFGは固定したほうが良さそうだ。

次にDQ9の結果を見ていこう。同様にTiming Analyzerの結果を見てみると、
Spa3A_DDR2_11_090325.png

FIFOに行くまでのデータのネット(dq_data<9>) は、5.544ns から1.761ns と大きく低減された。BUFGに入るまでのクロックパスの遅延dq_clk_node<1>は1.998nsで変わらない。FIFOに行くまでのデータのネットをFloorplan Editorで見てみよう。
Spa3A_DDR2_12_090325.png

だいぶ短いが、DQ0との差が大きい。
今回はRISINGしか見ていないが、FALLINGがわもあるし、更にばらついている可能性もある。すべてのDQを見てみたところ、FIFOに行くまでのデータのネット(dq_data)は最長がDQ12のRISINGで3.086ns、最短がDQ5のFALLINGで0.436nsだった。遅延の差は2.65nsもある。最長のDQ12のRISINGのFloorplan Editorのルート図を下に示す。
Spa3A_DDR2_13_090325.png

これだけ差があっては使えないので、今度はFloorplannerでFIFOの入力素子の位置を固定することにする。

  1. 2009年03月27日 05:44 |
  2. Spartan3A Starter Kit
  3. | トラックバック:0
  4. | コメント:0

Spartan3A Starter KitのDDR2 SDRAMコントローラの途中経過2(DQSからBUFGをまわしたクロック)

”Spartan3A Starter KitのDDR2 SDRAMコントローラの途中経過1”でエラーが解消できたのでDQSをクロックとして使用してグローバルクロックバッファ (BUFG) にまわして、そのクロックをLUTをFIFOとして使った分散RAMを使用した非同期FIFOのクロックとして使ってみた。
たぶん問題としては、DQSはBUFGの専用入力を使用していないので、BUFGに行くまでのネットの遅延が大きくなることが予想される。DQSは2本あるので、DQが8本ごとに1本のDQSをクロックとして使用してデータをサンプルする予定だ。ここで問題なのは、BUFGの位置が決まっているためにDQSごとにBUFGに行く遅延が異なるのではという懸念がある。

さて実際にやってみた結果を検証してみよう。はじめに制約はまだいい加減で、必要な制約もまだまだ足りない。その状態で、どのようなインプリメントになるのかを見ていこう。
下がDQ0のタイミング解析結果だ。ピンクの枠で囲ったのが、DQS0のIOパッドからBUFGまでのネットの遅延で、3.139nsかかっている。かなり遅延している。黄色の枠で囲ったDQ0のIOパッドから分散RAMを使用した非同期FIFOに入る部分の遅延が7.774nsとかなり遅延がある。
Spa3A_DDR2_3_090325.png

次に、DQS0のIOパッドからBUFGまでのネットをFPGA Editorで見てみよう。FPGA Editorで表示したDQS0のIOパッドからBUFGまでのネットを下に示す。
Spa3A_DDR2_4_090325.png

次にDQ9のTiming Analyzerの解析結果を見てみよう。DQ9のクロックリソースはDQS1であるので、DQ0とは違っているはずだ。
下の図で、ピンクの枠で囲ったのが、DQS0のIOパッドからBUFGまでのネットの遅延で、1.988nsかかっている。かなり遅延している。DQ0のIOパッドから分散RAM使用FIFOに入る部分の遅延が5.544nsだった。DQ0と比べるとDQSのIOパッドからBUFGまでのネットの遅延は1.988ns - 3.139ns = -1.151nsの差があり、DQのIOパッドから分散RAM使用FIFOに入る部分の遅延は5.544ns - 7.774ns = -2.230ns の差がある。かなり大きな差となっていると思う。
Spa3A_DDR2_5_090325.png

FPGA Editorで表示したDQS1のIOパッドからBUFGまでのネットを下に示す。
Spa3A_DDR2_6_090325.png

DQS0はFPGAチップの下のBUFGを使っているが、DQS1は上のBUFGを使っている。このようなところにBUFGまでにネットの遅延時間の差が出ていると思う。
とりあえずこれでは使えないので、2つのBUFGがどちらもチップの上の配線遅延が少ないBUFGを使うように位置を固定しようと思う。次に”ISE10.1iのFloorplan Editorでエリア制約”を参考にフロアプランをすることにしようと思う。

  1. 2009年03月25日 21:01 |
  2. その他のFPGAの話題
  3. | トラックバック:0
  4. | コメント:0

Spartan3A Starter KitのDDR2 SDRAMコントローラの途中経過1

Spartan3A Starter KitのDDR2 SDRAMコントローラを作っていますが、いろいろ問題がでてきた。前回は”Spartan3A Starter KitのDDR2 SDRAMコントローラの構想2”で書いたが、DQSのクロックがデータの来るときのみクロッキングして、その他はトライステート状態になっているため、DQのIOB内のFFを使うとデータが足りなくなる話をした。
今回はDQSの入力をクロックとしてBUFGに送っているのだが、その際に最適なIO(つまりクロック専用入力)を使っていないということでエラーになってしまった。
Spa3A_DDR2_1_090324.png

ソースはこんな感じ。

    generate // DQSクロック用BUFG
    genvar k;
        for (k=DDR2_DQS_DM_WIDTH-1; k>=0; k=k-1) begin: DQS_CLK_BUFG_INST
            BUFG BUFG_inst(
                .O(dqs_clk_bufg[k]),
                .I(dqs_clk_node[k])
            );
        end
    endgenerate
    assign dqs_clk = dqs_clk_bufg;


このエラーはXilinxのアンサーの”31290 - LogiCORE Endpoint PIPE v1.7 for PCI Express - ISE 10.1 SP2/SP3 で MAP 中にサンプル デザインで「ERROR:Place:1018」というエラー メッセージが表示される ”に書かれている。ISE10.1からエラーになったようだ。回避方法としては、ISEのエラーにも書かれているが、下のように制約を書けば良いようだ。

NET "ddr2_dqs<0>" CLOCK_DEDICATED_ROUTE = FALSE;
NET "ddr2_dqs<1>" CLOCK_DEDICATED_ROUTE = FALSE;


とりあえず上の制約を加えてもう一度インプリメントしてみたところ、インプリメントが通った。多分、DQSからのクロックがBUFGに行くまでに相当遅延しているかもしれないが、とりあえずタイミング解析をしてみることにする。

以前にISE8.1の時にODDR2を使ってIOBのDDRレジスタを書いたことがあった。その時は"INTERNAL_ERROR"が出て終了してしまったが、ISE10.1では大丈夫だった。下は今回のソース。

    ODDR2 #(
        .DDR_ALIGNMENT("NONE"),
        .SRTYPE("SYNC")
    ) ODDR2_TRI(
        .Q(tri_out),
        .C0(clk90),
        .C1(clk270),
        .CE(tri_ddr_ce_to_io),
        .D0(tri_ddr_d0_to_io),
        .D1(tri_ddr_d1_to_io),
        .R(reset),
        .S(1'b0)
    );
    
    ODDR2 #(
        .DDR_ALIGNMENT("NONE"),
        .SRTYPE("SYNC")
    ) ODDR2_DATA(
        .Q(to_io_pad),
        .C0(clk90),
        .C1(clk270),
        .CE(data_ddr_ce_to_io),
        .D0(data_ddr_d0_to_io),
        .D1(data_ddr_d1_to_io),
        .R(reset),
        .S(1'b0)
    );
    
    IOBUF IOBUF_DQ(
        .O(dq_data_to_io),
        .IO(io_pad),
        .I(to_io_pad),
        .T(tri_out)
    );


下がFPGA Editorで見たDQ9。どちらのODDR2もDDRレジスタにマップされている。
Spa3A_DDR2_2_090324.png

  1. 2009年03月24日 05:42 |
  2. Spartan3A Starter Kit
  3. | トラックバック:0
  4. | コメント:0

自分で作った机にパソコンを置きました

自分でタモ材で作って、オイルフィニュッシュを2度塗りして、3週間乾燥したテーブルをパソコンラックに換えてパソコンを置くようにしました。
今まで狭かった手を置くスペースが広くなって、キーボードが打ち易く、疲れにくくなりました。自分で作ったテーブルでパソコンをするのは本当に気持ちがいいです。まだ、オイルフィニッシュのにおいがしますが、気にならない、いや、結構良いにおいかも?知れません。先生によると塗りすぎとのことでした。今度からは、もっとケチって塗ろうと思います。
PC_table_090322.jpg

左脇に見えるプリンタの置き台も自分で作った長いすです。もっと左側は椅子として使っています。
黒いパソコンの上に載っているのは、ハウルの動く城のヒンという犬です。次はテーブルの下に入れるキャスターつきの書類、基板、部品入れを作りたいですね。でも、その前に食品棚か。。。壁に作りつけの本棚を作れという話も。。。作る予定があるのは目標があって良いことですね。。。
  1. 2009年03月22日 20:28 |
  2. 日記
  3. | トラックバック:0
  4. | コメント:2

Spartan3A Starter KitのDDR2 SDRAMコントローラの構想2

前回の”Spartan3A Starter KitのDDR2 SDRAMコントローラの構想”でDDR2 SDRAMコントローラの回路を考察したのだが、回路をVerilogで書いているうちにまずいところを発見した。
SD_LOOP_DDR2_rev_2_090322.png

それは、上の図でピンクで囲ったDQ用のIOBのDRRレジスタが入っているのが問題だ。Read時のDQSはReadデータの分しかこないため非同期FIFOにデータを最後まで入力することが出来ない。最後のデータはIOBのDDRレジスタに残ってしまうことになる。下の図参照。
Spa3A_StKit_DDR2_timing_2_090322.png

これを解決するには、IOBのDDRレジスタからもデータを取って他の3つのデータとあわせるとか考えられるが、素直な解決策としてはIOBのDDRレジスタを取り除く方法だと思う。
SD_LOOP_DDR2_rev_3_090322.png

この方法はIOBのレジスタを使えないので、タイミング的にクリティカルになるので、大丈夫かな?とりあえずやり始めてしまったので、一度インプリメントしてFloorplanしてタイミング見てみようと思う。
この問題は、以前考えてわかっていたはずなのに、間違ってしまった。忘れるのが早すぎる。。。
やはり、Virtex4のような専用のSERDESがあると、とっても楽だな。。。

PS. 今日は近所のお葬式の手伝いに行くことになって、家具作りサークルには行けなくなりました。茨城の田舎では組合というのがありまして、お葬式の時には助け合うようになっています。
  1. 2009年03月22日 07:04 |
  2. Spartan3A Starter Kit
  3. | トラックバック:0
  4. | コメント:0

花粉症が症状が悪くなった

今日は3連休の真ん中ですね。皆さん、いかがお過ごしですか?
私は花粉症なので、どこにも出かけられません。良い季節なのに、本当に残念なことです。
それに、昨日から、どうも鼻が詰まってしまっています。花粉症が酷くなったと思っているのですが?いまいち風邪との区別がつきません?
DDR2 SDRAMコントローラは継続して作っていますが、IO部分は作り直しているので、進みはのろいです。だいぶ出来てきたので、そろそろReadのタイミングを検証できそうです。

もう1つの趣味である家具作りは長いすを作成中ですが、食品棚も奥さんに作ってくれといわれています。今研修中の3D CADで試しに図面を書いてみました。
food_banq_090321.png

結構、簡単に書けました。四角を書いて、押し出し、の繰り返しです。後は引き出しを書く予定ですが、実物は、とりあえず引き出しはなしです。
これは、明日の午後から先生のところで木材を切ってきます。機械を使わないとなかなか直角に切れないです。それで切っていただくわけです。組み立てはじっくり時間をかけてやろうと思っています。

自宅の庭も梅が散って、桜の花が咲いてきました。これはソメイヨシノではなくさくらんぼがなる木です。たぶんソメイヨシノよりも開花が早いんだと思います。ソメイヨシノはまだ咲いていないです。
cherry_090321

  1. 2009年03月21日 13:58 |
  2. 日記
  3. | トラックバック:0
  4. | コメント:0

Notepad++のVerilogモードに新しいキーワードを追加

Spartan3AのDDR SDRAMコントローラを作っているが、その際にVerilog-HDLコードをNotepad++というエディタを使用して書いている。Verilog2001の文法で書いているのだが、generate やgenvar などのキーワードの色が変わらない。(ピンクの下線の部分) Notepad++はVerilogの文法にしか対応していないようだ。
Notepadpp_1_090318.png

そこで、これらのキーワードを色付けする方法を探ってみた。まずは設定メニューのスタイル設定... を選ぶと、スタイル設定ダイアログが開く。言語:からVerilogを選択して、コメント:からKEYWORD を選択する。ユーザー定義のキーワードにgenerate を入力してみた。
Notepadpp_2_090318.png

だが、色は変わらなかった。
ググってみると、どうやらNotepad++のキーワードはXMLファイルで指定しているようだ。そこでNotepad++ のインストールフォルダを見てみると、langs.xml というファイルがある。このファイルを開いて、Verilogで検索してみると、キーワードを書いているらしいところが見つかった。
Notepadpp_3_090318.png

試しに、ここにVerilog2001のキーワードを入れてみた。下の図でピンクの下線を引いたのが追加したキーワードだ。
Notepadpp_4_090318.png

これでNotepad++を再起動したら、うまくgenerate の色を変えることが出来た。
Notepadpp_5_090318.png

これでうまく行ったが、バージョンが変わって再インストールする場合はどうなるのか?という疑問がある。もしかして上書きされるともう一度書き換える必要が出てきてしまうかもしれない。
どうやらuserDefineLang.xml と言うファイルを Documents and Settings\<ユーザー名>\Application Data\Notepad++ においておけばよいのかもしれない。次はその辺を調査してみたい。
  1. 2009年03月18日 22:04 |
  2. その他のFPGA用ツールについての話題
  3. | トラックバック:0
  4. | コメント:0

Make: Tokyo Meeting 03、徒然日記

Make: Tokyo Meeting 03が5月23日(土)、24 日(日)にデジタルハリウッド大学 八王子制作スタジオで開催されるようです。八王子はうちから遠いです。電車で途中の徒歩を含めて2時間くらいかかるようです。でも、今のところ行こうと思っています。さて、今回はどんな面白いものが見られるか、わくわくですね。

以前のfpga-lab.orgさんが徒然日記というブログをFC2ブログで書いていらっしゃるようです。着々と以前のコンテンツもアップされています。これからが楽しみです。そのうちに私のブログの昔の記事のリンクも張りなおそうかな?
  1. 2009年03月18日 05:15 |
  2. 日記
  3. | トラックバック:0
  4. | コメント:0

DDR2 コントローラとCMOSカメラデータ入力、表示

Spartan3A Starter Kit のDDR2 SDRAMコントローラは、フロアプランすることを最優先に考えて、ブロックごとにフロアプランしやすいように考えて作っている。つまり1個のIOBの形にVerilog-HDLコードを書いて、それをまとめてgenerateでインスタンシエーションする方式にしようと思っている。そうすれば、IOBモジュールをフロアプランしやすくなるはずだ。
これは、Xilinx用だがAlteraでも似た様なもので、ラッパーをかませればポーティングできると思う。非同期FIFOの部分まで出来たらお見せしようと思う。その時にTiming Analyzerで解析が出来てタイミングが検討できることと思う。

お仕事のほうは、新たにイーエスピー企画が出している。画像ベースボード、デジタルCMOSカメラ、208ピンSpartan3E XC3S500+2M高速SRAM基板を購入した。この基板やデジタルCMOSカメラについては、DWM誌の2007年8月号2007年10月号に記事がある。
2007年10月号には、CMOSカメラから取り出したRGBデータをSRAMのフレームバッファに書き込んで、それを読み出してVGA出力に出力するサンプルが載っていた。(細かく言うと差分も取っているが。。。)その制御にはSH-2を使っている。Mico32でも組み込もうかと思ったがMico32のサイズが大きいし、この場合はたいした制御ではなさそうなのでステートマシンでやってみようと思っている。そして、とりあえずCMOSカメラの画像を出してみたい。
まだOmuniVisionのCMOSカメラモジュールについてわからないことがあるのだが、サンプルコードや実際の波形を見ながら解明しようと思っている。
実際の肝となる回路については書けないが、その周辺の回路については書いてもいいかな?と思う。そのうちに書き残しておくことにしようと思う。
  1. 2009年03月16日 22:08 |
  2. その他のFPGAの話題
  3. | トラックバック:0
  4. | コメント:0

今日の出来事

今朝は凄い雨と風でした。台風みたいでしたね。おかげで家具作りサークルの日だったのですが、延期になりました。それでは、ということで下の娘の鼻水の出が凄いということなので、早めにお医者さんに連れて行きました。てっきり花粉症かと思ったのですが、血液検査の結果、花粉に反応が出ないので、風邪だろうと言う事でした。薬をもらってきました。

昼食後には、少しSpartan3AのDDR2を作り始めたのですが、気分が乗らないので、懸案のもう一台の長いすを作り始めました。作っていると作業用の椅子を作らないと不便なことに気づいて、2X4材で椅子を作りました(作業台はすでに作ってあります)。椅子といってもお風呂の洗い場の椅子のように低い椅子です。
2X4_chair_090315.jpg
2X4_chair_2_090315.jpg

上の写真が作った椅子、下の写真が作業台と作った椅子です。これらは2X4材で出来ています。作業台は長いすのようですが、この高さだといろいろ都合がいいです。作業台の高さが低い(長いすの高さより数センチ高く作りました)ので、工作物を作業台の上にあげて作業しても木ねじを打つ位置が高すぎずに都合がいいです。

椅子が出来て作業がやりやすくなったので、タモ材の長いすを作り始めました。脚の部分だけ作ったのですが、やはりタモ材は2X4材に比べて硬いです。インパクトドライバのインパクト強度を強にしないと木ねじが入っていきません。この前、オフ会のときに買ってきたデジタルノギスで木ねじのねじの谷を計って、その太さのドリル刃で下穴を開けます。そうしないと、インパクトの衝撃で木ねじが途中で切れちゃうんです。ねじ山がつぶれるんでなく、木ねじが途中で切れて木ねじの役をはたさなくなるんですよ。。。物凄いインパクトドライバの威力、そして恐るべきタモ材の硬さです。

夜は、サックスのコンサートに行こうということで下の娘と出かけ、上の娘を拾って、腹ごしらえとマクドナルドに行って食べたんですが、クオーターパウンダーを頼んだはずなのに、よく見たらダブルクオーターパウンダーでした。取り替えてもらっても良かったのですが、(レジはダブルクオーターパウンダーで打ってあります)腹が減っていので、そのまま食べたのですが、肉が多い!!やっと食べました。やはり取り替えてもらうんだったなと後悔。さて、サックスのコンサートに行こうと思ったら、2人の娘とも帰りたいとのたまった。。。しょうがない、文句を言いながら家に戻って送り届けました。その後、サックスのコンサートに行きましたが、遅刻してしまいました。途中から入ったのですが、演奏は良かったです。アルスホールも響きが良くていい感じ。。。フルートを演奏しているのを近くから見ましたが、音を出すのが大変そうですね。その代わりといっては何ですが、本当に良い音色です。こんな音が好きです。演奏している人の息吹までかんじるような気がします。

今日もいろいろ忙しかったですが、明日は車のタイヤをスタッドレスからノーマルに替えてもらうのと、今日の雨で取り付けられなかったエアコンの取り付けがあります。奥さんは歩く会に行って10Km以上歩いてくるようだし、明日も忙しそうです。
  1. 2009年03月14日 22:45 |
  2. 木工
  3. | トラックバック:0
  4. | コメント:0

VHDLでのpackageの使用方法

私のVHDLのpackageの使用方法を書くことにする。

entityのポートの定義内に自分で定義した定数や2次元、3次元配列、またはステートマシンのステートを書きたい時がある。その場合はentityの前に定義をする必要があり、その定義はpackage で行う。
例えば、下のソースのような場合だ。

entity switch_unit is
    generic(
        switch_unit_id : in integer := 0
    );
    port(
        clk, reset : in std_logic;
        recv_data_ar : in recv_data_array; -- 読み出しポートアレイ
        recv_re : out std_logic_vector(7 downto 0); -- 読み出しポートFIFOのイネーブル信号
        ch0_rcapacity_ar : in rcapacity_array;
        ch1_rcapacity_ar : in rcapacity_array;
        ch0_wcapacity_ar : in wcapacity_array;
        ch1_wcapacity_ar : in wcapacity_array;
        send_data_war : out send_data_array_suout; -- 書き込みポートアレイ
        send_we : out std_logic_vector(NUMBER_OF_OUTPUT_PORT-1 downto 0);


上のソースでrecv_data_array, rcapacity_array, wcapacity_array, send_data_array_suout が2次元配列で、NUMBER_OF_OUTPUT_PORTがconstant値だ。
これらの定義は、すべてpackageにして、上のソースのentityの前でuse文を使って定義を呼んでくるようにしている。下にpackageのソースを示す。

library IEEE;
use IEEE.STD_LOGIC_1164.all;

package swcontroller_pkg is
    constant NUMBER_OF_SWITCH_UNIT : integer := 9; -- ここを変更する
    constant NUMBER_OF_OUTPUT_PORT : integer := 8/(NUMBER_OF_SWITCH_UNIT-1);
    
    type recv_data_array is array (7 downto 0) of std_logic_vector(63 downto 0);
    type send_data_array is array (8 downto 0) of std_logic_vector(63 downto 0);
    type send_data_array_suout is array (NUMBER_OF_OUTPUT_PORT-1 downto 0) of std_logic_vector(63 downto 0);
    type rcapacity_array is array (7 downto 0) of std_logic_vector(7 downto 0);
    type wcapacity_array is array (8 downto 0) of std_logic_vector(5 downto 0);
    type wcapacity_array_suout is array (NUMBER_OF_OUTPUT_PORT-1 downto 0) of std_logic_vector(5 downto 0);
end swcontroller_pkg;


この部分はconstant値でユニットの数を変更できる記述になっている。generateを使用してユニットをインスタンシエーションしているので、NUMBER_OF_SWITCH_UNITの値を変更すると、インスタンシエーションするユニット数が変更できるようになっている。
さて、entity文の前には、library work とpackage を使うためのuse文が必要になる。ieeeライブラリを使用するための文を加えるとentity の部分はこうなる。

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;

library work;
use work.swcontroller_pkg.all;

entity switch_unit is
    generic(
        switch_unit_id : in integer := 0
    );
    port(
        clk, reset : in std_logic;
        recv_data_ar : in recv_data_array; -- 読み出しポートアレイ
        recv_re : out std_logic_vector(7 downto 0); -- 読み出しポートFIFOのイネーブル信号
        ch0_rcapacity_ar : in rcapacity_array;
        ch1_rcapacity_ar : in rcapacity_array;
        ch0_wcapacity_ar : in wcapacity_array;
        ch1_wcapacity_ar : in wcapacity_array;
        send_data_war : out send_data_array_suout; -- 書き込みポートアレイ
        send_we : out std_logic_vector(NUMBER_OF_OUTPUT_PORT-1 downto 0);


package は必ずentity、architecture の部分とは別ファイルにしている。他のentity でもpackage の定義を使用することがあるため、コンパイルの順番で定義されていないというエラーを避けるためだ。そのため、必ずpackage文はシミュレーションのスクリプトでは先にコンパイルするようにしている。
更にpackage を入れ子にするのは避けている。前にISEのどのバージョンか忘れたが、packageに依存関係を作ってしまったらエラーで解決できないことがあった。packageの前にpackage の使用を定義することがないようにしている。
  1. 2009年03月13日 06:20 |
  2. VHDLの書き方
  3. | トラックバック:0
  4. | コメント:0

Spartan3Aのプログラマブル遅延素子3

”Spartan3Aのプログラマブル遅延素子1””Spartan3Aのプログラマブル遅延素子2”では、IOBバッドからSLICEに行く経路の遅延であるIBUF_DELAYを変更してその値を調べた。今度はIOBパッド内のFFへの遅延であるIFD_DELAYの値を調べてみる。

前回のVerilog-HDLの記述ではin_ff は、IOBのFFを使用することが出来なかったので、Verilog-HDLソース上にIOB制約を追加することにした。ソースを下に示す。

`timescale 1ns / 1ps

module IOB_Delay_test(
  input clk,
  input reset,
  input testin,
  output testout
  );
  
  (* IOB="TRUE" *)reg in_ff;
//  reg in_ff;
  reg in2_ff;
  
  always @(posedge clk) begin
        if (reset) begin
             in_ff <= 1'b0;
             in2_ff <= 1'b0;
        end else begin
             in_ff <= testin;
             in2_ff <= in_ff;
        end
  end
  
  assign testout = in2_ff;
endmodule


これでインプリメントしてFPGA Editorで見てみると、IOB内のFFを使っていることがわかった。
Spa3A_IDEALY_9_090311.png

上のFPGA Editorの図を見ると、最初からDLY5が入っているのがわかる。以前に”DCMを使わないクロックを使いIOB内のFFでデータを受ける”でもやったみたが、セットアップ時間をマイナスの値にしないようにするためや、Xilinxのアンサー”13309 - 10.1 タイミング - 遅延エレメントが使用されるとデータ有効ウィンドウが大きくなる (Tiopickd、Tioickpd)”にあるようにデータ有効ウインドウが大きくなるためだと思われる。
Timing Analyzerの解析結果を下に示す。
Spa3A_IDEALY_10_090311.png

Maximumのデータパス遅延が4.135ns、Minimumのクロックパス遅延が1.849ns、上の図には見えていないがMaximumのクロックパス遅延が2.215ns となっていた。

さて、”ISE10.1のFPGA EditorでIOBやSLICEのパラメータを変更”と同様の方法でFPGA Editorを使用してIFD_DELAYをいろいろな値に変更して、Tiopickdがどのように変化するかをTiming Analyzerで見て表にしみた。その表を下に示す。
Spa3A_IDEALY_11_0903112.png

IFD_DELAYは4タップあるので、Coarse Delayを入れると8タップということになる。上の表を見るとDLY5のところで不連続になっているので、ここでCoarse Delayが入ったのだろう。IBUF_DELAYに比べてタップごとの遅延が大きい。最大の遅延は同じくらいなので、タップごとのステップが大きいようだ。
実はこの値はSpartan3Aのデータシートの25ページのTable 20: Setup and Hold Times for the IOB Input Path (Continued) に載っている。ホールド時間のTioickpdの値も26ページに載っている。
そこでデータウインドウをIFD_DELAY_VALUE = 0 (DLY0) の時とIFD_DELAY_VALUE = 8 (DLY8) の時で比較してみよう。有効データの必要があるウインドウはセットアップ時間 - ホールド時間だ。

IFD_DELAY_VALUE = 0  1.51ns - 0.67ns = 0.84ns
IFD_DELAY_VALUE = 8  6.73ns - 3.81ns = 2.92ns


上の計算より、IFD_DELAY_VALUE = 8 (DLY8) の時のほうが有効データの必要があるウインドウが広がっていることがわかる。
  1. 2009年03月12日 06:23 |
  2. FPGAチップ内の配線方法
  3. | トラックバック:0
  4. | コメント:0

デジタル・デザイン・テクノロジの付録FPGA基板

さきほどトラ技を見てきたのですが、デジタル・デザイン・テクノロジの付録FPGA基板はLatticeのXP2-5の144pinのようです。LatticeのFPGAは知らないのでわかりませんが、SRAM構造なのでしょうか? ”LatticeXP2デバイスは、flexiFLASHと呼ぶアーキテクチャで、フラッシュ不揮発性セルをLUTベースのFPGAに組み合わせています。”と書いてあるのでフラッシュを内蔵しているということでしょうか?
XP2-5だとするとLUT数は5K、PLLも2個のっているようです。Mico32をLatticeのFPGAで使ってみたいので、非常に興味があります。uClinuxが動けば最高なんだけど、DDRかDDR2を載せないとだめですね。。。
  1. 2009年03月10日 12:45 |
  2. その他のFPGAの話題
  3. | トラックバック:0
  4. | コメント:2

ISE10.1のFPGA EditorでIOBやSLICEのパラメータを変更

”Spartan3Aのプログラマブル遅延素子2”でFPGA EditorでIOB_DELAYの値を変更したがFPGA EditorでのDLY値の変更方法を書いておこうと思う。

まずはProject NavigatorのProcessesウインドウからImplement Design -> Place & Route -> View/Edit Routed Design (FPGA Editor) をダブルクリックし、FPGA Editorを起動する。
FPGA_Editor_IOB_1_090309.png

List1ウインドウのtestinを選択し、ピンクの四角で囲ったZoom Selectionアイコンをクリックする。
FPGA_Editor_IOB_2_090309.png

testinのIOBがズームされるので、その選択されたIOBをダブルクリックする。
FPGA_Editor_IOB_3_090309.png

Block1ウインドウが開き、IOBの内容を見ることが出来る。
FPGA_Editor_IOB_4_090309.png

それではFPGA Editorを編集可能な状態にする。いつもやっているが、FileメニューからMain Properties...を選択する。
FPGA_Editor_IOB_5_090309.png

Main Propertiesダイアログが開く。Edit Mode: を Read Write に変更する。
FPGA_Editor_IOB_6_090309.png

変更したらOKボタンをクリックする。これでFPGA Editorは編集可能なモードになった。
FPGA_Editor_IOB_7_090309.png

編集可能なモードになると背景がグレーから黒に変更されるのだが、このBlock1ウインドウはまだグレーで編集可能になっていない。これを編集するには、下の図でピンクの枠で囲ったBegin Editing アイコンをクリックする。
FPGA_Editor_IOB_8_090309.png

これで背景が黒になって、緑の枠で囲ったIO STANDRARDSやSLEW RATE、IBUF DELAY, IFD DELAYが編集可能となった。
FPGA_Editor_IOB_9_090309.png

これでIBUF DELAY の値を変更したら、FileメニューからSAVEを選択して、IOB_Delay_test.ncd ファイルに書き込む。
FPGA_Editor_IOB_10_090309.png

これでめでたく、IBUF_DELAYの値を変更した.ncd ファイルを生成することが出来た。これでISEからでも単体で起動しても、Timing Analyzerで解析すると新しいDELAY値のタイミング解析をすることが出来る。
ISEでは、Generate Programming Fileのプロセスまで終わっていたら、FPGA Editorで.ncd ファイルを変更するとGenerate Programming Fileのプロセスにはオレンジの?マークがついていると思う。Generate Programming Fileのプロセスを再実行すると、FPGA Editorで変更した内容が反映されたbit ファイルを生成することが出来る。
今回はIOBのパラメータを変更したが、SLICEのパラメータの変更も同様に出来る。
  1. 2009年03月10日 05:52 |
  2. FPGA Editorの使い方
  3. | トラックバック:0
  4. | コメント:0

山形蔵王温泉スキー場に行ってきました

3月7日、8日と山形県の蔵王温泉スキー場に行ってきました。
カーナビのガーミンも役に立ってくれました。帰りに最後で北関東道の真岡で降りる予定が、真岡がカーナビの地図になくて、途中で降りてしまった落ちがつきましたが。。。

さて、3月7日に蔵王について、滑り始めたのですが、この日は本当に風が強かったです。天気は曇りですが、この前行ったハンター塩原スキー場と一緒で風で舞った雪粒で顔が痛かったです。ですが、蔵王温泉スキー場は広いので、風が当たらない下のほうのサンシャインゲレンデで滑っていました。そうそう、ゲレンデコンディションですが、山の上のほうは雪が良いのでしょうが、風が強くてとても行けません。山の中腹は本当のカリカリです。怖いほどのアイスバーン。一回雪が解けて、凍ったんでしょうね。。。というわけで下の方で滑っていました。やはり、カリカリ気味ではあったのですが、何とかスキー板のエッジもかかりました。
zao_1_090309.jpg

3月8日は、晴れの予報でしたが、曇りといった天気でした。それでも、昨日の強風が収まって気温も昨日よりは高いようです。何より風がないのが良いので今日は頂上まで行ってきてお地蔵様を見てきました。肩まで雪があったので雪が少ないわけではありません。蔵王名物の樹氷は雪が落ちていてただの木になっていました。このようなところにも温暖化の影が見えるのでしょう。。。
zao_2_090309.jpg

今日は昨日の夜に雪が降ったようで、山の上のほうが良い雪で滑りやすかったです。パラダイスゲレンデの迂回コースを滑っていました。雪もよく斜度も適当で気持ちよく滑れました。今日は昼の12時にはスキーをやめて帰る予定なので、11時40分ころ山を降りてきましたが、山の中腹もそれほどガリガリのアイスバーンではなかったので良かったです。昨日滑ったサンシャインスキー場はべちゃ雪でとても重くなっていました。気温が上がったのですね。。。
それからお土産を買って、帰ってきました。車で2時にでて7時に家に着いたので、ちょうど5時間かかりました。
  1. 2009年03月09日 05:50 |
  2. 日記
  3. | トラックバック:0
  4. | コメント:0

REFERENCE_PIN制約

ISE10.1SP3でConstraint Editorを使っていて、Clock to Padを設定しようとしていたら、
REFERENCE_PIN_2_090305.png

こんなダイアログが開いた。
REFERENCE_PIN_1_090305.png

REFERENCE_PINが設定できる。。。しかも自分でIOBのDDRレジスタで生成したTxClkからの制約ができるのか?これは、使えればとても良い。
REFERENCE_PINで検索すると”ISE Design Suite 10.1 の新機能 ”が見つかり、そこには”OFFSET OUT 制約で REFERENCE_PIN キーワードがサポートされるようになり、ソース同期インターフェイスのバス ベース出力スキューのレポートが向上しました。 ”と書いてあった。
早速、REFERENCE_PIN制約を書いてみた。

NET "sd_dq<0>" OFFSET = OUT AFTER "clk" REFERENCE_PIN "sd_ck_p" RISING;
NET "sd_dq<0>" OFFSET = OUT AFTER "clk" REFERENCE_PIN "sd_ck_p" FALLING;


これは、制約ガイドによると、” OFFSET OUT AFTER 値を指定し ないで、 レポー ト のみの制約を生成”するそうだ。
そして、インプリメントしてTiming Analyzerで見てみた。
REFERENCE_PIN_3_090305.png
REFERENCE_PIN_4_090305.png

なんか普通にタイミング解析しているみたい?別にREFERENCE_PINに対して、どの位ずれているとかのリポートがないようだ。
このREFERENCE_PIN制約に関して情報をお持ちの方はよろしければ教えてください。
  1. 2009年03月06日 12:24 |
  2. UCFの書き方
  3. | トラックバック:0
  4. | コメント:0

Spartan3Aのプログラマブル遅延素子2

”Spartan3Aのプログラマブル遅延素子1”でクロックにIBUF_DLY_ADJプリミティブを入れたらBUFGが入らなくなってしまった。とりあえず、BUFGを明示的に入れてみようと思う。下がソース。

`timescale 1ns / 1ps

module IOB_Delay_test(
    input clk,
    input reset,
    input testin,
    output testout
    );
    
    reg in_ff, in2_ff;
    wire ibuf_out, clk_bufg;

    IBUF_DLY_ADJ  #(
        .DELAY_OFFSET("OFF"),      //  Enable  Initial  Delay  Offset,  "OFF"  or  "ON"
        .IOSTANDARD("DEFAULT")    //  Specify  the  input  I/O  standard
    )IBUF_DLY_ADJ_inst  (
        .O(ibuf_out),      //  Buffer  output
        .I(clk),      //  Buffer  input  (connect  directly  to  top-level  port)
        .S(3'b000)        //  3-bit  buffer  delay  select  input
    );    
    
    BUFG BUFG_inst (
        .O(clk_bufg),
        .I(ibuf_out)
    );
    
    always @(posedge clk_bufg) begin
        if (reset) begin
            in_ff <= 1'b0;
            in2_ff <= 1'b0;
        end else begin
            in_ff <= testin;
            in2_ff <= in_ff;
        end
    end
    
    assign testout = in2_ff;
endmodule


これでインプリメントして、Timing Analyzerで見るとBUFGが入っているのがわかる。
Spa3A_IDEALY_6_090304.png

これでいろいろなIBUF_DELAY_VALUEの値を調べてみる。これは、clock pathのTiopidを比較することによって行う。

上のソースで、IBUF_DLY_ADJのS(3'b000)の値を変化させて、Timing Analyzer を見ているのだが遅延は変化がない。しかも、セットアップ時間で見たTiopidの値とclock to output時間でみたTiopidの値が違う。上のセットアップ時間のTiming AnalyzerではTiopidは1.495ns だが、下のclock to output時間では1.869nsとなっている。
Spa3A_IDEALY_7_090304.png

どうしてこうなるかわからないがFPGA Editorで見てみると、S()の値を変化してもIBUF_DELAYはDLY1のままで変化がないことがわかった。やはり動的遅延だからなのだろうか?Timing Analyzerで解析していないのだろうか?
そうかわかりました、セットアップ時間で見たTiopidの値はMinimum path、clock to output時間でみたTiopidの値はMaximum pathだった。より厳しい値を使っている。当然か。。。

それでは、”Spartan3Aのプログラマブル遅延素子1”の一番最初のソースに戻して、FPGA EditorでIOパッドのIBUF_DELAYのDLYを変更して、Timing Analyzerで見てみることにする。

下に結果を示す。
Spa3A_IDEALY_8_090304.png

DLY9のところでCoarse Delay が入るので、DLY8よりも遅延が減るようだ。DLYの量が増えるほど、MAXとMINの差が開く。大体300ps~550ps位の遅延タップのようだ。(FPGAはSpartan3Aのxc3s700a-4fg484)
  1. 2009年03月05日 06:38 |
  2. FPGAチップ内の配線方法
  3. | トラックバック:0
  4. | コメント:0

Spartan3Aのプログラマブル遅延素子1

Sparatan3Eの時もプログラマブルな遅延素子があったが、動的に遅延を変更することが出来なかった。Spartan3AはIBUF_DELAY_VALUEのうち8タップを変更することが出来る。下にSpartan-3 Generation FPGA User Guideの323ページの”Figure 10-10: Spartan-3A/3AN/3A DSP Programmable Dynamic Input Delay Elements”を引用する。
Spa3A_IDEALY_1_090302.png

上の図でCoarse Delayが前段の遅延素子でこれを入れるか、入れないかでIFD_DELAY_VALUEは2X4タップ、IBUF_DELAY_VALUEは2X8タップの遅延素子になる。IBUF_DELAY_VALUEの8タップはS[2:0]で選択することが出来て、動的に遅延を変更することが出来るようだ。

とりあえずSpartan3Aのxc3s700a-4fg484 でIBUF_DELAY_VALUEを測定してみよう。
まずはIOB_Delay_test.vをインプリメントしてみた。ソースを下に示す。

`timescale 1ns / 1ps

module IOB_Delay_test(
    input clk,
    input reset,
    input testin,
    output testout
    );
    
    reg in_ff, in2_ff;
    
    always @(posedge clk) begin
        if (reset) begin
            in_ff <= 1'b0;
            in2_ff <= 1'b0;
        end else begin
            in_ff <= testin;
            in2_ff <= in_ff;
        end
    end
    
    assign testout = in2_ff;
endmodule


次にUCF。遅延を見るだけなので位置は固定していない。

NET "clk" TNM_NET = clk;
TIMESPEC TS_clk = PERIOD "clk" 8 ns HIGH 50%;
NET "testin" OFFSET = IN 5 ns BEFORE "clk" RISING;
NET "testout" OFFSET = OUT 7 ns AFTER "clk";


これでインプリメントを行い、ProcessesウインドウのImplement Design -> View/Edit Routed Design (FPGA Editor) をダブルクリックしてFPGA Editor でclk 入力パッドのIOBを見てみる。
Spa3A_IDEALY_2_090303.png

入力パッドの遅延、IBUF_DELAY_VALUEが0 (IBUF_DELAYがDLY0) になっている。この時の入力の遅延をTiming Analyzerで見ると、下のようになる。
Spa3A_IDEALY_3_090303.png

右上の画面のを見ると、データのパスが1.718ns 、クロックのパスが1.844ns となっていて、クロックのパスの方が、0.126ns 遅延が多くなっている。これだとクロックがデータの真ん中だといい感じ。そしてclk のTiopiが0.730ns になっている。これを覚えておいて、今度はclk にIBUF_DLY_ADJ を挿入してインスタンシエーションしてみる。ソースは下のように変更した。IBUF_DLY_ADJはIBUFの遅延を変更できるプリミティブだ。S入力の値を変えることでダイナミックに遅延を変更することが出来る。Figure 10-10のCoarse Delay を入れるためには、DELAY_OFFSETをONにする。

`timescale 1ns / 1ps

module IOB_Delay_test(
    input clk,
    input reset,
    input testin,
    output testout
    );
    
    reg in_ff, in2_ff;
    wire ibuf_out;

    IBUF_DLY_ADJ  #(
        .DELAY_OFFSET("OFF"),      //  Enable  Initial  Delay  Offset,  "OFF"  or  "ON"
        .IOSTANDARD("DEFAULT")    //  Specify  the  input  I/O  standard
    )IBUF_DLY_ADJ_inst  (
        .O(ibuf_out),      //  Buffer  output
        .I(clk),      //  Buffer  input  (connect  directly  to  top-level  port)
        .S(3'b000)        //  3-bit  buffer  delay  select  input
    );    
    always @(posedge ibuf_out) begin
        if (reset) begin
            in_ff <= 1'b0;
            in2_ff <= 1'b0;
        end else begin
            in_ff <= testin;
            in2_ff <= in_ff;
        end
    end
    
    assign testout = in2_ff;
endmodule


これでインプリメントして、FPGA Editorで見てみると下のようになる。
Spa3A_IDEALY_4_090303.png

S入力の入力が増えて、IBUF_DELAYもDLY1になった。これでTiming Analyzer で見てみよう。
Spa3A_IDEALY_5_090303.png

クロックのパスを見ると1.844ns が2.841ns と遅延が変化した。その差は0.997nsだ。だが良く見ると、最初のインプリはBUFGが入っているが、今回はBUFGが入っていない。
とりあえず最初のTiming AnalyzerのクロックパスのTiopi = 0.730ns と次のTiming AnalyzerのクロックパスのTiopid = 1.495ns で比べてみると、0.765nsとなった。
次回ははBUFGを入れてインプリしなおしてみてみようと思う。BUFGを使うか使わないかはわからないが。。。
  1. 2009年03月04日 06:09 |
  2. FPGAチップ内の配線方法
  3. | トラックバック:0
  4. | コメント:2

ガーミン nuvi250 Plusでルート設定

”ナビを買いました(ガーミン nuvi250 Plus)”でガーミンというメーカーのナビを買ったことを書いたが、このキーワードでの検索がとても多い。そこでルート設定のやり方を書いておこうと思う。これから購入する方の参考になればと思う。
まずは電源を入れて、同意を促す画面が出るが、それに同意すると下のような画面になる。
GARMIN_1_090303.jpg

左上のアンテナ強度マークの一番下が赤でまだ衛星を捕らえていない。左上のアンテナ強度マークあたりをタッチすると衛星捕捉画面になる。
GARMIN_2_090303.jpg

ここで衛星が5つ取れているが、時間が経つともっと取れると思う。ちなみにこれは木造の家の中だ。家の中でも衛星をキャッチできる。問題なし。感度が凄い。
さてメイン画面に戻ると、左上のアンテナ強度マークが表示され準備OK。
GARMIN_3_090303.jpg

次に、今度行く蔵王温泉スキー場までルートを設定してみる。目的地検索を押して、画面が表示されたらジャンル別施設をタッチ。
GARMIN_4_090303.jpg

確か、蔵王温泉スキー場は山形市なので、都道府県周辺検索をタッチ。
GARMIN_5_090303.jpg

北海道、東北をタッチ。
GARMIN_6_090303.jpg

山形県をタッチ。
GARMIN_7_090303.jpg

レクリエーション(だよね?)をタッチ。
GARMIN_8_090303.jpg

スキー場リゾートをタッチ。
GARMIN_9_090303.jpg

蔵王温泉スキー場をタッチ。
GARMIN_10_090303.jpg

蔵王温泉スキー場がでてくるので出発をタッチ。
GARMIN_11_090303.jpg

これでルート検索をしてくれるので、現在地からのナビが始まる。
GARMIN_12_090303.jpg
図12 ナビスタート画面

全体のルートはこれ。
GARMIN_13_090303.jpg

図12の左下の到着をクリックすると、いろいろなデータの画面になる。
GARMIN_14_090303.jpg

図12の右下の転換地点をクリックすると、目的地までの曲がる場所が見られる。
GARMIN_15_090303.jpg

図12の上の部分をタッチすると、目的地までに通るルートとその距離が表示される。
GARMIN_16_090303.jpg

このナビはコンパクトで、衛星の感度も最高だが、ルートは当てにならないようだ。蔵王温泉スキー場までのルートでお釜のほうを通る厳しい道を選んでいるようだ。本当は山形道の山形蔵王インターで降りて国道13号で蔵王のふもとまで行って、蔵王温泉スキー場に行きたいのだが。。。
ナビのルートは当てにしないで、自分で事前にルートを決定したほうが身のためのようだ。ルートを無視していれば勝手にリルートしてくれるだろう。前のナビもそうだったし、もともとルートは当てにしていない。目的地の方向が分かれば良い。、事前に地図で検討しながら行くので問題ない。なお、経由地は1個所のみ設定できるようだ。山形蔵王インターを設定すれば、もっとましになるかも?設定してみよう。。。
  1. 2009年03月03日 05:57 |
  2. 日記
  3. | トラックバック:0
  4. | コメント:0

Spartan3A Starter KitのDDR2 SDRAMコントローラの構想

Spartan3A Starter KitのDDR2 SDRAMコントローラをどのように実装するかを考えてみる。
まずはSpartan3A Starter Kitのユーザーガイドを見て、DDR2 SDRAMを確認する。
そうすると、どうやらDDR2 SDRAMは、Suzaku-VのDDR2 SDRAMよりも容量が2倍の512Mbit品がついている。さらにループバック信号SD_LOOPがある。これがあるとどうしようかと悩む。下にpartan3A Starter Kitのユーザーガイドの113ページの図18-1を引用する。
Spa3A_SKit_DDR2_Cntrler_1_090301.png

どうしてかというと、SD_LOOPがあるとREADの時にどのタイミングでデータが出ているかが、よくわかるからだ。つまりREADコマンドを出してからCASレイテンシ後のリードデータの確定タイミングが、内部クロックから配線遅延の往復分遅れていることが問題なのだが、それがこのループバックでキャンセルすることが出来ると思う。その場合には、DQSを1/4クロック分遅延して受けることが前提だ。そのためには、多分IOBの入力ディレイを使用する必要がある。
下のDDR2 SDRAM READタイミングチャートで、上のリージョンがFPGA内部の信号を表す。上のリージョンのCLK_FPGA、CMD_FPGA、ADDR_FPGAはFPGA内部で発生させた信号だが、DQS_FPGA、DQ_FPGAは下のリージョンのDDR2 SDRAMが出力した信号だ。下のリージョンのCLK_DDR2、CMD_DDR2、ADDR_DDR2は上のリージョンの各信号がFPGAのIOバッファ、配線の遅延 (FPGAtoDDR2_delay) を経てDDR2 SDRAMに届いた先の信号だ。DDR2 SDRAMが出力したDQS_DDR2、DQ_DDR2は配線とIOバッファの遅延 (DDR2toFPGA_delay) を経て、DQS_FPGA、DQ_FPGAに現れる。つまりFPGAから見れば、CAS Latency (CL) = 3クロック後に現れるはずのDQS_FPGA、DQ_FPGAはFPGAtoDDR2_delay + DDR2toFPGA_delay 遅延することになる。
次にFPGAから出力されたREAD_timing_outは、FPGAのSD_LOOP_OUT ピンに出力され、DDR2 SDRAM付近に行ってREAD_timing_in (SD_LOOP_INピン)に戻ってくる。この間でFPGAtoDDR2_delay + DDR2toFPGA_delay 遅延しているので、DDR2 SDRAMが出力してFPGAが受けたDQS_FPGA、DQ_FPGAとタイミングが合っていることになる。
Spa3A_StKit_DDR2_timing_090301.png

これでREAD_timing_in を非同期FIFOのEnableとして使えば、うまくREADデータを受けることが出来るはずだ。
ブロック図を描いてみると、下の図になる。
SD_LOOP_DDR2_rev_090301.png

DQSはIOBの遅延でクロックの1/4遅延させた後で各IOBのFFのクロックとして使用する。DQは同様にIOBのFFでサンプルされた後で非同期FIFOのデータに入力される。SD_LOOP_INに入ってきたREAD_timingは、IOBのFFでサンプルした後で非同期FIFOのEnableとして使用する。
とりあえず、IOBの遅延回路がどのくらい遅延を可変できるかを調べることころから始めようと思う。
内部クロックで受けるのが考えるのが一番簡単なのだが、IOBの遅延READデータが受けられるとは限らないため(うまい遅延タップがあるかわからないため)とりあえず上記の方針で作ってみようと思う。
Spartan3A は、Spartan3Eとは違って、自分の回路から8つの遅延値を動的に変更できるようだ。更にプロパティで前段の遅延をつけることが出来る。こっちはダイナミックには遅延を変更できないようだ。

2009/03/22 追記:この回路は問題がありました。”Spartan3A Starter KitのDDR2 SDRAMコントローラの構想2”をご覧ください。
  1. 2009年03月01日 21:07 |
  2. Spartan3A Starter Kit
  3. | トラックバック:0
  4. | コメント:0