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

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

FPGAの部屋

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

QuartusⅡでSignalTapⅡを試してみるまでの準備1(テキストエディタの日本語表示)

VeritakでChipScopeとの協調検証を試してみたが、AlteraのQuartusⅡのSignalTapⅡでも同様にVCDファイルを出力できるようなので、試してみることにした。それにSignalTapⅡはWeb版でも使えるそうだ。
QuartusⅡは前に使ったことがあるが、もう忘れてしまっている。QuartusⅡやSignalTapⅡの操作を覚えながら進めていくことにする。
まずは、SignalTapⅡで検証するのにふさわしい回路だが、電子サイコロは人が見ることを前提にしているため、動作がゆっくりなので向かない。やはり、キャラクタ・ディスプレイ・コントローラが良いかと思う。
だが、キャラクタ・ディスプレイ・コントローラはDCMやBRAMなど、Xilinx専用のプリミティブを使っているので、その部分をAltera用に書き換える必要がある。
まずは、DCMの代わりにMegaWizard Plug-In Manager でALTPLL を生成した。これで入力周波数50MHzから25MHzに落とす。
Quartus2_signaltap2_1_090630.png

次にVerilog ソースを修正しようとしたら、日本語が化けている。
Quartus2_signaltap2_2_090630.png

ToolsメニューのOptions...からOptionsダイアログを表示して、Text EditorのFontsの項目のFontをMSゴシックに変更する。
Quartus2_signaltap2_3_090630.png

すると日本語を表示することができました。
Quartus2_signaltap2_4_090630.png

これで、XilinxのBRAM用の記述も変更してみることにする。
  1. 2009年06月30日 05:49 |
  2. QuartusⅡ
  3. | トラックバック:0
  4. | コメント:0

廃品回収、そして腰痛

今朝、小学校の廃品回収がありました。地域の家々を回って、好意で出していただいた新聞紙や雑誌の束、ビール瓶などをトラックで運んで集積所に持っていったのですが、私にとってはすごい重労働。廃品回収が終わるころ、ギクッと来て、腰が痛くなってしまいました。たぶん、ぎっくり腰です。ぎっくり腰は何度かやっています。廃品回収の前の日も背中から左腰への筋肉が硬くて危ない雰囲気だったんです。
今現在、直立できません。おじいさんみたいに腰が曲がっています。直立すると腰がすごく痛いです。今日は休日なので、医者にも行けないし。。。左足先が軽く痺れます。
明日も同じ状況だったら整形外科に行ってきます。皆様も腰痛にはお気を付けください。

2009/06/29 追記:
昨日、ロキソニン(痛み止め)を飲んで寝たら、だいぶ良くなりました。でもまだ完全に直立はできませんが、これだったら仕事に行けそうかも?

追記2:
整形外科に行ってきました。腰のレントゲンを撮ってみたところ、特に左が腰痛分離症の可能性があるとのことでした。そういえば腰が痛くなるのは決まって左腰です。今は痛いので痛み止めをもらってきましたが、特に治療が必要というわけではなく、腰痛が出やすい。つまり、無理が利かないとのことでした。
腰椎分離症は、若いころのスポーツでなるそうですが、心当たりはテニスですかね? 特に”マッケンローだ”と言って、クローズドスタンスでサーブ打っていたので、それでしょうか? テニスはやめたのですが、最後のころには試合に出ると腰が痛くなっていました。やはりサーブが悪いみたいです(打ち方が)。
  1. 2009年06月28日 19:11 |
  2. 日記
  3. | トラックバック:0
  4. | コメント:0

ChipScope Pro11.2からVCDファイルをExport

ChipScopeからVCDファイルをExportするやり方を書いておく。
ChipScopeのFileメニューからExportを選択する。
ChipScope_tips_1_090628.png

Export Signalsダイアログが開く。Signals to ExprotでWaveform signals/Busesを選択するとWaveformだけがExportされる。FormatはVCDがデフォルトで選択されているので、そのまま。
ChipScope_tips_2_090628.png

OKボタンをクリックすると、保存のダイアログが開く。保存するファイル名を入れて保存ボタンをクリックして保存する。
ChipScope_tips_3_090628.png

  1. 2009年06月28日 10:04 |
  2. Chipscope
  3. | トラックバック:0
  4. | コメント:0

Veritak 3.68AのChipScopeとシミュレーションの波形比較機能の補足

Veritak 3.68AのChipScopeとシミュレーションの波形比較機能”の補足をする。
Veritak3_68A_3_090624.png

上の図で”真ん中や、右はじに赤いところがあるが、詳しくは調査してみないとわからないが、どうもバースト長がシミュレーションと実機で違っているようだ。”と書いたが、それが本当ならばシミュレーションの意味を揺るがすほどの事実。(パソコンのPCIボードへのアクセスなど、シミュレーションするのが非常に難しい場合もあるが、この場合は実機とシミュレーションが、たぶん一致するはず。。。)シミュレーションと実機は同じであるはずだ。だって、シミュレーションと実機が違っていたら、シミュレーションの意味がない。そこには何らかの要因があるはず。
というわけで社運ならぬ私運をかけて解析した。おかげで首がこってしまったが、解明することができた。ふ~。前ふりが長かったが、皆さんなんだと思われますか?


実はリフレッシュ動作のタイミングの違いでした。
シミュレーションは、待つのがいやなので初期化の一部の時間を縮めてある。例えば”電源とクロックが安定した(リセットが解除されてから)200us後で、CKEを1にしてNOPまたはDESECTコマンドを入れる”などの項目だ。DDR2 SDRAMの初期化のシーケンスはここを参照
ところが実機の方はそのまま初期化シーケンスを実行しているので、リフレッシュのタイミングが双方で異なっていたのだ。それをとらえた波形をお見せしよう。
Veritak_cs_sim_test_11_090626.png

上の図で水色のrasb_node_2d, casb_node_2d, web_node_2dに注目してほしい。これらはChipScopeでキャプチャした波形だ。上図で緑色で囲ったところがプリチャージ・コマンド、紫色で囲ったところがリフレッシュ・コマンドになっている。そのためタイミングがずれて、後ろが真っ赤になってしまった。
これもVeritakの比較機能がなければ、このような現象が起こっていること自体がわからなかった。
  1. 2009年06月28日 04:56 |
  2. ChipScope、シミュレーション協調検証
  3. | トラックバック:0
  4. | コメント:0

Veritak3.69B以降とChipScopeによる協調検証

Veritak3.69B以降とChipScopeによる協調検証のやり方について書いてみようと思う。
まずは、Veritakをインストールしていない方は、VeritakのダウンロードページからPro版かBasic版をダウンロードして、試用してほしい。試用期間は14日に設定してあるそうだ。
次に、”Spartan3A Starter KitのDDR2 SDRAMコントローラのバーストテストのプロジェクト”からもう一度プロジェクトをダウンロードしてほしい。Veritakのプロジェクトをアップデートしたのとddr2_burst_test.vにバグがあったので修正した。
まずは、ファイルを解凍するとddr2_burst_testというフォルダができるはずだ。その下にsimulationフォルダがあるので、そこを開く。
simulationフォルダには、まだDDR2 SDRAMのVerilogモデルが足りないので、それをダウンロードしよう。
Micron社のMT47H32M16BN-3のページからVerilogのモデルをダウンロードする。
512Mb_ddr2.zip というZIPアーカイブがダウンロードされるので、ddr2_burst_test/simulation フォルダに512Mb_ddr2というフォルダを作って、その中に展開する。
Veritak_cs_sim_test_1_090626.png

今度は、Spartan3A Starter Kitに載っているMicron社製のDDR2 SDRAMのスピードグレードを調べることにする。実は型番はMicron社製のDDR2 SDRAMに刻印されていないで、何かコードが印刷されている。このSpartan3A Starter KitのDDR2 SDRAMには”8GD42 D9GMG cz98”と刻印されていた。この型番を知るためにはMicronのFBGA DecoderのページでFBGA Code:にD9GMGを入れて検索する。そうすると、パーツ・ナンバーがMT47H32M16BN-3:Dと出てくる。これで512MbitのDDR2 SDRAMのマニュアルから、データ幅が16ビットということと、スピードグレードが3ということが分かる。この値を上の図で緑色の四角で示したddr2_parameters.vh を多少書き換える。このファイルをエディタで開いて、下の図のピンクの四角で囲んだ部分を追加し、セーブする。
Veritak_cs_sim_test_2_090626.png

これでした準備は終了したので、一番上の図のddr2_burst_test.vtakprjをダブルクリックしてVeritak3.69Bを起動しよう。

Window02, VCD file has different timescale (-9) from Veritak Project(-12) というダイアログが出てくるので、OKボタンをクリックする。
そうするとシミュレーションが始まる。シミュレーションが終了した後もWorkspaceにDDR2のモデルのインフォメーションが表示されていることと思う。これはそのうち終わる。
次には”ChipScopeの波形とシミュレーション波形”というウインドウをクリックして前に出す。
Veritak_cs_sim_test_4_090626.png

ユーティリティメニューのVCD波形の表示スタート時刻を変更するをクリックする。
Veritak_cs_sim_test_5_090626.png

VCD Timestart Shift Dialogが開く。Set Time OffsetもScaleもToleranceもちょうど良く設定されているのでSetボタンをクリックする。すると、”ChipScope波形とシミュレーション波形の比較”ウインドウで水色で示されたVCDの信号(ChipScopeの信号)だけがシフトして、オレンジ色や黒で示されたシミュレーションの波形の波形と位置が合うはずだ。ちなみにオレンジ色の信号名はバスの信号の一部を抜き出した信号だ。rpなどは本当は4ビット幅なのだが、ChipScopeでどうしても下3ビットしか見つからなかった。そのため、シミュレーション波形も4ビットのところ3ビット幅としてWaveform Viewerに入れている。下にSetボタンをクリックした後のVeritakの図を示す。
Veritak_cs_sim_test_6_090626.png

