FC2カウンター FPGAの部屋 VGAコントローラ

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

FPGAの部屋

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

キャラクタ描画テスト回路の休止等々

これまで、キャラクタ描画テスト回路を作ってきた。シミュレーションでは、だいぶイケているようなのだが実機で動作しない。今日もバグが有ったので、潰したのだが、ディスプレイ画面は単色で塗りつぶされてしまう。ChipScope PROかなふたふさんのMITOU JTAGあたりが使えれば良いのだが、そのもない。とりあえずISE12.1が出たら、お試しで1ヶ月ChipScopeが使えると思うので、それまで保留にしようと思う。やはり、DDR2 SDRAMコントローラがおかしいのかな?DDR2 SDRAMコントローラは一連の流れで、動作を確認しChipScopeで見て、読み書きしているのを確認したハズのだが???それでも配線を同様にしてもReadデータが受からない自体が発生したので、まだ見落としがあるのかもしれない。
だいぶ、ブログを書きながら趣味でやるには辛くなってきた。やはりChipScopeがないと手詰まりだ。

仕事では今のところ、画像処理がメインで、Excelの値のテーブルからVHDLファイルを自動生成するRubyソフトウェアを開発して、自動生成したVHDLの演算回路に周辺を付けている。もう1つのプロジェクトも画像処理関係で、確か5月位(6月かもしれません?たしか場所はパシフィコ横浜だったと思うので)に画像関係?の展示会に出すそうだ。私も説明要員として行くので、その時はよろしくお願いします。展示会の名前を忘れてしまったが、もしかしてESEC?でも名前がないし?違うのかな?後で何に出すのかを聞いておくことにする。

次は、Xilinxを離れて、AlteraでVerification Engineerの戯言さんの無償ツールで実践する「ハード・ソフト協調検証」(全8回)を自分でやってみたいと思っています。かなり詳しく書かれているので、これをやってみた。ここがうまくいかなかった。とかの散発的なレポートになるかもしれませんが。。。
最近のQuartus2やAltera用ModlSimがライセンスいらなくなったことや、Nios2/eプロセッサコアの無償化、ChipScopeと同様のSignal Tap2が無償のことなど(どんな回路を作っているのかというレポートを承認する必要がある)Alteraの方が家でやるにはやりやすい環境ですね。(当然、対応FPGAの制限はありますが)それに、SOPC Builderも使いやすそうですし。現在のキャラクタ描画テスト回路をSDRAM対応にして、DE0ボードに載せてみても良いかもしれません。そうすればSignal Tap2でデバックし放題ですものね。。。魅力的です。
仕事では、Xilinxなので、ChipScopeも機能を限定的でもフリーで使えるようになればうれしいのですが。。。家でブログを書きながらいろいろ試しているのは、仕事をスムーズに進められるようにするための勉強の意味もあるので、Xilinxからは、なかなか離れられません。しかし、Alteraの環境が良いので浮気したいと思うようになってきました。
  1. 2010年02月24日 05:41 |
  2. VGAコントローラ
  3. | トラックバック:0
  4. | コメント:0

キャラクタ描画テスト回路の実機デバック4(DCMの配置)

前回、BUFG入力までの配線が長くなりすぎていたのが原因だったので、DCMの配置を見直すことにした。もともとDCMは1つも配置を固定してない。全部ツール任せになっていた。
DCMは3つ使っていて、水晶発振器の50MHzをDDR2 SDRAMの動作周波数150MHzに変換するDCM(DCM1とする)、水晶発振器の50MHzをVGAコントローラの動作周波数65MHzに変換するDCM(DCM2とする)、DCM1の150MHzを元にDDR2 SDRAMコントローラに必要な反転クロック、90度位相がずれたクロックを生成するDCM(DCM3とする)だ。
DCM1は2つのBUFG、DCM2は2つのBUFG、DCM3は3つのBUFGを使用する。このSpartan3A700には、24個のBUFGMUX(BUFGMUXはBUFGと市ても使える)があって、FPGAチップの上下の真ん中に4個ずつ、左右の真ん中に8個ずつ配置されている。水晶発振器のクロック入力はFPGAチップの上側の真ん中にあるので、最初のDCMはその近くが良い。下図のようにDCM1とDCM3が上側に配置されていて、DCM2が下側に配置されている。BUFGはDCMの真ん中に配置されている。色がついていないBUFGMUX、DCMは使用されていないもの。DCM1とDCM3で合計5個BUFGを使用するので、DCM1用のBUFGが下に追いやられてしまったようだ。
Bitmap_VGAC_debug_11_100221.png

解決策としては、豊富なBUFGMUXを持つ左側の真ん中にDCM3を持っていこうと思う。DCM3の配置を下の制約で示す位置に固定した。

INST "ddr2_sdram_cont_i/dcm_module_inst/DCM_INST1/DCM_SP" LOC = DCM_X0Y2;


インプリメントの結果、DCM1、DCM2が上側真ん中、DCM3が左側の真ん中に配置されて、DDR2 SDRAMのデータバス出力のタイミングエラーはなくなった。
これで、実機にダウンロードしてやってみたところ、VGA画面も出なくなってしまった?

この後、色々な試行錯誤を繰り返した。悶々とした時間が過ぎた。(途中で桜川市の真壁にひな人形まつりを見に行ってリフレッシュ)

結局DCMは配置によって、クロックパスが極端に遅くなることがあって、(これはすぐには気がつかないので、非常にわかりにくい。注意する必要がある)結局、DCM1は上側の真ん中、DCM2,DCM3は並んで、左側の真ん中に配置した。下に配置制約を示す。

