| [10] | 1 | //***************************************************************************** |
|---|
| 2 | // DISCLAIMER OF LIABILITY |
|---|
| 3 | // |
|---|
| 4 | // This file contains proprietary and confidential information of |
|---|
| 5 | // Xilinx, Inc. ("Xilinx"), that is distributed under a license |
|---|
| 6 | // from Xilinx, and may be used, copied and/or disclosed only |
|---|
| 7 | // pursuant to the terms of a valid license agreement with Xilinx. |
|---|
| 8 | // |
|---|
| 9 | // XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION |
|---|
| 10 | // ("MATERIALS") "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER |
|---|
| 11 | // EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING WITHOUT |
|---|
| 12 | // LIMITATION, ANY WARRANTY WITH RESPECT TO NONINFRINGEMENT, |
|---|
| 13 | // MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE. Xilinx |
|---|
| 14 | // does not warrant that functions included in the Materials will |
|---|
| 15 | // meet the requirements of Licensee, or that the operation of the |
|---|
| 16 | // Materials will be uninterrupted or error-free, or that defects |
|---|
| 17 | // in the Materials will be corrected. Furthermore, Xilinx does |
|---|
| 18 | // not warrant or make any representations regarding use, or the |
|---|
| 19 | // results of the use, of the Materials in terms of correctness, |
|---|
| 20 | // accuracy, reliability or otherwise. |
|---|
| 21 | // |
|---|
| 22 | // Xilinx products are not designed or intended to be fail-safe, |
|---|
| 23 | // or for use in any application requiring fail-safe performance, |
|---|
| 24 | // such as life-support or safety devices or systems, Class III |
|---|
| 25 | // medical devices, nuclear facilities, applications related to |
|---|
| 26 | // the deployment of airbags, or any other applications that could |
|---|
| 27 | // lead to death, personal injury or severe property or |
|---|
| 28 | // environmental damage (individually and collectively, "critical |
|---|
| 29 | // applications"). Customer assumes the sole risk and liability |
|---|
| 30 | // of any use of Xilinx products in critical applications, |
|---|
| 31 | // subject only to applicable laws and regulations governing |
|---|
| 32 | // limitations on product liability. |
|---|
| 33 | // |
|---|
| 34 | // Copyright 2007, 2008 Xilinx, Inc. |
|---|
| 35 | // All rights reserved. |
|---|
| 36 | // |
|---|
| 37 | // This disclaimer and copyright notice must be retained as part |
|---|
| 38 | // of this file at all times. |
|---|
| 39 | //***************************************************************************** |
|---|
| 40 | // ____ ____ |
|---|
| 41 | // / /\/ / |
|---|
| 42 | // /___/ \ / Vendor : Xilinx |
|---|
| 43 | // \ \ \/ Version : 3.6 |
|---|
| 44 | // \ \ Application : MIG |
|---|
| 45 | // / / Filename : sim_tb_top.v |
|---|
| 46 | // /___/ /\ Date Last Modified : $Date: 2010/06/29 12:03:42 $ |
|---|
| 47 | // \ \ / \ Date Created : Mon May 14 2007 |
|---|
| 48 | // \___\/\___\ |
|---|
| 49 | // |
|---|
| 50 | // Device : Virtex-5 |
|---|
| 51 | // Design Name : DDR2 |
|---|
| 52 | // Purpose : This is the simulation testbench which is used to verify the |
|---|
| 53 | // design. The basic clocks and resets to the interface are |
|---|
| 54 | // generated here. This also connects the memory interface to the |
|---|
| 55 | // memory model. |
|---|
| 56 | // Reference: |
|---|
| 57 | // Revision History: |
|---|
| 58 | //***************************************************************************** |
|---|
| 59 | |
|---|
| 60 | `timescale 1ns / 1ps |
|---|
| 61 | |
|---|
| 62 | module sim_tb_top; |
|---|
| 63 | |
|---|
| 64 | // memory controller parameters |
|---|
| 65 | parameter BANK_WIDTH = 2; // # of memory bank addr bits |
|---|
| 66 | parameter CKE_WIDTH = 1; // # of memory clock enable outputs |
|---|
| 67 | parameter CLK_WIDTH = 2; // # of clock outputs |
|---|
| 68 | parameter CLK_TYPE = "SINGLE_ENDED"; // # of clock type |
|---|
| 69 | parameter COL_WIDTH = 10; // # of memory column bits |
|---|
| 70 | parameter CS_NUM = 1; // # of separate memory chip selects |
|---|
| 71 | parameter CS_WIDTH = 1; // # of total memory chip selects |
|---|
| 72 | parameter CS_BITS = 0; // set to log2(CS_NUM) (rounded up) |
|---|
| 73 | parameter DM_WIDTH = 8; // # of data mask bits |
|---|
| 74 | parameter DQ_WIDTH = 64; // # of data width |
|---|
| 75 | parameter DQ_PER_DQS = 8; // # of DQ data bits per strobe |
|---|
| 76 | parameter DQS_WIDTH = 8; // # of DQS strobes |
|---|
| 77 | parameter DQ_BITS = 6; // set to log2(DQS_WIDTH*DQ_PER_DQS) |
|---|
| 78 | parameter DQS_BITS = 3; // set to log2(DQS_WIDTH) |
|---|
| 79 | parameter HIGH_PERFORMANCE_MODE = "TRUE"; // Sets the performance mode for IODELAY elements |
|---|
| 80 | parameter ODT_WIDTH = 1; // # of memory on-die term enables |
|---|
| 81 | parameter ROW_WIDTH = 13; // # of memory row & # of addr bits |
|---|
| 82 | parameter APPDATA_WIDTH = 128; // # of usr read/write data bus bits |
|---|
| 83 | parameter ADDITIVE_LAT = 0; // additive write latency |
|---|
| 84 | parameter BURST_LEN = 4; // burst length (in double words) |
|---|
| 85 | parameter BURST_TYPE = 0; // burst type (=0 seq; =1 interlved) |
|---|
| 86 | parameter CAS_LAT = 3; // CAS latency |
|---|
| 87 | parameter ECC_ENABLE = 0; // enable ECC (=1 enable) |
|---|
| 88 | parameter MULTI_BANK_EN = 1; // enable bank management |
|---|
| 89 | parameter TWO_T_TIME_EN = 1; // 2t timing for unbuffered dimms |
|---|
| 90 | parameter ODT_TYPE = 1; // ODT (=0(none),=1(75),=2(150),=3(50)) |
|---|
| 91 | parameter REDUCE_DRV = 0; // reduced strength mem I/O (=1 yes) |
|---|
| 92 | parameter REG_ENABLE = 0; // registered addr/ctrl (=1 yes) |
|---|
| 93 | parameter TREFI_NS = 7800; // auto refresh interval (ns) |
|---|
| 94 | parameter TRAS = 40000; // active->precharge delay |
|---|
| 95 | parameter TRCD = 15000; // active->read/write delay |
|---|
| 96 | parameter TRFC = 105000; // ref->ref, ref->active delay |
|---|
| 97 | parameter TRP = 15000; // precharge->command delay |
|---|
| 98 | parameter TRTP = 7500; // read->precharge delay |
|---|
| 99 | parameter TWR = 15000; // used to determine wr->prech |
|---|
| 100 | parameter TWTR = 7500; // write->read delay |
|---|
| 101 | parameter SIM_ONLY = 1; // = 0 to allow power up delay |
|---|
| 102 | parameter DEBUG_EN = 0; // Enable debug signals/controls |
|---|
| 103 | parameter RST_ACT_LOW = 1; // =1 for active low reset, =0 for active high |
|---|
| 104 | parameter DLL_FREQ_MODE = "HIGH"; // DCM Frequency range |
|---|
| 105 | parameter CLK_PERIOD = 5000; // Core/Mem clk period (in ps) |
|---|
| 106 | |
|---|
| 107 | localparam DEVICE_WIDTH = 16; // Memory device data width |
|---|
| 108 | localparam real CLK_PERIOD_NS = CLK_PERIOD / 1000.0; |
|---|
| 109 | localparam real TCYC_200 = 5.0; |
|---|
| 110 | localparam real TPROP_DQS = 0.01; // Delay for DQS signal during Write Operation |
|---|
| 111 | localparam real TPROP_DQS_RD = 0.01; // Delay for DQS signal during Read Operation |
|---|
| 112 | localparam real TPROP_PCB_CTRL = 0.01; // Delay for Address and Ctrl signals |
|---|
| 113 | localparam real TPROP_PCB_DATA = 0.01; // Delay for data signal during Write operation |
|---|
| 114 | localparam real TPROP_PCB_DATA_RD = 0.01; // Delay for data signal during Read operation |
|---|
| 115 | |
|---|
| 116 | |
|---|
| 117 | reg sys_clk; |
|---|
| 118 | wire sys_clk_n; |
|---|
| 119 | wire sys_clk_p; |
|---|
| 120 | reg sys_clk200; |
|---|
| 121 | wire clk200_n; |
|---|
| 122 | wire clk200_p; |
|---|
| 123 | reg sys_rst_n; |
|---|
| 124 | wire sys_rst_out; |
|---|
| 125 | |
|---|
| 126 | |
|---|
| 127 | wire [DQ_WIDTH-1:0] ddr2_dq_sdram; |
|---|
| 128 | wire [DQS_WIDTH-1:0] ddr2_dqs_sdram; |
|---|
| 129 | wire [DQS_WIDTH-1:0] ddr2_dqs_n_sdram; |
|---|
| 130 | wire [DM_WIDTH-1:0] ddr2_dm_sdram; |
|---|
| 131 | reg [DM_WIDTH-1:0] ddr2_dm_sdram_tmp; |
|---|
| 132 | reg [CLK_WIDTH-1:0] ddr2_clk_sdram; |
|---|
| 133 | reg [CLK_WIDTH-1:0] ddr2_clk_n_sdram; |
|---|
| 134 | reg [ROW_WIDTH-1:0] ddr2_address_sdram; |
|---|
| 135 | reg [BANK_WIDTH-1:0] ddr2_ba_sdram; |
|---|
| 136 | reg ddr2_ras_n_sdram; |
|---|
| 137 | reg ddr2_cas_n_sdram; |
|---|
| 138 | reg ddr2_we_n_sdram; |
|---|
| 139 | reg [CS_WIDTH-1:0] ddr2_cs_n_sdram; |
|---|
| 140 | reg [CKE_WIDTH-1:0] ddr2_cke_sdram; |
|---|
| 141 | reg [ODT_WIDTH-1:0] ddr2_odt_sdram; |
|---|
| 142 | |
|---|
| 143 | |
|---|
| 144 | wire [DQ_WIDTH-1:0] ddr2_dq_fpga; |
|---|
| 145 | wire [DQS_WIDTH-1:0] ddr2_dqs_fpga; |
|---|
| 146 | wire [DQS_WIDTH-1:0] ddr2_dqs_n_fpga; |
|---|
| 147 | wire [DM_WIDTH-1:0] ddr2_dm_fpga; |
|---|
| 148 | wire [CLK_WIDTH-1:0] ddr2_clk_fpga; |
|---|
| 149 | wire [CLK_WIDTH-1:0] ddr2_clk_n_fpga; |
|---|
| 150 | wire [ROW_WIDTH-1:0] ddr2_address_fpga; |
|---|
| 151 | wire [BANK_WIDTH-1:0] ddr2_ba_fpga; |
|---|
| 152 | wire ddr2_ras_n_fpga; |
|---|
| 153 | wire ddr2_cas_n_fpga; |
|---|
| 154 | wire ddr2_we_n_fpga; |
|---|
| 155 | wire [CS_WIDTH-1:0] ddr2_cs_n_fpga; |
|---|
| 156 | wire [CKE_WIDTH-1:0] ddr2_cke_fpga; |
|---|
| 157 | wire [ODT_WIDTH-1:0] ddr2_odt_fpga; |
|---|
| 158 | |
|---|
| 159 | wire error; |
|---|
| 160 | wire phy_init_done; |
|---|
| 161 | |
|---|
| 162 | |
|---|
| 163 | // Only RDIMM memory parts support the reset signal, |
|---|
| 164 | // hence the ddr2_reset_n signal can be ignored for other memory parts |
|---|
| 165 | wire ddr2_reset_n; |
|---|
| 166 | reg [ROW_WIDTH-1:0] ddr2_address_reg; |
|---|
| 167 | reg [BANK_WIDTH-1:0] ddr2_ba_reg; |
|---|
| 168 | reg [CKE_WIDTH-1:0] ddr2_cke_reg; |
|---|
| 169 | reg ddr2_ras_n_reg; |
|---|
| 170 | reg ddr2_cas_n_reg; |
|---|
| 171 | reg ddr2_we_n_reg; |
|---|
| 172 | reg [CS_WIDTH-1:0] ddr2_cs_n_reg; |
|---|
| 173 | reg [ODT_WIDTH-1:0] ddr2_odt_reg; |
|---|
| 174 | |
|---|
| 175 | //*************************************************************************** |
|---|
| 176 | // Clock generation and reset |
|---|
| 177 | //*************************************************************************** |
|---|
| 178 | |
|---|
| 179 | initial |
|---|
| 180 | sys_clk = 1'b0; |
|---|
| 181 | always |
|---|
| 182 | sys_clk = #(CLK_PERIOD_NS/2) ~sys_clk; |
|---|
| 183 | |
|---|
| 184 | assign sys_clk_p = sys_clk; |
|---|
| 185 | assign sys_clk_n = ~sys_clk; |
|---|
| 186 | |
|---|
| 187 | initial |
|---|
| 188 | sys_clk200 = 1'b0; |
|---|
| 189 | always |
|---|
| 190 | sys_clk200 = #(TCYC_200/2) ~sys_clk200; |
|---|
| 191 | |
|---|
| 192 | assign clk200_p = sys_clk200; |
|---|
| 193 | assign clk200_n = ~sys_clk200; |
|---|
| 194 | |
|---|
| 195 | initial begin |
|---|
| 196 | sys_rst_n = 1'b0; |
|---|
| 197 | #200; |
|---|
| 198 | sys_rst_n = 1'b1; |
|---|
| 199 | end |
|---|
| 200 | assign sys_rst_out = RST_ACT_LOW ? sys_rst_n : ~sys_rst_n; |
|---|
| 201 | |
|---|
| 202 | |
|---|
| 203 | |
|---|
| 204 | |
|---|
| 205 | // ============================================================================= |
|---|
| 206 | // BOARD Parameters |
|---|
| 207 | // ============================================================================= |
|---|
| 208 | // These parameter values can be changed to model varying board delays |
|---|
| 209 | // between the Virtex-5 device and the memory model |
|---|
| 210 | |
|---|
| 211 | |
|---|
| 212 | always @( * ) begin |
|---|
| 213 | ddr2_clk_sdram <= #(TPROP_PCB_CTRL) ddr2_clk_fpga; |
|---|
| 214 | ddr2_clk_n_sdram <= #(TPROP_PCB_CTRL) ddr2_clk_n_fpga; |
|---|
| 215 | ddr2_address_sdram <= #(TPROP_PCB_CTRL) ddr2_address_fpga; |
|---|
| 216 | ddr2_ba_sdram <= #(TPROP_PCB_CTRL) ddr2_ba_fpga; |
|---|
| 217 | ddr2_ras_n_sdram <= #(TPROP_PCB_CTRL) ddr2_ras_n_fpga; |
|---|
| 218 | ddr2_cas_n_sdram <= #(TPROP_PCB_CTRL) ddr2_cas_n_fpga; |
|---|
| 219 | ddr2_we_n_sdram <= #(TPROP_PCB_CTRL) ddr2_we_n_fpga; |
|---|
| 220 | ddr2_cs_n_sdram <= #(TPROP_PCB_CTRL) ddr2_cs_n_fpga; |
|---|
| 221 | ddr2_cke_sdram <= #(TPROP_PCB_CTRL) ddr2_cke_fpga; |
|---|
| 222 | ddr2_odt_sdram <= #(TPROP_PCB_CTRL) ddr2_odt_fpga; |
|---|
| 223 | ddr2_dm_sdram_tmp <= #(TPROP_PCB_DATA) ddr2_dm_fpga;//DM signal generation |
|---|
| 224 | end |
|---|
| 225 | |
|---|
| 226 | assign ddr2_dm_sdram = ddr2_dm_sdram_tmp; |
|---|
| 227 | |
|---|
| 228 | |
|---|
| 229 | // Controlling the bi-directional BUS |
|---|
| 230 | genvar dqwd; |
|---|
| 231 | generate |
|---|
| 232 | for (dqwd = 0;dqwd < DQ_WIDTH;dqwd = dqwd+1) begin : dq_delay |
|---|
| 233 | WireDelay # |
|---|
| 234 | ( |
|---|
| 235 | .Delay_g (TPROP_PCB_DATA), |
|---|
| 236 | .Delay_rd (TPROP_PCB_DATA_RD) |
|---|
| 237 | ) |
|---|
| 238 | u_delay_dq |
|---|
| 239 | ( |
|---|
| 240 | .A (ddr2_dq_fpga[dqwd]), |
|---|
| 241 | .B (ddr2_dq_sdram[dqwd]), |
|---|
| 242 | .reset (sys_rst_n) |
|---|
| 243 | ); |
|---|
| 244 | end |
|---|
| 245 | endgenerate |
|---|
| 246 | |
|---|
| 247 | genvar dqswd; |
|---|
| 248 | generate |
|---|
| 249 | for (dqswd = 0;dqswd < DQS_WIDTH;dqswd = dqswd+1) begin : dqs_delay |
|---|
| 250 | WireDelay # |
|---|
| 251 | ( |
|---|
| 252 | .Delay_g (TPROP_DQS), |
|---|
| 253 | .Delay_rd (TPROP_DQS_RD) |
|---|
| 254 | ) |
|---|
| 255 | u_delay_dqs |
|---|
| 256 | ( |
|---|
| 257 | .A (ddr2_dqs_fpga[dqswd]), |
|---|
| 258 | .B (ddr2_dqs_sdram[dqswd]), |
|---|
| 259 | .reset (sys_rst_n) |
|---|
| 260 | ); |
|---|
| 261 | |
|---|
| 262 | WireDelay # |
|---|
| 263 | ( |
|---|
| 264 | .Delay_g (TPROP_DQS), |
|---|
| 265 | .Delay_rd (TPROP_DQS_RD) |
|---|
| 266 | ) |
|---|
| 267 | u_delay_dqs_n |
|---|
| 268 | ( |
|---|
| 269 | .A (ddr2_dqs_n_fpga[dqswd]), |
|---|
| 270 | .B (ddr2_dqs_n_sdram[dqswd]), |
|---|
| 271 | .reset (sys_rst_n) |
|---|
| 272 | ); |
|---|
| 273 | end |
|---|
| 274 | endgenerate |
|---|
| 275 | |
|---|
| 276 | |
|---|
| 277 | |
|---|
| 278 | //*************************************************************************** |
|---|
| 279 | // FPGA memory controller |
|---|
| 280 | //*************************************************************************** |
|---|
| 281 | |
|---|
| 282 | dram # |
|---|
| 283 | ( |
|---|
| 284 | .BANK_WIDTH (BANK_WIDTH), |
|---|
| 285 | .CKE_WIDTH (CKE_WIDTH), |
|---|
| 286 | .CLK_WIDTH (CLK_WIDTH), |
|---|
| 287 | .COL_WIDTH (COL_WIDTH), |
|---|
| 288 | .CS_NUM (CS_NUM), |
|---|
| 289 | .CS_WIDTH (CS_WIDTH), |
|---|
| 290 | .CS_BITS (CS_BITS), |
|---|
| [22] | 291 | .DM_WIDTH (DM_WIDTH), |
|---|
| [10] | 292 | .DQ_WIDTH (DQ_WIDTH), |
|---|
| 293 | .DQ_PER_DQS (DQ_PER_DQS), |
|---|
| 294 | .DQ_BITS (DQ_BITS), |
|---|
| 295 | .DQS_WIDTH (DQS_WIDTH), |
|---|
| 296 | .DQS_BITS (DQS_BITS), |
|---|
| 297 | .HIGH_PERFORMANCE_MODE (HIGH_PERFORMANCE_MODE), |
|---|
| 298 | .ODT_WIDTH (ODT_WIDTH), |
|---|
| 299 | .ROW_WIDTH (ROW_WIDTH), |
|---|
| 300 | .APPDATA_WIDTH (APPDATA_WIDTH), |
|---|
| 301 | .ADDITIVE_LAT (ADDITIVE_LAT), |
|---|
| 302 | .BURST_LEN (BURST_LEN), |
|---|
| 303 | .BURST_TYPE (BURST_TYPE), |
|---|
| 304 | .CAS_LAT (CAS_LAT), |
|---|
| 305 | .ECC_ENABLE (ECC_ENABLE), |
|---|
| 306 | .MULTI_BANK_EN (MULTI_BANK_EN), |
|---|
| 307 | .ODT_TYPE (ODT_TYPE), |
|---|
| 308 | .REDUCE_DRV (REDUCE_DRV), |
|---|
| 309 | .REG_ENABLE (REG_ENABLE), |
|---|
| 310 | .TREFI_NS (TREFI_NS), |
|---|
| 311 | .TRAS (TRAS), |
|---|
| 312 | .TRCD (TRCD), |
|---|
| 313 | .TRFC (TRFC), |
|---|
| 314 | .TRP (TRP), |
|---|
| 315 | .TRTP (TRTP), |
|---|
| 316 | .TWR (TWR), |
|---|
| 317 | .TWTR (TWTR), |
|---|
| 318 | .SIM_ONLY (SIM_ONLY), |
|---|
| 319 | .RST_ACT_LOW (RST_ACT_LOW), |
|---|
| [22] | 320 | .CLK_TYPE (CLK_TYPE), |
|---|
| 321 | .DLL_FREQ_MODE (DLL_FREQ_MODE), |
|---|
| [10] | 322 | .CLK_PERIOD (CLK_PERIOD) |
|---|
| 323 | ) |
|---|
| 324 | u_mem_controller |
|---|
| 325 | ( |
|---|
| 326 | .sys_clk (sys_clk_p), |
|---|
| 327 | .idly_clk_200 (clk200_p), |
|---|
| 328 | .sys_rst_n (sys_rst_out), |
|---|
| 329 | .ddr2_ras_n (ddr2_ras_n_fpga), |
|---|
| 330 | .ddr2_cas_n (ddr2_cas_n_fpga), |
|---|
| 331 | .ddr2_we_n (ddr2_we_n_fpga), |
|---|
| 332 | .ddr2_cs_n (ddr2_cs_n_fpga), |
|---|
| 333 | .ddr2_cke (ddr2_cke_fpga), |
|---|
| 334 | .ddr2_odt (ddr2_odt_fpga), |
|---|
| 335 | .ddr2_dm (ddr2_dm_fpga), |
|---|
| 336 | .ddr2_dq (ddr2_dq_fpga), |
|---|
| 337 | .ddr2_dqs (ddr2_dqs_fpga), |
|---|
| 338 | .ddr2_dqs_n (ddr2_dqs_n_fpga), |
|---|
| 339 | .ddr2_ck (ddr2_clk_fpga), |
|---|
| 340 | .ddr2_ck_n (ddr2_clk_n_fpga), |
|---|
| 341 | .ddr2_ba (ddr2_ba_fpga), |
|---|
| 342 | .ddr2_a (ddr2_address_fpga), |
|---|
| [22] | 343 | //.error (error), |
|---|
| [10] | 344 | |
|---|
| 345 | |
|---|
| 346 | .phy_init_done (phy_init_done) |
|---|
| 347 | ); |
|---|
| 348 | |
|---|
| 349 | // Extra one clock pipelining for RDIMM address and |
|---|
| 350 | // control signals is implemented here (Implemented external to memory model) |
|---|
| 351 | always @( posedge ddr2_clk_sdram[0] ) begin |
|---|
| 352 | if ( ddr2_reset_n == 1'b0 ) begin |
|---|
| 353 | ddr2_ras_n_reg <= 1'b1; |
|---|
| 354 | ddr2_cas_n_reg <= 1'b1; |
|---|
| 355 | ddr2_we_n_reg <= 1'b1; |
|---|
| 356 | ddr2_cs_n_reg <= {CS_WIDTH{1'b1}}; |
|---|
| 357 | ddr2_odt_reg <= 1'b0; |
|---|
| 358 | end |
|---|
| 359 | else begin |
|---|
| 360 | ddr2_address_reg <= #(CLK_PERIOD_NS/2) ddr2_address_sdram; |
|---|
| 361 | ddr2_ba_reg <= #(CLK_PERIOD_NS/2) ddr2_ba_sdram; |
|---|
| 362 | ddr2_ras_n_reg <= #(CLK_PERIOD_NS/2) ddr2_ras_n_sdram; |
|---|
| 363 | ddr2_cas_n_reg <= #(CLK_PERIOD_NS/2) ddr2_cas_n_sdram; |
|---|
| 364 | ddr2_we_n_reg <= #(CLK_PERIOD_NS/2) ddr2_we_n_sdram; |
|---|
| 365 | ddr2_cs_n_reg <= #(CLK_PERIOD_NS/2) ddr2_cs_n_sdram; |
|---|
| 366 | ddr2_odt_reg <= #(CLK_PERIOD_NS/2) ddr2_odt_sdram; |
|---|
| 367 | end |
|---|
| 368 | end |
|---|
| 369 | |
|---|
| 370 | // to avoid tIS violations on CKE when reset is deasserted |
|---|
| 371 | always @( posedge ddr2_clk_n_sdram[0] ) |
|---|
| 372 | if ( ddr2_reset_n == 1'b0 ) |
|---|
| 373 | ddr2_cke_reg <= 1'b0; |
|---|
| 374 | else |
|---|
| 375 | ddr2_cke_reg <= #(CLK_PERIOD_NS) ddr2_cke_sdram; |
|---|
| 376 | |
|---|
| 377 | //*************************************************************************** |
|---|
| 378 | // Memory model instances |
|---|
| 379 | //*************************************************************************** |
|---|
| 380 | |
|---|
| 381 | genvar i, j; |
|---|
| 382 | generate |
|---|
| 383 | if (DEVICE_WIDTH == 16) begin |
|---|
| 384 | // if memory part is x16 |
|---|
| 385 | if ( REG_ENABLE ) begin |
|---|
| 386 | // if the memory part is Registered DIMM |
|---|
| 387 | for(j = 0; j < CS_NUM; j = j+1) begin : gen_cs |
|---|
| 388 | for(i = 0; i < DQS_WIDTH/2; i = i+1) begin : gen |
|---|
| 389 | ddr2_model u_mem0 |
|---|
| 390 | ( |
|---|
| 391 | .ck (ddr2_clk_sdram[CLK_WIDTH*i/DQS_WIDTH]), |
|---|
| 392 | .ck_n (ddr2_clk_n_sdram[CLK_WIDTH*i/DQS_WIDTH]), |
|---|
| 393 | .cke (ddr2_cke_reg[j]), |
|---|
| 394 | .cs_n (ddr2_cs_n_reg[CS_WIDTH*i/DQS_WIDTH]), |
|---|
| 395 | .ras_n (ddr2_ras_n_reg), |
|---|
| 396 | .cas_n (ddr2_cas_n_reg), |
|---|
| 397 | .we_n (ddr2_we_n_reg), |
|---|
| 398 | .dm_rdqs (ddr2_dm_sdram[(2*(i+1))-1 : i*2]), |
|---|
| 399 | .ba (ddr2_ba_reg), |
|---|
| 400 | .addr (ddr2_address_reg), |
|---|
| 401 | .dq (ddr2_dq_sdram[(16*(i+1))-1 : i*16]), |
|---|
| 402 | .dqs (ddr2_dqs_sdram[(2*(i+1))-1 : i*2]), |
|---|
| 403 | .dqs_n (ddr2_dqs_n_sdram[(2*(i+1))-1 : i*2]), |
|---|
| 404 | .rdqs_n (), |
|---|
| 405 | .odt (ddr2_odt_reg[ODT_WIDTH*i/DQS_WIDTH]) |
|---|
| 406 | ); |
|---|
| 407 | end |
|---|
| 408 | end |
|---|
| 409 | end |
|---|
| 410 | else begin |
|---|
| 411 | // if the memory part is component or unbuffered DIMM |
|---|
| 412 | if ( DQ_WIDTH%16 ) begin |
|---|
| 413 | // for the memory part x16, if the data width is not multiple |
|---|
| 414 | // of 16, memory models are instantiated for all data with x16 |
|---|
| 415 | // memory model and except for MSB data. For the MSB data |
|---|
| 416 | // of 8 bits, all memory data, strobe and mask data signals are |
|---|
| 417 | // replicated to make it as x16 part. For example if the design |
|---|
| 418 | // is generated for data width of 72, memory model x16 parts |
|---|
| 419 | // instantiated for 4 times with data ranging from 0 to 63. |
|---|
| 420 | // For MSB data ranging from 64 to 71, one x16 memory model |
|---|
| 421 | // by replicating the 8-bit data twice and similarly |
|---|
| 422 | // the case with data mask and strobe. |
|---|
| 423 | for(j = 0; j < CS_NUM; j = j+1) begin : gen_cs |
|---|
| 424 | for(i = 0; i < DQ_WIDTH/16 ; i = i+1) begin : gen |
|---|
| 425 | ddr2_model u_mem0 |
|---|
| 426 | ( |
|---|
| 427 | .ck (ddr2_clk_sdram[CLK_WIDTH*i/DQS_WIDTH]), |
|---|
| 428 | .ck_n (ddr2_clk_n_sdram[CLK_WIDTH*i/DQS_WIDTH]), |
|---|
| 429 | .cke (ddr2_cke_sdram[j]), |
|---|
| 430 | .cs_n (ddr2_cs_n_sdram[CS_WIDTH*i/DQS_WIDTH]), |
|---|
| 431 | .ras_n (ddr2_ras_n_sdram), |
|---|
| 432 | .cas_n (ddr2_cas_n_sdram), |
|---|
| 433 | .we_n (ddr2_we_n_sdram), |
|---|
| 434 | .dm_rdqs (ddr2_dm_sdram[(2*(i+1))-1 : i*2]), |
|---|
| 435 | .ba (ddr2_ba_sdram), |
|---|
| 436 | .addr (ddr2_address_sdram), |
|---|
| 437 | .dq (ddr2_dq_sdram[(16*(i+1))-1 : i*16]), |
|---|
| 438 | .dqs (ddr2_dqs_sdram[(2*(i+1))-1 : i*2]), |
|---|
| 439 | .dqs_n (ddr2_dqs_n_sdram[(2*(i+1))-1 : i*2]), |
|---|
| 440 | .rdqs_n (), |
|---|
| 441 | .odt (ddr2_odt_sdram[ODT_WIDTH*i/DQS_WIDTH]) |
|---|
| 442 | ); |
|---|
| 443 | end |
|---|
| 444 | ddr2_model u_mem1 |
|---|
| 445 | ( |
|---|
| 446 | .ck (ddr2_clk_sdram[CLK_WIDTH-1]), |
|---|
| 447 | .ck_n (ddr2_clk_n_sdram[CLK_WIDTH-1]), |
|---|
| 448 | .cke (ddr2_cke_sdram[j]), |
|---|
| 449 | .cs_n (ddr2_cs_n_sdram[CS_WIDTH-1]), |
|---|
| 450 | .ras_n (ddr2_ras_n_sdram), |
|---|
| 451 | .cas_n (ddr2_cas_n_sdram), |
|---|
| 452 | .we_n (ddr2_we_n_sdram), |
|---|
| 453 | .dm_rdqs ({ddr2_dm_sdram[DM_WIDTH - 1], |
|---|
| 454 | ddr2_dm_sdram[DM_WIDTH - 1]}), |
|---|
| 455 | .ba (ddr2_ba_sdram), |
|---|
| 456 | .addr (ddr2_address_sdram), |
|---|
| 457 | .dq ({ddr2_dq_sdram[DQ_WIDTH - 1 : DQ_WIDTH - 8], |
|---|
| 458 | ddr2_dq_sdram[DQ_WIDTH - 1 : DQ_WIDTH - 8]}), |
|---|
| 459 | .dqs ({ddr2_dqs_sdram[DQS_WIDTH - 1], |
|---|
| 460 | ddr2_dqs_sdram[DQS_WIDTH - 1]}), |
|---|
| 461 | .dqs_n ({ddr2_dqs_n_sdram[DQS_WIDTH - 1], |
|---|
| 462 | ddr2_dqs_n_sdram[DQS_WIDTH - 1]}), |
|---|
| 463 | .rdqs_n (), |
|---|
| 464 | .odt (ddr2_odt_sdram[ODT_WIDTH-1]) |
|---|
| 465 | ); |
|---|
| 466 | end |
|---|
| 467 | end |
|---|
| 468 | else begin |
|---|
| 469 | // if the data width is multiple of 16 |
|---|
| 470 | for(j = 0; j < CS_NUM; j = j+1) begin : gen_cs |
|---|
| 471 | for(i = 0; i < DQS_WIDTH/2; i = i+1) begin : gen |
|---|
| 472 | ddr2_model u_mem0 |
|---|
| 473 | ( |
|---|
| 474 | .ck (ddr2_clk_sdram[CLK_WIDTH*i/DQS_WIDTH]), |
|---|
| 475 | .ck_n (ddr2_clk_n_sdram[CLK_WIDTH*i/DQS_WIDTH]), |
|---|
| 476 | .cke (ddr2_cke_sdram[j]), |
|---|
| 477 | .cs_n (ddr2_cs_n_sdram[CS_WIDTH*i/DQS_WIDTH]), |
|---|
| 478 | .ras_n (ddr2_ras_n_sdram), |
|---|
| 479 | .cas_n (ddr2_cas_n_sdram), |
|---|
| 480 | .we_n (ddr2_we_n_sdram), |
|---|
| 481 | .dm_rdqs (ddr2_dm_sdram[(2*(i+1))-1 : i*2]), |
|---|
| 482 | .ba (ddr2_ba_sdram), |
|---|
| 483 | .addr (ddr2_address_sdram), |
|---|
| 484 | .dq (ddr2_dq_sdram[(16*(i+1))-1 : i*16]), |
|---|
| 485 | .dqs (ddr2_dqs_sdram[(2*(i+1))-1 : i*2]), |
|---|
| 486 | .dqs_n (ddr2_dqs_n_sdram[(2*(i+1))-1 : i*2]), |
|---|
| 487 | .rdqs_n (), |
|---|
| 488 | .odt (ddr2_odt_sdram[ODT_WIDTH*i/DQS_WIDTH]) |
|---|
| 489 | ); |
|---|
| 490 | end |
|---|
| 491 | end |
|---|
| 492 | end |
|---|
| 493 | end |
|---|
| 494 | |
|---|
| 495 | end else |
|---|
| 496 | if (DEVICE_WIDTH == 8) begin |
|---|
| 497 | // if the memory part is x8 |
|---|
| 498 | if ( REG_ENABLE ) begin |
|---|
| 499 | // if the memory part is Registered DIMM |
|---|
| 500 | for(j = 0; j < CS_NUM; j = j+1) begin : gen_cs |
|---|
| 501 | for(i = 0; i < DQ_WIDTH/DQ_PER_DQS; i = i+1) begin : gen |
|---|
| 502 | ddr2_model u_mem0 |
|---|
| 503 | ( |
|---|
| 504 | .ck (ddr2_clk_sdram[CLK_WIDTH*i/DQS_WIDTH]), |
|---|
| 505 | .ck_n (ddr2_clk_n_sdram[CLK_WIDTH*i/DQS_WIDTH]), |
|---|
| 506 | .cke (ddr2_cke_reg[j]), |
|---|
| 507 | .cs_n (ddr2_cs_n_reg[CS_WIDTH*i/DQS_WIDTH]), |
|---|
| 508 | .ras_n (ddr2_ras_n_reg), |
|---|
| 509 | .cas_n (ddr2_cas_n_reg), |
|---|
| 510 | .we_n (ddr2_we_n_reg), |
|---|
| 511 | .dm_rdqs (ddr2_dm_sdram[i]), |
|---|
| 512 | .ba (ddr2_ba_reg), |
|---|
| 513 | .addr (ddr2_address_reg), |
|---|
| 514 | .dq (ddr2_dq_sdram[(8*(i+1))-1 : i*8]), |
|---|
| 515 | .dqs (ddr2_dqs_sdram[i]), |
|---|
| 516 | .dqs_n (ddr2_dqs_n_sdram[i]), |
|---|
| 517 | .rdqs_n (), |
|---|
| 518 | .odt (ddr2_odt_reg[ODT_WIDTH*i/DQS_WIDTH]) |
|---|
| 519 | ); |
|---|
| 520 | end |
|---|
| 521 | end |
|---|
| 522 | end |
|---|
| 523 | else begin |
|---|
| 524 | // if the memory part is component or unbuffered DIMM |
|---|
| 525 | for(j = 0; j < CS_NUM; j = j+1) begin : gen_cs |
|---|
| 526 | for(i = 0; i < DQS_WIDTH; i = i+1) begin : gen |
|---|
| 527 | ddr2_model u_mem0 |
|---|
| 528 | ( |
|---|
| 529 | .ck (ddr2_clk_sdram[CLK_WIDTH*i/DQS_WIDTH]), |
|---|
| 530 | .ck_n (ddr2_clk_n_sdram[CLK_WIDTH*i/DQS_WIDTH]), |
|---|
| 531 | .cke (ddr2_cke_sdram[j]), |
|---|
| 532 | .cs_n (ddr2_cs_n_sdram[CS_WIDTH*i/DQS_WIDTH]), |
|---|
| 533 | .ras_n (ddr2_ras_n_sdram), |
|---|
| 534 | .cas_n (ddr2_cas_n_sdram), |
|---|
| 535 | .we_n (ddr2_we_n_sdram), |
|---|
| 536 | .dm_rdqs (ddr2_dm_sdram[i]), |
|---|
| 537 | .ba (ddr2_ba_sdram), |
|---|
| 538 | .addr (ddr2_address_sdram), |
|---|
| 539 | .dq (ddr2_dq_sdram[(8*(i+1))-1 : i*8]), |
|---|
| 540 | .dqs (ddr2_dqs_sdram[i]), |
|---|
| 541 | .dqs_n (ddr2_dqs_n_sdram[i]), |
|---|
| 542 | .rdqs_n (), |
|---|
| 543 | .odt (ddr2_odt_sdram[ODT_WIDTH*i/DQS_WIDTH]) |
|---|
| 544 | ); |
|---|
| 545 | end |
|---|
| 546 | end |
|---|
| 547 | end |
|---|
| 548 | |
|---|
| 549 | end else |
|---|
| 550 | if (DEVICE_WIDTH == 4) begin |
|---|
| 551 | // if the memory part is x4 |
|---|
| 552 | if ( REG_ENABLE ) begin |
|---|
| 553 | // if the memory part is Registered DIMM |
|---|
| 554 | for(j = 0; j < CS_NUM; j = j+1) begin : gen_cs |
|---|
| 555 | for(i = 0; i < DQS_WIDTH; i = i+1) begin : gen |
|---|
| 556 | ddr2_model u_mem0 |
|---|
| 557 | ( |
|---|
| 558 | .ck (ddr2_clk_sdram[CLK_WIDTH*i/DQS_WIDTH]), |
|---|
| 559 | .ck_n (ddr2_clk_n_sdram[CLK_WIDTH*i/DQS_WIDTH]), |
|---|
| 560 | .cke (ddr2_cke_reg[j]), |
|---|
| 561 | .cs_n (ddr2_cs_n_reg[CS_WIDTH*i/DQS_WIDTH]), |
|---|
| 562 | .ras_n (ddr2_ras_n_reg), |
|---|
| 563 | .cas_n (ddr2_cas_n_reg), |
|---|
| 564 | .we_n (ddr2_we_n_reg), |
|---|
| 565 | .dm_rdqs (ddr2_dm_sdram[i]), |
|---|
| 566 | .ba (ddr2_ba_reg), |
|---|
| 567 | .addr (ddr2_address_reg), |
|---|
| 568 | .dq (ddr2_dq_sdram[(4*(i+1))-1 : i*4]), |
|---|
| 569 | .dqs (ddr2_dqs_sdram[i]), |
|---|
| 570 | .dqs_n (ddr2_dqs_n_sdram[i]), |
|---|
| 571 | .rdqs_n (), |
|---|
| 572 | .odt (ddr2_odt_reg[ODT_WIDTH*i/DQS_WIDTH]) |
|---|
| 573 | ); |
|---|
| 574 | end |
|---|
| 575 | end |
|---|
| 576 | end |
|---|
| 577 | else begin |
|---|
| 578 | // if the memory part is component or unbuffered DIMM |
|---|
| 579 | for(j = 0; j < CS_NUM; j = j+1) begin : gen_cs |
|---|
| 580 | for(i = 0; i < DQS_WIDTH; i = i+1) begin : gen |
|---|
| 581 | ddr2_model u_mem0 |
|---|
| 582 | ( |
|---|
| 583 | .ck (ddr2_clk_sdram[CLK_WIDTH*i/DQS_WIDTH]), |
|---|
| 584 | .ck_n (ddr2_clk_n_sdram[CLK_WIDTH*i/DQS_WIDTH]), |
|---|
| 585 | .cke (ddr2_cke_sdram[j]), |
|---|
| 586 | .cs_n (ddr2_cs_n_sdram[CS_WIDTH*i/DQS_WIDTH]), |
|---|
| 587 | .ras_n (ddr2_ras_n_sdram), |
|---|
| 588 | .cas_n (ddr2_cas_n_sdram), |
|---|
| 589 | .we_n (ddr2_we_n_sdram), |
|---|
| 590 | .dm_rdqs (ddr2_dm_sdram[i]), |
|---|
| 591 | .ba (ddr2_ba_sdram), |
|---|
| 592 | .addr (ddr2_address_sdram), |
|---|
| 593 | .dq (ddr2_dq_sdram[(4*(i+1))-1 : i*4]), |
|---|
| 594 | .dqs (ddr2_dqs_sdram[i]), |
|---|
| 595 | .dqs_n (ddr2_dqs_n_sdram[i]), |
|---|
| 596 | .rdqs_n (), |
|---|
| 597 | .odt (ddr2_odt_sdram[ODT_WIDTH*i/DQS_WIDTH]) |
|---|
| 598 | ); |
|---|
| 599 | end |
|---|
| 600 | end |
|---|
| 601 | end |
|---|
| 602 | end |
|---|
| 603 | endgenerate |
|---|
| 604 | |
|---|
| 605 | |
|---|
| 606 | endmodule |
|---|