このように、VCDの波形とシミュレーションの波形がそろって、異なるところを赤で表示できるようになった。
水色(VCDつまりChipScope波形)のdout_nodeとその下のシミュレーション波形のdout_nodeの値がこのウインドウ幅の中ではぴったり合っているのが確認できる。また、...../DQS2intck_FIFO_FALL/wp[2:0]と下のシミュレーション波形のパートセレクトしたwp[2:0]では、少し位相が異なっている。これは、基本的にwpはWriteのクロック、つまりDDR2 SDRAMの場合はDQSのクロックで動作する。ChipScopeでは決められたFPGA内部のクロックでサンプルされるが、実際はそのタイミングで変化しているかわからないためだ。シミュレーションでは大体こんなものかな?という値の遅延を付加している。

次に各機能を私なりに説明しようと思う。
最初にToleranceだが、これはVeritakチュートリアルによると公差で、どうしても生じる微妙な誤差を無視する設定だ。今、0.1ns が入っていると思うが0ns にしてみよう。すると、いろいろな波形の値の変化の境界に赤い部分が生じるはずだ。下の図参照。
Veritak_cs_sim_test_7_090626.png

従って、正常な部分が赤に表示されないようにToleranceをうまく設定してほしい。ちなみに、3nsと設定(Setボタンをクリック)すると、...../DQS2intck_FIFO_FALL/wp[2:0]と下のシミュレーション波形の差異も消えてしまうので、設定値の決定にはくれぐれもご用心を。。。
Veritak_cs_sim_test_8_090626.png

Toleranceは0.1nsに戻しておく。
Scaleは動作周波数の周期で問題ない。現在はDDR2-300なので、FPGA内部の動作周波数は150MHz、周期に直すと6.666...ns なので6.66667と設定する。
最後にSet Time Offsetの値の設定の仕方だが、これは最初からやるためにとりあえず0nsに設定する。全体を表示するアイコンをクリックして全体を表示する。下の図は全体表示した状態。それに見にくいのでCheck by Red Markerのチェックもとりあえず外そう。
Veritak_cs_sim_test_9_090626.png

ここで2つのdout_nodeに注目する。見にくいが水色のVCD波形の始まりのあたりに黒いカーソルを、黒色のシミュレーションの波形の始まりのあたりに赤カーソルをセットする。(上の図参照、左クリックと右クリックでカーソルをセットする) そしてOffset ByをBetween T1 and T2にセットして、Setボタンを押すと波形が大体そろったのではないだろうか? 大体そろった状態を下の図に示す。
Veritak_cs_sim_test_10_090626.png

ちなみにVCD波形(ChipScope波形)のdout_nodeが下のシミュレーションのdout_nodeよりもだいぶ短いのは、ChipScopeのサンプル数を1024ポイントにしているからだ。1024×6.6667nsで6.83us程度の幅となっている。
この後はOffset ByをEdit box aboveに戻し、値を増減させて、ぴったり合う位置を探る。その際に波形をズームしないとあっているかどうかが分からない。ズームインはシフトキーを押しながら、ズーム範囲を選択する。ズームアウトはシフトキーを押しながら右クリックする。

これで大体、一通りの説明をしたが、皆さん、できましたでしょうか?何か質問があったらコメント欄にお願いします。

Veritakのこの機能については、”2.4.1.4 VCD波形とVeritak波形を一緒に表示する”を参照のこと。
私は、とても良い機能だと思っているが、反応が少ないし、あまり便利な機能ではないのだろうか?でも、少なくとも私はとても便利な機能だと思っている。ただ、惜しいのはChipScopeが評価版のみで、ずっと使い続けるためには購入する必要があることだ。出来れば、ISE WebPACKでも標準の機能としてほしい。

追加:
ChipScopeからExportしたVCDファイルの本体は、ddr2_burst_test/Synth111/VCD_Filesフォルダの中のDDR2_Burst_Test_Start.vcd です。
  1. 2009年06月27日 05:34 |
  2. ChipScope、シミュレーション協調検証
  3. | トラックバック:0
  4. | コメント:2

ISE11.2iが出た?

昨日、ISE11.2が出て、Spartan-6とVirtex-6が使えますというメールがXilinxから来た。早速、ダウンロードしてみようとして、やってみたが、昨日はダウンロードの認証が通らずに断念した。今日、ダウンロードの認証が通って、リストを見てみたが、ISE WebPACKもISE Design Suiteも11.1のままだった。どうして? もしかして、11.1と名前があるがダウンロードしてみると実は11.2がダウンロードできるという落ちなのかな?
とりあえず、ISE11.2 が出るまで待つことにする。
Xilinxの資料のページにもSpartan-6の資料Virtex-6の資料が増えてきた。そろそろ、ツールもリリースされそうなんだけど。。。

追加
astrayさんにコメントで教えていただきました。ISE11.1からupdateかけたらISE11.2になるようです。現在、Updateしているところです。
ISE11_2_updata_090626.png

アップデートできました。後で使ってみようと思います。
ISE112_090626.png

  1. 2009年06月26日 04:40 |
  2. Xilinx ISEについて
  3. | トラックバック:0
  4. | コメント:8

Veritak 3.68AのChipScopeとシミュレーションの波形比較機能

Verilogシミュレータ、Veritak 3.68Aの波形比較機能は、なんと、シミュレーションの波形とChipScope Proから出力したVCDファイルを同時に表示して、それを比較できるのだ。これは本当にすごいと思う。世界初かもしれない?
具体的には、下の図を見てほしい。これはVeritak作者のたっくさんからいただいたプロジェクトを一部変更したものだ。
Veritak3_68A_2_090624.png

表示されているWaveform Viewerには、青いChipScopeのVCDファイルの信号と対応するVeritakでシミュレーションした信号波形(黒またはオレンジ色)が縦に並べてある。上下の信号の異なっている部分が赤で表示されているわけだ。Waveform Viewerの右はじに’]’が表示されているのが、比較している信号となる。
VCD Timestart Shift Dialogを見てほしい。Set Time Offsetが、VCDをシミュレーション波形からどのくらいシフトするかを決めている。そのシフトする条件はOffset Byで決定されている。そして、ChipScopeはクロックでサンプリングされているので、クロックのスケールをかける必要がある。現在のDDR2 SDRAMコントローラの周期は6.6667ns なので、Scaleに6.6667が入っている。そして、Check by Red Makerにチェックを入れているので、波形を比較して異なっている部分が赤く表示されている。
詳しくは、Veritakチュートリアルの”2.4.1.4 VCD波形とVeritak波形を一緒に表示する”を参照のこと。
上の波形でDQS2intclk_RISE/wgray2 は赤くなっているが、これはDQSクロックで動作する非同期FIFOのWRITEポインタ用グレーコードカウンタをFPGA内部クロックで2度サンプルした後の信号だ。よって1クロック程度遅れるのは仕方がないと言えると思う。

ChipScopeでとった波形の全体像を下に示す。
Veritak3_68A_3_090624.png

真ん中や、右はじに赤いところがあるが、詳しくは調査してみないとわからないが、どうもバースト長がシミュレーションと実機で違っているようだ。ChipScopeの試用期間が終わる前に詳しく解析しようと思っている。このように違いが良くわかる。
後で、ダウンロードできるプロジェクトでのやり方を書こうと思っている。
  1. 2009年06月24日 20:40 |
  2. ChipScope、シミュレーション協調検証
  3. | トラックバック:0
  4. | コメント:0

diceのVerilog版

Sim's blogさんの”diceをverilogに書き換えてみました”でdiceのVeriog版が載っていたので、私の作った電子サイコロのVerilog版も貼ってみた。
非同期リセットのVHDL版と説明はこちら

まずはdice_top.vから

`default_nettype none
`timescale 1ns / 1ps

// 電子サイコロ Verilog2001

module dice_top(
    input wire reset_sw,
    input wire clk,
    input wire roll,
    output wire [3:0] an_n,
    output wire a_n,
    output wire b_n,
    output wire c_n,
    output wire d_n,
    output wire e_n,
    output wire f_n,
    output wire g_n,
    output wire dp_n
);
    
    wire roll_sig;
    wire roll_ena;
    wire [2:0] binary;
    
    assign an_n = 4'b1110; // AN0のみ点灯
    assign dp_n = 1'b1; // ドットの消灯
    
    reject_chatter inst_reject_chatter(
        .reset_sw(reset_sw),
        .clk(clk),
        .roll(roll),
        .roll_sig(roll_sig),
        .roll_ena(roll_ena)
    );
        
    dice_state_machine inst_dice_sm(
        .reset_sw(reset_sw),
        .clk(clk),
        .roll(roll_sig),
        .roll_ena(roll_ena),
        .spots(binary)
    );

    seven_seg_dec inst_seven_seg_dec(
        .binary(binary),
        .a_n(a_n),
        .b_n(b_n),
        .c_n(c_n),
        .d_n(d_n),
        .e_n(e_n),
        .f_n(f_n),
        .g_n(g_n)
    );
    