INST "ddr2_sdram_cont_i/dcm_module_inst/DCM_INST1/DCM_SP" LOC = DCM_X0Y1;
INST "dcm_DDR2_VGA_clk_i/dcm_VGA_clk_dcm/DCM_SP" LOC = DCM_X0Y2;
INST "dcm_DDR2_VGA_clk_i/dcm_DDR2_clk_dcm/DCM_SP" LOC = "DCM_X2Y3";


さて、ddr2_dqとddr2_dqsにIBUF_DELAY_VALUE = 1を入れると、データが安定することが分かった。となるとRead関係で残るはsd_loop_inのみ。sd_loop_inにもIBUF_DELAY_VALUE = 1を入れると、データが不安定になった。そういえば、前回、sd_loop_inは配線を固定してない。
sd_loop_inもDDR2 SDRAMバーストテスト回路から配線制約を吐き出させて、キャラクタ描画テスト回路の制約ファイルに追加した。下が制約。

NET "sd_loop_in_IBUF"
ROUTE="{3;1;3s700afg484;df4ab136!-1;-70632;33392;S!0;-159;0!1;1612;-912!"
"1;1596;1056!1;1680;-1720!1;-1464;-3608!1;-1618;10040!1;-225;1797!1;-1632;"
"-10456!2;-3069;-3647!3;450;5392!3;4355;1359!4;4;-12032!4;4255;-597!5;"
"3927;-4329!5;0;-7000!6;-474;9200!6;178;6576!6;184;13320!7;-1185;4651!7;"
"-1867;-629!8;4111;-10997!8;192;-13688!9;0;-6876!9;3952;222!10;3905;-657!"
"11;2808;3082!11;2917;-5975!11;1152;657;L!11;1152;313;L!12;2123;3408;L!13;"
"-511;-4883!13;1168;-1715;L!13;1168;-1371;L!14;13605;-139!14;-447;-2703!"
"15;24;-6784!16;1099;79!17;-17;-7547!17;-652;-752!18;-658;-744!19;3905;"
"-657!20;1099;-97!21;2976;-3486!22;3935;-4073!22;-652;-752!23;3952;98!24;"
"1152;313;L!24;1152;657;L!25;1152;313;L!25;1152;657;L!26;-2848;-1044!27;"
"-2957;1261!31;-2953;1265!34;-8965;428;L!34;-8965;772;L!35;3935;-4073!36;"
"3935;-4073!37;6944;-24!38;3952;98!39;1099;79!40;1099;79!41;1152;313;L!41;"
"1152;657;L!42;6912;0!43;-2968;104!44;12173;-119!45;1099;79!46;1152;657;L!"
"46;1152;313;L!51;1352;-701;L!51;-2104;-1045;L!52;1352;-701;L!53;1176;"
"-1377;L!56;1152;657;L!56;1152;313;L!57;1152;657;L!57;1152;313;L!58;-2304;"
"313;L!58;1152;313;L!58;1152;657;L!58;-2304;657;L!59;1152;657;L!59;1152;"
"313;L!60;6944;-24!61;6944;-24!64;-2112;-1039;L!65;1160;651;L!65;1160;307;"
"L!66;-7565;776;L!66;-7565;432;L!67;15333;-139!84;1152;657;L!84;1152;313;L"
"!85;-2304;313;L!85;-2304;657;L!91;-7237;772;L!91;-7237;428;L!}";


これを追加して、ddr2_dqとddr2_dqsのIBUF_DELAY_VALUE = 1をとってみたが、やはり安定しない。
sd_loop_inの配線を固定した状態でも、ddr2_dqとddr2_dqsのIBUF_DELAY_VALUE = 1を制約に加えれば安定する。
DDR2 SDRAMバーストテスト回路とキャラクタ描画テスト回路のsd_loop_inの配線の遅延値は配線を固定したにも関わらず、1.439nsec と1.412nsec と異なっている。この僅かな遅れが致命的なのか?
とりあえず、一部、最初に少しがまだ動いていて、おかしいようだが、これは他の原因かもしれないので、とりあえず、現在は動作を禁止しているキャラクタ生成コントローラを動作させてみようと思う。
UCFに追加した制約を以下に示す。

