XGMIIはPMCのチップとのインタフェースを担うインタフェース。 これを使うにはDCMとODDR,ISERDES, OSERDESを活用する必要がある。 ここにはそのヒントを書き残す。 参考ページをまず2つ。 [1] http://www.google.co.jp/url?sa=t&source=web&ct=res&cd=3&ved=0CBEQFjAC&url=http%3A%2F%2Fjapan.xilinx.com%2Fxapp%2Fj_xapp606.pdf&ei=6cUxS8_wLpLq7APq7rWQBg&usg=AFQjCNG0oavN6ZSWHghA4oSCV8EjnZNGUg&sig2=vjTjBv9jmxhgG0HcUOfiyA [2] http://www.google.co.jp/url?sa=t&source=web&ct=res&cd=1&ved=0CAcQFjAA&url=http%3A%2F%2Fwww.xilinx.com%2Fsupport%2Fdocumentation%2Fuser_guides%2Fug070.pdf&ei=eRAyS4D0No_s7AO32KCFBg&usg=AFQjCNFv3i5aW4HYOwg531GIoBBNwwaxsQ&sig2=4kkrOyAwTuSoZl_Pvo3wNA ([2]はI/Oパッドの仕組みとして 322と353ページも必見です) 出力の場合、送信クロックのエッジにデータが乗っている状態を作りたいので、 あらかじめDCMでシステムクロックに対して位相を90度ずらしておくとよい。
この出力の方法はプリミティブ名の違いはあれど、他のデバイスでも通用するので覚えておくと便利す。 厳密にはこの後に hoge0 をOBUFプリミティブ(247ページ)に通して出力するのがよい。(けど近年のISEはそこまでしなくても良くなった)
OSERDES # ( .DATA_RATE_OQ("DDR"), // double clock edge .DATA_RATE_TQ("DDR"), // double clock edge .DATA_WIDTH(4), // データ幅を4に .INIT_OQ(1'd0), // 初期値 .INIT_TQ(1'd0), // TQの初期値 .SERDES_MODE("MASTER"), // もし単一OSERDESでよければこれで .SRVAL_OQ(1'd0), // 謎です。初期値は0らしいが… .SRVAL_TQ(1'd0), // 同じく謎。 .TRISTATE_WIDTH(4) // トライステートバッファへの入力の幅 ) oserdesTest ( .CLK(CLK), // bit 幅4 なら CLK_DIVの2倍の速度でないとダメ .CLKDIV(CLK_DIV), // 基本クロック .D1(dataIn[0]), .D2(dataIn[1]), .D3(dataIn[2]), .D4(dataIn[3]), .D5(1'b0), .D6(1'b0), .OCE(1'b1), // クロックイネーブルずっと動くのが嫌なら制御 .REV(1'b0), // 謎。使わない? .SHIFTIN1(1'b0), // SLAVEモードも合わせて使うなら必要。 .SHIFTIN2(1'b0), // 同上 .SR( ~RST_), // Active High の非同期リセット .TCE(1'b1), // トライステートバッファのイネーブルシグナル .T1(1'b0), .T2(1'b0), .T3(1'b0), .T4(1'b0), .OQ(dataOut), // もし databit が4なら 1CLK_DIV+1CLKで出力 .SHIFTOUT1(), // SLAVEモードも合わせて使うなら必要。 .SHIFTOUT2(), // 同上 .TQ() // もしOBUFにトライステートバッファを使いたいならこれを使う。 ); 基本的に言うことはないす。 一回波形を追ってみるとこの挙動がわかりやすいかなぁと。 |