今、VHDLコードを書いていて奇妙な現象に遭遇した。ModelSimのシミュレーションでは、問題なく動作しているように見受けられるが、実機が動作しなかった。なぜだろうとかなり調べていたら、XSTとModelSimの解釈が違っているところが見受けられるようだ。
まずは、ソースコードの一部を示す。
library IEEE;
use IEEE.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
...
constant THRESHOLD_LEVEL : integer := 6; -- 符号化する数値の下限
attribute keep : string;
attribute keep of h_data_th : signal is "TRUE";
attribute keep of h_data_9bits : signal is "TRUE";
begin
...
h_data_9bits <= ('0'&bram_rd_data) - ('0'&bram_data_1d);
v_data_9bits <= ('0'&ydata_1d) - ('0'&bram_data_1d);
d_data_9bits <= ('0'&cam_ydata_2d) - ('0'&bram_data_1d);
...
-- スレッショルド処理を行ったh, v, d データ
th_level_9bit <= CONV_STD_LOGIC_VECTOR(THRESHOLD_LEVEL, 9);
-- th_level_9bit_mi <= not(th_level_9bit-1);
th_level_9bit_mi <= not(th_level_9bit)+1;
h_data_th<=(others => '0') when signed(h_data_9bits)>signed(th_level_9bit_mi) and signed(h_data_9bits)<signed(th_level_9bit) else h_data_9bits;
v_data_th<=(others => '0') when signed(v_data_9bits)>signed(th_level_9bit_mi) and signed(v_data_9bits)<signed(th_level_9bit) else v_data_9bits;
d_data_th<=(others => '0') when signed(d_data_9bits)>signed(th_level_9bit_mi) and signed(d_data_9bits)<signed(th_level_9bit) else d_data_9bits;
結局は、小さい値を0に丸める回路を生成しようとしている。その場合のth_level_9bit_mi が問題となった。上のVHDLコードでModelSimではエラーやウォーニングなしにコンパイルが通って、シミュレーションでも正しい値が出ていた。

(注:h_data_9bits とh_data_thに 注目すると、h_data_9bits の002 がh_data_th では000 に丸められている)
ISE11.4での結果がおかしいので、ChipScopeを入れて監視しようとすると、h_data_th をKeepしていたはずが、信号がなくなってh_data_th_mi だけになってしまった。(h_data_th_mi <= not (h_data_th-1);、ちなみにどちらも2の補数表示の同じ絶対値のマイナスの数を計算する式)
ChipScope Analyzer の結果を見ると、全く丸めていない。

おかしいので、XSTのレポートを見ると、データ幅がちがうというウォーニングが出ていた。
WARNING Xst:1610 - "C:/HDL/FndISEWork/DWM2008_07/CamDispCntrl_SRAM_MPWavelet_inv/Sources/Camera_Controller.vhd" line 876: Width mismatch. has a width of 9 bits but assigned expression is 10-bit wide.
9ビットの予定なのに10ビットだそうだ。おかしい?
上のVHDLコードの代わりにコメントアウトされている
th_level_9bit_mi <= not(th_level_9bit-1);
に変更したら、XSTのウォーニングもなくなって正常動作するようになった。ChipScope Analyzer の表示画面を示す。今度は、正常にh_data_th がプローブできた。

何がおかしいのか分からないが、XSTでは、少なくとも9ビットのデータをnot して、+1 するとビット幅が増えてしまうことがあるようだ。注意する必要がありそうだ。
- 2010年01月04日 15:13 |
- FPGAのトラブル
-
| トラックバック:0
-
| コメント:2
今日もウイルス性胃腸炎でお休みです。でも、今朝はおかゆを少し食べられました。
さて、体力がないので、ちょっとずづDDR2 SDRAMコントローラのバーストテストのインプリメントをしているのだが、MAPでERROR:Pack:1664とERROR:Pack:1665が出てMAPプロセスを完了できないという問題が発生してしまった。

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かの違いだった。

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

