2010年10月26日火曜日

PHY部の検討

DDR2 SDRAM CONTROLLERのPHY部に検討を行っている。
Spartan3AはIDELAYを持っているが、IOB内部のF/Fを使用する場合は4tapしか使えず自由度が低い。Spartan3Aではread dataの取り込みはDQSの位相をずらして使用するのではなく、DCMでCapture用のclockを生成して使うのが作法のようだ。その作法に則って設計することにしよう。

Write系のData pathは以下のようにした。


//--------------------------------------------------------------------------------
// circuit description
//--------------------------------------------------------------------------------
OBUF i_obuf_dm [(PHYDMW/2)-1:0] (
        .O( DM  ),
        .I( dmo )
);


IOBUF   i_iobuf_dq [(PHYDW/2)-1:0] (
        .IO( DQ ),
        .O ( dqi),
        .I ( dqo),
        .T ( oen)
);


IOBUFDS i_iobufds_dqs [(PHYDW/16)-1:0] (
        .IO ( DQS_P),
        .IOB( DQS_N),
        .O  ( dqsi ),
        .I  ( dqso ),
        .T  ( oen  )
) ;


//--------------------------------------------------------------------------------
// write
//--------------------------------------------------------------------------------


/*********************************************************************************


 tx_clk_270 ~~|___|~~~|___|~~~|___|~~~|___|~~~|___|~~~|___|~~~|_
 tx_clk_180 |___|~~~|___|~~~|___|~~~|___|~~~|___|~~~|___|~~~|___
 tx_clk_90  __|~~~|___|~~~|___|~~~|___|~~~|___|~~~|___|~~~|___|~
 tx_clk  ___|~~~|___|~~~|___|~~~|___|~~~|___|~~~|___|~~~|___|~~~
            : : : : : : : : : : : : : : : : : : : : : : : : : : 
 dp_ten  ____/~~~~~~~~~~~~~~~~\_________________________________
 dp_ten_1d __________/~~~~~~~~~~~~~~~~\_________________________
 ten_pd    __________________/~~~~~~~~~~~~~~~~\_________________
 ten_nd    ________________/~~~~~~~~~~~~~~~~\___________________
            : : : : : : : : : : : : : : : : : : : : : : : : : : 
 oen       __________/~~~~~~~~~~~~~~~~~~~~~~~~\_________________
 dqso_en   __________/~~~~~~~~~~~~~~~~~~~~~~\___________________
 DQS       ----------_______|~~~|___|~~~|_____------------------
            : : : : : : : : : : : : : : : : : : : : : : : : : : 
 tx_clk_90  __|~~~|___|~~~|___|~~~|___|~~~|___|~~~|___|~~~|___|~
          ___ _______ _______ _______ _______ _______ _______ __
 dp_wd    ___X__Va___X__Vb___X_______X_______X_______X_______X__
           ______ _______ _______ _______ _______ _______ ______
 wd_180    ______X__Va___X__Vb___X_______X_______X_______X______
           ____ _______ _______ _______ _______ _______ _______ 
 wd_90     ____X_______X___Va__X__Vb___X_______X_______X_______X
                           ___ ___ ___ ___              
 DQ       -----------#####X_a_X_a_X_b_X_b_X####-----------------
            : : : : : : : : : : : : : : : : : : : : : : : : : : 
                           ___ ___ ___ ___              
 DQ       -----------#####X_a_X_a_X_b_X_b_X####-----------------
            : : : : : : : : : : : : : : : : : : : : : : : : : : 
 DQS       ----------_______|~~~|___|~~~|_____------------------


 latency = 2
*********************************************************************************/


FDC i_ten_1d (.C(tx_clk    ),.D(dp_ten   ),.Q(dp_ten_1d),.CLR(tx_rst));
FDC i_ten_pd (.C(tx_clk    ),.D(dp_ten_1d),.Q(ten_pd   ),.CLR(tx_rst));
FDC i_ten_nd (.C(tx_clk_270),.D(dp_ten_1d),.Q(ten_nd   ),.CLR(tx_rst));


NOR2 i_nor_oen     (.I0(ten_pd), .I1(dp_ten_1d), .O(oen    ));
NOR2 i_nor_dqso_en (.I0(ten_nd), .I1(dp_ten_1d), .O(dqso_en));
OR2  i_or_dqo_en   (.I0(ten_nd), .I1(dp_ten_1d), .O(dqo_en));


