論理回路デザイン
ArchiTek home page
テストモジュールサンプル

コード(test and top RTL)

/* **************************** MODULE PREAMBLE ********************************

        Copyright (c) 2012, ArchiTek
        This document constitutes confidential and proprietary information
        of ArchiTek. All rights reserved.
*/

// ***************************** MODULE HEADER *********************************

`timescale 1ps / 1ps

module test;

// ************************ PARAMETER DECLARATIONS *****************************

        parameter       D       = 1;
        // 基本クロックの周期は今回の動作周波数175MHzに設定する
        parameter       DCLK    = 5714;
        parameter       DCLK2   = DCLK/2;

// ************************** LOCAL DECLARATIONS *******************************

        reg             clk, clk_n;
        reg             resetin;

// ****************************** MODULE BODY **********************************

// -----------------------------------------------------------------------------
// 差動クロック信号入力(無限ループ)
initial begin clk=0; forever begin #(DCLK2) clk=~clk; end end
initial begin clk_n=1; forever begin #(DCLK2) clk_n=~clk_n; end end

// -----------------------------------------------------------------------------
// 基板上のプッシュボタンによるリセット信号入力(正論理)
initial begin resetin=1; #D resetin=1; #(DCLK*3.5) resetin=0; end

// -----------------------------------------------------------------------------
// topモジュールのI/0は、クロック/リセット入力、DDR3 I/F、LED出力のみ
top top_0 (
        clk, clk_n, resetin, ddr_clk_p, ddr_clk_n,
        ddr_cke, ddr_cs_n, ddr_ras_n, ddr_cas_n,
        ddr_we_n, ddr_dqm, ddr_ba, ddr_addr,
        ddr_dq, ddr_dqs_p, ddr_dqs_n,
        ddr_odt, ddr_reset_n,
        led_init, led_exec, led_err
	);

// ************************** FUNCTIONS and TASKS ******************************

endmodule

// *****************************************************************************
/* **************************** MODULE PREAMBLE ********************************

        Copyright (c) 2012, ArchiTek
        This document constitutes confidential and proprietary information
        of ArchiTek. All rights reserved.
*/

// ***************************** MODULE HEADER *********************************

module top (
        clk, clk_n, resetin, ddr_clk_p, ddr_clk_n,
        ddr_cke, ddr_cs_n, ddr_ras_n, ddr_cas_n,
        ddr_we_n, ddr_dqm, ddr_ba, ddr_addr,
        ddr_dq, ddr_dqs_p, ddr_dqs_n,
        ddr_odt, ddr_reset_n,
        led_init, led_exec, led_err
        );

// ************************ PARAMETER DECLARATIONS *****************************

        parameter       REGWD   = 34;                   // Register width
        parameter       REFWAIT = 41;                   // Refresh wait
        parameter       REFACS  = 42;                   // Refresh access

// ***************************** I/O DECLARATIONS ******************************

        input           clk;
        input           clk_n;
        input           resetin;

        output          ddr_clk_p;
        output          ddr_clk_n;
        output          ddr_cke;
        output          ddr_cs_n;
        output          ddr_ras_n;
        output          ddr_cas_n;
        output          ddr_we_n;
        output  [1:0]   ddr_dqm;
        output  [2:0]   ddr_ba;
        output  [15:0]  ddr_addr;
        inout   [15:0]  ddr_dq;
        inout   [1:0]   ddr_dqs_p;
        inout   [1:0]   ddr_dqs_n;
//      input   [1:0]   ddr_rdqs_n;
        output          ddr_odt;
        output          ddr_reset_n;

        output          led_init;                       // LED for initialize
        output  [5:0]   led_exec;                       // LED for execution
        output          led_err;                        // LED for diff error

// ************************** LOCAL DECLARATIONS *******************************

        wire            reset_n;

        // PLL IPコアからのクロック信号
        wire            ddr_clk_0;
        wire            ddr_clk_180;
        wire            ddr_clk_270;

        // 通常アクセスマスター信号(内部バス32bit対応)
        wire            iReq;
        wire            iGnt;
        wire            iRxw;
        wire    [31:0]  iAddr;
        wire            iWrStrb;
        wire            iWrAck;
        wire    [31:0]  iWrData;
        wire    [3:0]   iWrMask;
        wire            iRdStrb;
        wire            iRdAck;
        wire    [31:0]  iRdData;

        // 割り込みアクセスマスター信号
        wire            pReq;
        wire            pGnt;
        wire    [31:0]  pAddr;

        // sdcモジュールのDDR信号(内部バス32bit対応)
        // reset_n信号、cke信号は初期化制御のためそれぞれpAddr[3]、pAddr[4]を割り当て
        wire            sd_cs_n;
        wire            sd_ras_n;
        wire            sd_cas_n;
        wire            sd_we_n;
        wire            sd_cke          = ~pAddr[4];
        wire    [2:0]   sd_ba;
        wire    [15:0]  sd_addr;
        wire            sd_odt          = 1'b0;
        wire            sd_reset_n      = ~pAddr[3];
        wire            sd_wdvldt;
        wire            sd_wdvldd;
        wire            sd_wdvld        = sd_wdvldt | sd_wdvldd;
        wire    [31:0]  sd_wd;
        wire    [3:0]   sd_wdqm;
        wire            sd_rdvld;
        wire    [31:0]  sd_rd;

        // ACタイミングの設定
        wire    [7:0]   reg_pACCW       = 8'h19;
        wire    [7:0]   reg_pACCR       = 8'h14;
        wire    [7:0]   reg_pCOM        = 8'h2c;
        wire    [4:0]   reg_pFAW        = 5'h14;
        wire    [4:0]   reg_pRRD        = 5'h04;
        wire    [4:0]   reg_dTWR        = 5'h0d;
        wire    [4:0]   reg_dTRW        = 5'h05;
        wire    [4:0]   reg_dWL         = 5'h08;
        wire    [4:0]   reg_dRL         = 5'h08;

        reg     [1:0]   rst;
        reg             reset;

        // sdcモジュールとI/Oバッファ間のDDR信号(16bitバス対応)
        wire    [15:0]  ddr_din;
        wire    [15:0]  ddr_dout;
        wire    [15:0]  ddr_oe;
        wire    [1:0]   ddr_dqsout;
        wire    [1:0]   ddr_dqsin;
        wire    [1:0]   ddr_dqs_poe;
        wire    [1:0]   ddr_dqs_noe;
        wire    [1:0]   ddr_dqs_pbus;

        // ステート実行用信号
        wire            ts_req;
        wire            ts_gnt;
        wire    [31:0]  ts_addr;
        wire            ts_omit;

        reg             omit;

        wire    [5:0]   exec;

// ******************************** MODULE BODY ********************************

  IBUF  IBUF_rst_i0    (.I (resetin),   .O (rst_i));

// Generate the internal reset - it is asserted whenever the reset pin
// is asserted, or the DCM is not locked
  assign reset_n        = !rst_i & clock_locked;

// Core Generatorで作成したクロック供給用PLL IPコア
// Clock source
  clk_core clk_core_i0
   (// Clock in ports
    .CLK_IN1_P(clk),             // IN
    .CLK_IN1_N(clk_n),           // IN
    // Clock out ports
    .CLK_OUT1(ddr_clk_0),        // OUT
    .CLK_OUT2(ddr_clk_180),      // OUT
    .CLK_OUT3(ddr_clk_270),      // OUT
    // Status and control signals
    .RESET(rst_i),// IN
    .LOCKED(clock_locked));      // OUT

// -----------------------------------------------------------------------------
// Reset
always @(posedge ddr_clk_0 or negedge reset_n)
        if (!reset_n)
                rst     <= #1 2'b11;
        else
                rst     <= #1 {rst[0], 1'b0};

always @(posedge ddr_clk_0 or negedge reset_n)
        if (!reset_n)
                reset   <= #1 1'b1;
        else
                reset   <= #1 rst[1];

// -----------------------------------------------------------------------------
// Initialize Term
// DDR初期化中、通常アクセス可能状態の判定に使用
always @(posedge ddr_clk_0 or negedge reset_n)
        if (!reset_n)
                omit    <= #1 1'b1;
        else
                omit    <= #1 ts_omit;

// -----------------------------------------------------------------------------
// Parameter Access
assign pReq             = ts_req;
assign pAddr            = ts_addr;

assign ts_gnt           = pGnt;

// -----------------------------------------------------------------------------
// Master
// パラメータは8Meg×16×8banksの1Gbit DDR3デバイスアクセスに合わせる
master #(32'h03fffff0, 2, 5) master_0 (
        iReq, iGnt, iRxw, iAddr,
        iWrStrb, iWrAck, 1'b0, iWrData, iWrMask,
        iRdStrb, iRdAck, 1'b0, iRdData,
        omit, exec, error,
        reset, ddr_clk_0
        );

// -----------------------------------------------------------------------------
// Body
// RowアドレスはiAddrの13bit目からマッピング
sdc #(13) sdc_0 (
        .iReq                           (iReq),
        .iGnt                           (iGnt),
        .iRxw                           (iRxw),
        .iAddr                          (iAddr),
        .iWrAck                         (iWrAck),
        .iWrData                        (iWrData),
        .iWrMask                        (iWrMask),
        .iRdAck                         (iRdAck),
        .iRdData                        (iRdData),
        .pReq                           (pReq),
        .pGnt                           (pGnt),
        .pAddr                          (pAddr),
        .cs_n                           (sd_cs_n),
        .ras_n                          (sd_ras_n),
        .cas_n                          (sd_cas_n),
        .we_n                           (sd_we_n),
        .addr                           (sd_addr),
        .ba                             (sd_ba),
        .wdvld                          (sd_wdvldt),
        .wdvldd                         (sd_wdvldd),
        .wd                             (sd_wd),
        .wdqm                           (sd_wdqm),
        .rdvld                          (sd_rdvld),
        .rd                             (sd_rd),
        .reg_pACCW                      (reg_pACCW),
        .reg_pACCR                      (reg_pACCR),
        .reg_pCOM                       (reg_pCOM),
        .reg_pFAW                       (reg_pFAW),
        .reg_pRRD                       (reg_pRRD),
        .reg_dTWR                       (reg_dTWR),
        .reg_dTRW                       (reg_dTRW),
        .reg_dWL                        (reg_dWL),
        .reg_dRL                        (reg_dRL),
        .clk                            (ddr_clk_0),
        .clk_n                          (ddr_clk_180),
        .reset_n                        (reset_n)
        );

// -----------------------------------------------------------------------------
// Clock
// ここから先はI/O部品
// デバイスのデータバス幅を16bitに対応
dobuf1 cbuf_0 (
        .datain                         (ddr_clk_0),
        .dataout                        (ddr_clk_p),
        .dataout_b                      (ddr_clk_n)
        );

// -----------------------------------------------------------------------------
// Command Buffer
obuf26 abuf_0 (
        .datain_h                       ({sd_cs_n, sd_ras_n, sd_cas_n, sd_we_n,
                                          sd_cke, sd_ba, sd_addr,
                                          sd_odt, sd_reset_n
                                        }),
        .datain_l                       ({sd_cs_n, sd_ras_n, sd_cas_n, sd_we_n,
                                          sd_cke, sd_ba, sd_addr,
                                          sd_odt, sd_reset_n
                                        }),
        .dataout                        ({ddr_cs_n, ddr_ras_n, ddr_cas_n, ddr_we_n,
                                          ddr_cke, ddr_ba, ddr_addr,
                                          ddr_odt, ddr_reset_n
                                        }),
        .outclock                       (ddr_clk_180)
        );

// -----------------------------------------------------------------------------
// DQM
obuf1 qbuf_0 (
        .datain_h                       (sd_wdqm[0]),
        .datain_l                       (sd_wdqm[2]),
        .dataout                        (ddr_dqm[0]),
        .outclock                       (ddr_clk_270)
        );

obuf1 qbuf_1 (
        .datain_h                       (sd_wdqm[1]),
        .datain_l                       (sd_wdqm[3]),
        .dataout                        (ddr_dqm[1]),
        .outclock                       (ddr_clk_270)
        );

// -----------------------------------------------------------------------------
// DQS
diobuf1 sbuf_0 (
        .datain                         (ddr_dqsout[0]),
        .dataout                        (ddr_dqsin[0]),
        .dataio                         (ddr_dqs_p[0]),
        .dataio_b                       (ddr_dqs_n[0]),
        .oe                             (ddr_dqs_poe[0]),
        .oe_b                           (ddr_dqs_noe[0])
        );

diobuf1 sbuf_1 (
        .datain                         (ddr_dqsout[1]),
        .dataout                        (ddr_dqsin[1]),
        .dataio                         (ddr_dqs_p[1]),
        .dataio_b                       (ddr_dqs_n[1]),
        .oe                             (ddr_dqs_poe[1]),
        .oe_b                           (ddr_dqs_noe[1])
        );

// -----------------------------------------------------------------------------
// Data Lane
// Xilinx Vertex-6 SelectIOリソースを使用したPHYモデル
dlyd dlyd_0 (
        .bidir_dq_input_data_in         (ddr_din[7:0]),
        .bidir_dq_oe_in                 ({8{sd_wdvld}}),
        .bidir_dq_output_data_in_high   (sd_wd[7:0]),
        .bidir_dq_output_data_in_low    (sd_wd[23:16]),
        .dll_delayctrlin                (6'h00),
        .dq_output_reg_clk              (ddr_clk_270),
        .dq_output_reg_clkena           (1'b1),
        .dqs_enable_in                  (sd_rdvld),
        .dqs_input_data_in              (ddr_dqsin[0]),
        .dqs_oe_in                      (sd_wdvld),
        .dqs_output_data_in_high        (sd_wdvldd),
        .dqs_output_data_in_low         (1'b0),
        .dqs_output_reg_clk             (ddr_clk_0),
        .dqs_output_reg_clkena          (1'b1),
        .dqsn_oe_in                     (sd_wdvld),
        .bidir_dq_input_data_out_high   (sd_rd[23:16]),
        .bidir_dq_input_data_out_low    (sd_rd[7:0]),
        .bidir_dq_oe_out                (ddr_oe[7:0]),
        .bidir_dq_output_data_out       (ddr_dout[7:0]),
        .dqs_bus_out                    (ddr_dqs_pbus[0]),
        .dqs_oe_out                     (ddr_dqs_poe[0]),
        .dqs_output_data_out            (ddr_dqsout[0]),
        .dqsn_oe_out                    (ddr_dqs_noe[0])
        );

dlyd dlyd_1 (
        .bidir_dq_input_data_in         (ddr_din[15:8]),
        .bidir_dq_oe_in                 ({8{sd_wdvld}}),
        .bidir_dq_output_data_in_high   (sd_wd[15:8]),
        .bidir_dq_output_data_in_low    (sd_wd[31:24]),
        .dll_delayctrlin                (6'h00),
        .dq_output_reg_clk              (ddr_clk_270),
        .dq_output_reg_clkena           (1'b1),
        .dqs_enable_in                  (sd_rdvld),
        .dqs_input_data_in              (ddr_dqsin[1]),
        .dqs_oe_in                      (sd_wdvld),
        .dqs_output_data_in_high        (sd_wdvldd),
        .dqs_output_data_in_low         (1'b0),
        .dqs_output_reg_clk             (ddr_clk_0),
        .dqs_output_reg_clkena          (1'b1),
        .dqsn_oe_in                     (sd_wdvld),
        .bidir_dq_input_data_out_high   (sd_rd[31:24]),
        .bidir_dq_input_data_out_low    (sd_rd[15:8]),
        .bidir_dq_oe_out                (ddr_oe[15:8]),
        .bidir_dq_output_data_out       (ddr_dout[15:8]),
        .dqs_bus_out                    (ddr_dqs_pbus[1]),
        .dqs_oe_out                     (ddr_dqs_poe[1]),
        .dqs_output_data_out            (ddr_dqsout[1]),
        .dqsn_oe_out                    (ddr_dqs_noe[1])
        );

iobuf8 dbuf_0 (
        .datain                         (ddr_dout[7:0]),
        .oe                             (ddr_oe[7:0]),
        .dataio                         (ddr_dq[7:0]),
        .dataout                        (ddr_din[7:0])
        );

iobuf8 dbuf_1 (
        .datain                         (ddr_dout[15:8]),
        .oe                             (ddr_oe[15:8]),
        .dataio                         (ddr_dq[15:8]),
        .dataout                        (ddr_din[15:8])
        );

// SelectIOリソースでIODELAYを使用する際に必要なコントロールブロック
IDELAYCTRL idelayctrl_inst (
        .REFCLK                         (),             // Default 200MHz
        .RST                            (reset),
        .RDY                            ()
        );

// 実際の実行動作を司るステートマシンとその変数
// プログラムカウンタpc[7:0]の値により実行状態を管理する
// **************************** STATE PARAMETER ********************************

        parameter       IDLE    = 2'b00;
        parameter       WAIT    = 2'b01;
        parameter       REGACS  = 2'b10;

// **************************** FUNCTIONS and TASKS ****************************

       	reg     [1:0]   state;
        reg     [15:0]  count;
        reg     [7:0]   pc;

        wire [REGWD-1:0] current;
        wire [REGWD-1:0] next;

// **************************** STATE DESCRIPTION ******************************

always @(posedge ddr_clk_0 or negedge reset_n)
        if (!reset_n) begin
                count   <= #1 16'h0000;
                pc      <= #1 8'h00;
                state   <= #1 IDLE;
        end
        else
        case (state)
        IDLE: if (current[32])
                        state   <= #1 REGACS;
                else    state   <= #1 WAIT;
        WAIT: if (!next[32] && (count == current[15:0])) begin
                        count   <= #1 16'h0000;
                        pc      <= #1 pc + 8'd1;
                        state   <= #1 WAIT;
                end else
                if (next[32] && (count == current[15:0])) begin
                        count   <= #1 16'h0000;
                        pc      <= #1 pc + 8'd1;
                        state   <= #1 REGACS;
                end else
                begin   count   <= #1 count + 16'd1;
                        state   <= #1 WAIT;
                end
        REGACS: if (ts_gnt && (current[33:32] == 2'b11)) begin
                        pc      <= #1 pc - 8'd1;
                        state   <= #1 WAIT;
                end else
                if (ts_gnt && !next[32]) begin
                        pc      <= #1 pc + 8'd1;
                        state   <= #1 WAIT;
                end else
                if (ts_gnt && next[32]) begin
                        pc      <= #1 pc + 8'd1;
                        state   <= #1 REGACS;
                end else state  <= #1 REGACS;
        endcase

assign          current = Write( pc );
assign          next    = Write( pc + 8'd1 );
assign          ts_req  = (state == REGACS);
assign          ts_addr = (state == REGACS) ? current[31:0] : 32'h00000000;
assign          ts_omit = ~(pc == REFWAIT || pc == REFACS);

// 初期化完了、実行動作中、エラーを表示するLED出力
  OBUF  OBUF_led_i0    (.I (~ts_omit),  .O(led_init));
  OBUF  OBUF_led_i1    (.I (exec[0]),   .O(led_exec[0]));
  OBUF  OBUF_led_i2    (.I (exec[1]),   .O(led_exec[1]));
  OBUF  OBUF_led_i3    (.I (exec[2]),   .O(led_exec[2]));
  OBUF  OBUF_led_i4    (.I (exec[3]),   .O(led_exec[3]));
  OBUF  OBUF_led_i5    (.I (exec[4]),   .O(led_exec[4]));
  OBUF  OBUF_led_i6    (.I (exec[5]),   .O(led_exec[5]));
  OBUF  OBUF_led_i7    (.I (error),     .O(led_err));

// -----------------------------------------------------------------------------
// Initialize SDRAM
// -----------------------------------------------------------------------------
// DDR3:
//      AL=3, CL=5, WR=6, RL=AL+CL=8, WL=AL+CWL=8
//      tRP=5(12.5ns), tRRD=4(10ns), tRFC=44/28000(110ns/70us)
//      tRAS=15(37.5ns), tRC=20(50ns), tWTR=4(10ns), tFAW=20(50ns)
//
//              FAW     = tFAW                  = 20
//              RRD     = tRRD                  = 4
//              CP      = tRFC                  = 44
//              APR     = tRC                   = 20
//                      = tRAS+tRP              = 20
//                      = 2+RL+BL/2+tRP         = 19
//              APW     = tRC                   = 20
//                      = tRAS+tRP              = 20
//                      = 2+WL+BL/2+tRP+WR      = 25
//              RCL     = RL                    = 8
//              WCL     = WL                    = 8
//              TRW     = RL-WL+BL/2+1          = 5
//              TWR     = WL+BL/2-AL+tWTR       = 13
//

// 電源投入直後から実際の処理を実行するファクション
// 初期化終了後はリフレッシュとリフレッシュウェイトを繰り返す
// -----------------------------------------------------------------------------
// Function
// -----------------------------------------------------------------------------
function [REGWD-1:0] Write;
        input   [7:0]	pc;
case (pc)
// reset_nとckeの制御でμオーダーの待機時間は暫定的に短く設定
         0: Write = 34'h000000000;
         1: Write = 34'h100000719;
         2: Write = 34'h100000719;
         3: Write = 34'h100000719;
         4: Write = 34'h100000719;
         5: Write = 34'h100000719;
         6: Write = 34'h100000719;
         7: Write = 34'h100000719;
         8: Write = 34'h100000719;
         9: Write = 34'h100000719;
        10: Write = 34'h100000719;
        11: Write = 34'h100000719;
        12: Write = 34'h100000719;
        13: Write = 34'h100000711;              // (reset inactive)
        14: Write = 34'h100000711;
        15: Write = 34'h100000711;
        16: Write = 34'h100000711;
        17: Write = 34'h100000711;
        18: Write = 34'h100000711;
        19: Write = 34'h100000711;
        20: Write = 34'h100000711;
        21: Write = 34'h100000711;
        22: Write = 34'h100000711;
        23: Write = 34'h100000711;
        24: Write = 34'h100000711;
        25: Write = 34'h100000711;
        26: Write = 34'h100000711;
        27: Write = 34'h100000711;
        28: Write = 34'h100000711;
        29: Write = 34'h100000711;
        30: Write = 34'h100000711;
        31: Write = 34'h100000711;
        32: Write = 34'h100000711;
        33: Write = 34'h000000060;              // (wait)
        34: Write = 34'h100002000;              // (MRS:CWL=5)
        35: Write = 34'h100003000;              // (MR3:0)
        36: Write = 34'h100101000;              // (MRS:AL=CL-2)
        37: Write = 34'h115100000;              // (MRS:DLL on,WR=6,DLL reset,CL=5,BL=8)
        38: Write = 34'h104000300;              // (ZQCL CMD)
        39: Write = 34'h000000200;              // (wait)
        40: Write = 34'h100000400;              // (Refresh)
// リフレッシュウェイト(周期)は実時間で70us必要なので、動作周波数に合わせて変更が必要
// 400MHz時28000なので、28000×175/400=12250
   REFWAIT: Write = 34'h000002fda;              // (Refresh period on 175MHz)
    REFACS: Write = 34'h300000400;              // (Refresh)
   default: Write = 34'h000000000;
endcase

endfunction

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

endmodule

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

I/Oバッファ

/* **************************** MODULE PREAMBLE ********************************

        Copyright (c) 2012, ArchiTek
        This document constitutes confidential and proprietary information
        of ArchiTek. All rights reserved.
*/

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

module obuf1 (
        datain_h, datain_l, outclock, dataout
        );

        input           datain_h;
        input           datain_l;
        output          dataout;
        input           outclock;

// ****************************** MODULE BODY **********************************

ODDR # (
        .DDR_CLK_EDGE                   ("SAME_EDGE"),
        .INIT                           (1'b0),
        .SRTYPE                         ("ASYNC")
        )
    u_dqm_out (
        .Q                              (dataout),
        .C                              (outclock),
        .CE                             (1'b1),
        .D1                             (datain_h),
        .D2                             (datain_l),
        .R                              (1'b0),
        .S                              (1'b0)
        );

endmodule

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

module obuf26 (
        datain_h, datain_l, outclock, dataout
        );

        input   [25:0]  datain_h, datain_l;
        output  [25:0]  dataout;
        input           outclock;

// ****************************** MODULE BODY **********************************

ODDR # (
        .DDR_CLK_EDGE                   ("SAME_EDGE"),
        .INIT                           (1'b0),
        .SRTYPE                         ("ASYNC")
        )
    u_ddr_ctrl_out[25:0] (
        .Q                              (dataout),
        .C                              (outclock),
        .CE                             (1'b1),
        .D1                             (datain_h),
        .D2                             (datain_l),
        .R                              (1'b0),
        .S                              (1'b0)
        );

endmodule

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

module dobuf1 (
        datain, dataout, dataout_b
        );

        input           datain;
        output          dataout;
        output          dataout_b;

// ****************************** MODULE BODY **********************************

ODDR # (
        .DDR_CLK_EDGE                   ("SAME_EDGE"),
        .INIT                           (1'b0),
        .SRTYPE                         ("ASYNC")
        )
    u_clk_p_out (
        .Q                              (dataout),
        .C                              (datain),
        .CE                             (1'b1),
        .D1                             (1'b1),
        .D2                             (1'b0),
        .R                              (1'b0),
        .S                              (1'b0)
        );

ODDR # (
        .DDR_CLK_EDGE                   ("SAME_EDGE"),
        .INIT                           (1'b0),
        .SRTYPE                         ("ASYNC")
        )
    u_clk_p_out (
        .Q                              (dataout_b),
        .C                              (datain),
        .CE                             (1'b1),
        .D1                             (1'b0),
        .D2                             (1'b1),
        .R                              (1'b0),
        .S                              (1'b0)
        );

endmodule

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

module iobuf8 (
        datain, oe, dataio, dataout
        );

        input   [7:0]   datain;
        output  [7:0]   dataout;
        inout   [7:0]   dataio;
        input   [7:0]   oe;

// ****************************** MODULE BODY **********************************

IOBUF u_iobuf_dq[7:0] (
        .I                              (datain),       
        .T                              (~oe),
        .IO                             (dataio),
        .O                              (dataout)
        );

endmodule

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

module diobuf1 (
        datain, dataout, dataio, dataio_b, oe, oe_b
        );

        input           datain;
        output          dataout;
        inout           dataio;
        inout           dataio_b;
        input           oe;
        input           oe_b;

// ****************************** MODULE BODY **********************************

IOBUFDS u_iobuf_dqs (
        .I                              (datain),
        .O                              (dataout),
        .IO                             (dataio),
        .IOB                            (dataio_b),
        .T                              (~oe)
        );

endmodule

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

PHYモデル(RTL)

/* **************************** MODULE PREAMBLE ********************************

        Copyright (c) 2012, ArchiTek
        This document constitutes confidential and proprietary information
        of ArchiTek. All rights reserved.
*/

// ***************************** MODULE HEADER *********************************

module dlyd (
        bidir_dq_input_data_in, bidir_dq_oe_in,
        bidir_dq_output_data_in_high, bidir_dq_output_data_in_low,
        dll_delayctrlin,
        dq_output_reg_clk, dq_output_reg_clkena,
        dqs_enable_in, dqs_input_data_in, dqs_oe_in,
        dqs_output_data_in_high, dqs_output_data_in_low,
        dqs_output_reg_clk, dqs_output_reg_clkena,
        dqsn_oe_in,
        bidir_dq_input_data_out_high, bidir_dq_input_data_out_low,
        bidir_dq_oe_out, bidir_dq_output_data_out,
        dqs_bus_out, dqs_oe_out, dqs_output_data_out, dqsn_oe_out
        );

// **************************** DELAY PARAMETER ********************************

        // リードデータをサンプリングするためのDQS入力遅延パラメータ(1Tap 78ps)
        parameter       DQSDELAY        = 21;           // DQS INPUT DELAY(TAP:0-31)

// *************************** I/O DECLARATIONS ********************************

        input   [7:0]   bidir_dq_input_data_in;
        input   [7:0]   bidir_dq_oe_in;
        input   [7:0]   bidir_dq_output_data_in_high;
        input   [7:0]   bidir_dq_output_data_in_low;
        input   [5:0]   dll_delayctrlin;
        input           dq_output_reg_clk;
        input           dq_output_reg_clkena;
        input           dqs_enable_in;
        input           dqs_input_data_in;
        input           dqs_oe_in;
        input           dqs_output_data_in_high;
        input           dqs_output_data_in_low;
        input           dqs_output_reg_clk;
        input           dqs_output_reg_clkena;
        input           dqsn_oe_in;
        output  [7:0]   bidir_dq_input_data_out_high;
        output  [7:0]   bidir_dq_input_data_out_low;
        output  [7:0]   bidir_dq_oe_out;
        output  [7:0]   bidir_dq_output_data_out;
        output          dqs_bus_out;
        output          dqs_oe_out;
        output          dqs_output_data_out;
        output          dqsn_oe_out;

// ************************** LOCAL DECLARATIONS *******************************

        wire    [7:0]   bidir_dq_input_data_out_high;
        reg     [7:0]   bidir_dq_input_data_out_low;
        wire    [7:0]   dq_data_latch;

        wire            dqs_bus_out;

        wire            dqs_input_delay;
        reg             dqs;
        reg             en;
        reg     [7:0]   doea, doeb;
        reg             soea, soeb;
//      reg             dqs_output_data_out;

// ****************************** MODULE BODY **********************************

// -----------------------------------------------------------------------------
// DQ Input

IDDR # (
        .DDR_CLK_EDGE                   ("OPPOSITE_EDGE"),
        .INIT_Q1                        (1'b0),
        .INIT_Q2                        (1'b0),
        .SRTYPE                         ("ASYNC")
        )
    u_ddr_dq_in[7:0] (
        .Q1                             (dq_data_latch),
        .Q2                             (bidir_dq_input_data_out_high),
        .C                              (dqs_bus_out),
        .CE                             (1'b1),
        .D                              (bidir_dq_input_data_in),
        .R                              (1'b0),
        .S                              (1'b0)
        );

always @(negedge dqs_bus_out)
        bidir_dq_input_data_out_low
                        <= #1 dq_data_latch;

always @(negedge dqs or posedge dqs_enable_in)
        if (dqs_enable_in)
                en      <= #1 1'b1;
        else
                en      <= #1 1'b0;

// DQS入力遅延制御部、遅延値はパラメータ設定
IODELAYE1 # (
        .IDELAY_TYPE                    ("FIXED"),
        .IDELAY_VALUE                   (DQSDELAY),
        )
    iodelay_inst (
        .C                              (1'b0),
        .CE                             (1'b0),
        .DATAIN                         (1'b0),
        .IDATAIN                        (dqs_input_data_in),
        .INC                            (1'b0),
        .ODATAIN                        (1'b0),
        .RST                            (1'b0),
        .T                              (1'b1),
        .DATAOUT                        (dqs_input_delay)
        );

always @(dqs_input_delay)
        dqs             <= #2 dqs_input_delay;

BUFGCE u_bufgce_dqs (
        .O                              (dqs_bus_out),
        .CE                             (en),
        .I                              (dqs)
        );

// -----------------------------------------------------------------------------
// DQ OE
always @(posedge dq_output_reg_clk)
        if (dq_output_reg_clkena)
                doea    <= #1 bidir_dq_oe_in;

always @(negedge dq_output_reg_clk)
        if (dq_output_reg_clkena)
                doeb    <= #1 doea;

assign bidir_dq_oe_out          = {8{doea & doeb}};

// -----------------------------------------------------------------------------
// DQ Out

ODDR # (
        .DDR_CLK_EDGE                   ("SAME_EDGE"),
        .INIT                           (1'b0),
        .SRTYPE                         ("ASYNC")
        )
    u_ddr_dq_out[7:0] (
        .Q                              (bidir_dq_output_data_out),
        .C                              (dq_output_reg_clk),
        .CE                             (dq_output_reg_clkena),
        .D1                             (bidir_dq_output_data_in_high),
        .D2                             (bidir_dq_output_data_in_low),
        .R                              (1'b0),
        .S                              (1'b0)
        );

// -----------------------------------------------------------------------------
// DQS OE
always @(posedge dqs_output_reg_clk)
        if (dqs_output_reg_clkena)
                soea    <= #1 dqs_oe_in;

always @(negedge dqs_output_reg_clk)
        if (dqs_output_reg_clkena)
                soeb    <= #1 soea;

assign dqs_oe_out               = soea;
assign dqsn_oe_out              = soea;

// -----------------------------------------------------------------------------
// DQS Out

ODDR # (
        .DDR_CLK_EDGE                   ("SAME_EDGE"),
        .INIT                           (1'b0),
        .SRTYPE                         ("ASYNC")
        )
    u_ddr_dqs_out (
        .Q                              (dqs_output_data_out),
        .C                              (dqs_output_reg_clk),
        .CE                             (dqs_output_reg_clkena),
        .D1                             (dqs_output_data_in_high),
        .D2                             (dqs_output_data_in_low),
        .R                              (1'b0),
        .S                              (1'b0)
        );

// ************************** FUNCTIONS and TASKS ******************************

endmodule

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

回路デザイン > 設計例 [DDR制御(実装)] > 動作検証2    次のページ(タイミング調整)   このページのTOP ▲