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

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

FPGAの部屋

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

DQSをクロックとしてDQをリードするDDR2 SDRAMコントローラのISERDES使用法

DDR2 SDRAMコントローラは一応の完成を見たが、ここでISERDESのタイミングを検証してみようと思う。
まずは、”DQSをクロックとしてDQをリードするDDR2 SDRAMコントローラの遅延の検討”で、READデータのFPGA⇔DDR2 SDRAM間(FPGA内部クロックでサンプルするまで)の遅延は6.986 ns と計算できた。これは最悪値なので標準値を考えて、シミュレーションでの遅延を片方向 3 ns 、両方向 6 ns でシミュレーションすることにした。
それが下の図だ。
ISERDES_DDR2_1_080731.png
マーカー1(M1) の緑色のカーソルがFPGAがアドレス(ddr2_address)、バンク・アドレス(ddr2_ba) 、RAS# (ddr2_rasb) ='1' 、CAS# (ddr2_casb) ='0' 、WE# (ddr2_web) ='1' をドライブしてREADコマンドを発行したところ。
FPGAから出力したddr2_clkは3 ns 遅延してDDR2 SDRAMに到着している。それがsdram_clkだ。M2の緑色のカーソルが、FPGAからのREADコマンドがクロックと同様に 3 ns 遅延してDDR2 SDRAMに到着したところだ。その信号がその次からのsdram_address から sdram_webまでの信号だ。
M3の緑色のカーソルが、M2でDDR2 SDRAMに到着したREADコマンドをDDR2 SDRAMが受けた結果、CAS Latency=3 でREADデータが出力されている。
M4の緑のカーソルで、M3でDDR2 SDRAMから出力されたREADデータが 3 ns 遅延してFPGAの内部に届いた。
ddr2_dqs_fpga を1/4クロック分IDELAYで遅延させたのがddr2_dqsin_bufioだ。ddr2_dqsin_bufioをクロックとして、ddr2_dq_in のデータをサンプルする。

ここから先は、Virtex4 User Guide (UG070 (v2.5) June 17, 2008) の373ページの図、Figure 8-6: Internal Connections of ISERDES When in Memory Mode を引用して説明しようと思う。
下が引用したFigure 8-6 だ。
ISERDES_DDR2_3_080731.png
上の図で、Dにはddr2_dq_in、CLKにはddr2_dqsin_bufio、OCLKとCLKDIVにはclk270、Q1はdq_fall_1d、Q2はdq_rise_1d、Q3とQ4はnon connection だ。
ISERDESのMEMORYモードを使用して、OCLKとCLKDIVに同じクロック(必ずしもそうではないが。。。)を入れるとQ1とQ2を使用すれば、同じ位相でREADデータを受けられる。それは受信クロックの立下りで受けたREADデータもCLKDIVの立ち上がりに同期して出てくるようになっているからだ。

話をその上のシミュレーション波形に戻すと、をクロックとして、ddr2_dq_in のデータをddr2_dqsin_bufioの立ち上がりでサンプルされたデータがFig. 8.6 のFF0 にラッチされる。FF0 の出力は次のclk270 の立ち上がりでサンプルされFF2 にラッチされる(黒いカーソルの位置)。FF2の出力は、その次のclk270 の立ち上がりでサンプルされてFF7 にラッチされる(赤のカーソルの位置)。その出力が dq_fall_1d と dq_rise_1d だ。
dq_fall_1d と dq_rise_1d をFIFOに入力して、FIFOの出力からDDR2 SDRAMコントローラの外へ出力する。それが、output_data。そのイネーブル信号がrddata_valid だ。
  1. 2008年07月31日 05:49 |
  2. DDR SDRAMコントローラ
  3. | トラックバック:0
  4. | コメント:0

やったー! DDR2 SDRAMコントローラが動いたようだ?

ついにDDR2-400のDDR2 SDRAMコントローラが動いたようだ。

まだSUZAKU-Vのスイッチと7セグLEDでしか確かめていないが、7セグLEDに値をセットして、WRITEボタンでWRITEして、READボタンでREADするとWRITEした値が読める。おなじLEDに読んでいるので、同じ値になるのが気に入らずに、違う値を7セグLEDに表示して、WRITEボタンを押さずにREADボタンを押したら、前にWRITEした値が表示された。
今まで作ってきたDDR2 SDRAMコントローラでは、まったく違った値が表示されていたので、うまく読めていることと思う。
今後はDDR SDRAMコントローラのテストのようにランダムなバースト長でテストするつもりだ。

やはりDDR2-400ともなると内部クロックでサンプルするのは難しいのかもしれない。原因はよくはわからないが、やはりジッタとかが影響してくるのだろうか?
DQSで受ければ、内部クロックで乗せかえるときのマージンも取れるし、やはりDQSで受けるのが正解なのだろう。思い起こせば、長い道のりで、ほうぼう道草をしていたが、いろいろな方法を試せて、OSERDESやISERDESについても勉強できたし、よかったと思う。
DQSをクロックとしてDQをうける方法は、リージョナル・クロックバッファや配線やSERDESを持ったVirtex4だったので、比較的楽に実現できた。しかし、これがSpartan3シリーズやVirtex2pro以前だと難しくなってしまうと思う。

(2008/07/31 追記) SUZAKU-V持っている方が少ないかもしれませんが、もし、ご要望があれば全ソースを公開したいと思います。
  1. 2008年07月30日 05:48 |
  2. DDR SDRAMコントローラ
  3. | トラックバック:0
  4. | コメント:6

DQSをクロックとしてDQをリードするDDR2 SDRAMコントローラのOSERDES使用法

(2008/07/29 間違いを修正しました)

DQSをクロックとしてDQをリードするDDR2 SDRAMコントローラのOSEDES使用法を書いておこうと思う。
大体できてきたOSERDESを使用したDQとDQS, DQSNを見てみる。
OSERDES_DDR2_1_080726.png
上の図では3回WRITEコマンドが発行されている。1クロック置きにddr2_rasb='1', ddr2_casb='0', ddr2_web='0' の時がWRITEコマンドだ。
黒いカーソルで発行されたWRITEコマンドの最初のWRITEするデータが赤のコマンドのところになる。本当はddr2_dqs は赤のカーソルの前1クロック分0になって、赤のカーソルのところで1になるはずだが、半クロック分の0が2つあるように見える。これは0と0の間に 0 ps のZが挟まっている。デルタ遅延でZになっているのだろか?
とりあえず実用的には問題ないものと思われる。