ODDR2 #(
    .DDR_ALIGNMENT( "NONE"      ),
    .INIT         ( 1'b0        ),
    .SRTYPE       ( "ASYNC"     )
) i_oddr_dqso [(PHYDW/16)-1:0] (
    .CE           ( 1'b1        ),
    .R            ( dqso_en     ),
    .S            ( 1'b0        ),
    .Q            ( dqso        ),
    .C0           ( tx_clk_180  ),
    .C1           ( tx_clk      ),
    .D1           ( 1'b1        ),
    .D0           ( 1'b0        )
);


FD i_fd_wd_180  [PHYDW-1 :0] (.C(tx_clk_180), .D(dp_wd  ), .Q(wd_180 ));
FD i_fd_wdm_180 [PHYDMW-1:0] (.C(tx_clk_180), .D(dp_wdm ), .Q(wdm_180));
FD i_fd_wd_90   [PHYDW-1 :0] (.C(tx_clk_90 ), .D(wd_180 ), .Q(wd_90  ));
FD i_fd_wdm_90  [PHYDMW-1:0] (.C(tx_clk_90 ), .D(wdm_180), .Q(wdm_90 ));


ODDR2 # (
    .DDR_ALIGNMENT( "NONE"      ),
    .INIT         ( 1'b0        ),
    .SRTYPE       ( "ASYNC"     )
) i_dqo_ddr[(PHYDW/2)-1:0] (
    .CE           ( dqo_en      ),
    .R            ( 1'b0        ),
    .S            ( 1'b0        ),
    .Q            ( dqo         ),
    .C0           ( tx_clk_270  ),
    .D0           ( wd_90[ 7:0] ),
    .C1           ( tx_clk_90   ),
    .D1           ( wd_90[15:8] )
) ;

ODDR2 # (
    .DDR_ALIGNMENT( "NONE"      ),
    .INIT         ( 1'b0        ),
    .SRTYPE       ( "ASYNC"     )
) i_dmo_ddr [(PHYDMW/2)-1:0] (
    .CE           ( dqo_en      ),
    .R            ( 1'b0        ),
    .S            ( 1'b0        ),
    .Q            ( dmo         ),
    .C0           ( tx_clk_270  ),
    .C1           ( tx_clk_90   ),
    .D1           ( wdm_90[1]   ),
    .D0           ( wdm_90[0]   )
) ;

また、Read系は以下だ。



//--------------------------------------------------------------------------------
// read
//--------------------------------------------------------------------------------
IDDR2 #(
    .DDR_ALIGNMENT( "NONE"      ),
    .SRTYPE       ( "ASYNC"     ),
    .INIT_Q0      ( 1'b0        ),
    .INIT_Q1      ( 1'b0        )
)
i_ddr [(PHYDW/2)-1:0] (
    .C0           ( rx_clk_180  ),
    .C1           ( rx_clk      ),
    .D            ( dqi         ),
    .Q1           ( dqip        ),
    .Q0           ( dqin        ),
    .CE           ( 1'b1        ),
    .S            ( 1'b0        ),
    .R            ( 1'b0        )
);


wire dp_ren_dly;


FDC i_ren_dly1 (.C (rx_clk),.D(dp_ren),.Q(dp_ren_dly),.CLR(rx_rst));
FDC i_ren_dly2 (.C (rx_clk),.D(dp_ren_dly),.Q(af_wen),.CLR(rx_rst));


afifo #(.DW(PHYDW), .AW(3)) i_asq (
        .wclk   (rx_clk     ),
        .wrst   (tx_rst     ),
        .full   (/* open */ ),
        .amfull (/* open */ ),
        .wen    (af_wen     ),
        .wdt    ({dqin,dqip}),


        .rclk   (bf_clk     ),
        .rrst   (bf_rst     ),
        .empty  (asq_empty  ),
        .ren    (dp_rd_rdy  ),
        .rdt    (pd_rd      )
);


INV i_vld (.I(asq_empty),.O(pd_rd_vld));


Icarus Verilogでsimulationを行った。


Write系


Read系は上記Write dataを折り返して確認した。





































0 件のコメント:

コメントを投稿

自作CPUで遊ぶ 25

まだ制御ソフトが完成していないので今まではスピンドルを移動するために一々簡単なプログラムを書いて移動させていたのだが、非常に面倒なのでCNCペンダント的なものを作ることにした。 右側の縦に2つ並んでいるスイッチ...