endmodule
`default_nettype wire


次は、reject_chatter.v。

`default_nettype none
`timescale 1ns / 1ps

// スイッチのチャタリング除去とサイコロの表示変更タイミング20msをカウントする
// Verilog2001

module reject_chatter(
    input wire reset_sw,
    input wire clk,
    input wire roll,
    output wire roll_sig,
    output reg roll_ena
);
    reg [17:0] sw_cnt;
    reg [1:0] roll_cnt;
    reg roll_node;
    
    parameter frequency_KHz = 50000; // KHz単位でのクロック周波数
    parameter divided_200Hz = frequency_KHz * 5; // 200Hzに分周するための分周比
    
    // 200Hz, 5ms
    always @(posedge clk) begin
        if (reset_sw)
            sw_cnt <= 18'd0;
        else begin
            if (sw_cnt == (divided_200Hz-1))
                sw_cnt <= 18'd0;
            else
                sw_cnt <= sw_cnt + 18'd1;
        end
    end
    
    always @(posedge clk) begin
        if (reset_sw)
            roll_node <= 1'b0;
        else
            if (sw_cnt == (divided_200Hz-1))
                roll_node <= roll;
    end
    assign roll_sig = roll_node;
    
    // 50Hz, 20ms
    always @(posedge clk) begin
        if (reset_sw) begin
            roll_cnt <= 2'd0;
            roll_ena <= 1'b0;
        end else begin
            if (sw_cnt==(divided_200Hz-1)) begin
                if (roll_cnt==2'b11) begin
                    roll_cnt <= 2'd0;
                    roll_ena <= 1'b1;
                end else begin
                    roll_cnt <= roll_cnt + 2'd1;
                    roll_ena <= 1'b0;
                end
            end else
                roll_ena <= 1'b0;
        end
    end
endmodule    
`default_nettype wire


dice_state_machine.v

`default_nettype none
`timescale 1ns / 1ps

// 1から6までのサイコロの目を表すステートマシン, Verilog2001

module dice_state_machine(
    input wire reset_sw,
    input wire clk,
    input wire roll,
    input wire roll_ena,
    output reg [2:0] spots
);

    parameter        st_one        = 6'b000001,
                    st_two        = 6'b000010,
                    st_three    = 6'b000100,
                    st_four        = 6'b001000,
                    st_five        = 6'b010000,
                    st_six        = 6'b100000;
    reg [5:0] current_state, next_state;
    
    always @(posedge clk) begin
        if (reset_sw)
            current_state <= st_one;
        else
            current_state <= next_state;
    end
            
    always @* begin
        case (current_state)
            st_one : begin
                spots <= 3'd1;
                if (roll & roll_ena)
                    next_state <= st_two;
                else
                    next_state <= st_one;
            end
            st_two : begin
                spots <= 3'd2;
                if (roll & roll_ena)
                    next_state <= st_three;
                else
                    next_state <= st_two;
            end
            st_three : begin
                spots <= 3'd3;
                if (roll & roll_ena)
                    next_state <= st_four;
                else
                    next_state <= st_three;
            end
            st_four : begin
                spots <= 3'd4;
                if (roll & roll_ena)
                    next_state <= st_five;
                else
                    next_state <= st_four;
            end
            st_five : begin
                spots <= 3'd5;
                if (roll & roll_ena)
                    next_state <= st_six;
                else
                    next_state <= st_five;
            end
            st_six : begin 
                spots <= 3'd6;
                if (roll & roll_ena)
                    next_state <= st_one;
                else
                    next_state <= st_six;
            end
            default : begin
                spots <= 3'd1;
                next_state <= st_one;
            end
        endcase
    end
    
// synthesis translate_off
    reg [20*8:1] DICE_STATE; 
    
    always @(current_state) begin
        case (current_state)
            st_one    : DICE_STATE <= "ST_ONE";
            st_two    : DICE_STATE <= "ST_TWO";
            st_three: DICE_STATE <= "ST_THREE";
            st_four    : DICE_STATE <= "ST_FOUR";
            st_five    : DICE_STATE <= "ST_FIVE";
            st_six    : DICE_STATE <= "ST_SIX";
            default    : DICE_STATE <= "ST_ONE";
        endcase
    end
// synthesis translate_on
endmodule
`default_nettype wire


seven_seg_dec.v

`default_nettype none
`timescale 1ns / 1ps

// 7セグメントLEDデコーダ、0で点灯します。

(* bram_map="yes" *)
module seven_seg_dec(
    input wire [2:0] binary,
    output reg a_n,
    output reg b_n,
    output reg c_n,
    output reg d_n,
    output reg e_n,
    output reg f_n,
    output reg g_n
);

    always @* begin
        case (binary)
            3'd1 : begin
                a_n<=1'b1; b_n<=1'b0; c_n<=1'b0; d_n<=1'b1; e_n<=1'b1; f_n<=1'b1; g_n<=1'b1;
            end
            3'd2 : begin
                a_n<=1'b0; b_n<=1'b0; c_n<=1'b1; d_n<=1'b0; e_n<=1'b0; f_n<=1'b1; g_n<=1'b0;
            end
            3'd3 : begin
                a_n<=1'b0; b_n<=1'b0; c_n<=1'b0; d_n<=1'b0; e_n<=1'b1; f_n<=1'b1; g_n<=1'b0;
            end
            3'd4 : begin
                a_n<=1'b1; b_n<=1'b0; c_n<=1'b0; d_n<=1'b1; e_n<=1'b1; f_n<=1'b0; g_n<=1'b0;
            end
            3'd5 : begin
                a_n<=1'b0; b_n<=1'b1; c_n<=1'b0; d_n<=1'b0; e_n<=1'b1; f_n<=1'b0; g_n<=1'b0;
            end
            3'd6 : begin
                a_n<=1'b0; b_n<=1'b1; c_n<=1'b0; d_n<=1'b0; e_n<=1'b0; f_n<=1'b0; g_n<=1'b0;
            end
            default : begin
                a_n<=1'b1; b_n<=1'b0; c_n<=1'b0; d_n<=1'b1; e_n<=1'b1; f_n<=1'b1; g_n<=1'b1;
            end
        endcase
    end
endmodule
`default_nettype wire


同期リセットになっているはず。。。
特徴は`default_nettype none ~`default_nettype wireで括ってあることと、ステートマシンのステートをワンホットにしてあることだろうか?
痛い目にあったので、integerのリテラルには必ずビット幅を書くようにしている。

VHDL版非同期リセット電子サイコロとVerilog版同期リセットの電子サイコロのISE10.1iでのインプリメント結果を下に示す。
まずは、VHDL版非同期リセット電子サイコロから。
dice_VHDL_ISE101_090623.png

次は、Verilog版同期リセットの電子サイコロ。
dice_Verilog_ISE101_090623.png

VHDL版非同期リセット電子サイコロの方が、Verilog版同期リセットの電子サイコロよりもLUTの使用数が倍近く多い。

何か間違いがあったらお知らせください。
  1. 2009年06月23日 20:40 |
  2. その他のFPGAの話題
  3. | トラックバック:0
  4. | コメント:8

Spartan3A Starter KitのDDR2 SDRAMコントローラのバーストテストのプロジェクト

Spartan3A Starter KitのDDR2 SDRAMコントローラのバーストテストのプロジェクトを置いておくので、興味のある方はダウンロードしてください。いつものように保証なし、原則転載禁止(転載したい方はメールでお知らせください)とします。それからSpartan3A Starter Kitを持っている方は正常に動作したかどうかをぜひ教えてください。よろしくお願いします。ISE11.1iを持っていない方もddr2_burst_testフォルダの下にビットファイルddr2_burst_test.bitを入れておきますので、iMPACTでコンフィグすれば確かめてみることができます。これはChipScope入りのビットファイルです。

ZIPファイルを開けて、ddr2_burst_test/Synth111フォルダの中にISE11.1iのプロジェクトファイルddr2_burst_test.xise がある。今回のプロジェクトにはChipScopeは入っていないが、ChipScopeをインストールしてある方は、DDR2_burst_test_cs.cdc をプロジェクトに入れてほしい。ChipScopeのプロジェクトDDR2_burst_test_cs.cpj も入れてある。ddr2_burst_test/Synth111フォルダの内容を下に示す。
Spa3A_STKit_DDR2_proj_1_090622.png

下がProject Navigatorのプロジェクトの階層だ。
Spa3A_STKit_DDR2_proj_2_090622.png

プロジェクトはインプリメントしていない状態なので、ビットファイルを生成して、iMPACTでSpartan3A Starter KitのSpartan3Aをコンフィギュレーションしてほしい。その辺のやり方は、”ISE11.1iのチュートリアル6(デザインのインプリメント)”、”ISE11.1iのチュートリアル7(FPGAのコンフィギュレーション)”を参照のこと。

使用方法だが、チップスコープを使って、Readデータを見ないと本当に詰まらない動作だ。使用するのはLD0, LD1の2つのLEDとリセット用の押しボタンスイッチSOUTH (T15) 。LD0 はDDR2 SDRAMのバーストテストが正常に読み書きできているときに点灯している。これが点灯していれば、Writeしたバーストデータが正常にバーストRead出来ていることを表す。LD0 が消えてLD1 が点灯するとWriteしたデータと異なるデータがReadされたことを示す。
ChipScopeがインストールされていて、DDR2_burst_test_cs.cdc をプロジェクトに入れてインプリメントすると下の図のようにどのようなデータをリードしているかが分かる。
Spa3A_STKit_DDR2_Debug_6_090617.png

Spartan3A Starter KitでのLD0、LD1と押しボタンスイッチSOUTH (T15) の位置を下の写真に示す。
Spa3A_STKit_Pict_090623.jpg

シミュレーションのやり方は次回に。

2009/06/27 追記:
ddr2_bust_testのダウンロードできるプロジェクトを変更しました。

2009/08/21 追記:
ISE11.2でインプリメントエラーが出るようになってしまったので、ダウンロードプロジェクトを変更しました。詳しくは、”Spartan3A Starter KitのDDR2 SDRAMコントローラのバーストテストのインプリメントエラー”をご覧ください。