ところで、以前のタイミングチャートとの違いに気がついている方もいらっしゃると思うのだが、今回のタイミングチャートは以前のよりも1/4クロック前にずれている。
マイクロン社DDR2 SDRAM (HT47H) データシートの88ページにある。Figure 56 : WRITE Burst を下に引用する。
OSERDES_DDR2_2_080726.png
上図でWLはWrite Latency でWriteコマンドを発行してから DDR2 SDRAMにデータが書き込まれるまでの時間を表している。 WL = AL (Posted CAS Additive Latency) + CL (CAS Latency) - 1 = 0 + 3 -1 = 2 クロック。
tDQSS は DQS rising edge to CK rising edge で MIN = –0.25 × tCK, MAX = +0.25 × tCK だ。つまりWrite時のDQSの立ち上がりエッジがWLの–0.25 × tCK から +0.25 × tCK の間にあれば良いことになる。
上図ではそのタイミングのうちのNOM、MIN、MAX (MIN~MAX) のタイミングを紹介している。今までのDDRやDDR2 SDRAMコントローラではデータをCLK位相0度で出したかったので、MAXのタイミングを使用していた。今回はtDQSSをNOMにすることにした。理由は特にないのだが、NOMの方がtDQSSのタイミングの真ん中なのでちょうど良いのかな?と思ったのだ。それでこの機会に修正した。