// 02/20 @ 12:48:23
NET "ddr2_sdram_cont_i/read_write_io_inst/ddr2_cont_iob_inst/dqs_clk_node<0>"
ROUTE="{3;1;3s700afg484;c20d0b8b!-1;-70632;12888;S!0;-159;0!1;-161;-887!"
"2;-1291;-2737!3;-29;-8091!4;259;-695!5;-1703;-139!6;108;53;L!}";
// 02/20 @ 12:51:22
NET "ddr2_sdram_cont_i/read_write_io_inst/dq_data<0>"
ROUTE="{3;1;3s700afg484;a5bd1784!-1;-70632;26072;S!0;-159;0!1;2447;-605!"
"2;4489;301!2;4489;645!3;167;0;L!4;167;0;L!}";
NET "ddr2_sdram_cont_i/read_write_io_inst/dq_data<1>"
ROUTE="{3;1;3s700afg484;751a0e0!-1;-70632;19640;S!0;-159;0!1;1696;1720!2;"
"1784;1376!2;1784;1032!3;167;0;L!4;167;0;L!}";
NET "ddr2_sdram_cont_i/read_write_io_inst/dq_data<2>"
ROUTE="{3;1;3s700afg484;89ffb99b!-1;-70632;6136;S!0;-159;0!1;1696;1720!2;"
"1784;1376!2;1784;1032!3;167;0;L!4;167;0;L!}";
NET "ddr2_sdram_cont_i/read_write_io_inst/dq_data<3>"
ROUTE="{3;1;3s700afg484;61a7f9cb!-1;-70632;9192;S!0;-159;0!1;2447;-605!2;"
"4489;645!2;4489;301!3;167;0;L!4;167;0;L!}";
NET "ddr2_sdram_cont_i/read_write_io_inst/dq_data<4>"
ROUTE="{3;1;3s700afg484;5a9ec78e!-1;-70632;9512;S!0;-159;0!1;1696;1720!2;"
"1784;1376!2;1784;1032!3;167;0;L!4;167;0;L!}";
NET "ddr2_sdram_cont_i/read_write_io_inst/dq_data<5>"
ROUTE="{3;1;3s700afg484;c3906147!-1;-70632;5816;S!0;-159;0!1;2447;-605!2;"
"4489;645!2;4489;301!3;167;0;L!4;167;0;L!}";
NET "ddr2_sdram_cont_i/read_write_io_inst/dq_data<6>"
ROUTE="{3;1;3s700afg484;3cdde0e5!-1;-70632;19320;S!0;-159;0!1;2447;-605!"
"2;4489;645!2;4489;301!3;167;0;L!4;167;0;L!}";
NET "ddr2_sdram_cont_i/read_write_io_inst/dq_data<7>"
ROUTE="{3;1;3s700afg484;48045bde!-1;-70632;26392;S!0;-159;0!1;1696;1968!"
"2;1784;1032!2;1784;1376!3;167;0;L!4;167;0;L!}";
NET "ddr2_sdram_cont_i/read_write_io_inst/dq_data<8>"
ROUTE="{3;1;3s700afg484;8152c779!-1;-70632;40144;S!0;-159;0!1;1696;1720!"
"2;1784;1376!2;1784;1032!3;167;0;L!4;167;0;L!}";
NET "ddr2_sdram_cont_i/read_write_io_inst/dq_data<9>"
ROUTE="{3;1;3s700afg484;bfa7b4d9!-1;-70632;53328;S!0;-159;0!1;1696;2040!"
"2;1784;1376!2;1784;1032!3;167;0;L!4;167;0;L!}";
NET "ddr2_sdram_cont_i/read_write_io_inst/dq_data<10>"
ROUTE="{3;1;3s700afg484;ace04032!-1;-70632;36448;S!0;-159;0!1;2447;-605!"
"2;4489;645!2;4489;301!3;167;0;L!4;167;0;L!}";
NET "ddr2_sdram_cont_i/read_write_io_inst/dq_data<11>"
ROUTE="{3;1;3s700afg484;fc333603!-1;-70632;49952;S!0;-159;0!1;2447;-605!"
"2;4489;645!2;4489;301!3;167;0;L!4;167;0;L!}";
NET "ddr2_sdram_cont_i/read_write_io_inst/dq_data<12>"
ROUTE="{3;1;3s700afg484;4ce19306!-1;-70632;50272;S!0;-159;0!1;1696;1720!"
"2;1784;1032!2;1784;1376!3;167;0;L!4;167;0;L!}";
NET "ddr2_sdram_cont_i/read_write_io_inst/dq_data<13>"
ROUTE="{3;1;3s700afg484;7f7f4c8c!-1;-70632;39824;S!0;-159;0!1;2447;-605!"
"2;4489;301!2;4489;645!3;167;0;L!4;167;0;L!}";
NET "ddr2_sdram_cont_i/read_write_io_inst/dq_data<14>"
ROUTE="{3;1;3s700afg484;10d3a509!-1;-70632;36768;S!0;-159;0!1;1696;1720!"
"2;1784;1032!2;1784;1376!3;167;0;L!4;167;0;L!}";
NET "ddr2_sdram_cont_i/read_write_io_inst/dq_data<15>"
ROUTE="{3;1;3s700afg484;473a4c3d!-1;-70632;53648;S!0;-159;0!1;2479;-949!"
"2;4457;661!3;0;8!3;0;-336!4;167;0;L!5;167;0;L!}";

INST "ddr2_sdram_cont_i/dcm_module_inst/DCM_INST1/DCM_SP" LOC = DCM_X0Y1;
INST "dcm_DDR2_VGA_clk_i/dcm_VGA_clk_dcm/DCM_SP" LOC = DCM_X0Y2;
INST "dcm_DDR2_VGA_clk_i/dcm_DDR2_clk_dcm/DCM_SP" LOC = "DCM_X2Y3";

NET "ddr2_dq[0]" IBUF_DELAY_VALUE = 1;
NET "ddr2_dq[1]" IBUF_DELAY_VALUE = 1;
NET "ddr2_dq[2]" IBUF_DELAY_VALUE = 1;
NET "ddr2_dq[3]" IBUF_DELAY_VALUE = 1;
NET "ddr2_dq[4]" IBUF_DELAY_VALUE = 1;
NET "ddr2_dq[5]" IBUF_DELAY_VALUE = 1;
NET "ddr2_dq[6]" IBUF_DELAY_VALUE = 1;
NET "ddr2_dq[7]" IBUF_DELAY_VALUE = 1;
NET "ddr2_dq[8]" IBUF_DELAY_VALUE = 1;
NET "ddr2_dq[9]" IBUF_DELAY_VALUE = 1;
NET "ddr2_dq[10]" IBUF_DELAY_VALUE = 1;
NET "ddr2_dq[11]" IBUF_DELAY_VALUE = 1;
NET "ddr2_dq[12]" IBUF_DELAY_VALUE = 1;
NET "ddr2_dq[13]" IBUF_DELAY_VALUE = 1;
NET "ddr2_dq[14]" IBUF_DELAY_VALUE = 1;
NET "ddr2_dq[15]" IBUF_DELAY_VALUE = 1;
#
NET "ddr2_dqs[0]" IBUF_DELAY_VALUE = 1;
# NET "sd_loop_in" IBUF_DELAY_VALUE = 1;