2010/08/27 追記:
<注意> バグが発覚したので、Spartan3A Starter KitのDDR2 SDRAMコントローラのバーストテストのプロジェクトを修正しました。必要な方はもう一度ダウンロードしてください。
Spartan-3A Starter KitでCMOSカメラ・ディスプレイ回路19(DDR2 SDRAMコントローラのバグフィック)”参照
  1. 2009年06月23日 05:30 |
  2. Spartan3A Starter Kit
  3. | トラックバック:0
  4. | コメント:0

”劔岳 点の記”を見てきました

昨晩はうちの奥さんは夜勤だったのですが、今日の10時10分からイーアスの映画館で”劔岳 点の記”を一緒に見てきました。例によって、夫婦50割引なので、夫婦で2,000円です。ネットで予約していたので、本当に楽でした。
映画はというと、全部実写だそうですが、死にそうになりながら撮影したのでしょうか?ものすごい暴風雨や風雪の中での撮影、本当にすごいと思いました。昔の地図は本当にそんな苦労をしながら作っていたんですね。今だったら、差分GPSで一発なんでしょうか? 新田次郎が好きなので楽しめました。映画としては寡黙な男たちの映画ですね。映画の観客の平均年齢が高かったです。
今度は7月15日からのハリーポッターの謎のプリンスが楽しみです。今まで全部見ているので、これはぜひ見たいですね。
今日は、午後から父の日のプレゼントを買いに行ってきました。結局、夏用のサンダルになりました。
夕方は、下妻の円家にみんなでラーメンを食べに行きました。私はここの支那そばが好きです。さっぱりしょうゆ味でだしが効いていておいしいです。下の娘もおいしいと言って食べていました。画像がないのが残念です。携帯、電池切れで持っていきませんでした。
  1. 2009年06月21日 21:17 |
  2. 日記
  3. | トラックバック:0
  4. | コメント:2

地デジテレビが来た、食品棚が完成に近づく

この前購入した液晶テレビが午前中に届きました。東芝の37インチの37H8000です。300GBのハードディスクが入っていて録画できます。早速、F1を予約しました。あとUSBのハードディクスもつけられるので、AmazonでIOデータの1TBを注文しました。(下の写真は著作権に考慮して、わざとぼかしを入れてあります。画面はきれいですよ)
ekisyou_TV_090620.jpg

最初、全部の地デジ局が映らなくてあせりました。NHK総合はどうしてもキャッチできません。その他の局もブロックノイズが出ています。おかしいということで、アンテナ直下に設置したブースターの具合をチェックしに、梯子をかけて屋根に上りました。VHF、UHF、FM、BSの4波用ブースターを空けて、UHFのゲインを見てみるとだいぶ低く設定されていました。UHFはどうでもいいので、低くしといたんだっけ?フルゲインにしました。確か32dBのはず。これで、下に降りてアンテナゲインを見てみると十分なゲインが得られました。良かったですが、梯子を持って腰を痛めました。

午後からは家具作りサークル、かねてからの課題の食品棚を作りました。大体出来てきました。後は上の棚の後ろにシナべニアを張るために溝を掘って、シナべニアをつけて、白色に塗れば終了です。
syokuhindana_090620.jpg

上の棚は調味料などを入れるそうなので、落ちないように後ろに板を貼ります。真ん中の天板(棚)は出っ張っています。なぜかというと、真ん中には炊飯器を載せるので、ご飯を盛った茶碗を、手前に置くためです。下の2X3個の棚は食品を置きます。市販のかごを入れて食品を入れておくつもりです。
  1. 2009年06月20日 20:38 |
  2. 日記
  3. | トラックバック:0
  4. | コメント:3

Spartan3A Starter KitのDDR2 SDRAMコントローラのバーストテストのデバック2(sd_loop_outの処理)

Spartan3A Starter KitのDDR2 SDRAMコントローラのバーストテストのデバック”でsd_loop_inを前に1クロック前に伸ばすという結論になった。sd_loop_inを前に1クロック前に伸ばすには、sd_loop_outを1クロック前に伸ばす必要がある。(結局、sd_loop_outのタイミングはそのままとしました)
その前に、そういえばsd_loop_outのケアを忘れていたことに気がついた。はたしてsd_loop_outはどのようにインプリメントされているの調べるということでFPGA Editorを立ち上げて調べてみた。
sd_loop_outのIOBをのぞいてみたところが下の図。
Spa3A_STKit_DDR2_Debug_3_090617.png

IOBのフリップフロップ(FF)を使用していない。これはまずい。最初にIOBのFFを使うようにVerilog ソースを変更し、もう一度データを取る必要がある。この状態ではsd_loop_outが遅れてREADの時の最初のデータを取れていない可能性がある。UCFも調べてみたらsd_loop_outの制約もなかった。早速、sd_loop_outの最終のフリップフロップ(FF)をIOBに入れることにした。具体的には下のようにVerilogファイルを変更した。(一部です)

    (* IOB = "FORCE" *)output    reg    sd_loop_out;    // DDR2の遅延をキャンセルするための出力パッド


    always @ (posedge clk) begin
        if (reset)
            sd_loop_out = 1'b0;
        else begin
            sd_loop_out = read_timing_1b;
        end
    end


一番上の行は宣言文だが(* IOB ="FORCE" *)制約を付けている。今回、制約ガイドを見て初めて知ったのだが、こうするとsd_loop_outがIOBに入らないとエラーが出るそうだ。
これでインプリメントしたところに下に示すようにIOBにFFが入った。
Spa3A_STKit_DDR2_Debug_4_090617.png

これでコンフィグしてやってみたところ、ChipScopeでの波形もOKだった。波形は下。信号名が表示されていないが、前回と一緒で、その下にread_error信号が追加されている。
Spa3A_STKit_DDR2_Debug_5_090617.png

前回のシミュレーション波形と比べてみる。
Spa3A_STKit_DDR2_Debug_2_090617.png

シミュレーションと波形が一致した。
この前、シミュレーションでマージンがないという話をしたが、それはTiming Analyzerで性的 静的に解析したタイミング情報を論理シミュレーションに反映していないためだった。実際はReadデータとDQSのクロックはFPGA内部では1.5nsの差がある。同位相できたReadデータとDQSクロックは、DQSクロックのほうが約1.5ns程度、FPGA内部で遅れるようにタイミングを組み上げている。よってsd_loop_outから出たReadのタイミング信号はsd_loop_inから入って、ReadのEnableとして使えば、Readのデータが読めるはずだ。そのためにsd_loop_inにはMAXDEALY制約とMAXSKEW制約をかけてある。
ずーとバーストテストをしながらSparatan3A Starter Kitを放置していたが、エラーは出ていないようだ。
ChipScopeで見ても、正常にテストを行っている。
Spa3A_STKit_DDR2_Debug_6_090617.png

1時間バーストテストを行ったが結局エラーは出なかった。これでSpartan3A Starter KitのDDR2-300 SDRAMコントローラは完成とする!!!
うれしいです!!!みなさん、拍手などでのご声援ありがとうございました。
思えばいろいろな苦労があった。自分で非同期FIFOも作ることになったし、Readデータを受ける初段に分散RAMを使用したので、フロアプランに苦労した。でも、だいぶ勉強になった気がする。
Spartan3A Starter KitのDDR2-300 SDRAMコントローラ、誰か欲しいでしょうか? Verilog ソースとUCFにノウハウが詰まっているので、Verilogをそのまま他の基板に移植しただけでは、まず動かないと思います。Spartan3A Starter Kitの下の写真のような等長配線があって初めて実現できたとも言えます。
Spa3A_STKit_DDR2_1_090619.jpg

インプリメント結果ですが、ChipScopeを入れると、少しですがタイミングエラーが出ていますが、動作には問題ないようです。
Spa3A_STKit_DDR2_Debug_7_090617.png

ChipScopeを入れないとタイミングエラーは出ません。どっちにしろタイミングはきついところみたいです。やりませんけど、IPとして配布する場合には相対配置制約をかけたほうがいいかもしれません。
  1. 2009年06月19日 04:52 |
  2. Spartan3A Starter Kit
  3. | トラックバック:0
  4. | コメント:2

ISE11.1iのチュートリアル1(導入編)の訂正

Sim's blogさんの”diceを動かしてみました”で、”ISE11.1iのチュートリアル1(導入編)”のVHDL記述のバグについてご指摘をいただきました。訂正いたします。なお、すでにブログは訂正いたしました。
確かにprocess文のsensitivity listにreset_sw が抜けていました。抜けていてもISE11.1でのインプリメントは通ります。ただしXSTでwarningがでます。reset_sw が抜けている状態でインプリメントしたものをFPGA Editorで見ると非同期リセットになっています。電子サイコロの動作は、process文のsensitivity listにreset_sw が抜けた状態でも問題はありませんでした。
シミュレーションもclkのイベントでreset_swが1となっていれば、リセットされると思いますので、表面上は問題なく動作していたようです。
初めはVerilogで同期リセットFFでdiceを作ったので、VHDLにするときに勘違いしたようです。また、何か間違っているソースや記述があったらご指摘ください。よろしくお願いいたします。
  1. 2009年06月18日 05:47 |
  2. その他のFPGAの話題
  3. | トラックバック:0
  4. | コメント:0

Spartan3A Starter KitのDDR2 SDRAMコントローラのバーストテストのデバック

ChipScope Pro 11.1を使ってSpartan3A Starter KitのDDR2 SDRAMコントローラのバーストテストのデバックをしている。
だいぶ原因が分かってきた。
下がチップスコープの波形。
Spa3A_STKit_DDR2_Debug_1_090617.png