DQの部分のOSERDES, ISERDESのところのVerilogコードを下に示す。

    // ddr2_dqのIOBをプリミティブでインスタンシエーション
    generate
    genvar i;
        for (i=DDR2_DATA_WIDTH-1; i>=0; i=i-1) begin: WRDATA_INOUT
            OSERDES # (
                .DATA_RATE_OQ("DDR"),
                .DATA_RATE_TQ("DDR"),
                .DATA_WIDTH(4),
                .INIT_OQ(1'b0),
                .INIT_TQ(1'b1),
                .SERDES_MODE("MASTER"),
                .SRVAL_OQ(1'b0),
                .SRVAL_TQ(1'b1),
                .TRISTATE_WIDTH(4)
            ) WRDATA_DDR2_OUT (
                .OQ(ddr2_out[i]),
                .SHIFTOUT1(),
                .SHIFTOUT2(),
                .TQ(out_tri[i]),
                .CLK(clk270),
                .CLKDIV(~clk100MHz),
                .D1(wrdata_3d[i]),
                .D2(wrdata_3d[i+16]),
                .D3(wrdata_2d[i]),
                .D4(wrdata_2d[i+16]),
                .D5(),
                .D6(),
                .OCE(1'b1),
                .REV(1'b0),
                .SHIFTIN1(1'b0),
                .SHIFTIN2(1'b0),
                .SR(reset),
                .T1(dq_oserdes_t_2d[i*4]),
                .T2(dq_oserdes_t_2d[i*4+1]),
                .T3(dq_oserdes_t_2d[i*4+2]),
                .T4(dq_oserdes_t_2d[i*4+3]),
                .TCE(1'b1)
            );
                        
             ISERDES #(
                .BITSLIP_ENABLE("FALSE"),
                .DATA_RATE("DDR"),
                .DATA_WIDTH(4),
                .INTERFACE_TYPE("MEMORY"),
                .IOBDELAY("IFD"),
                .IOBDELAY_TYPE("FIXED"),
                .IOBDELAY_VALUE(0),
                .NUM_CE(1),
                .SERDES_MODE("MASTER")
            ) DDR2_DQ_INPUT (
                 .O(),
                 .Q1(dq_fall_1d[i]), 
                 .Q2(dq_rise_1d[i]), 
                 .Q3(), 
                 .Q4(), 
                 .Q5(), 
                 .Q6(), 
                 .SHIFTOUT1(), 
                 .SHIFTOUT2(),
                 .BITSLIP(1'b0),
                 .CE1(1'b1), 
                 .CE2(1'b1),
                 .CLK(ddr2_dqsin_bufio[i/8]),
                 .CLKDIV(clk270),
                 .D(ddr2_dq_in[i]),
                 .DLYCE(1'b0),
                 .DLYINC(1'b0),
                 .DLYRST(1'b0),
                 .OCLK(clk270), 
                 .REV(1'b0),  
                 .SHIFTIN1(1'b0), 
                 .SHIFTIN2(1'b0),
                 .SR(reset)
              );
             
            IOBUF DDD2_DQ_BUF (
                .O(ddr2_dq_in[i]),
                .IO(ddr2_dq[i]),
                .I(ddr2_out[i]),
                .T(out_tri[i])
            );
        end
    endgenerate


OSERDESのCLKにはclk270 (クロックの位相が270度の200MHzクロック)、CLKDIVには~clk100MHz (100MHzクロックの反転)が入っている。D1からD4には4つデータを用意する必要があるため、D1には3クロック分遅れたデータの下16ビット(1個のOSERDESは1ビットなので、generateで16ビット分生成されている)、D2には3クロック分遅れたデータの上16ビット、D3には2クロック分遅れたデータの下16ビット、D4には2クロック分遅れたデータの上16ビットが入っている。
これのタイミングチャートを下に示す。
OSERDES_DDR2_3_080726.png
黒カーソル位置で100MHzクロック (clk100MHz) の立下りでwrdata_3dとwrdata_2d がサンプルされる。そのサンプルされたデータは、赤カーソル位置のclk270の立ち上がりでD1のデータから順に出力された (out_tri 信号)。

後はMASKの実装が残っているので、それをテストしたら、ISERDESのタイミングの調整に移る。

(2008/07/29追加)
Xilinx社のアプリケーションノートXAPP721J、”ISERDES とOSERDESを使用した高性能DDR2 SDRAMインターフェイスのデー タキャプチャ”の3ページの図3を引用する。
OSERDES_DDR2_4_080726.png
私の回路では図3のCLKDIVに~clk100MHzが、CLKにclk270 が入っている。そうするとCLKDIVでサンプルしたデータは次のclk270 でDQに出力されるはずなので、あっていると思う。
  1. 2008年07月27日 06:52 |
  2. DDR SDRAMコントローラ
  3. | トラックバック:0
  4. | コメント:0

インターフェースの2008年9月号

インターフェース2008年9月号を買いました。いわずと知れたColdFire基板が付属している雑誌です。
ブログを検索してみると、シンセ・アンプラグドさんの”ColdFire MCF52233 基板 (2) ベースボード製作中”がヒット。
そのブログを読んだところ、電源表示用のLED1が実装されていないとのことでした。
あわてて、私が購入したインターフェースの基板を取り出して、LED1を見たところ同様に実装されていません。実装ミス?
確かに電流制限抵抗R21は実装されているので本当に付け忘れでしょうか。。。
CQ出版またミスったのか? それとも原価が高騰したため、わざと抜いたのでしょうか?
  1. 2008年07月26日 05:19 |
  2. マイコン関連
  3. | トラックバック:0
  4. | コメント:6

2008年7月24日の近況

昨日、ハリーポッターの最終巻が届きました。早速、夜に読んだのですが、面白そう。早速、????(文字数は関係ありません)が死んでしまった。でも、遺体がないのが怪しいかも。。。楽しみながら読むことにします。

早朝はDDR2やっています。なかなかOSERDESが言うことを聞きませんが、何とかなりそうです。OSERDESがうまくいったら、今度はISERDES。しかしTEDの資料でも内部構造はありませんでした。完全ブラックボックスか? その割にタイミングチャートも少ないですね。

夏休み自由研究お助け企画がもうすぐに迫ってきました。今年は2つのテーマを担当します。4年越しの音声、音のテーマに今年は、FMラジオのテーマを新しく担当します。
FMラジオの受信状況を数字で出すのは難しいので、観念的な評価になりますが、結構楽しめるのでは?と思っています。
FMラジオはエレキットFMはこらじを使っています。箱は段ボールですが、結構、家でも使えるラジオだと思います。
放送局の方角を探ったり、できればフォックスハンティングもしてもらおうと思っています。
  1. 2008年07月24日 13:18 |
  2. 日記
  3. | トラックバック:0
  4. | コメント:0

話題のXilinx Spartan™-3A Evaluation Kitのその後2

”話題のXilinx Spartan™-3A Evaluation Kitのその後”で7月10日に入荷する予定だったXilinx Spartan™-3A Evaluation Kit だが、どうにも遅いので、アヴネット社にメールしてみた。
その結果、生産が遅れて結局、7月下旬~8月上旬になったそうだ。。。
結局、元の予定と同じではないか?
なんか、ぬか喜びさせられた気が。。。 まあ、気長に待つとしよう。。。
  1. 2008年07月22日 12:23 |
  2. その他のFPGAの話題
  3. | トラックバック:0
  4. | コメント:2

お祭り終了

土曜、日曜と行われたお祭りも終了して、今日は後片付けでした。疲れました。お昼からは居眠りをしてしまいました。
夜の神輿は、各地区の中学生の神輿が集まってきます。大人の神輿はこの地区の神輿一基だけです。8時過ぎころ、臨時のやぐらの上から餅やお菓子を撒きます。それを競い合って拾うと言う行事があります。私も去年餅を見事キャッチしました。
3年位前から始まったのですが、やはりこういうのは盛り上がります。
gion_1_080721.jpg
右上の提灯の間のやぐらに登っている人が餅やお菓子を撒きます。
話は変わりますが、私は、昔子供のころに、お葬式でお金を家の縁側から撒いたことがあるのですが、そのときは、たくさんの人が先を争ってお金を拾っていました。そのときには、お金を撒くのに快感を覚えた記憶があります。
そんな感じで、撒かれたものを人が拾うのに熱狂しているのが、面白かったです。でも、取り合いはしていません。あくまで、自分のところに来た物を取るだけです。その辺は常識ある日本人の性格が出ているのかもしれませんが、周囲が知り合いばかりと言うこともあるかと思います。

さて、この辺の中学生のお神輿は電気装飾が派手です。ディズニーリゾートのエレクトリカルパレード並かもしれません。うちの地区のお神輿は地味なほうです。下に写真を示しますが。。。
gion_2_080721.jpg
パトライト、LED、スポット照明、いろいろついています。大きな車用のパッテリーが神輿に乗っていますよ。
  1. 2008年07月21日 21:22 |
  2. 日記
  3. | トラックバック:0
  4. | コメント:0

お祭り

例年、このころはお祭りです。
大人神輿、中学生神輿、小学生神輿(大、小)が出て、賑わいます。
わたしも、小学生と中学生がいるので、子供神輿の付き添い出ます。
昨日の日中に神輿が出たときには、暑くて大変でした。給水、アイスクリームなどでしのぎましたが、最初はくらくらきました。だんだん慣れてきましたが。。。
夜のお神輿は、涼しくて楽でした。でも寝るときに薄着過ぎて、今朝は風邪気味です。今日も夜のお神輿があります。風邪を本格的に引かないようにしないと。。。
gion_080720.jpg
  1. 2008年07月20日 08:39 |
  2. 日記
  3. | トラックバック:0
  4. | コメント:0

DQSをクロックとしてDQをリードするDDR2 SDRAMコントローラの遅延の検討

Trac Lightning と TortoiseSVN をインストールしたので、これで安心してDDR2 SDRAMコントローラの検討に戻ろうと思う。

まずはDDR2 SDRAM(以下DDR2と略す)に出力するクロックの検討から。DDR2 へのクロック出力ddr2_clk<0> の遅延をTiming Analyzer で見てみる。
ddr2_controller_delay_1_080718.png
上の画面によると、ddr2_clk<0>パッドの出力信号はSYS_CLKから 3.328ns 遅延している。
次にDDR2 がデータを受けられるかを確認するためにDQの遅延を見てみる。
ddr2_controller_delay_2_080718.png
上の画面によると、ddr2_dq<0>パッドの出力信号はSYS_CLKから 3.111ns 遅延している。
その後、7つの ddr2_dq の遅延を見てみたが、最大遅延と最小遅延の差が31ps だったので、ほかも大丈夫だろう。(もう計算するのが飽きた)

次にDQSをクロックとしたDQの入力の遅延を見てみよう。これはddr2_dqs<0>がddr2_dq<0>~ddr2_dq<7> にクロックを供給していて、ddr2_dqs<1>がddr2_dq<8>~ddr2_dq<15>にクロックを供給している。
それぞれの代表の遅延を見ていこう。最初にddr2_dq<0>の遅延を下に示す。
ddr2_controller_delay_3_080719.png
パッドから最初にサンプルするFFまでの遅延が 2.908nsである。クロックの遅延は2.422ns。クロックの遅延のほうが0.486ns 少ない。後で遅延の量を考慮することにする。
次にdd2_dq<9> の遅延を下に示す。(dd2_dq<8>を示そうと思ったのだが、間違えてしまった)
ddr2_controller_delay_4_080719.png
パッドから最初にサンプルするFFまでの遅延が 2.899ns で、クロックの遅延は2.407ns。クロックの遅延のほうが 0.492ns 少ない。ddr2_dq<0> との差はどれも数ps で少ない。

ここで内部の200MHzからDDR2 SDRAMのクロックに出力するまでの遅延をTcd_fpga とすると、これにクロック配線の遅延 (Tpd_clk) を足したものがDDR2 SDRAMがFPGAの200MHzの内部クロックからの遅延になる。FPGA動作クロックからDDR2 SDRAMの動作クロック間での遅延をTddr2_clk とすると、

Tddr2_clk = Tcd_fpga + Tpd_clk


となる。Tcd_fpga は3.328ns。tpd_clk はFR-4の配線遅延を75ps/cmとして、長さを5cm とすると 0.375ns となる。よってTddr2_clk = 3.328 + 0.375 = 3.703ns となる。
DDR2 SDRAMの動作クロックがFPGAの内部動作クロックより3.703ns 遅延していることになる。
次にDDR2 SDRAMからFPGAのddr2_dq までの遅延はどうか計算してみよう。
ここでDDR2 SDRAMからddr2_dq パッドまでの配線遅延をTpd_dataとし、FPGAのパッドから最初のFFまでの遅延をTpad2ff_fpgaとする。さらに、DDR2 SDRAMからFPGAのddr2_dq の最初のFFまでのトータルの遅延をTrecv_dataとすると、

Trecv_data = Tpd_data + Tpad2ff_fpga


となる。
Tpd_data はTpd_clk と同様に0.375ns とし、Tpad2ff_fpga はddr2_dq<0>のデータを採用して2.908ns とすると、Trecv_data = 0.375 + 2.908 = 3.283ns。
ddr2_dq でリードしたデータがFPGA内部クロックからの遅延量はTddr2_clk + Trecv_data なので、3.703ns + 3.283ns = 6.986ns となる。
これをFPGA動作クロックの270度で受けようとすると2クロック目で8.75ns となり、DQSクロックから270度クロックの乗せ変えのためのセットアップ時間として、8.75ns - 6.986ns = 1.764ns 見込めることになる。これはタイミング・アナライザで最悪の遅延量を見込んでいるので、これよりも多少遅延が少なくなることからも、この辺で受けられるだろうと思う。
前回では、入力遅延を変化させて最良のポイントを探ってみたが、今回のDQSのクロックで受ける場合には、あらかじめDQSの遅延を総遅延量の半分以上入れる必要があるため、固定遅延でやることにした。
  1. 2008年07月19日 07:14 |
  2. DDR SDRAMコントローラ
  3. | トラックバック:0
  4. | コメント:0

TortoiseSVNとTrac Lightning でVerilogファイルのバージョン管理

この前インストールしたTrac Lightning TortoiseSVNでVerilogファイルのバージョン管理をやってみた。
Trac Lightning の create-projectコマンドで作った SVNリポジトリに Tortoise SVN を使ってDDR2 SDRAMコントローラのVerilogファイルをインポートした。
さらに、そのVerilogファイルをTortoiseSVNでチェックアウトした。
SVN_checkout_080717.png
そして、それを修正した。そうすると修正したファイルの名前に赤い丸がつく。
それをTortoiseSVNでコミットすると、リビジョン2になった。
これをTrac Lightning のリポジトリブラウザから”変更箇所を見る”でリビジョン1と2の差分が下のように見える。
trac_lightning_1_080717.png
どのリビジョンも取り出すことができるし、とても便利になったと思う。
  1. 2008年07月17日 20:02 |
  2. SVN, TRAC
  3. | トラックバック:0
  4. | コメント:0

Trac Lightningのインストール2

”Trac Lightningのインストール”でApacheが起動しなかったのがなぜかを探ってみることにした。
まずは”(OS 10048)通常、各ソケット アドレスに対してブロトコル、ネットワーク アドレス、またはボートのどれか1つのみを使用できます。”というエラーメッセージが出ているのでこれをネットで検索してみた。
そうすると、TCP80番ポートをすでに使っているアプリ、プロセスがあるのでエラーになっているようだった。
早速、コマンドプロンプトから”netstat -ano"コマンドを実行。80番ポートがプロセスID 2760番のプロセスに使われてしまっている。このプロセスのプロセスはなんだろうということで、タスクマネージャーを立ち上げて、PIDを表示項目に追加してみた。
やってみたのが下の写真、ほかに何を起動しているのかは隠させていただいた。
trac_1_080715.png

そうしたところ、Skypeが原因と判明。終了してTrac のコマンドプロンプトから起動でApacheを起動したら、うまく起動しました。よかった。
trac_2_080715.png
 
やっと、試してみることができるようになった。あまり、1人ではいらないと思うがガントチャートやスケジュールが簡単にかけるようだし、SVNを使ってバージョン管理ができて、バージョン間の差分もブラウザ上から見えるようなので、非常に興味がある。
皆様もVHDLやVerilogコードのバージョン管理にどうだろうか?

最後にApacheを起動済みの時にSkypeを起動したが、きちんとオンラインになった。今度は443、7128番ポートを使用しているようだ。Skypeというのはしぶといソフトなんだなと思った。ポートが使われていても開いているポートを探してコネクションしてしまうのは凄い。

#ブラウザのタブが表示されているので、普段何をしているのかわかってしまう。。。ニコ動見ているのがわかってしまった。。。ちなみに検索キーワードはWRC。最近、WRCを地上波でやっていないのでお世話になっています。三角関数は娘に聞かれたので、説明するのに思い出すために見ていました。
  1. 2008年07月16日 05:04 |
  2. SVN, TRAC
  3. | トラックバック:0
  4. | コメント:0

Trac Lightningのインストール

いろいろなプロジェクトの管理をしようと本(入門Trac with Subversion)を購入してTrac を自分のパソコンでもインストールして試してみようとした。
この本によると、WindowsのオールインワンのTracアプリがTrac Lightningだそうだ。
Trac Lightning-2.0.0 をインストールして、”コマンドプロンプトから実行”でアパッチを立ち上げようとしたら、エラーであがらない。

h:\TracLight>"\bin\java.exe" -Duser.home="h:\TracLight\projects\hudson" -jar hudson\hudson.war --prefix=/hudson --ajp13Port=8009 --ajp13ListenAddress=127.0.0.1
--httpListenAddress=127.0.0.1 --httpPort=8010
指定されたパスが見つかりません。


上のエラーで止まっているいるようだった。
上のコマンドが書いてある行は下のように書いてあった。

"%JAVA_HOME%\bin\java.exe" -Duser.home="%TL_PROJECT_HOME%\hudson" -jar hudson\hudson.war --prefix=/hudson --ajp13Port=8009 --ajp13ListenAddress=127.0.0.1 --httpListenAddress=127.0.0.1 --httpPort=8010


java.exe が必要なようだ。さらにJAVA_HOMEも設定する必要がありそうだ。
早速、JAVAをインストールした。
JAVA_HOME環境変数もセットした。
そうすると上のエラーでは止まらなくなったが、アパッチはまだあがっていないようだ。
今のところうまくいっていないが、もう少し試してみようと思う。
  1. 2008年07月14日 21:22 |
  2. SVN, TRAC
  3. | トラックバック:0
  4. | コメント:0

スピード・レーサーを見てきた

映画館でスピード・レーサーを見てきました。
昔々、子供のころマッハGO, GO, GOを見ていました。車がジャンプしたり、のこぎりが出てくるのに驚いたもんでした。かっこいいマッハ号のプラモを買ってもらって作りましたね。憧れでした。
そんな子供のころのことを考えながら見てきました。
はっきり言って、おやじさんがはまり役。もともと外人さんが似合いそうな感じでしたのでぴったりでした。映画のほうはCGぐりぐりのゲーム画面という感じでしたが、昔のギミックが出てきたので懐かしかったです。時間の関係で日本語吹き替え版で見ましたが、英語版で見たかったかも?
でも、今見ると余計なこと考えちゃいますね。のこぎりが出てくるのはいいけど。どうやってまわしているのかな?とか、傘歯車とかで駆動している?
ジャンプ用のジャッキはあのスピードで出したら、折れちゃうんじゃ~?とか。
フルカバーシールドはどうやって収納しているの?とか。
でも、そんなのはどうでもいいんです。楽しめれば。。。楽しめたのではないでしょうか?大作とはいえないと思いますが。。。人は少なかったです。。。

そういえばトラ技8月号私も買いました。USBでマイコンボードがすぐに接続できるのが良いですね。しかし、USBの電源よりも信号ラインの基板のパターンが後退していす。これは時間差をつけ、電源ラインを先に供給されるようにということですよね?これで、基板にBコネクタをつなぐとケーブルをつなぐと同時に入ると思うのですが、大丈夫なのでしょうか?
  1. 2008年07月12日 20:57 |
  2. 日記
  3. | トラックバック:0
  4. | コメント:2

1次元配列データのパートセレクト

OSERDESを使ってDDR2 SDRAMコントローラを作成しているが、その際に、どうしてもVerilogの構文がわからないところが出てきた。
OSERDESはDDRモードで4:1のシリアライザとして使用している。CLKDIV (100MHz, CLKは200MHz) 1クロックごとにOSERDESのD1, D2, D3, D4 のデータの4ビットとT1, T2, T3, T4 のトライステート状態ビット4ビット分を一度に入れる。DQSはSUZAKU-Vでは2ビットあるので、2ビット(2つ)分のデータ4ビットとトライステート状態4ビット分を確保したいと思った。1つ分ではないのは、ネットを短くして動作周波数を確保するためだ。
これを宣言するためには、2次元配列で宣言するのが一番自然なので、最初に2次元配列で宣言した。
だが、どうしても出力ポートを2次元配列にして上のモジュールに渡そうとしてもエラーになってしまう。どうしてよいか困ったため、mixiのVeritak友の会で聞いてみたところ、たっくさんからお返事があった。やはり、ポートの宣言に2次元配列は書けないということなので、1次元配列でやることにした。それでためしに自分で作ってみたのが下。

    output reg [4*DDR2_DQS_DM_WIDTH-1 : 0] dqs_oserdes_d_1d;
    output reg [4*DDR2_DQS_DM_WIDTH-1 : 0] dqs_oserdes_t_1d;

    always @(posedge clk) begin : DQS_OSERDES_1D // dqs_oserdes_d_1dとdqs_oserdes_t_1dがOSERDESに入力される
        integer k;
        
        for(k=0; k<=DDR2_DQS_DM_WIDTH-1; k=k+1) begin // 8bitに1個インスタンシエーション
             if (reset) begin
                 dqs_oserdes_d_1d[k*4+3 : k*4] <= 4'bXXXX;
                 dqs_oserdes_t_1d[k*4+3 : k*4] <= 4'b1111;
             end else begin
                 dqs_oserdes_d_1d[k*4+3 : k*4] <= dqs_oserdes_d;
                 dqs_oserdes_t_1d[k*4+3 : k*4] <= dqs_oserdes_t;
             end        
        end
    end


でもこれではエラーになってしまって、XSTの論理合成が通らない。(とりあえず、インプリメントできるかやっているので)
Veritak友の会で、べりろじしゃんという方に教えていただいて、2重ループで書いてみたらOKだった。

    always @(posedge clk) begin : DQS_OSERDES_1D // dqs_oserdes_d_1dとdqs_oserdes_t_1dがOSERDESに入力される
    integer k, m;

        for(k=0; k<=DDR2_DQS_DM_WIDTH-1; k=k+1) begin // 8bitに1個インスタンシエーション
            for(m=0; m<4; m=m+1) begin
                if (reset) begin
                    dqs_oserdes_d_1d[k*4+m] <= 1'bX;
                    dqs_oserdes_t_1d[k*4+m] <= 1'b1;
                end else begin
                    dqs_oserdes_d_1d[k*4+m] <= dqs_oserdes_d[m];
                    dqs_oserdes_t_1d[k*4+m] <= dqs_oserdes_t[m];
                end
            end
        end
    end



また、違う書き方を、たっくさんに教えていただいた。それによるとVerilog2001では下のように書けるそうだ。

    always @(posedge clk) begin : DQS_OSERDES_1D // dqs_oserdes_d_1dとdqs_oserdes_t_1dがOSERDESに入力される
        integer k, m;
        
        for(k=0; k<=DDR2_DQS_DM_WIDTH-1; k=k+1) begin // 8bitに1個インスタンシエーション
            if (reset) begin
                dqs_oserdes_d_1d[k*4 +: 4] <= 4'bXXXX;
                dqs_oserdes_t_1d[k*4 +: 4] <= 4'b1111;
            end else begin
                dqs_oserdes_d_1d[k*4 +: 4] <= dqs_oserdes_d;
                dqs_oserdes_t_1d[k*4 +: 4] <= dqs_oserdes_t;
            end
        end 
    end


下にたっくさんの書き込みを引用させていただきます。

reg [8:0] a;

のとき、

a[1 +:4] は、a[4:1] に等価です。1から出発して1,2,3,4 のパートセレクト
a[5 -:4: は、a[5:2] に等価です。5から出発して5,4,3,2のパートセレクト


ちなみに
reg [0:8] a;
のとき、
a[1 +: 4] は、a[1:4]に等価、a[5 -: 4] はa[2:5] に等価だそうだ。
たっくさん、貴重な知識を教えていただいてありがとうございました。

次に、べろりじしゃんさんにもgenerate を使用した書き方の例を教えていただいた。その例を参考に自分で書き直してみたのが下。

    generate
    genvar k, m;
        for(k=0; k<=DDR2_DQS_DM_WIDTH-1; k=k+1) begin : OSERDES_NO // 8bitに1個インスタンシエーション
            for(m=0; m<4; m=m+1) begin : OSERDES_PIN_NO
                always @(posedge clk) begin
                    if (reset) begin
                        dqs_oserdes_d_1d[k*4+m] <= 1'bX;
                        dqs_oserdes_t_1d[k*4+m] <= 1'b1;
                    end else begin
                        dqs_oserdes_d_1d[k*4+m] <= dqs_oserdes_d[m];
                        dqs_oserdes_t_1d[k*4+m] <= dqs_oserdes_t[m];
                    end
                end
            end
        end
    endgenerate


べろりじしゃんさん、貴重なVerilogコードを開示していただいてありがとうございます。

べろりじしゃんさんは、CQ出版でVerilog関連の本を何冊も書いている方のようだ。
  1. 2008年07月11日 21:18 |
  2. 入門Verilog
  3. | トラックバック:0
  4. | コメント:0

OSERDESとISERDESその後

先週、今週はパソコンのリプレース、プロバイダの乗換えなど、いろいろイベントがあってなかなか進まなかったが、DDR2 SDRAMコントローラ関連のOSERDESとISERDESの問題にはまっている。
どうも最後でPlace & Routeで配線できないと言われてエラーになってしまう。
こんな感じ。

ERROR:Route:472 - 
   This design is unrouteable.
   To evaluate the problem please use fpga_editor.
Routing Conflict 1: 
    Net:GLOBAL_LOGIC0 on pin SR on location OLOGIC_X0Y111 
    Net:SYS_RST_IBUF_1 on pin SR on location ILOGIC_X0Y111 
    Conflict detected on wire: PINFEED(-63835,80448)

Routing Conflict 2: 
    Net:GLOBAL_LOGIC0 on pin SR on location OLOGIC_X0Y113 
    Net:SYS_RST_IBUF_1 on pin SR on location ILOGIC_X0Y113 
    Conflict detected on wire: PINFEED(-63835,84320)


どうやらSR(リセット)ピンがOSERDESとISERDESで違っているのがだめなのか?
DQS付近の入出力用ソースはこの辺。

    // Instantiate DQS DDR registers
    generate
    genvar n;
        for (n=DDR2_DQS_DM_WIDTH-1; n>=0; n=n-1) begin: WRDATA_DQS
            OSERDES # (
                .DATA_RATE_OQ("DDR"),
                .DATA_RATE_TQ("DDR"),
                .DATA_WIDTH(4),
                .INIT_OQ(1'b0),
                .INIT_TQ(1'b1),
                .SERDES_MODE("MASTER"),
                .SRVAL_OQ(1'b0),
                .SRVAL_TQ(1'b1),
                .TRISTATE_WIDTH(4)
            ) WRDATA_DDR2_OUT (
                .OQ(dqs_oq[n]),
                .SHIFTOUT1(),
                .SHIFTOUT2(),
                .TQ(dqs_tq[n]),
                .CLK(clk),
                .CLKDIV(clk100MHz),
                .D1(dqs_oserdes_d_1d[n*4]),
                .D2(dqs_oserdes_d_1d[n*4+1]),
                .D3(dqs_oserdes_d_1d[n*4+2]),
                .D4(dqs_oserdes_d_1d[n*4+3]),
                .D5(),
                .D6(),
                .OCE(1'b1),
                .REV(1'b0),
                .SHIFTIN1(1'b0),
                .SHIFTIN2(1'b0),
                // .SR(dqs_reset_3d[n]),
                .SR(1'b0),
                .T1(dqs_oserdes_t_1d[n*4]),
                .T2(dqs_oserdes_t_1d[n*4+1]),
                .T3(dqs_oserdes_t_1d[n*4+2]),
                .T4(dqs_oserdes_t_1d[n*4+3]),
                .TCE(1'b1)
            );
            
             ISERDES #(
                .BITSLIP_ENABLE("TRUE"),
                .DATA_RATE("DDR"),
                .DATA_WIDTH(4),
                .INTERFACE_TYPE("NETWORKING"),
                .IOBDELAY("IFD"),
                .IOBDELAY_TYPE("FIXED"),
                .IOBDELAY_VALUE(32),
                .NUM_CE(1),
                .SERDES_MODE("MASTER")
            ) DQS_DDR2_IN (
                 .O(ddr2_dqsin_out[n]),
                 .Q1(), 
                 .Q2(), 
                 .Q3(), 
                 .Q4(), 
                 .Q5(), 
                 .Q6(), 
                 .SHIFTOUT1(), 
                 .SHIFTOUT2(),
                 .BITSLIP(1'b0),
                 .CE1(1'b1), 
                 .CE2(1'b1),
                 .CLK(1'b0),
                 .CLKDIV(1'b0),
                 .D(ddr2_dqsin[n]),
                 .DLYCE(1'b0),
                 .DLYINC(1'b0),
                 .DLYRST(1'b0),
                 .OCLK(1'b0), 
                 .REV(1'b0),  
                 .SHIFTIN1(1'b0), 
                 .SHIFTIN2(1'b0),
                 .SR(reset)
              );
             
             BUFIO DQS_DDR2_IN_BUFIO (
                .I(ddr2_dqsin_out[n]),
                .O(ddr2_dqsin_bufio[n])
            );
            
            IOBUF DDD2_DQS_BUF (
                .O(ddr2_dqsin[n]),
                .IO(ddr2_dqs[n]),
                .I(dqs_oq[n]),
                .T(dqs_tq[n])
            );
        end
    endgenerate


.SR(1'b0) と .SR(reset) の違いがある。これをどちらも .SR(reset) にしてみた。
そうするとやはり、このコンフリクトはなくなったが、まだ後、18個のコンフリクトを解消する必要がある。

次は、下のコンフリクト。

Routing Conflict 1: 
    Net:ddr2_sdram_cont_inst/clk90 on pin CLK on location OLOGIC_X0Y97 
    Net:clk on pin OCLK on location ILOGIC_X0Y97 
    Conflict detected on wire: BOUNCEIN(-63349,57088)


これはDQのclk90 と clk がコンフリクトしているようだ。DQのISERDESのOCLK と CLKDIV は clkネットがつながっていて、OSERDESのCLKには clk270 がつながっていた。どうやら、これらのピンは同じクロックがつながっている必要がありようだ。
事実、XAPP721 ISERDES と OSERDES を使用した高性能DDR2 SDRAM インターフェイスを見ても、ISERDESのOCLK と CLKDIV、OSERDESのCLKには同じ CLKfast_90 がつながっている。やはり、配線がこれしかないのだろう。
これで、Place & Route は通ったが、タイミング制約が満足していない。クロックを変更してしまったので、タイミングダイアグラムをもう一度考察する必要が出てきてしまったし。。。

今日の教訓、OSERDES, ISERDESの決まりごと
1.OSERDESとISERDESのSRには同じリセット信号をつなぐ。
2.ISERDESのOCLK と CLKDIV、OSERDESのCLKには同じクロックを入力する。


注:コンフリクトの方がclk90 なのに、なぜclk270 の話になるのかというと、グローバルバッファを削減するためにclk270 は ~clk90として定義してあるからです。
assign clk270 = ~clk90;
  1. 2008年07月11日 04:30 |
  2. Virtex4のお勉強
  3. | トラックバック:0
  4. | コメント:0

FPGA BBSの記事”fanoutを減らしたい・・・”

FPGA BBS”fanoutを減らしたい・・・”という記事が載っていた。
その記事では、16ビットのデータバスのイネーブルを16個に分割して、遅延を減らしいたいということだった。でも、例によって、XSTでFFが削除されてしまい苦労されたようだ。いろいろ試されたそうで、keep属性もmax_fanout属性も駄目だったそうだ。
私も”DDR2 SDRAMコントローラのインプリメントテスト2(動作周波数の確保2)”でXSTのmax_fanout属性を使用して、ファンアウトをツリー状に負荷を分散していった。その時はmax_fanout属性でうまくいったのだが、うまくいかなかったようだ。まあそういうこともあるということで。。。
その方が、試してうまくいったのが、equivalent_register_removal制約だそうだ。これは、ISE10.1のマニュアル XSTガイド381ページの”等価レジスタの削除 (EQUIVALENT_REGISTER_REMOVAL)”に書いてあるようだ。
忘れないように、このブログにメモしておく。

しかし、FPGA BBSの記事を書かれた方は、もしかして、私のブログを見ていただいているのだろうか?
  1. 2008年07月10日 17:40 |
  2. FPGAチップ内の配線方法
  3. | トラックバック:0
  4. | コメント:2

60万アクセスを超えた

ADSL乗り換え騒ぎでネットにつなげないうちに、FPGAの部屋のアクセス数も60万アクセスを超えたようだ。皆様、ありがとうございます。
2008年の月別アクセス数のグラフを張っておく。
2008_access_080709.png

だんだん、アクセス数が伸びてきているようだ。なんでだろうか?
画像のアップロードもだいぶ速くなった。
  1. 2008年07月09日 04:31 |
  2. 日記
  3. | トラックバック:0
  4. | コメント:0

YahooBB ADSLが使えるようになった

一昨日にNTTのADSLを解除して、昨日YahooBB ADSLの局内工事をしてもらった。仕事が終わって家に帰ってからADSLモデムの取り付けを自分でして、やっと開通となった。やはり1日でもネットにつながらないとさびしい。しかし、昨日の朝はネットができないので思う存分F1を見られたので、たまにはないのもいいかも?という思いもある。
そういえば、ADSLモデムというかモデム付きルータはすぐにつながったのだが、ローカルIPアドレスが、192.168.3. となっていて、無線LANアクセスポイントは192.168.1.128 だったので見えなかった。モデム付きルータの方のネットマスクを255.255.252.0に設定してサブネットを広げることを考えたが、ネットマスクの設定は3桁目までがハイドされていて設定できない。そこで無線LANアクセスポイントのアドレスを変更した。あれ、パスワードなんだっけ?といった混乱はあったが、スムーズに設定できたほうだと思う。
YahooBBのプランは50M Revo というプランで一番速いプランだ。早速、gooでスピードを測定してみたが、27Mbps程度出ているようだ。YahooBBで測定した見たら下り21Mbps、上り7Mbps程度出ていた。今までの約3倍のスピードになったので、満足した。

今まで知らなかったのだが、YahooBBのメールというのはYahooメールと同じだった。?????.ybb.ne.jp からメーラーにPOPで取り込んだら、Yahooメールのメールがすべてなくなってしまった。驚いた~。早速、サーバーにメールを残す設定をチェック。しまった!
  1. 2008年07月09日 04:27 |
  2. 日記
  3. | トラックバック:0
  4. | コメント:0

パソコンをリプレースした

先週からやっていたパソコンのリプレース作業がやっと終わって、パソコンが新しくなった。
いろいろなデータの移行や、ソフトウェアのインストールなどがやはりとても大変だった。古いパソコンはお蔵入りというか、息子か妹にあげると思うので、FPGA関連ソフト、マイコンプログラミングソフト、もろもろをアンインストールして、だいぶ、まっさらな状態に近づけた。これが結構大変だった。
ブラウザとメールソフトはFirefox とTunderbird なので、profile をコピーしただけで、いろいろなサイトのIDやパスワード、メール履歴などを引き継げたのでラッキーだった。
これで、新しいパソコンにリプレースできて、快適にいろいろなものが使えるようになった。以前パソコンではmixiのページの表示がとても時間がかかって大変だったのだが、とても速くなった。

7月7日七夕の今日はNTTのADSL回線の解除がある。そして次の日にYahoo BBのADSLを開通してもらう予定。つまりプロバイダを乗り換える。
今のも、24MbpsではあるがNTTからの距離が460mなので、下りのリンクスピードは15Mbps位出ていたので、満足のできるスピードだったのだが、Yahooの携帯を持っているのでホワイトコール24が魅力的だったのだ。今度のプランは一番速い50Mbpsのプランにした。どのくらいの速度が出るのか楽しみだ。
というわけで、今日の夜はインターネットに家から接続できない。
  1. 2008年07月07日 06:05 |
  2. 日記
  3. | トラックバック:0
  4. | コメント:2

ISE10.1iサービスパック2

今日、新しいパソコンをインストールしていて、XilinxのISE WebPACK10.1iをインストールして、Web Updateをしたら、ISEのバージョンが10.1.02になっていた。ありゃ、これはもしかしてサービスパック2が出ているかな?
Xilinxのサイトを見たら、2008年6月27日にサービスパック2が出ていた。
  1. 2008年07月04日 23:04 |
  2. Xilinx ISEについて
  3. | トラックバック:0
  4. | コメント:0

VeritakでのWaveform Viewer内のSignal検索機能

私が、とても欲しかったVeritakでのWaveform Viewer内のSignal検索機能が実装された。
私は、今までModelSimでシミュレーションしていたので、Signalを可能な限り追加して、必要なSignalを検索で探していたのだが、Veritakではその機能がなかった。ただし、Veritakでは波形はすべて保存されているので、Signalを追加しても再度シミュレーションする必要がないという利点がある。でも、長い時間シミュレーションをすると、Signalを追加するだけでも、非力なマシンでは結構時間がかかるものだ。
そこで、Signalを出来るだけつかして、いろいろな信号を見ていたのだが、どうしてもWaveform Viewerの信号名が見つからないことがある。それでWaveform Viewer内のSignal検索機能が欲しかった。
この度、バージョン3.46Cで実装したので、確かめてみた。
やり方は、
1.シミュレーション後、Scope Tree View ウインドウで右クリック
2.右クリックメニューから”ワイルドカードによる検索”を選択する
Veritak_Find_1_080703.png

3.Enter Wildcardダイアログが開くので、ワイルドカードを使いながら検索して、必要なSignalを見つける。(例: *wrdata* )
4.Wave Next.. ボタン、Wave Prev... ボタンをクリックして、一致する波形を検索する。
Veritak_Find_2_080703.png

私は、そこで、重要なSignal名を右クリックして、”波形の色”を変更したりしている。
本当に、私にとっては便利になった。ありがとうございました。

DDR2はISERDES, OSERDESに順調に変更できつつある。しかし、新しいパソコンが来たので、設定に忙しくなってしまった。しばらくは古いパソコンと並列に使うことになるだろう。
  1. 2008年07月03日 21:01 |
  2. シミュレーション
  3. | トラックバック:0
  4. | コメント:2

DoxygenでSHIFT-JISを使用する

中村様からメールで、SHIFT-JISで書いたVHDLのコメントを文字化けなくDoxygenでドキュメント化する方法を教えていただいた。
その方法はおっちょこちょいさんのブログdoxygen備忘録に書いてあった。
それによると"DOXYFILE_ENCODING"と"INPUT_ENCODING"に"CP932"を設定すれば、SHIFT-JISで書いたVHDLのコメントをドキュメント化できるとのこと。中村様からは"INPUT_ENCODING"に"CP932"を設定するだけでOKとのことだった。実際にやってみたところ"INPUT_ENCODING"に"CP932"を設定するだけでOKだった。

Doxygen GUI での実際のやり方は、Doxygen GUI で"Expert..."ボタンをクリックする。
Doxygen_sjis_1_080701.png

doxywizardダイアログが開くので、Inputタブをクリックして、"INPUT_ENCODING"に"CP932"を入力する。
Doxygen_sjis_2_080701.png

これで、SHIFT-JISでも大丈夫だった。

本当に中村様、ありがとうございました。
そのほか、シーケンス図が作れる方法が書いてあるページを教えてもらった。そのうちに試してみようと思う。
  1. 2008年07月01日 12:32 |
  2. Doxygen
  3. | トラックバック:0
  4. | コメント:0