# sd_loop_in // 02/21 @ 20:52:31
NET "sd_loop_in_IBUF"
ROUTE="{3;1;3s700afg484;df4ab136!-1;-70632;33392;S!0;-159;0!1;1612;-912!"
"1;1596;1056!1;1680;-1720!1;-1464;-3608!1;-1618;10040!1;-225;1797!1;-1632;"
"-10456!2;-3069;-3647!3;450;5392!3;4355;1359!4;4;-12032!4;4255;-597!5;"
"3927;-4329!5;0;-7000!6;-474;9200!6;178;6576!6;184;13320!7;-1185;4651!7;"
"-1867;-629!8;4111;-10997!8;192;-13688!9;0;-6876!9;3952;222!10;3905;-657!"
"11;2808;3082!11;2917;-5975!11;1152;657;L!11;1152;313;L!12;2123;3408;L!13;"
"-511;-4883!13;1168;-1715;L!13;1168;-1371;L!14;13605;-139!14;-447;-2703!"
"15;24;-6784!16;1099;79!17;-17;-7547!17;-652;-752!18;-658;-744!19;3905;"
"-657!20;1099;-97!21;2976;-3486!22;3935;-4073!22;-652;-752!23;3952;98!24;"
"1152;313;L!24;1152;657;L!25;1152;313;L!25;1152;657;L!26;-2848;-1044!27;"
"-2957;1261!31;-2953;1265!34;-8965;428;L!34;-8965;772;L!35;3935;-4073!36;"
"3935;-4073!37;6944;-24!38;3952;98!39;1099;79!40;1099;79!41;1152;313;L!41;"
"1152;657;L!42;6912;0!43;-2968;104!44;12173;-119!45;1099;79!46;1152;657;L!"
"46;1152;313;L!51;1352;-701;L!51;-2104;-1045;L!52;1352;-701;L!53;1176;"
"-1377;L!56;1152;657;L!56;1152;313;L!57;1152;657;L!57;1152;313;L!58;-2304;"
"313;L!58;1152;313;L!58;1152;657;L!58;-2304;657;L!59;1152;657;L!59;1152;"
"313;L!60;6944;-24!61;6944;-24!64;-2112;-1039;L!65;1160;651;L!65;1160;307;"
"L!66;-7565;776;L!66;-7565;432;L!67;15333;-139!84;1152;657;L!84;1152;313;L"
"!85;-2304;313;L!85;-2304;657;L!91;-7237;772;L!91;-7237;428;L!}";


しかし、だいぶ苦労してしまった。昨日一日は、ひな人形まつりを見に行った以外はインプリメントし続けた。MIGのDDR2 SDRAMのIPもUCFがガチガチになっているんだろう?もしくはLUTのプリミティブで直接書いてあって、配線も固定されているとか?もしくはエリア制約をうまくかけてあるのかな?機会があればMIGでやってみたい。
  1. 2010年02月22日 04:57 |
  2. VGAコントローラ
  3. | トラックバック:0
  4. | コメント:0

キャラクタ描画テスト回路の実機デバック3(配線の固定)

前回、配線がとんでもないことになっていたので、以前のDDR2 SDRAMバーストテスト回路の配線をUCFに吐き出して、キャラクタ描画テスト回路の制約ファイルにコピーすることにした。
配線の制約ファイル(UCF)への吐き出し方については、”FPGA Editorで配置と配線を割り当てる3”を参照のこと。
最初にデータバスdq_dataの配線の制約を吐き出させる。FPGA Editor を起動して、Directec Routing Constraintsダイアログを起動して、dq_dataを選択して、制約を吐き出させる。
DDR2_burst_test_4_100220.png

これがその制約。