主に、リードデータを受けるためのrddata_afifoを見ている。FALLが立下り用の非同期FIFOで、RISEが立ち上がり用の非同期FIFO。dout_nodeがリードデータの出力で途中で00000001が見えると思うが、その後は00000002, 00000003, 00000004, 00000005と続いている。読まれる予定のデータは0, 1, 2, 3, 4, 5の6個なので、最初の0が読めていないことになる。
次に、似たような信号をVeritakでシミュレーションした結果を示す。
Spa3A_STKit_DDR2_Debug_2_090617.png

上のChipScopeの波形と比べてみるとRISE非同期FIFOのwpの値が1つ多い。wpはVeritakの結果では、FALLのwpより早く、赤いカーソルのところで増え始めている。ChipScopeでは1つ遅れている。Veritakでwr_clkをとwr_enの関係を見てみると、ほんの少しの余裕しかない。たぶん、これが悪いのだろう。sd_loop_inを前に1クロック伸ばしてみることにする。

しかし、本当にChipScopeは便利だ。これがあればスタータキット内をいじる限りでは、オシロスコープもいらない場合が多いだろう。ChipScopeで波形を取って、シミュレーション結果と比べられると本当にどこが悪いのかよくわかると思う。

#もしChipScope ProがWebPACKからも無料で使えるならば、本当にうれしいんだけど。。。
#Veritakもできれば、ChipScopeのように階層が信号名の前に表示されて、信号名の右合わせで信号を表示できるオプションがあれば良いと思う。(注:今でも、Scopeで階層は表示できます)
  1. 2009年06月17日 05:51 |
  2. Spartan3A Starter Kit
  3. | トラックバック:0
  4. | コメント:2

ChipScope Pro 11.1

Spartan3A Starter KitのDDR2 SDRAMコントローラだが、やはりどうして動作しないかわからないので、ChipScope Pro 11.1の評価版をダウンロードして使用してみた。
ChipScope Pro 11.1の評価版を使ってみたところ、ビットファイルをコンフィギュレーションするときにCDCファイルも指定出来て、自動的にバスを作るオプションもあった。便利になった。
ChipScope_111_1_090616.png

左のSignalsペインのData Portの信号も右クリックからAuto-create Buses...を選択することができる。
ChipScope_111_2_090616.png

一番良かったのは、WaveformのBus/Signalの表示方法だ。
今までは、階層の深い長い信号名と階層の浅い短い信号名があると、どちらかの信号はよくわからない表示しかできなかった。つまり階層の浅い短い信号名に表示を合わせると階層の深い長い信号名は階層の初期部分のみの表示となって、どの信号かわからない。階層の深い長い信号名の信号を読めるようにすると、階層の浅い短い信号名は空白が表示されて読めなくなっていた。
今回のChipScope Pro 11.1では、どの信号も信号名の右合わせで表示される。これは、ModelSimの表示と同様だ。便利。。。
例えば、下の図のように新語名の長さが違う信号がある。
ChipScope_111_3_090616.png

このBus/Signalの幅を縮めても全部の信号名が見える。
ChipScope_111_4_090616.png

次にChipScope Pro 11.1とは直接関係がないが、XSTを使ってタイミングが厳しくXSTで階層を保持するオプションを使えない場合のチップスを書いてみようと思う。
それは、この前やり方を覚えた(* KEEP_HIERARCHY = "TRUE" *)を使う方法だ。自分が信号を見たいモジュールだけをこれで階層を保持するようにすることだ。これで階層を保持するとChipScopeのインサーターに階層が見え、内部の信号もかなりキープされるようだし、インサーターで信号名を見つけるときに階層があるので見つけやすい。
下の図の下から3つ目までは、階層から信号を確保しているし、上から3番目のemptyはLUTの出力なので、階層を部分的にキープしなかったら、なくなっていたかもしれない。
ChipScope_111_3_090616.png

これは、async_fifo_rise.vとasync_fifo_fall.vに(* KEEP_HIERARCHY = "TRUE" *)属性を付けてインプリメントした。

