論理回路デザイン |
|
/* **************************** 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 // *****************************************************************************
/* **************************** 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 // *****************************************************************************
/* **************************** 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 ▲