// 02/20 @ 12:51:22
NET "ddr2_sdram_cont_i/read_write_io_inst/dq_data<0>"
ROUTE="{3;1;3s700afg484;a5bd1784!-1;-70632;26072;S!0;-159;0!1;2447;-605!"
"2;4489;301!2;4489;645!3;167;0;L!4;167;0;L!}";
NET "ddr2_sdram_cont_i/read_write_io_inst/dq_data<1>"
ROUTE="{3;1;3s700afg484;751a0e0!-1;-70632;19640;S!0;-159;0!1;1696;1720!2;"
"1784;1376!2;1784;1032!3;167;0;L!4;167;0;L!}";
NET "ddr2_sdram_cont_i/read_write_io_inst/dq_data<2>"
ROUTE="{3;1;3s700afg484;89ffb99b!-1;-70632;6136;S!0;-159;0!1;1696;1720!2;"
"1784;1376!2;1784;1032!3;167;0;L!4;167;0;L!}";
NET "ddr2_sdram_cont_i/read_write_io_inst/dq_data<3>"
ROUTE="{3;1;3s700afg484;61a7f9cb!-1;-70632;9192;S!0;-159;0!1;2447;-605!2;"
"4489;645!2;4489;301!3;167;0;L!4;167;0;L!}";
NET "ddr2_sdram_cont_i/read_write_io_inst/dq_data<4>"
ROUTE="{3;1;3s700afg484;5a9ec78e!-1;-70632;9512;S!0;-159;0!1;1696;1720!2;"
"1784;1376!2;1784;1032!3;167;0;L!4;167;0;L!}";
NET "ddr2_sdram_cont_i/read_write_io_inst/dq_data<5>"
ROUTE="{3;1;3s700afg484;c3906147!-1;-70632;5816;S!0;-159;0!1;2447;-605!2;"
"4489;645!2;4489;301!3;167;0;L!4;167;0;L!}";
NET "ddr2_sdram_cont_i/read_write_io_inst/dq_data<6>"
ROUTE="{3;1;3s700afg484;3cdde0e5!-1;-70632;19320;S!0;-159;0!1;2447;-605!"
"2;4489;645!2;4489;301!3;167;0;L!4;167;0;L!}";
NET "ddr2_sdram_cont_i/read_write_io_inst/dq_data<7>"
ROUTE="{3;1;3s700afg484;48045bde!-1;-70632;26392;S!0;-159;0!1;1696;1968!"
"2;1784;1032!2;1784;1376!3;167;0;L!4;167;0;L!}";
NET "ddr2_sdram_cont_i/read_write_io_inst/dq_data<8>"
ROUTE="{3;1;3s700afg484;8152c779!-1;-70632;40144;S!0;-159;0!1;1696;1720!"
"2;1784;1376!2;1784;1032!3;167;0;L!4;167;0;L!}";
NET "ddr2_sdram_cont_i/read_write_io_inst/dq_data<9>"
ROUTE="{3;1;3s700afg484;bfa7b4d9!-1;-70632;53328;S!0;-159;0!1;1696;2040!"
"2;1784;1376!2;1784;1032!3;167;0;L!4;167;0;L!}";
NET "ddr2_sdram_cont_i/read_write_io_inst/dq_data<10>"
ROUTE="{3;1;3s700afg484;ace04032!-1;-70632;36448;S!0;-159;0!1;2447;-605!"
"2;4489;645!2;4489;301!3;167;0;L!4;167;0;L!}";
NET "ddr2_sdram_cont_i/read_write_io_inst/dq_data<11>"
ROUTE="{3;1;3s700afg484;fc333603!-1;-70632;49952;S!0;-159;0!1;2447;-605!"
"2;4489;645!2;4489;301!3;167;0;L!4;167;0;L!}";
NET "ddr2_sdram_cont_i/read_write_io_inst/dq_data<12>"
ROUTE="{3;1;3s700afg484;4ce19306!-1;-70632;50272;S!0;-159;0!1;1696;1720!"
"2;1784;1032!2;1784;1376!3;167;0;L!4;167;0;L!}";
NET "ddr2_sdram_cont_i/read_write_io_inst/dq_data<13>"
ROUTE="{3;1;3s700afg484;7f7f4c8c!-1;-70632;39824;S!0;-159;0!1;2447;-605!"
"2;4489;301!2;4489;645!3;167;0;L!4;167;0;L!}";
NET "ddr2_sdram_cont_i/read_write_io_inst/dq_data<14>"
ROUTE="{3;1;3s700afg484;10d3a509!-1;-70632;36768;S!0;-159;0!1;1696;1720!"
"2;1784;1032!2;1784;1376!3;167;0;L!4;167;0;L!}";
NET "ddr2_sdram_cont_i/read_write_io_inst/dq_data<15>"
ROUTE="{3;1;3s700afg484;473a4c3d!-1;-70632;53648;S!0;-159;0!1;2479;-949!"
"2;4457;661!3;0;8!3;0;-336!4;167;0;L!5;167;0;L!}";


インスタンス名はキャラクタ描画テスト回路用に変更した。

次に、dqs_clk_nodeノードも遅延が大きいので、DDR2 SDRAMバーストテスト回路の配線の制約として吐き出させる。
DDR2_burst_test_5_100220.png

インスタンス名はキャラクタ描画テスト回路用に変更した制約を下に示す。同時にdqs_clk用のBUFGを固定した。

// 02/20 @ 12:48:23
NET "ddr2_sdram_cont_i/read_write_io_inst/ddr2_cont_iob_inst/dqs_clk_node<0>"
ROUTE="{3;1;3s700afg484;c20d0b8b!-1;-70632;12888;S!0;-159;0!1;-161;-887!"
"2;-1291;-2737!3;-29;-8091!4;259;-695!5;-1703;-139!6;108;53;L!}";
INST "ddr2_sdram_cont_i/read_write_io_inst/ddr2_cont_iob_inst/BUFG_inst" LOC = BUFGMUX_X0Y5;


これらの変更を加えて、インプリメントしたらエラーが発生。dcm_DDR2_VGA_clk_i/dcm_DDR2_clk_dcm/DCM_SP.CLKFXのクロックルートがクロック専用ラインを通れないようだ。下の制約を加えたらインプリメントが成功した。

PIN "dcm_DDR2_VGA_clk_i/dcm_DDR2_clk_dcm/DCM_SP.CLKFX" CLOCK_DEDICATED_ROUTE = FALSE;


とりあえずこれでインプリメントした。DDR2 SDRAMのデータバスDQで出力タイミング続出。入力タイミングはDDR2 SDRAMバーストテスト回路と同様となってOKそうだ。タイミング解析結果を下に示す。
Bitmap_VGAC_debug_9_100220.png

ピンク枠の部分がBUFGへの入力で問題の部分。FPGA Editorでクロスプローブする。(リンクをクリック)配線が表示されるが、FPGAのチップの上から下まで配線が伸びている。
Bitmap_VGAC_debug_10_100220.png

これだと、通常の配線を長く通り過ぎているので、まずい。

なぜそうなったかは、長くなったので、次回に。。。
  1. 2010年02月20日 21:36 |
  2. VGAコントローラ
  3. | トラックバック:0
  4. | コメント:0