いろいろ忘れているものや動作クロックを落とさないとだめだったが、一応、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 (
- 2009年06月09日 09:18 |
- FPGAのトラブル
-
| トラックバック:0
-
| コメント:0
以前、32本の100MHzのLVCMOS33のデータ転送をチップ間で行ったことがあるが、同時スイッチング出力(SSO, Simultaneous Switching Output)だと思われる原因でエラーが出てしまったことがある。BGAパッケージの基板の裏側にパスコンを付けずにFPGAが付いている面のFPGAの周りにパスコンを置いてしまった。そのため電源のインピーダンスが上がって、SSOが少なくなってしまい、エラーになってしまったようだ。。
その時の最善の可決策としては、基板の作り直しなのだが、次善の策としては、IO規格の電流の制限値を12mAから4mAにすることでエラーを回避することができた。実際に波形を観測したが、12mAに時に比べて8mA、そして4mAとなるに従って、波形がなまっていくのが見えた。この基板では8mAの時の波形が一番良いように見えたが、確かエラーが出るので4mAに固定したと思う。波形のデータを取っていなかったのが残念。。。(ちなみに100MHzの矩形破を見ようとするとアクティブプローブを使用しないと矩形波に見えなかった。パッシブプローブだと100MHzクロックは正弦波に見えてしまう。)
実際の物は、もう名前が割れていると思うので、
リンクを示そうと思う。この文の最後の6. まとめに書いてある。
次に作った基板では、この点は特にパターン設計をお願いした会社さんに考慮していただいた。”図 8. バイパスコンデンサの実装状況”を参照。
パスコンつけすぎだと思うが、Xilinxの指針に従っていると、このくらいつけることになってしまった。
この基板ではSSOは今のところ大丈夫のようだ。伝送線路シミュレーションをお願いして、最適と思われる電流値を採用している。
- 2009年05月27日 05:01 |
- FPGAのトラブル
-
| トラックバック:0
-
| コメント:0
”DWM誌の2007年8月号と2007年10月号の基板でカメラの画像を表示”でカメラの画像をディスプレイに表示できたが、どうやらDCMの位置でおかしくなるという現象が出た。今日は、どこのDCMを使うとどうだめなのか検証してみた。
まずは、ダメなところから、CLKパッドからIBUFG(つまりGCLK入力を使用している)、そしてBUFG(BUFGMUX)を通してDCMに入力するパターン。途中のBUFGはBUFGMUX_X2Y1、DCM_X1Y1、DCMのCLK0のフィードバック用BUFGはBUFGMUX_X2Y10。概略図は下の図。FPGAの中身で、FPGAチップの左右の真ん中あたり、上下の端にあるDCMとBUFGMUXだ。

左下のXが示すとおりに、この配置を使うとディスプレイはNO SIGNALとなって、何も表示しない。DCMからの出力クロックが消えているっぽい。
次に、CLKパッドからのBUFGを取り去って、近くのBUFGを使うことにしてみる。CLKパッドからIBUFGを通してDCMへ入力、DCM(DCM_X1Y0)のCLK0のフィードバック用BUFGはBUFGMUX_X1Y0。子の概略図は下図参照。

三角が示す通り、これはコンフィグが不安定、数分はCMOSカメラの画像がディスプレイに表示されるが、数分でNO SIGNAL。
今度は、上と同じようだが、DCMの位置をDCM_X0Y0に、BUFGの位置はBUFGMUX_X2Y1にした。概略図は下図を参照。

これはOK。30分、ディスプレイに表示させてもOK。
ちなみに各図の青色の線がメインの48MHzクロックだ。
原因は考えにくいけれど、やはり水晶発振規のジッタが問題になるだろうか?今のところ皆目分からない?今日見てみたが、確かに48MHzの水晶発振器の直近にはパスコンはついていないように見える。アキシャル部品になってしまうが、積層セラミックコンデンサを上に抱かせてみようかと思う。
- 2009年04月24日 21:48 |
- FPGAのトラブル
-
| トラックバック:0
-
| コメント:3
DWM誌の
2007年8月号と
2007年10月号に記事が載っていて、
イーエスピー企画が出している。
画像ベースボード、デジタルCMOSカメラ、208ピンSpartan3E XC3S500+2M高速SRAM基板を使って、カメラで撮影した画像をアナログRGBディスプレイに表示することができた。
2007年10月号と基板を買った時のCDにプロジェクトが入っているが、それはSH2のプロセッサボードをつけた時のISEプロジェクトとSH2のソフトウェアだった。SH2のボードは持っていはいるが、SH2を今から勉強するのも面倒だし、部品を買う必要もあるので、FPGA内にステートマシンを実装してCMOSカメラの設定と画面キャプチャの設定を行うことにした。(PicBlazeやMico32などの組み込みプロセッサを組み込むことも考えたが、それほどでもないという結論になった)
ISEの添付されたプロジェクトをとりあえずインプリメントしてみると、動作周波数が仕様を満たさない。。。48MHzの水晶のクロックも、使用するが、その半分の24MHzのクロックも使用する。24MHzのクロックを作る回路はDフリップフロップの反転Q出力をD入力にフィードバックするような記述だった。DCMも使用してなかったので、こちらでDCMを追加してCLKDV出力で24MHzのクロックを出力するようにした。(CLKDV_DIVIDE => 2.0)
DCMはCoreGeneratorのIPを使用した。これで、インプリメントして、ダウンロードしてみたら、アナログRGBディスプレイに表示されない。おまけにNO SIGNALだった。HSYNCやVSYNCも出ていないみたい。ModelSimでのシミュレーションだとそれは出ているはずなんだけど。。。
もしかしてと思い、Chipscopeを組み込むと波形が表示できない。これはDCMのクロック出力がおかしい。。。
試しに自分でDCMをプリミティブでVHDLファイルを記述すると、映った!!!やった~。しかし、動作が不安定。コンフィグを数回やらないと失敗するときがある。カメラの画像をアナログRGBディスプレイに表示していても、数分後には映らなくなってしまう。その場合はChipscopeも表示されなくなってしまうので、やはりクロックが止まっているっぽい。。。
いろいろDCMの設定を変えてみる。
FACTORY_JFをいじってみたら、現象変わらず。。。DCMに入力する前にIBUFGの後にBUFGを通してみると完全に映らない。CoreGenのIPを使った時のような症状になった。
これは、もしかして、DCMの位置が問題なのでは?と思い、FPGA Editorで見るとDCM_X1Y0を使用してた(不安定な状態のとき)。これはCLK入力から一番近いDCMなので、妥当な線だと思ったが、試しにFloorplannerで隣のDCM_X0Y0にアサインしてみた。下がアサイン後のFPGA Editorの図。

<注>訂正。上図のDCM_D0Y1はDCM_X0Y0の間違いです
こうしたら、うまく行きました。30分たっても画像は消えない。コンフィグも安定している。原因は何だろうかわからない。DCM_X1Y0がおかしいのか?それともジッタの多い配線ルート、少ない配線ルートがあるのか?
そういえばDCMのフィードバック入力用のBUFGの位置もどうだろか?このDCMはFPGAチップの下側の中央に位置している。確かめてみると、BUFGMUX_X2Y1を使っていて、上のFPGA Editorの図の一番右下のBUFGを使っているから問題なさそうだし。。。(これはうまくいった時のBUFGだったので、いい位置にあるのは当たり前?でした)
なにか、原因に心当たりがある方はぜひ教えてください。


明日、おかしい状態のときに、どのDCMやBUFGを使っているか調べてみようと思う。
- 2009年04月23日 20:00 |
- FPGAのトラブル
-
| トラックバック:0
-
| コメント:2