(* KEEP_HIERARCHY = "TRUE" *)module async_fifo_rise (


これでインプリメントしても制約は満足している。
このように、見たい信号があって、XSTで階層をキープできない場合は、モジュールごとに部分的に階層をキープしてChipScopeで信号名を見つけやすくしながら、インプリメントの品質も確保することができることが分かった。

皆さんもいろいろ便利なやり方があったらご紹介ください。

さて、肝心のSpartan3A Starter KitのDDR2 SDRAMコントローラだが、ChipScopeの解析の結果リードデータはだいたい受けられているが最初がおかしいことが分かった。それはまたあとで。。。
  1. 2009年06月16日 05:22 |
  2. Chipscope
  3. | トラックバック:0
  4. | コメント:2

ウォシュレットを買って取り付けた

昨日は、土曜日に買ってきたウォシュレットを取り付けた。買ってきたのは東芝のSCS-S500というタイプ。瞬間湯沸かしでお湯を温める待機電力なし、温風乾燥はなしのタイプ。ケーズデンキで35,000円くらい。
自分でつけたらどうですかというお店の人の言葉に従って、自分でつけてみることにした。説明書を読みながら付けたら結構簡単に付いたのだが、どうも水タンクとのコネクタの部分で水漏れしてしまう。どうやら、ここに水タンクのプラスチックのストレーナーがついていてゴムパッキンの密着性が悪いみたい。真ん中でだめらならねじ部分でシーリングしようと、たまたま持っていたシーリングテープを巻きつけて対策した。
しかしフレキシブルなホースなので、締めるときにひねってしまうと締めこんでも水の通る力で自分で戻ってねじがゆるんでしまうようだ。これじゃダメなので、最初に逆にひねってからねじを締めた。これで大丈夫かな?これでだめな時には専門家を呼ぶことにする。
toine_1_090615.jpg

だいぶ苦労してしまったが、そういえばリモコンは無線を使っている。ZigBeeを使っているのだろうか無線だと本当に便利だ。
toine_2_090615.jpg

今週末は家具作り教室、地デジテレビ購入(買っちゃいました。。。)、ウォシュレット取り付け、地域のお祭りの会合と本当に忙しかった。
  1. 2009年06月15日 05:08 |
  2. 日記
  3. | トラックバック:0
  4. | コメント:3

Spartan3A Starter KitのDDR2 SDRAMコントローラのその後2

前回、うまくインプリメントが出来た!!と思ったSpartan3A Starter KitのDDR2 SDRAMコントローラだが、動作しなかった。がっくり。。。
よく調べてみると、Spartan3A Starter Kitの水晶発振器って50MHz!!100MHzと思ってやっていた。ということで入力周波数を50MHzに変更。良しこれで、と思ってもやはりだめ。

そういえばDCMの位置固定を今回外してしまったんだっけ。ということで、前の自分のブログの記事を読みながら、お勉強しています。こんなとき、経過を書いてあると便利です。でも、全く忘れてしまうなんて、本当に困ります。もう一度調整しなおしですね。

前の月曜日に下痢で大変な目にあったので、昨日、ウォシュレットを買ってきました。汚い話で申し訳ないですが、10分に1回トイレに行っていたので、お尻がはんぱなく痛かったです。ウォシュレット必須です。今日自分で取り付けます。
  1. 2009年06月14日 05:31 |
  2. Spartan3A Starter Kit
  3. | トラックバック:0
  4. | コメント:0

Spartan3A Starter KitのDDR2 SDRAMコントローラのバーストテストのインプリメント3(DDR2-300がOK)

さて、Spartan3A Starter KitのDDR2 SDRAMコントローラのバーストテストのインプリメントはDDR2-300に目標を変更してインプリメントを行っている。
1つクリティカルパスをつぶしたところ、タイミングが満足した。それは、ddr2_ckeを出力するためのカウンタだが、そのイネーブルを180度位相のクロックからとっていたのが、問題だった。+1するので、キャリーチェーンが伸びているのだが、そこが半分のクロックのパスとなり、タイミングが満足できなかった。イネーブルを0度位相のクロックで一度ラッチしたらクリティカルパスではなくなった。
インプリメントの結果は無事にタイミングを満足した。クロック周波数は150MHz。下にSummaryを示す。
Spa3A_STKit_DDR2_imp_16_090613.png

さて、よく考えてみると制約を忘れているところが。。。それはDQをサンプルする非同期FIFOのライトイネーブルになるsd_loop_inの制約だ。これは150MHzの周期6.67nsの半分タイミングでサンプルされるので、少なくとも3.34ns - 分散RAMのWEのセットアップタイムである必要がある。(入力パッドの遅延時間はDQも入っているので相殺されるとします)
とりあえず制約がかかっていない状態をFPGA Editorで見てみよう。Project NavigatorからFPGA Editorを立ち上げ、sd_loop_inの入力パッドからのネットsd_loop_in_IBUFをハイライトしてみてみた。
Spa3A_STKit_DDR2_imp_17_090613.png

遅延も0.753nsから3.041ns まで幅がある。
これでは困るので、制約をかけてみよう。かけるのはMAXDELAYとMAXSKEW。
Project NavigatorのProcessesペインのUser Constraintsを開いて、Create Timing Constraintsをダブルクリックする。
Spa3A_STKit_DDR2_imp_18_090613.png

するとタイミング制約用のContraints Editorが立ち上がる。左のConstraint TypeからExceptionsを開いてNetsをクリックする。そして右側上のdouble click to add a new constraint.. をダブルクリックして制約を追加しよう。
Spa3A_STKit_DDR2_imp_19_090613.png

ダイアログが開く。
1.Filter:のところにsd_loop_in_IBUF と入れて、Findボタンを押すとsd_loop_in_IBUFがAvailable nets:のところに表示される。
2.sd_loop_in_IBUFを選択し、真ん中の>ボタンを押してNet Targets: のところにsd_loop_in_IBUFを入れる。
3.MaxDelay & MaxSkewのラジオボタンをクリック。
4.MaxDelayに1.51ns、MaxSkewに0.865nsを入れる。
Spa3A_STKit_DDR2_imp_20_090613.png

6.OKボタンをクリックする。

そうすると、MaxDelay & MaxSkewが表示されるので、SaveしてContraints Editorを閉じよう。ちなみに制約がやけに細かいのは、一旦やってみて様子を見てからブログを書いているからなのだ。ぶっつけ本番でブログを書くこともあるし、様子を見てから書くこともある。
さて、これまでの作業で実際に追加された制約を下に示す。

NET "sd_loop_in_IBUF" MAXDELAY = 1.51 ns;
NET "sd_loop_in_IBUF" MAXSKEW = 0.865 ns;


これでもう一度インプリメントをしてみよう。インプリメントしたら制約はすべて満たされた。
FPGA Editorでもう一度sd_loop_in_IBUFネットを見てみたのが下の図。
Spa3A_STKit_DDR2_imp_21_090613.png

上の制約がないsd_loop_in_IBUFの配線よりもすっきりしている。
遅延は0.808ns~1.492nsの0.684nsの間に収まっている。

これでインプリメントは終了したので、実機で動かしてみることにする。わくわく、ドキドキだ。すぐに動かし見たいような、でも結果を見るのが怖いような。。。複雑な気持ち。。。でも、今日中にはやってみようと思う。その前にUCFのIOパッド番号だけでももう一度チェックしよう。。。
  1. 2009年06月13日 13:16 |
  2. Spartan3A Starter Kit
  3. | トラックバック:0
  4. | コメント:0

Spartan3A Starter KitのDDR2 SDRAMコントローラのインプメントをPlanAheadでフロアプラン

Spartan3A Starter KitのDDR2 SDRAMコントローラのインプメントをPlanAheadでフロアプランしてみることにした。インプリメント後の配置をPlanAheadでいじるのではなく、配置配線前にエリア制約をかけてみることにした。
最初にISE11.1iのProject NavigatorのProcessesペインの下のUser Constraints -> Floorplan Area/IO/Logic (PlanAhead) をダブルクリックした。
Spa3A_STKit_DDR2_imp_14_090612.png

PlanAheadが立ち上がるので、DQやDM、DQS以外のプリミティブをIOパッドから近いところにエリア制約をかけた。まだ、やり方はよく知っているわけではないので、書かない。やってみた結果が下の図。
Spa3A_STKit_DDR2_imp_12_090612.png

FPGAチップの左側にDDR2 SDRAM関係のIOパッドがあるので、そっちに集めるようにエリア制約をかけた。
その後、再度インプリメントして、P&R(Place & Route)後のタイミングを解析したのが下の図。
Spa3A_STKit_DDR2_imp_13_090612.png

クリティカルパスの遅延が大きくなってしまった。残念。
どうしてだろうかと、もう一度P&R後の配置をPlanAheadで表示してみた。
Spa3A_STKit_DDR2_imp_15_090612.png

クリティカルパスを表示してみると、間のブロックRAMで論理素子同士が分断されているようだ(白い線がクリティカルパス)。これで遅延が大きくなったのかな?
やはりフロアプランしてもだめか。。。

現実的なところでとりあえずDDR2-300を目指すことにしようと思う。
  1. 2009年06月12日 05:33 |
  2. PlanAheadについて
  3. | トラックバック:0
  4. | コメント:0

Spartan3A Starter KitのDDR2 SDRAMコントローラのバーストテストのその後

Spartan3A Starter KitのDDR2 SDRAMコントローラのバーストテストの2度目のシミュレーションを行った。
やはり、FFでクリティカルパスを切ったので、全体的にタイミングがずれていて、DQに出すデータやマスクを再度FFでラッチする必要があった。いろいろなタイミング関係を調整して、やっとバースト転送テストで正常に動作するようになった。当たり前だが、前のものより1クロック動作するのが遅くなった。当然ながら、FFを使ったので回路規模も増えた。
下に、以前と今回のタイミングチャートの違いを示す。
Spa3A_STKit_DDR2_Sim_9_090610.png

上のタイミングチャートが以前のもの、下が今回修正後のタイミングチャートだ。上のタイミングチャートはピンクの楕円で囲ったMAIN_STATEがWRITになった時から、実際にDDR2 SDRAMにWRITEコマンドを発行するまでの遅延は1クロックだが、下のタイミングチャートでは2クロックに増加している。これが遅延の増加分だ。

動作がOKになったものをISE11.1iでインプリメントして、FPGA Editorで見てみると結構、配線が散らばっている。
Spa3A_STKit_DDR2_imp_8_090611.png

Timing Analyzerのタイミング解析結果はこれ、Timing Analyzerを単体で動作させている。
Spa3A_STKit_DDR2_imp_9_090611.png

ここで疑問なのは、クロックの制約が5nsで、スラックが-1.648nsなのに、なんで Minimum period is 7.974ns.なのかということだ。後の1.362ns はどこから来たんだろうか?

ともかく、SDRAMの配置の領域がFPGA内部に散らばっているようなので、PlanAheadでフロアプランを試みる。
まずはPlace & Route後の配置をPlanAheadで見てみよう。ISE11.1iのProject NavigatorのProcessesペインでImplement Desin -> Place & Route -> Analyze Timing / Floorplan Design (PlanAhead) をダブルクリックしてPlanAheadを立ち上げる。
Spa3A_STKit_DDR2_imp_10_090611.png

すると下にTiming Resultsが表示されている。エラーがあるパスが表示される。エラーがあるパスをクリックすると右上のデバイスの中にそのパスが表示されるみたいだ。
下のTiming Resultsでクリティカルパスを右クリックしてSchematicを選択すれば、クリティカルパスの回路も表示することができる。
Spa3A_STKit_DDR2_imp_11_090611.png

ここは、次のアドレスがアクティブバンクかどうかを比較するところで、DDR2 SDRAMコントローラの動作上仕方のないところだ。
今現在だとPlace & Route後のPlanAheadを使っているが、Place & Routeする前にPlanAheadを使ってフロアプランしようと思う。そのためには、もう少し部分的なモジュールの階層キープを使っていこうと思っている。
  1. 2009年06月11日 05:45 |
  2. Spartan3A Starter Kit
  3. | トラックバック:0
  4. | コメント:0

Spartan3A Starter KitのDDR2 SDRAMコントローラのバーストテストのインプリメント2(弱音を吐く編)

Spartan3A Starter KitのDDR2 SDRAMコントローラのバーストテストのインプメントをしているのだが、Virtex-4と違ってSpartan-3Aだと200MHz動作、DDR2-400は厳しいみたい。
クリティカルパスをとりあえずFFでぶった切ってきたのだけれど、そろそろモグラたたきになってしまったようだ(こっちをケアしても、あっちがだめ)。
今のところ、クリティカルパスは6.920ns。5nsが目標なのでまだまだだ。
Spa3A_STKit_DDR2_imp_7_090608.png

Syntesize-XSTのプロパティのKeep HierarchyはNoになっている。

しかし、なひたふさんは”Spartan3E+DDR2メモリで400Mbps”ということなので凄い。。。少しタイミングエラーは出ているということだったが、200MHzで動作させるのは難易度が高い。
Spatan-3Aもデータシートによると”DDR/DDR2 SDRAMを最大で333Mbpsまでサポート”だそうなので、これで行くと166MHzということだな。そこまでは行けそうかな?これもスピードグレードが-5かもしれないし、どうだろうか?

とりあえず、だいぶ回路を変更してしまったので、もう一度シミュレーションで動作するかどうかを調べて、PlanAheadによるフロアプランでどのくらい改善できるかを見てみようと思う。
  1. 2009年06月09日 18:34 |
  2. Spartan3A Starter Kit
  3. | トラックバック:0
  4. | コメント:0

MAPエラー(ERROR:Pack:1664とERROR:Pack:1665)の回避方法

今日もウイルス性胃腸炎でお休みです。でも、今朝はおかゆを少し食べられました。

さて、体力がないので、ちょっとずづDDR2 SDRAMコントローラのバーストテストのインプリメントをしているのだが、MAPでERROR:Pack:1664とERROR:Pack:1665が出てMAPプロセスを完了できないという問題が発生してしまった。
Spa3A_STKit_DDR2_imp_4_090608.png

ddr2_dq<0>に関するエラーの全文を下に示す。

ERROR:Pack:1664 - A dual data rate register could not be packed into an I/O componet as required. The SET/RESET signal usage of dual data rate register symbol "ddr2_sdram_cont_inst/read_write_io_inst/ddr2_cont_iob_inst/DQ_IOB_INST[0].dq_io_pad_inst/ODDR2_TRI" conflicts with another register in the I/O component.
Please examine the connectivity and attributes of all registers in the I/O
component involving pad net "ddr2_dq<0>".
ERROR:Pack:1665 - A dual data rate register could not be packed into an I/O component as required. Please try constraining the dual data rate register "ddr2_sdram_cont_inst/read_write_io_inst/ddr2_cont_iob_inst/DQ_IOB_INST[0].dq_io_pad_inst/ODDR2_TRI" together with a valid pad or buffer symbol.


ERROR:Pack:1664でSET/RESET信号がコンフリクトしていると言っているけど、これはあわせてあるはずなんだけど。。。
dq_io_pad.v のソースを下に示す。

// IO padの形にVerilog-HDLファイルを作る。後でフロアプランする時に使いやすくするため// トライステート用のDDRをインスタンシエーションしてある
// DQ用
// DQの入力用のFFは使用しないで直接AFIFOの入力に入れる。

`default_nettype none
`timescale 1ns / 1ps

module dq_io_pad (
    input    wire    input_clk,    // 入力用クロック
    input    wire    clk,        // 出力用、及び汎用クロック
    input    wire    clk90,        // 90度位相のクロック
    input    wire    reset,
    inout    wire    io_pad,        // IO PAD入出力
    output    wire    dq_data_from_io,    // DQのデータ(IOBのFFは使用しない)
    input    wire    tri_ddr_ce_to_io,    // トライステート用DDRレジスタのCE
    input    wire    tri_ddr_d0_to_io,    // トライステート用DDRレジスタのD0
    input    wire    tri_ddr_d1_to_io,    // トライステート用DDRレジスタのD1
    input    wire    data_ddr_ce_to_io,    // データ用DDRレジスタのCE
    input    wire    data_ddr_d0_to_io,    // データ用DDRレジスタのD0
    input    wire    data_ddr_d1_to_io    // データ用DDRレジスタのD1    
);
    wire input_clkx;
    wire clkx;
    wire tri_out;
    // wire from_io_pad;
    wire to_io_pad;
    wire clk270;
    
    assign input_clkx = ~input_clk;
    assign clkx = ~clk;
    assign clk270 = ~clk90;
    
    ODDR2 #(
        .DDR_ALIGNMENT("NONE"),
        .SRTYPE("ASYNC")
    ) ODDR2_TRI(
        .Q(tri_out),
        .C0(clk270),
        .C1(clk90),
        .CE(tri_ddr_ce_to_io),
        .D0(tri_ddr_d0_to_io),
        .D1(tri_ddr_d1_to_io),
        .R(1'b0),
        .S(reset)
    );
    
    ODDR2 #(
        .DDR_ALIGNMENT("NONE"),
        .SRTYPE("SYNC")
    ) ODDR2_DATA(
        .Q(to_io_pad),
        .C0(clk270),
        .C1(clk90),
        .CE(data_ddr_ce_to_io),
        .D0(data_ddr_d0_to_io),
        .D1(data_ddr_d1_to_io),
        .R(1'b0),
        .S(reset)
    );
    
    IOBUF IOBUF_DQ(
        .O(dq_data_from_io),
        .IO(io_pad),
        .I(to_io_pad),
        .T(tri_out)
    );
        
endmodule


そういえば”Spartan3A Starter KitのDDR2 SDRAMコントローラIOテストモジュール公開”で公開したテストモジュールもほとんど同じ形なのにインプリメントできているのはなぜだろう?
違いを見てみると、違いはSyntesize-XSTのプロパティのKeep HierarchyがNoかYesかの違いだった。
Spa3A_STKit_DDR2_imp_5_090608.png

Yesにしてもう一度MAPを実行すると、エラーなく終了した。
Spa3A_STKit_DDR2_imp_6_090608.png

いろいろ忘れているものや動作クロックを落とさないとだめだったが、一応、Place & Routeまで通った。

やはり、XSTの階層保持がYesでないと、ODDR2も最適化されてしまうのだろうか?Yesでもそれらしいウォーニングが出ていたようだが、Place & Routeまで通った。もしかして、ODDR2の前までのネットをKeepすればNoでも大丈夫とか?そのうち必要があったらやってみることにする。

この辺の情報を持っている方がいらしたら教えてください。

追記:
Keep HierarchyがYesだと、動作周波数が100MHz程度になってしまいます。とりあえずsoftに変更しました。それでも今のところ、クリティカルパスは6.5nsです。

追記2:
Keep HierarchyがNoでも各モジュールごとにKEEP_HIERARCHY属性を付けることができた。moduleの頭に(* KEEP_HIERARCHY = "TRUE" *)を付ければOKだった。

(* KEEP_HIERARCHY = "TRUE" *)module dq_io_pad (

  1. 2009年06月09日 09:18 |
  2. FPGAのトラブル
  3. | トラックバック:0
  4. | コメント:0

Spartan3A Starter KitのDDR2 SDRAMコントローラのインプリメント(準備編)

さて、現在は下痢に悩まされているのだが、それ以外は普通なので、ブログを書くことにする。
UCFにDDR2 SDRAMのアドレスや制御信号を加えてUCFを完成させる。
最初に問題が起こった。Spartan3A Starter Kitのユーザーズガイドの116ページにはSD_A<15>, SD_A<14>, SD_A<13>(下参照)があるけど、DDR2 SDRAM (MT47H32M16) のアドレスはA12までしかないはず。。。

NET "SD_A<15>" LOC = "W3" | IOSTANDARD = SSTL18_II ;
NET "SD_A<14>" LOC = "V4" | IOSTANDARD = SSTL18_II ;
NET "SD_A<13>" LOC = "V3" | IOSTANDARD = SSTL18_II ;


DDR2 SDRAM (MT47H32M16) のマニュアルの14ページ、"Figure 5: 32 Meg x 16 Functional Block Diagram" を見てもA12までしか存在しない。
Spartan3A Starter Kitのユーザーズガイドの114ページの"表 13-1 : FPGA と DDR2 SDRAM の接続"を見ると、将来のアップグレードのために用意されているとのこと。
Spa3A_STKit_DDR2_imp_1_090608.png

これは削除することにした。
次に、Bank Addressをつないでいると、SD_BA<2>がある。。。

NET "SD_BA<2>" LOC = "P5" | IOSTANDARD = SSTL18_II ;


DDR2 SDRAM (MT47H32M16) のマニュアルの14ページ、"Figure 5: 32 Meg x 16 Functional Block Diagram" を見てもBA1までしか存在しない。これは何だろう???今度はSpartan3A Starter Kitのユーザーズガイドにも何も書いていない。
Spartan-3A/3AN Starter Kit Schematicsを見てみることにした。11ページを見てみると、SD-BA2はDDR2 SDRAMのL1ピンにつながっている。
Spa3A_STKit_DDR2_imp_2_090608.png
これをDDR2 SDRAMのマニュアルで調べると、19ページに載っていた。それによると Reserved for future use だそうだ。
Spa3A_STKit_DDR2_imp_3_090608.png

これで安心して削除することにする。

LEDのところで見慣れない記述を見た。SLEW = QUIETIO て何?
Spartan-3ジェネレーションFPGAユーザーズガイドの349ページによると、

各IOBにはスルーレート制御があり 、LVCMOS および LVTTL 出力の出力スイッチエッジレート を設定 します。 スルーレートはSLEW属性で制御され、SLOW(デフォルト)、FAST、またはQUIETIO (Spartan-3A/3AN/3A DSPデバイスのみ。最も低速) に設定できます。


だそうです。Spatan-3Aシリーズだけらしい。
  1. 2009年06月08日 16:59 |
  2. Spartan3A Starter Kit
  3. | トラックバック:0
  4. | コメント:0

ウイルス性胃腸炎

今日起きたら、気持ちが悪くなっておう吐してしまった。そのあとは下痢、またおう吐、下痢。。。
とても仕事に行けないので、今日はお休みです。
少しおさまったので、医者に行ってきたらウイルス性の胃腸炎だろうという診断でした。いまプリンぺランを飲んで様子を見ているところです。

今朝は、Spartan3A Starter Kit用DDR2 SDRAMコントローラのインプリメントをして、実際に動作させてみようと思っていたんだけど、明日以降に持ち越します。
  1. 2009年06月08日 10:23 |
  2. 日記
  3. | トラックバック:0
  4. | コメント:6

工作室の整備

私の家は昔、製麺所を営んでいて、私が小さい頃はそうめんや冷麦を干していたものだった。その以前に乾燥場だった所を工作部屋として使おうとしている。
やはり、机がないとやりずらいので、今日は机を作った。180cm程度の2X4材を7本買ってきて、そのうちの5本を使って天板作り、足の長さが60cmだったので、その長さを180cmからとったため、必然的に机の幅は120cm程度となった。天板の間隔は4mmにするので、シナべニアを挟んで、真ん中に板を渡してねじ止め。足を作って、足を付けた。3時間くらいでできた。
値段は80cm程度の236円の2X4材が6本なので、236 X 6 = 1,416円だった。
机と、前に作った長椅子(作業台)があるので、雰囲気が出てきた。
板を磨いたり、切ったりするのには、背の高い机が良いのだが、物が出来上がってくると、高さが出てくる。その場合には長椅子を作業台として使い、もっと高くなると、床にパレットを置いて作る。
kousakushitu_090607.jpg

  1. 2009年06月07日 21:09 |
  2. 木工
  3. | トラックバック:0
  4. | コメント:0

数学ガールのsin(x)のテイラー展開をMaximaで検証

私は数学ガールという本を近頃読んでいる。言ってみれば数学の萌え本だ。
いつもは読む気になれない数学の証明を萌え本形式で書いている。だいたいなるほどと思うところがあるが、よくわからないところは読み飛ばしている。
その中でそうなのか~と思ったのはsin(x)のテイラー展開だった。(232ページ~233ページ)
sin(x)のテイラー展開の部分和を徐々に加えていくと、徐々にsin(x)のグラフに近づいて行くというのが予想していなかったので面白かった。それじゃということで、私が大学のころはなかった文明の利器を使って検証してみた。
使ったのは数値計算のためのソフトウェア。初めはOctaveを使おうと思ったんだけど、どうもよくやり方が分からなくて断念。前から使っていたMaximaを使うことにした。このMaximaは娘に2次方程式を聞かれたときに、答え合わせ用に使っていたものだ。これで検証してみることにした。
作ったファイル (sin_taylor.wxm) を下に示す。

F(x) := sin(x);
G(x) := x/1;
H(x) := x/1 - x*x*x/(1*2*3);
I(x) := x/1 - x*x*x/(1*2*3) + x*x*x*x*x/(1*2*3*4*5);
J(x) := x/1 - x*x*x/(1*2*3) + x*x*x*x*x/(1*2*3*4*5) - x*x*x*x*x*x*x/(1*2*3*4*5*6*7);
plot2d([F,G,H,I,J],[x,-7,7],[y,-10,10]);


このファイルをwxMaximaからOpenするとwxMaxmaの画面はこうなる。
Maxima_1_090606.png

そしてMaximaによって書かれたグラフが下。
Maxima_2_090606.png

最初の部分和 F(x)は y=x で、これはsin(x)を微分したcos(x)のx=0の時の値に等しいので、sin(x)のx=0の時の接線になっている。そこから部分和を追加ていくごとにsin(x)に近づいて行くのが分かる。これはよくわかるのではないだろうか?
面白そうなのでもう少しやってみた。

K(x) := x/1 - x*x*x/(1*2*3) + x*x*x*x*x/(1*2*3*4*5) - x*x*x*x*x*x*x/(1*2*3*4*5*6*7) + x^9/9!;
L(x) := x/1 - x*x*x/(1*2*3) + x*x*x*x*x/(1*2*3*4*5) - x*x*x*x*x*x*x/(1*2*3*4*5*6*7) + x^9/9! - x^11/11!;
plot2d([F,K,L],[x,-7,7],[y,-10,10]);


下がそのグラフ。
Maxima_3_090606.png

だいぶsin(x)に近づいてきた。このように部分和の数を増やしていくと、x=0の点から段々とsin(x)に近づいてくるとは思わなかった。面白い。。。

数学ガールも読み物としては面白いが、もう1冊買ったのだった。”やり直しのための工業数学”という本を買った。こちらは、CRCや暗号、フーリエ変換などが書いてある。こっちを勉強することにしようと思う。特にCRCやハフマン符号化。

#こんなにsin(x)の近似していないところの発散がひどいのでは近似式として使えないなと思ったけど、考えてみたら-π~πまで近似していれば、後は-π~πに折り返せばいいのか? そうすると9の階乗の部分和くらいまででいいのかな?
  1. 2009年06月06日 19:28 |
  2. EDAツールについて
  3. | トラックバック:0
  4. | コメント:3

Spartan3A Starter KitのDDR2 SDRAMコントローラのシミュレーション4(バースト転送テスト)

Spartan3A Starter KitのDDR2 SDRAMコントローラのシミュレーション3(リードデータのバグフィックス)”でリードした時の出力データも正常になったので、今度はバースト転送テストのシミュレーションをしてみることにした。
以前のSuzaku-Vのバースト転送テストの際にトップモジュールとテストベンチは作ってあるので、それに修正を加えた。
動作しました。動作している最初の様子が下の図。Suzaku-Vのバースト転送テストの一番目の図と同じ位置のキャプチャ波形だ。
Spa3A_STKit_DDR2_7_090606.png

バースト転送テストは、ランダムなバースト長のWrite, そして同じアドレスをバーストReadして、Writeした値とチェックという作業を繰り返しテストする。LED0がついている間はエラーなしで、エラーが起こるとLED0は消え、LED1が点灯する。エラーが出るとWrite, Readテストも停止する。
シミュレーションの全体図を表示すると下の図のようになる。
Spa3A_STKit_DDR2_8_090606.png

50usの間シミュレーションを行ったが、Write, Readが止まってもいないし、一番下の信号nLEDもずーとeのまま変化がないので、エラーは発生していない。

これでシミュレーションは終了したので、とりあえずバースト転送テストのインプリメントをすることにしよう。
  1. 2009年06月06日 05:59 |
  2. Spartan3A Starter Kit
  3. | トラックバック:0
  4. | コメント:0

Spartan3A Starter KitのDDR2 SDRAMコントローラのシミュレーション3(リードデータのバグフィックス)

Spartan3A Starter KitのDDR2 SDRAMコントローラのシミュレーション2(DMの機能検証)”でリードした時の出力データが正しくないという課題があったが、バグをフィックスして正常に出力されるようになった。
Spa3A_STKit_DDR2_6_090605.png

ピンクの四角で囲ったrddata_validが1の時に、output_dataにリードしたデータが出力されているのが分かる。これでOK。。。
どんなバグがあったかというと、まずはテストベンチでループバックの信号sd_loop_inとsd_loop_outをddr2_sdram_contに接続を忘れてしまっていた。後は非同期FIFOのクロックの位相が間違っていた。お恥ずかしい。。。まあ、バグなんてそんなものさと開き直る。。。
これでやっとバースト転送テストに移ることができる。
  1. 2009年06月05日 05:28 |
  2. Spartan3A Starter Kit
  3. | トラックバック:0
  4. | コメント:0

FPGAの部屋が100万ヒット達成

ブログ”FPGAの部屋”が100万ヒットを達成しました。皆様、ありがとうございます。
これからも、自分の物忘れを補うためにも書いていこうと思います。かなり巨大な備忘録になりました。
FPGAs_room_1milion_090604.png

  1. 2009年06月04日 20:15 |
  2. 日記
  3. | トラックバック:0
  4. | コメント:0

Spartan3A Starter KitのDDR2 SDRAMコントローラのシミュレーション2(DMの機能検証)

Spartan3A Starter KitのDDR2 SDRAMコントローラのシミュレーション1”でDQとDQSの動作はOKになったので、今度はDMの動作のバグを取ることにする。

DM(ddr2_dm) とは何なのか?ということから説明すると、このDDR2 SDRAMは16ビットのデータ幅を持っている。しかもプリフェッチ4なので、4つの16ビットのデータをWriteでは書き込むことになる。これでは一度に8バイトのデータを書き込むことになってしまう。もしC言語などでcharで宣言した i という変数を1つだけ書きたいとする。変数 i の隣のメモリ番地には、変数 j がアサインされたら。。。このメモリをDDR2 SDRAMとすると、変数 i の番地に i の値を書きこもうとしたら、変数 j も書き換えることになってしまう(8バイト単位でWriteするから)。そこでDM(ddr2_dm)信号で、書き換えたくないバイトはマスク、つまり書き込まないようにしようということだ。ddr2_dmが1の時には、そのバイトはDDR2 SDRAMに書き込まれない。
以上のことを踏まえて、シミュレーションでDDR2 SDRAMにWriteするtaskを見てみよう。

DDR2_WRITE(25'h000_0100, 4'b1001, 32'h1234_5678, 4'b0110, 32'h9ABC_DEF0);
DDR2_WRITE(25'h000_0104, 4'b1100, 32'h2233_4455, 4'b0011, 32'h3344_5566);
DDR2_WRITE(25'h000_0108, 4'b1010, 32'h7788_99AA, 4'b0101, 32'hBBCC_DDEE);


DDR2_WRITEというのがDDR2 SDRAMへWriteするtaskで、最初のフィールドが先頭のアドレス、2番目のフィールドが3番目のフィールドのマスクの値(DM)、3番目のフィールドはDQSの最初の立ち上がりと立下りのクロックエッジで書き込まれるデータ(DQ)、4番目のフィールドは5番目のフィールドのマスクの値(DM)、5目のフィールドはDQSの2番目の立ち上がりと立下りのクロックエッジで書き込まれるデータ(DQ)となっている。都合64ビット、8バイトのデータがバーストで書き込まれる。2番目と4番目のフィールドのマスク値が1のバイトはDDR2 SDRAMにバイトデータが書き込まれない。
バグを修正したDDR2 SDRAMのWrite時のシミュレーション波形で見てみる。
Spa3A_STKit_DDR2_4_090604.png

上の図でピンクの矢印の部分はddr2_dqの値が16進数で"5678"で、ddr2_dmの値が2進数で"01"なので、"5678"というWriteデータのうちの"56"のみDDR2 SDRAMに書きこまれることになる。"78"の部分は書き込まれずに元のデータが残る。
緑の矢印の部分はddr2_dqの値が16進数で"1234"で、ddr2_dmの値が2進数で"10"なので、"1234"というWriteデータのうちの"34"のみDDR2 SDRAMに書きこまれることになる。"12"の部分は書き込まれずに元のデータが残る。
それでは、Readのシミュレーション波形を見てみよう。
Spa3A_STKit_DDR2_5_090604.png

上の波形を見るとddr2_dqにReadされる波形はピンクの矢印のところに"56xx"が見えて"56"のみWriteされているのが分かる。緑の矢印のところに"xx34"が見えて"34"のみWriteされているのが分かる。
これでddr2_dmの動作もOKとなった。
これからは、バースト転送テストを行うことにしようと思ったが、出力データが正常に出ていないようだ。これをバグフィックスする。

#このようにいまのSDRAMはデータの粒度が大きいので、小さいデータ粒度でアクセスすると無駄が多い。例えば、通常のx86パソコンのDIMMは64ビット幅なのでDDR2のプリフェッチ4だと、32バイトを一度に読み書きすることになる。そこで1バイトを書きかえるとすると、残りの31バイトのアクセスは無駄になる。つまり、その場合は1/32 = 3パーセント程度しか使っていないことになる。DDR3のプリフェッチ8だと1/64 = 1.6パーセント程度しか使えていない。データキャッシュがないとやっていられないだろうな~。。。
  1. 2009年06月04日 05:32 |
  2. Spartan3A Starter Kit
  3. | トラックバック:0
  4. | コメント:0
»