キャラクタ描画テスト回路の実機デバック2(テスト回路の挿入)

さて、ビットマップVGAコントローラはOKのようなので、DDR2 SDRAMコントローラを疑うことにした。具体的には、DDR2 SDRAMコントローラから読んでくる値が毎回正しいのかを検証することにした。Chipscope PROがあれば簡単なのだが、家ではライセンスがないので、検証回路を組んで、LEDに表示することにした。
下がBitmap_VGA_Controller.v に組み込んだ検証回路だ。

    // テスト回路
    always @(posedge clk_vga) begin
        if (reset_vga)
            start_vram_data <= 16'd0;
        else begin
            if (h_count==1 && v_count==0 && pixel_afifo_rd_en)
                start_vram_data <= vram_data_out;
        end
    end
    always @(posedge clk_vga) begin
        if (reset_vga)
            diff_start_data <= 1'b0;
        else begin
            if (h_count==1 && v_count==0 && pixel_afifo_rd_en) begin
                if (start_vram_data==vram_data_out)
                    diff_start_data <= 1'b1;
                else
                    diff_start_data <= 1'b0;
            end
        end
    end
    assign start_vram_data_out = start_vram_data[6:0];    


検証回路の動作は、h_countは水平カウンタ、v_countは垂直カウンタでそれらが1, 0で、非同期FIFOのリード・イネーブル(pixel_afifo_rd_en)が1の時のデータを1フレーム前と今とで比べて、同じだったらdiff_start_dataを1にする。これはLEDに出力する。LEDは8個あるので、後の7個にはラッチしたデータの下位7ビットを出力する。うまくいけば、diff_start_dataは1のまま、start_vram_data_outは固定された値になるはず。
これでインプリメントして、実機にダウンロード。すると、最初の列の幾つかは流れているものの、その他は流れていない画像が表示された。
Bitmap_VGAC_3_100219.jpg

最初の方は、流れているので、LEDはかなりちかちかしている。これはデータが安定しないことを示す。diff_start_dataのLEDにもちかちかしている。データがあっている時も有れば、違っている時もあるみたい。
次にh_count==1の部分をh_count==512として、ちょうど真ん中のデータを見るとdiff_start_dataもずっと1のままで、データのLEDも安定した。
理由はわからないが、安定してきたようだ。これからなぜ、安定してきたかを検証してみよう。

まずは、動いている以前のDDR2 SDRAMのバーストテストのプロジェクトをリファレンスとしてみていく。
DQ0(データバス)の入力の静的タイミングを下の図に示す。
DDR2_burst_test_1_100219.png

データパスのネットの遅延が0.411nsec でとても良い感じになっている。
つぎに、キャラクタ描画テスト回路(ビットマップVGAコントローラ)のDQ0(データバス)の入力の静的タイミングを下の図に示す。
Bitmap_VGAC_debug_7_100219.png

データパスの遅延は、3.618nsec となっていて、DDR2 SDRAMバーストテストの0.411nsec とはかけ離れてしまっている。これが原因か?

次にFPGA Editor でDQ0(データバス)の配線をチェックしてみよう。まずは、DDR2 SDRAMバーストテストのDQ0(データバス)の配線を示す。
DDR2_burst_test_3_100219.png

非常に素直に配線されている。
次に、キャラクタ描画テスト回路のDQ0(データバス)の配線をFPGA Editor で見てみよう。下の図に示す。
Bitmap_VGAC_debug_8_100219.png

なんじゃこりゃ―?というような配線になっている。少なくとも原因の1つはこれだ。。。
制約もほとんど違いがないし、なぜなんだろうか?違いがあるとすればTIG制約だな。今、TIG制約を外してやってみたが、Place & Routeでエラー発生。やはり外せない。。。やるとすれば、配線の固定をする必要があるのか?IPでも、そこまでやっているのを見たことはないが、やる必要があるならば、するしかないかな???

上記の事柄について、アドバイスやなにか情報があったら教えて下さい。
  1. 2010年02月19日 06:08 |
  2. VGAコントローラ
  3. | トラックバック:0
  4. | コメント:0

ビットマップVGAコントローラのデバック2(実機デバック)

キャラクタ描画テスト回路の実機デバックをしていたが、どうも全体をデバックしていると問題の切り分けが難しいので、単体でデバックしてみることにした。
ビットマップVGAコントローラを単体でデバックするには、新たに画像データを作る回路とDCMで50MHzクロックから65MHzと150MHzを生成する回路を付け加える必要がある。画像データはRGBが000から始まって、インクリメントして行くような回路を付け加えた。DCMは使っていたdcm_DDR2VGA_clk.vが使えるので、そのまま使用した。
その、Bitmap_VGA_Controller_top.vを下に示す。

// Bitmap_VGA_Controller_top.v
// Bitmap_VGA_Controllerをテストするトップファイル

