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 件のコメント:
コメントを投稿