module Bitmap_VGA_Controller_top(SYS_CLK, SYS_RST, red_out, green_out, blue_out, hsyncx, vsyncx);
`include "Address_Map_Define.vh"

    input wire SYS_CLK;
    input wire SYS_RST;
    output wire    [3:0] red_out;
    output wire    [3:0] green_out;
    output wire  [3:0] blue_out;
    output wire hsyncx;
    output wire vsyncx;

    wire clk_vga; // 65MHz クロック入力(VGA用)
    wire clk_ddr2; // 150MHz クロック入力(DDR2へのインターフェース用)
    wire reset_vga; // clk_vga用リセット
    wire reset_ddr2; // clk_ddr2リセット
    wire [31:0] vram_start_addr; // バイトアドレス
    wire vram_request; // VRAMへのRead要求。アービタへ
    wire vram_grant; // VRAMへのRead許可。アービタから
    wire [31:0] vram_address; // バイトアドレス
    wire read_write;
    wire vram_req_we; // VRAM へのRead要求のWrite Enable
    wire vram_addr_fifo_full; // VRAMのRead要求用FIFOのFULL
    wire [31:0] vram_data_in;
    reg vram_data_valid;
    wire afifo_overflow; // 非同期FIFO のオーバーフロー・エラー
    wire afifo_underflow; // 非同期FIFO 
    wire clk_ddr2_locked, clk_vga_locked;
    
    reg [15:0] vram_data_in1, vram_data_in2;
    reg vram_req_we_1d;
    
    dcm_DDR2_VGA_clk dcm_DDR2_VGA_clk_i(
        .sysclk(SYS_CLK),
        .reset(SYS_RST),
        .clk_ddr2(clk_ddr2),
        .dcm_ddr2_locked(clk_ddr2_locked),
        .clk_vga(clk_vga),
        .dcm_vga_locked(clk_vga_locked)
    );
    assign reset_vga = SYS_RST | ~clk_vga_locked;
    assign reset_ddr2 = SYS_RST | ~ clk_ddr2_locked;
    
    Bitmap_VGA_Controller Bitmap_VGA_Cntrler_i(
        .clk_vga(clk_vga),
        .clk_ddr2(clk_ddr2),
        .reset_vga(reset_vga),
        .reset_ddr2(reset_ddr2),
        .vram_start_addr(VRAM_START_ADDRESS),
        .vram_request(vram_request),
        .vram_grant(vram_grant),
        .vram_address(vram_address),
        .read_write(read_write),
        .vram_req_we(vram_req_we),
        .vram_addr_fifo_full(vram_addr_fifo_full), 
        .vram_data_in(vram_data_in), 
        .vram_data_valid(vram_data_valid), 
        .red_out(red_out), 
        .green_out(green_out), 
        .blue_out(blue_out), 
        .hsyncx(hsyncx), 
        .vsyncx(vsyncx), 
        .afifo_overflow(afifo_overflow), 
        .afifo_underflow(afifo_underflow)
    );        

    assign vram_addr_fifo_full = 1'b0;
    assign vram_grant = 1'b1;
    always @(posedge clk_ddr2) begin // vram_req_weを1クロック遅延する
        if (reset_ddr2) 
            vram_req_we_1d <= 1'b0;
        else
            vram_req_we_1d <= vram_req_we;
    end
    
    always @(posedge clk_ddr2) begin
        if (reset_ddr2) begin
            vram_data_in1 <= 16'h0000;
            vram_data_in2 <= 16'h0fff;
        end else begin
            if (vram_req_we || vram_req_we_1d) begin // 1リクエストで2つデータを出力する
                if (vram_address==VRAM_START_ADDRESS) begin
                    vram_data_in1 <= 16'h0000;
                    vram_data_in2 <= 16'h0000;
                end else begin
                    vram_data_in1 <= vram_data_in1 + 16'd1;
                    vram_data_in2 <= vram_data_in2 + 16'd1;
                end
            end
        end
    end
    assign vram_data_in = {vram_data_in1, vram_data_in2};
    
    always @(posedge clk_ddr2) begin
        if (reset_ddr2)
            vram_data_valid <= 1'b0;
        else begin
            if (vram_req_we || vram_req_we_1d) // 1リクエストで2つデータを出力する
                vram_data_valid <= 1'b1;
            else
                vram_data_valid <= 1'b0;
        end
    end
endmodule

`default_nettype wire


テストベンチを作成して、シミュレーションを行った。その結果、アービタに出力するアドレスがおかしいバグが1つ見つかったが、他は大丈夫そうだった。シミュレーション結果を下に示す。
Bitmap_VGAC_debug_5_100217.png

大丈夫そうだったので、ISE11.4でインプリメントした。
やはり、以前のTIG制約をUCFに追加しないとタイミングエラーが出てしまった。

PIN "dcm_DDR2_VGA_clk_i/dcm_VGA_clk_dcm.CLKFX" TNM = VGA_CLK_OUTPUT;
PIN "dcm_DDR2_VGA_clk_i/dcm_DDR2_clk_dcm.CLKFX" TNM = DDR2_CLK_OUTPUT;
TIMESPEC TS_VGA2DDR2_CLK_TIG = FROM "VGA_CLK_OUTPUT" TO "DDR2_CLK_OUTPUT" TIG;
TIMESPEC TS_DDR22VGA_CLK_TIG = FROM "DDR2_CLK_OUTPUT" TO "VGA_CLK_OUTPUT" TIG;


無事にインプリメントできた。
Bitmap_VGAC_debug_6_100217.png

実機にダウンロードして、ディスプレイに表示させた。
Bitmap_VGAC_2_100217.jpg

画像は安定している。問題ない気がする。1つバグは修正したので、もう一度、キャラクタ描画テスト回路に戻ってやってみよう。それでもおかしい場合はDDR2 SDRAMコントローラがうまくDDR2 SDRAMのデータを読めていないのかもしれない。
もう1つ心配なのが、Spartan3A Starter Kitの抵抗分割A/Dコンバータで、果たしてドットクロック65MHzのXGAがうまく出力出来て、1ドットが見えるのか?ということが心配になってきた。その場合はSGAかVGAに落とすしかないかな?

(2010/02/18:修正)
Bitmap_VGA_Controller_top.vとシミュレーション波形を変更しました。DDR2 SDRAMコントローラは1つReadコマンドを投げると、32ビットデータ2つが帰ってくるので、整合が取れなくなっていました。
  1. 2010年02月17日 05:28 |
  2. VGAコントローラ
  3. | トラックバック:0
  4. | コメント:0

キャラクタ描画テスト回路の実機デバック1

前回、キャラクタ描画テスト回路のインプリメントをして、実機にダウンロードしてテストしてみたが、おかしな画面になってしまった。もう一度、シミュレーションをしてみることにした。
シミュレーションしてみたのが、下の画面。
Bitmap_VGAC_debug_3_100214.png

あれ?clk_vgaのクロックがでていない。以前のシミュレーション波形を下に示す。
Bitmap_VGAC_debug_2_100211.png

やはり、clk_vgaがでていない。Verilogソースは、”キャラクタ描画テスト回路のインプリメント1(TIG制約)”で”最初にVGA信号用のDCMとDDR2 SDRAM用のDCMを同じクロック入力パッドから入力していたので、片方のクロック配線が一般配線に回ってしまうというエラーが出てしまった。これは、DDR2 SDRAM用のDCM出力 (BUFG出力) からVGA信号用のDCMのクロック入力につなぐくことにして問題解決。”というところしか、いじってないので、ここが悪いのだろう?
DDR2 SDRAM用のDCMのLOCKED信号を反転して、VGA信号用のDCMのリセットに入れることにした。この対策をした結果、clk_vgaも出力されて、元のシミュレーション波形と一致した。
とりあえず、インプリメントして、実機で見てみた。少し画面は変化したが、あまり変わらない。
次に、キャラクタ生成コントローラへのGRNATを止めてみた。つまり、画面には何も書かないようにした。そうしたところ色はなくなったが、まだ動いているように感じる画像だった。
次に、シミュレーションで確認してみようと思ったが、時間とディスク容量がかかりすぎるので、このままでは無理だ。そこで、VGA信号のタイミングをいじることにした。垂直関係の信号を下のようにいじってみた。(パラメータ化しておくと、こういう時に一発でタイミングを変更出来て便利だ)

parameter V_ACTIVE_VIDEO = 2;
parameter V_FRONT_PORCH = 0;
parameter V_SYNC_PULSE = 1;
parameter V_BACK_PORCH = 0;
// parameter V_ACTIVE_VIDEO = 768;
// parameter V_FRONT_PORCH = 3;
// parameter V_SYNC_PULSE = 6;
// parameter V_BACK_PORCH = 29;


これで垂直同期までシミュレーションで現実的な時間で見ることが出来る。
シミュレーションを下の図に示す。
Bitmap_VGAC_debug_4_100215.png

hsyncxとvsyncxが水平同期と垂直同期だ。問題なさそう。
次に、pixel_afifo_rd_enの長さを測る。15,753,848psecだった。これをクロックの65MHzの逆数で割ると、約1024となり(ぴったりには割れないが、誤差かな?)、非同期FIFOから読み出しているデータ数にも問題はなさそう。

今のところ、どこが問題なのか良くわからなくなってきたので、ビットマップVGAコントローラ単体で、適当なデータを与えて表示させてみようと思う。やはり、単体テストを行わないのは、まずかったか?やはり、単体テストからですね。当たり前か。。。
  1. 2010年02月15日 05:35 |
  2. VGAコントローラ
  3. | トラックバック:0
  4. | コメント:0

キャラクタ描画テスト回路のインプリメント2(配置制約を付加)

”キャラクタ描画テスト回路のインプリメント1(TIG制約)”で150MHzと65MHzの2つの周波数のクロック間のタイミング解析を解析しないように設定した。今度は、DDR2 SDRAMコントローラのRead用FIFO素子の配置を固定する。配置は、以前、DDR2 SDRAMコントローラを作ったときに、作ってある(Spartan3A Starter KitのDDR2 SDRAMコントローラの途中経過5(ロジックセルの固定の微調整)を参照)。その制約をインスタンス名を少し変えて、UCFファイルに追加した。下にその制約の一部を示す。

INST "ddr2_sdram_cont_i/read_write_io_inst/rddata_afifo_inst/DQS2intclk_FIFO_FALL/DPRAM_GEN[15].RAM16X1D_inst" LOC = SLICE_X2Y79;
INST "ddr2_sdram_cont_i/read_write_io_inst/rddata_afifo_inst/DQS2intclk_FIFO_FALL/DPRAM_GEN[14].RAM16X1D_inst" LOC = SLICE_X0Y71;


この制約を追加して、インプリメントした。その結果を下に示す。
Bitmap_VGAC_implement_10_100213.png

タイミング制約が1つ満たされていない。タイミング解析結果を下図に示す。
Bitmap_VGAC_implement_11_100213.png

150MHzパスが123psecほどタイミングエラーが出ている。色々、コストテーブルを変更してインプリメントしてみたが、この結果が最良のようだ。とりあえず、これでも動作に支障はないだろうということで、実際にSpartan3A Starter Kitにコンフィギュレーションして実機で確認してみた。
そうすると下のように、なんだか分からない画面が出た。
Bitmap_VGAC_1_100214.jpg

訳がわからない。液晶ディスプレイのメニューを表示させた。
Bitmap_VGAC_2_100214.jpg

同期は取れているようなので、書くキャラクタのアドレスを間違えているのかもしれない?
もう一度、シミュレーションで確認してみようと思う。
  1. 2010年02月14日 05:09 |
  2. VGAコントローラ
  3. | トラックバック:0
  4. | コメント:0
»