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 2006, 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.vhd |
---|
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 | library ieee; |
---|
61 | use ieee.std_logic_1164.all; |
---|
62 | use ieee.numeric_std.all; |
---|
63 | library unisim; |
---|
64 | use unisim.vcomponents.all; |
---|
65 | |
---|
66 | entity sim_tb_top is |
---|
67 | |
---|
68 | end entity sim_tb_top; |
---|
69 | |
---|
70 | architecture arch of sim_tb_top is |
---|
71 | |
---|
72 | -- memory controller parameters |
---|
73 | constant BANK_WIDTH : integer := 2; -- # of memory bank addr bits |
---|
74 | constant CKE_WIDTH : integer := 1; -- # of memory clock enable outputs |
---|
75 | constant CLK_WIDTH : integer := 1; -- # of clock outputs |
---|
76 | constant CLK_TYPE : string := "SINGLE_ENDED"; -- # of clock type |
---|
77 | constant COL_WIDTH : integer := 10; -- # of memory column bits |
---|
78 | constant CS_NUM : integer := 1; -- # of separate memory chip selects |
---|
79 | constant CS_WIDTH : integer := 1; -- # of total memory chip selects |
---|
80 | constant CS_BITS : integer := 0; -- set to log2(CS_NUM) (rounded up) |
---|
81 | constant DM_WIDTH : integer := 9; -- # of data mask bits |
---|
82 | constant DQ_WIDTH : integer := 72; -- # of data width |
---|
83 | constant DQ_PER_DQS : integer := 8; -- # of DQ data bits per strobe |
---|
84 | constant DQ_BITS : integer := 7; -- set to log2(DQS_WIDTH*DQ_PER_DQS) |
---|
85 | constant DQS_WIDTH : integer := 9; -- # of DQS strobes |
---|
86 | constant DQS_BITS : integer := 4; -- set to log2(DQS_WIDTH) |
---|
87 | constant HIGH_PERFORMANCE_MODE : boolean := TRUE; -- Sets the performance mode for IODELAY elements |
---|
88 | constant ODT_WIDTH : integer := 1; -- # of memory on-die term enables |
---|
89 | constant ROW_WIDTH : integer := 14; -- # of memory row & # of addr bits |
---|
90 | constant APPDATA_WIDTH : integer := 144; -- # of usr read/write data bus bits |
---|
91 | constant ADDITIVE_LAT : integer := 0; -- additive write latency |
---|
92 | constant BURST_LEN : integer := 4; -- burst length (in double words) |
---|
93 | constant BURST_TYPE : integer := 0; -- burst type (=0 seq; =1 interlved) |
---|
94 | constant CAS_LAT : integer := 3; -- CAS latency |
---|
95 | constant ECC_ENABLE : integer := 0; -- enable ECC (=1 enable) |
---|
96 | constant MULTI_BANK_EN : integer := 1; -- enable bank management |
---|
97 | constant TWO_T_TIME_EN : integer := 1; -- 2t timing for unbuffered dimms |
---|
98 | constant ODT_TYPE : integer := 1; -- ODT (=0(none),=1(75),=2(150),=3(50)) |
---|
99 | constant REDUCE_DRV : integer := 0; -- reduced strength mem I/O (=1 yes) |
---|
100 | constant REG_ENABLE : integer := 0; -- registered addr/ctrl (=1 yes) |
---|
101 | constant TREFI_NS : integer := 7800; -- auto refresh interval (ns) |
---|
102 | constant TRAS : integer := 40000; -- active->precharge delay |
---|
103 | constant TRCD : integer := 15000; -- active->read/write delay |
---|
104 | constant TRFC : integer := 105000; -- ref->ref, ref->active delay |
---|
105 | constant TRP : integer := 15000; -- precharge->command delay |
---|
106 | constant TRTP : integer := 7500; -- read->precharge delay |
---|
107 | constant TWR : integer := 15000; -- used to determine wr->prech |
---|
108 | constant TWTR : integer := 7500; -- write->read delay |
---|
109 | constant SIM_ONLY : integer := 1; -- = 0 to allow power up delay |
---|
110 | constant DEBUG_EN : integer := 0; -- Enable debug signals/controls |
---|
111 | constant RST_ACT_LOW : integer := 1; -- =1 for active low reset, =0 for active high |
---|
112 | constant DLL_FREQ_MODE : string := "HIGH"; -- DCM Frequency range |
---|
113 | constant CLK_PERIOD : integer := 5000; -- Core/Mem clk period (in ps) |
---|
114 | |
---|
115 | constant DEVICE_WIDTH : integer := 8; -- Memory device data width |
---|
116 | constant CLK_PERIOD_NS : real := 5000.0 / 1000.0; |
---|
117 | constant TCYC_SYS : real := CLK_PERIOD_NS/2.0; |
---|
118 | constant TCYC_SYS_0 : time := CLK_PERIOD_NS * 1 ns; |
---|
119 | constant TCYC_SYS_DIV2 : time := TCYC_SYS * 1 ns; |
---|
120 | constant TEMP2 : real := 5.0/2.0; |
---|
121 | constant TCYC_200 : time := TEMP2 * 1 ns; |
---|
122 | constant TPROP_DQS : time := 0.01 ns; -- Delay for DQS signal during Write Operation |
---|
123 | constant TPROP_DQS_RD : time := 0.01 ns; -- Delay for DQS signal during Read Operation |
---|
124 | constant TPROP_PCB_CTRL : time := 0.01 ns; -- Delay for Address and Ctrl signals |
---|
125 | constant TPROP_PCB_DATA : time := 0.01 ns; -- Delay for data signal during Write operation |
---|
126 | constant TPROP_PCB_DATA_RD : time := 0.01 ns; -- Delay for data signal during Read operation |
---|
127 | |
---|
128 | |
---|
129 | component dram is |
---|
130 | generic ( |
---|
131 | BANK_WIDTH : integer; |
---|
132 | CKE_WIDTH : integer; |
---|
133 | CLK_WIDTH : integer; |
---|
134 | COL_WIDTH : integer; |
---|
135 | CS_NUM : integer; |
---|
136 | CS_WIDTH : integer; |
---|
137 | CS_BITS : integer; |
---|
138 | DM_WIDTH : integer; |
---|
139 | DQ_WIDTH : integer; |
---|
140 | DQ_PER_DQS : integer; |
---|
141 | DQ_BITS : integer; |
---|
142 | DQS_WIDTH : integer; |
---|
143 | DQS_BITS : integer; |
---|
144 | HIGH_PERFORMANCE_MODE : boolean; |
---|
145 | ODT_WIDTH : integer; |
---|
146 | ROW_WIDTH : integer; |
---|
147 | APPDATA_WIDTH : integer; |
---|
148 | ADDITIVE_LAT : integer; |
---|
149 | BURST_LEN : integer; |
---|
150 | BURST_TYPE : integer; |
---|
151 | CAS_LAT : integer; |
---|
152 | ECC_ENABLE : integer; |
---|
153 | MULTI_BANK_EN : integer; |
---|
154 | ODT_TYPE : integer; |
---|
155 | REDUCE_DRV : integer; |
---|
156 | REG_ENABLE : integer; |
---|
157 | TREFI_NS : integer; |
---|
158 | TRAS : integer; |
---|
159 | TRCD : integer; |
---|
160 | TRFC : integer; |
---|
161 | TRP : integer; |
---|
162 | TRTP : integer; |
---|
163 | TWR : integer; |
---|
164 | TWTR : integer; |
---|
165 | SIM_ONLY : integer; |
---|
166 | RST_ACT_LOW : integer; |
---|
167 | CLK_TYPE : string; |
---|
168 | DLL_FREQ_MODE : string; |
---|
169 | CLK_PERIOD : integer |
---|
170 | ); |
---|
171 | port ( |
---|
172 | sys_rst_n : in std_logic; |
---|
173 | sys_clk : in std_logic; |
---|
174 | idly_clk_200 : in std_logic; |
---|
175 | ddr2_a : out std_logic_vector((ROW_WIDTH-1) downto 0); |
---|
176 | ddr2_ba : out std_logic_vector((BANK_WIDTH-1) downto 0); |
---|
177 | ddr2_ras_n : out std_logic; |
---|
178 | ddr2_cas_n : out std_logic; |
---|
179 | ddr2_we_n : out std_logic; |
---|
180 | ddr2_cs_n : out std_logic_vector((CS_WIDTH-1) downto 0); |
---|
181 | ddr2_odt : out std_logic_vector((ODT_WIDTH-1) downto 0); |
---|
182 | ddr2_cke : out std_logic_vector((CKE_WIDTH-1) downto 0); |
---|
183 | ddr2_ck : out std_logic_vector((CLK_WIDTH-1) downto 0); |
---|
184 | ddr2_ck_n : out std_logic_vector((CLK_WIDTH-1) downto 0); |
---|
185 | ddr2_dq : inout std_logic_vector((DQ_WIDTH-1) downto 0); |
---|
186 | ddr2_dqs : inout std_logic_vector((DQS_WIDTH-1) downto 0); |
---|
187 | ddr2_dqs_n : inout std_logic_vector((DQS_WIDTH-1) downto 0); |
---|
188 | ddr2_dm : out std_logic_vector((DM_WIDTH-1) downto 0); |
---|
189 | |
---|
190 | error : out std_logic; |
---|
191 | |
---|
192 | phy_init_done : out std_logic |
---|
193 | ); |
---|
194 | end component; |
---|
195 | |
---|
196 | component ddr2_model is |
---|
197 | port ( |
---|
198 | ck : in std_logic; |
---|
199 | ck_n : in std_logic; |
---|
200 | cke : in std_logic; |
---|
201 | cs_n : in std_logic; |
---|
202 | ras_n : in std_logic; |
---|
203 | cas_n : in std_logic; |
---|
204 | we_n : in std_logic; |
---|
205 | dm_rdqs : inout std_logic_vector((DEVICE_WIDTH/16) downto 0); |
---|
206 | ba : in std_logic_vector((BANK_WIDTH - 1) downto 0); |
---|
207 | addr : in std_logic_vector((ROW_WIDTH - 1) downto 0); |
---|
208 | dq : inout std_logic_vector((DEVICE_WIDTH - 1) downto 0); |
---|
209 | dqs : inout std_logic_vector((DEVICE_WIDTH/16) downto 0); |
---|
210 | dqs_n : inout std_logic_vector((DEVICE_WIDTH/16) downto 0); |
---|
211 | rdqs_n : out std_logic_vector((DEVICE_WIDTH/16) downto 0); |
---|
212 | odt : in std_logic |
---|
213 | ); |
---|
214 | end component; |
---|
215 | |
---|
216 | component WireDelay |
---|
217 | generic ( |
---|
218 | Delay_g : time; |
---|
219 | Delay_rd : time); |
---|
220 | port ( |
---|
221 | A : inout Std_Logic; |
---|
222 | B : inout Std_Logic; |
---|
223 | reset : in Std_Logic); |
---|
224 | end component; |
---|
225 | |
---|
226 | signal sys_clk : std_logic := '0'; |
---|
227 | signal sys_clk_n : std_logic; |
---|
228 | signal sys_clk_p : std_logic; |
---|
229 | signal sys_clk200 : std_logic:= '0'; |
---|
230 | signal clk200_n : std_logic; |
---|
231 | signal clk200_p : std_logic; |
---|
232 | signal sys_rst_n : std_logic := '0'; |
---|
233 | signal sys_rst_out : std_logic; |
---|
234 | signal sys_rst_i : std_logic; |
---|
235 | signal gnd : std_logic_vector(1 downto 0); |
---|
236 | |
---|
237 | signal ddr2_dq_sdram : std_logic_vector((DQ_WIDTH - 1) downto 0); |
---|
238 | signal ddr2_dqs_sdram : std_logic_vector((DQS_WIDTH - 1) downto 0); |
---|
239 | signal ddr2_dqs_n_sdram : std_logic_vector((DQS_WIDTH - 1) downto 0); |
---|
240 | signal ddr2_dm_sdram : std_logic_vector((DM_WIDTH - 1) downto 0); |
---|
241 | signal ddr2_clk_sdram : std_logic_vector((CLK_WIDTH - 1) downto 0); |
---|
242 | signal ddr2_clk_n_sdram : std_logic_vector((CLK_WIDTH - 1) downto 0); |
---|
243 | signal ddr2_address_sdram : std_logic_vector((ROW_WIDTH - 1) downto 0); |
---|
244 | signal ddr2_ba_sdram : std_logic_vector((BANK_WIDTH - 1) downto 0); |
---|
245 | signal ddr2_ras_n_sdram : std_logic; |
---|
246 | signal ddr2_cas_n_sdram : std_logic; |
---|
247 | signal ddr2_we_n_sdram : std_logic; |
---|
248 | signal ddr2_cs_n_sdram : std_logic_vector((CS_WIDTH - 1) downto 0); |
---|
249 | signal ddr2_cke_sdram : std_logic_vector((CKE_WIDTH - 1) downto 0); |
---|
250 | signal ddr2_odt_sdram : std_logic_vector((ODT_WIDTH - 1) downto 0); |
---|
251 | signal error : std_logic; |
---|
252 | signal phy_init_done : std_logic; |
---|
253 | |
---|
254 | |
---|
255 | -- Only RDIMM memory parts support the reset signal, |
---|
256 | -- hence the ddr2_reset_n_sdram and ddr2_reset_n_fpga signals can be |
---|
257 | -- ignored for other memory parts |
---|
258 | signal ddr2_reset_n_sdram : std_logic; |
---|
259 | signal ddr2_reset_n_fpga : std_logic; |
---|
260 | signal ddr2_address_reg : std_logic_vector((ROW_WIDTH - 1) downto 0); |
---|
261 | signal ddr2_ba_reg : std_logic_vector((BANK_WIDTH - 1) downto 0); |
---|
262 | signal ddr2_cke_reg : std_logic_vector((CKE_WIDTH - 1) downto 0); |
---|
263 | signal ddr2_ras_n_reg : std_logic; |
---|
264 | signal ddr2_cas_n_reg : std_logic; |
---|
265 | signal ddr2_we_n_reg : std_logic; |
---|
266 | signal ddr2_cs_n_reg : std_logic_vector((CS_WIDTH - 1) downto 0); |
---|
267 | signal ddr2_odt_reg : std_logic_vector((ODT_WIDTH - 1) downto 0); |
---|
268 | |
---|
269 | signal dq_vector : std_logic_vector(15 downto 0); |
---|
270 | signal dqs_vector : std_logic_vector(1 downto 0); |
---|
271 | signal dqs_n_vector : std_logic_vector(1 downto 0); |
---|
272 | signal dm_vector : std_logic_vector(1 downto 0); |
---|
273 | signal command : std_logic_vector(2 downto 0); |
---|
274 | signal enable : std_logic; |
---|
275 | signal enable_o : std_logic; |
---|
276 | signal ddr2_dq_fpga : std_logic_vector((DQ_WIDTH - 1) downto 0); |
---|
277 | signal ddr2_dqs_fpga : std_logic_vector((DQS_WIDTH - 1) downto 0); |
---|
278 | signal ddr2_dqs_n_fpga : std_logic_vector((DQS_WIDTH - 1) downto 0); |
---|
279 | signal ddr2_dm_fpga : std_logic_vector((DM_WIDTH - 1) downto 0); |
---|
280 | signal ddr2_clk_fpga : std_logic_vector((CLK_WIDTH - 1) downto 0); |
---|
281 | signal ddr2_clk_n_fpga : std_logic_vector((CLK_WIDTH - 1) downto 0); |
---|
282 | signal ddr2_address_fpga : std_logic_vector((ROW_WIDTH - 1) downto 0); |
---|
283 | signal ddr2_ba_fpga : std_logic_vector((BANK_WIDTH - 1) downto 0); |
---|
284 | signal ddr2_ras_n_fpga : std_logic; |
---|
285 | signal ddr2_cas_n_fpga : std_logic; |
---|
286 | signal ddr2_we_n_fpga : std_logic; |
---|
287 | signal ddr2_cs_n_fpga : std_logic_vector((CS_WIDTH - 1) downto 0); |
---|
288 | signal ddr2_cke_fpga : std_logic_vector((CKE_WIDTH - 1) downto 0); |
---|
289 | signal ddr2_odt_fpga : std_logic_vector((ODT_WIDTH - 1) downto 0); |
---|
290 | |
---|
291 | begin |
---|
292 | gnd <= "00"; |
---|
293 | --*************************************************************************** |
---|
294 | -- Clock generation and reset |
---|
295 | --*************************************************************************** |
---|
296 | process |
---|
297 | begin |
---|
298 | sys_clk <= not sys_clk; |
---|
299 | wait for (TCYC_SYS_DIV2); |
---|
300 | end process; |
---|
301 | |
---|
302 | sys_clk_p <= sys_clk; |
---|
303 | sys_clk_n <= not sys_clk; |
---|
304 | |
---|
305 | process |
---|
306 | begin |
---|
307 | sys_clk200 <= not sys_clk200; |
---|
308 | wait for (TCYC_200); |
---|
309 | end process; |
---|
310 | |
---|
311 | clk200_p <= sys_clk200; |
---|
312 | clk200_n <= not sys_clk200; |
---|
313 | |
---|
314 | process |
---|
315 | begin |
---|
316 | sys_rst_n <= '0'; |
---|
317 | wait for 200 ns; |
---|
318 | sys_rst_n <= '1'; |
---|
319 | wait; |
---|
320 | end process; |
---|
321 | |
---|
322 | sys_rst_i <= not sys_rst_n; |
---|
323 | sys_rst_out <= (sys_rst_n) when (RST_ACT_LOW = 1) else (not sys_rst_n); |
---|
324 | |
---|
325 | |
---|
326 | --*************************************************************************** |
---|
327 | -- FPGA memory controller |
---|
328 | --*************************************************************************** |
---|
329 | |
---|
330 | u_mem_controller : dram |
---|
331 | generic map ( |
---|
332 | BANK_WIDTH => BANK_WIDTH, |
---|
333 | CKE_WIDTH => CKE_WIDTH, |
---|
334 | CLK_WIDTH => CLK_WIDTH, |
---|
335 | COL_WIDTH => COL_WIDTH, |
---|
336 | CS_NUM => CS_NUM, |
---|
337 | CS_WIDTH => CS_WIDTH, |
---|
338 | CS_BITS => CS_BITS, |
---|
339 | DM_WIDTH => DM_WIDTH, |
---|
340 | DQ_WIDTH => DQ_WIDTH, |
---|
341 | DQ_PER_DQS => DQ_PER_DQS, |
---|
342 | DQ_BITS => DQ_BITS, |
---|
343 | DQS_WIDTH => DQS_WIDTH, |
---|
344 | DQS_BITS => DQS_BITS, |
---|
345 | HIGH_PERFORMANCE_MODE => HIGH_PERFORMANCE_MODE, |
---|
346 | ODT_WIDTH => ODT_WIDTH, |
---|
347 | ROW_WIDTH => ROW_WIDTH, |
---|
348 | APPDATA_WIDTH => APPDATA_WIDTH, |
---|
349 | ADDITIVE_LAT => ADDITIVE_LAT, |
---|
350 | BURST_LEN => BURST_LEN, |
---|
351 | BURST_TYPE => BURST_TYPE, |
---|
352 | CAS_LAT => CAS_LAT, |
---|
353 | ECC_ENABLE => ECC_ENABLE, |
---|
354 | MULTI_BANK_EN => MULTI_BANK_EN, |
---|
355 | ODT_TYPE => ODT_TYPE, |
---|
356 | REDUCE_DRV => REDUCE_DRV, |
---|
357 | REG_ENABLE => REG_ENABLE, |
---|
358 | TREFI_NS => TREFI_NS, |
---|
359 | TRAS => TRAS, |
---|
360 | TRCD => TRCD, |
---|
361 | TRFC => TRFC, |
---|
362 | TRP => TRP, |
---|
363 | TRTP => TRTP, |
---|
364 | TWR => TWR, |
---|
365 | TWTR => TWTR, |
---|
366 | SIM_ONLY => SIM_ONLY, |
---|
367 | RST_ACT_LOW => RST_ACT_LOW, |
---|
368 | CLK_TYPE => CLK_TYPE, |
---|
369 | DLL_FREQ_MODE => DLL_FREQ_MODE, |
---|
370 | CLK_PERIOD => CLK_PERIOD |
---|
371 | ) |
---|
372 | port map ( |
---|
373 | sys_clk => sys_clk_p, |
---|
374 | idly_clk_200 => clk200_p, |
---|
375 | sys_rst_n => sys_rst_out, |
---|
376 | ddr2_ras_n => ddr2_ras_n_fpga, |
---|
377 | ddr2_cas_n => ddr2_cas_n_fpga, |
---|
378 | ddr2_we_n => ddr2_we_n_fpga, |
---|
379 | ddr2_cs_n => ddr2_cs_n_fpga, |
---|
380 | ddr2_cke => ddr2_cke_fpga, |
---|
381 | ddr2_odt => ddr2_odt_fpga, |
---|
382 | ddr2_dm => ddr2_dm_fpga, |
---|
383 | ddr2_dq => ddr2_dq_fpga, |
---|
384 | ddr2_dqs => ddr2_dqs_fpga, |
---|
385 | ddr2_dqs_n => ddr2_dqs_n_fpga, |
---|
386 | ddr2_ck => ddr2_clk_fpga, |
---|
387 | ddr2_ck_n => ddr2_clk_n_fpga, |
---|
388 | ddr2_ba => ddr2_ba_fpga, |
---|
389 | ddr2_a => ddr2_address_fpga, |
---|
390 | |
---|
391 | error => error, |
---|
392 | |
---|
393 | phy_init_done => phy_init_done |
---|
394 | ); |
---|
395 | |
---|
396 | --*************************************************************************** |
---|
397 | -- Delay insertion modules for each signal |
---|
398 | --*************************************************************************** |
---|
399 | -- Use standard non-inertial (transport) delay mechanism for unidirectional |
---|
400 | -- signals from FPGA to SDRAM |
---|
401 | ddr2_address_sdram <= TRANSPORT ddr2_address_fpga after TPROP_PCB_CTRL; |
---|
402 | ddr2_ba_sdram <= TRANSPORT ddr2_ba_fpga after TPROP_PCB_CTRL; |
---|
403 | ddr2_ras_n_sdram <= TRANSPORT ddr2_ras_n_fpga after TPROP_PCB_CTRL; |
---|
404 | ddr2_cas_n_sdram <= TRANSPORT ddr2_cas_n_fpga after TPROP_PCB_CTRL; |
---|
405 | ddr2_we_n_sdram <= TRANSPORT ddr2_we_n_fpga after TPROP_PCB_CTRL; |
---|
406 | ddr2_cs_n_sdram <= TRANSPORT ddr2_cs_n_fpga after TPROP_PCB_CTRL; |
---|
407 | ddr2_cke_sdram <= TRANSPORT ddr2_cke_fpga after TPROP_PCB_CTRL; |
---|
408 | ddr2_odt_sdram <= TRANSPORT ddr2_odt_fpga after TPROP_PCB_CTRL; |
---|
409 | ddr2_clk_sdram <= TRANSPORT ddr2_clk_fpga after TPROP_PCB_CTRL; |
---|
410 | ddr2_clk_n_sdram <= TRANSPORT ddr2_clk_n_fpga after TPROP_PCB_CTRL; |
---|
411 | ddr2_reset_n_sdram <= TRANSPORT ddr2_reset_n_fpga after TPROP_PCB_CTRL; |
---|
412 | ddr2_dm_sdram <= TRANSPORT ddr2_dm_fpga after TPROP_PCB_DATA; |
---|
413 | |
---|
414 | dq_delay: for i in 0 to DQ_WIDTH - 1 generate |
---|
415 | u_delay_dq: WireDelay |
---|
416 | generic map ( |
---|
417 | Delay_g => TPROP_PCB_DATA, |
---|
418 | Delay_rd => TPROP_PCB_DATA_RD) |
---|
419 | port map( |
---|
420 | A => ddr2_dq_fpga(i), |
---|
421 | B => ddr2_dq_sdram(i), |
---|
422 | reset => sys_rst_n); |
---|
423 | end generate; |
---|
424 | |
---|
425 | dqs_delay: for i in 0 to DQS_WIDTH - 1 generate |
---|
426 | u_delay_dqs: WireDelay |
---|
427 | generic map ( |
---|
428 | Delay_g => TPROP_DQS, |
---|
429 | Delay_rd => TPROP_DQS_RD) |
---|
430 | port map( |
---|
431 | A => ddr2_dqs_fpga(i), |
---|
432 | B => ddr2_dqs_sdram(i), |
---|
433 | reset => sys_rst_n); |
---|
434 | end generate; |
---|
435 | |
---|
436 | dqs_n_delay: for i in 0 to DQS_WIDTH - 1 generate |
---|
437 | u_delay_dqs: WireDelay |
---|
438 | generic map ( |
---|
439 | Delay_g => TPROP_DQS, |
---|
440 | Delay_rd => TPROP_DQS_RD) |
---|
441 | port map( |
---|
442 | A => ddr2_dqs_n_fpga(i), |
---|
443 | B => ddr2_dqs_n_sdram(i), |
---|
444 | reset => sys_rst_n); |
---|
445 | end generate; |
---|
446 | |
---|
447 | -- Extra one clock pipelining for RDIMM address and |
---|
448 | -- control signals is implemented here (Implemented external to memory model) |
---|
449 | process (ddr2_clk_sdram) |
---|
450 | begin |
---|
451 | if (rising_edge(ddr2_clk_sdram(0))) then |
---|
452 | if ( ddr2_reset_n_sdram = '0' ) then |
---|
453 | ddr2_ras_n_reg <= '1'; |
---|
454 | ddr2_cas_n_reg <= '1'; |
---|
455 | ddr2_we_n_reg <= '1'; |
---|
456 | ddr2_cs_n_reg <= (others => '1'); |
---|
457 | ddr2_odt_reg <= (others => '0'); |
---|
458 | else |
---|
459 | ddr2_address_reg <= TRANSPORT ddr2_address_sdram after TCYC_SYS_DIV2; |
---|
460 | ddr2_ba_reg <= TRANSPORT ddr2_ba_sdram after TCYC_SYS_DIV2; |
---|
461 | ddr2_ras_n_reg <= TRANSPORT ddr2_ras_n_sdram after TCYC_SYS_DIV2; |
---|
462 | ddr2_cas_n_reg <= TRANSPORT ddr2_cas_n_sdram after TCYC_SYS_DIV2; |
---|
463 | ddr2_we_n_reg <= TRANSPORT ddr2_we_n_sdram after TCYC_SYS_DIV2; |
---|
464 | ddr2_cs_n_reg <= TRANSPORT ddr2_cs_n_sdram after TCYC_SYS_DIV2; |
---|
465 | ddr2_odt_reg <= TRANSPORT ddr2_odt_sdram after TCYC_SYS_DIV2; |
---|
466 | end if; |
---|
467 | end if; |
---|
468 | end process; |
---|
469 | |
---|
470 | -- to avoid tIS violations on CKE when reset is deasserted |
---|
471 | process (ddr2_clk_n_sdram) |
---|
472 | begin |
---|
473 | if (rising_edge(ddr2_clk_n_sdram(0))) then |
---|
474 | if ( ddr2_reset_n_sdram = '0' ) then |
---|
475 | ddr2_cke_reg <= (others => '0'); |
---|
476 | else |
---|
477 | ddr2_cke_reg <= TRANSPORT ddr2_cke_sdram after TCYC_SYS_0; |
---|
478 | end if; |
---|
479 | end if; |
---|
480 | end process; |
---|
481 | |
---|
482 | --*************************************************************************** |
---|
483 | -- Memory model instances |
---|
484 | --*************************************************************************** |
---|
485 | |
---|
486 | comp_16: if (DEVICE_WIDTH = 16) generate |
---|
487 | -- if memory part is x16 |
---|
488 | registered_dimm: if (REG_ENABLE = 1) generate |
---|
489 | -- if the memory part is Registered DIMM |
---|
490 | gen_cs: for j in 0 to (CS_NUM - 1) generate |
---|
491 | gen: for i in 0 to (DQS_WIDTH/2 - 1) generate |
---|
492 | u_mem0: ddr2_model |
---|
493 | port map ( |
---|
494 | ck => ddr2_clk_sdram(CLK_WIDTH*i/DQS_WIDTH), |
---|
495 | ck_n => ddr2_clk_n_sdram(CLK_WIDTH*i/DQS_WIDTH), |
---|
496 | cke => ddr2_cke_reg(j), |
---|
497 | cs_n => ddr2_cs_n_reg((CS_WIDTH*i/DQS_WIDTH)), |
---|
498 | ras_n => ddr2_ras_n_reg, |
---|
499 | cas_n => ddr2_cas_n_reg, |
---|
500 | we_n => ddr2_we_n_reg, |
---|
501 | dm_rdqs => ddr2_dm_sdram((2*(i+1))-1 downto i*2), |
---|
502 | ba => ddr2_ba_reg, |
---|
503 | addr => ddr2_address_reg, |
---|
504 | dq => ddr2_dq_sdram((16*(i+1))-1 downto i*16), |
---|
505 | dqs => ddr2_dqs_sdram((2*(i+1))-1 downto i*2), |
---|
506 | dqs_n => ddr2_dqs_n_sdram((2*(i+1))-1 downto i*2), |
---|
507 | rdqs_n => open, |
---|
508 | odt => ddr2_odt_reg(ODT_WIDTH*i/DQS_WIDTH) |
---|
509 | ); |
---|
510 | end generate gen; |
---|
511 | end generate gen_cs; |
---|
512 | end generate registered_dimm; |
---|
513 | -- if the memory part is component or unbuffered DIMM |
---|
514 | comp16_mul8: if (((DQ_WIDTH mod 16) /= 0) and (REG_ENABLE = 0)) generate |
---|
515 | -- for the memory part x16, if the data width is not multiple |
---|
516 | -- of 16, memory models are instantiated for all data with x16 |
---|
517 | -- memory model and except for MSB data. For the MSB data |
---|
518 | -- of 8 bits, all memory data, strobe and mask data signals are |
---|
519 | -- replicated to make it as x16 part. For example if the design |
---|
520 | -- is generated for data width of 72, memory model x16 parts |
---|
521 | -- instantiated for 4 times with data ranging from 0 to 63. |
---|
522 | -- For MSB data ranging from 64 to 71, one x16 memory model |
---|
523 | -- by replicating the 8-bit data twice and similarly |
---|
524 | -- the case with data mask and strobe. |
---|
525 | gen_cs: for j in 0 to (CS_NUM - 1) generate |
---|
526 | gen: for i in 0 to (DQ_WIDTH/16 - 1) generate |
---|
527 | u_mem0: ddr2_model |
---|
528 | port map ( |
---|
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((2*(i+1))-1 downto i*2), |
---|
537 | ba => ddr2_ba_sdram, |
---|
538 | addr => ddr2_address_sdram, |
---|
539 | dq => ddr2_dq_sdram((16*(i+1))-1 downto i*16), |
---|
540 | dqs => ddr2_dqs_sdram((2*(i+1))-1 downto i*2), |
---|
541 | dqs_n => ddr2_dqs_n_sdram((2*(i+1))-1 downto i*2), |
---|
542 | rdqs_n => open, |
---|
543 | odt => ddr2_odt_sdram(ODT_WIDTH*i/DQS_WIDTH) |
---|
544 | ); |
---|
545 | end generate gen; |
---|
546 | |
---|
547 | --Logic to assign the remaining bits of DQ and DQS |
---|
548 | u1: for i in 0 to 7 generate |
---|
549 | u_delay_dq: WireDelay |
---|
550 | generic map ( |
---|
551 | Delay_g => 0 ps, |
---|
552 | Delay_rd => 0 ps) |
---|
553 | port map( |
---|
554 | A => ddr2_dq_sdram(DQ_WIDTH - 8 + i), |
---|
555 | B => dq_vector(i), |
---|
556 | reset => sys_rst_n); |
---|
557 | end generate; |
---|
558 | |
---|
559 | u2: WireDelay |
---|
560 | generic map ( |
---|
561 | Delay_g => 0 ps, |
---|
562 | Delay_rd => 0 ps) |
---|
563 | port map( |
---|
564 | A => ddr2_dqs_sdram(DQS_WIDTH - 1), |
---|
565 | B => dqs_vector(0), |
---|
566 | reset => sys_rst_n); |
---|
567 | |
---|
568 | u3: WireDelay |
---|
569 | generic map ( |
---|
570 | Delay_g => 0 ps, |
---|
571 | Delay_rd => 0 ps) |
---|
572 | port map( |
---|
573 | A => ddr2_dqs_n_sdram(DQS_WIDTH - 1), |
---|
574 | B => dqs_n_vector(0), |
---|
575 | reset => sys_rst_n); |
---|
576 | |
---|
577 | dq_vector(15 downto 8) <= dq_vector(7 downto 0); |
---|
578 | dqs_vector(1) <= dqs_vector(0); |
---|
579 | dqs_n_vector(1) <= dqs_n_vector(0); |
---|
580 | dm_vector <= (ddr2_dm_sdram(DM_WIDTH - 1) & |
---|
581 | ddr2_dm_sdram(DM_WIDTH - 1)); |
---|
582 | |
---|
583 | u_mem1: ddr2_model |
---|
584 | port map ( |
---|
585 | ck => ddr2_clk_sdram(CLK_WIDTH-1), |
---|
586 | ck_n => ddr2_clk_n_sdram(CLK_WIDTH-1), |
---|
587 | cke => ddr2_cke_sdram(j), |
---|
588 | cs_n => ddr2_cs_n_sdram(CS_WIDTH-1), |
---|
589 | ras_n => ddr2_ras_n_sdram, |
---|
590 | cas_n => ddr2_cas_n_sdram, |
---|
591 | we_n => ddr2_we_n_sdram, |
---|
592 | dm_rdqs => dm_vector, |
---|
593 | ba => ddr2_ba_sdram, |
---|
594 | addr => ddr2_address_sdram, |
---|
595 | dq => dq_vector, |
---|
596 | dqs => dqs_vector, |
---|
597 | dqs_n => dqs_n_vector, |
---|
598 | rdqs_n => open, |
---|
599 | odt => ddr2_odt_sdram(ODT_WIDTH-1) |
---|
600 | ); |
---|
601 | end generate gen_cs; |
---|
602 | end generate comp16_mul8; |
---|
603 | comp16_mul16: if (((DQ_WIDTH mod 16) = 0) and (REG_ENABLE = 0)) generate |
---|
604 | -- if the data width is multiple of 16 |
---|
605 | gen_cs: for j in 0 to (CS_NUM - 1) generate |
---|
606 | gen: for i in 0 to ((DQS_WIDTH/2) - 1) generate |
---|
607 | u_mem0: ddr2_model |
---|
608 | port map ( |
---|
609 | ck => ddr2_clk_sdram(CLK_WIDTH*i/DQS_WIDTH), |
---|
610 | ck_n => ddr2_clk_n_sdram(CLK_WIDTH*i/DQS_WIDTH), |
---|
611 | cke => ddr2_cke_sdram(j), |
---|
612 | cs_n => ddr2_cs_n_sdram(CS_WIDTH*i/DQS_WIDTH), |
---|
613 | ras_n => ddr2_ras_n_sdram, |
---|
614 | cas_n => ddr2_cas_n_sdram, |
---|
615 | we_n => ddr2_we_n_sdram, |
---|
616 | dm_rdqs => ddr2_dm_sdram((2*(i+1))-1 downto i*2), |
---|
617 | ba => ddr2_ba_sdram, |
---|
618 | addr => ddr2_address_sdram, |
---|
619 | dq => ddr2_dq_sdram((16*(i+1))-1 downto i*16), |
---|
620 | dqs => ddr2_dqs_sdram((2*(i+1))-1 downto i*2), |
---|
621 | dqs_n => ddr2_dqs_n_sdram((2*(i+1))-1 downto i*2), |
---|
622 | rdqs_n => open, |
---|
623 | odt => ddr2_odt_sdram(ODT_WIDTH*i/DQS_WIDTH) |
---|
624 | ); |
---|
625 | end generate gen; |
---|
626 | end generate gen_cs; |
---|
627 | end generate comp16_mul16; |
---|
628 | end generate comp_16; |
---|
629 | |
---|
630 | comp_8: if (DEVICE_WIDTH = 8) generate |
---|
631 | -- if the memory part is x8 |
---|
632 | registered_dimm: if (REG_ENABLE = 1) generate |
---|
633 | -- if the memory part is Registered DIMM |
---|
634 | gen_cs: for j in 0 to (CS_NUM - 1) generate |
---|
635 | gen: for i in 0 to (DQS_WIDTH - 1) generate |
---|
636 | u_mem0: ddr2_model |
---|
637 | port map ( |
---|
638 | ck => ddr2_clk_sdram(CLK_WIDTH*i/DQS_WIDTH), |
---|
639 | ck_n => ddr2_clk_n_sdram(CLK_WIDTH*i/DQS_WIDTH), |
---|
640 | cke => ddr2_cke_reg(j), |
---|
641 | cs_n => ddr2_cs_n_reg((CS_WIDTH*i/DQS_WIDTH)), |
---|
642 | ras_n => ddr2_ras_n_reg, |
---|
643 | cas_n => ddr2_cas_n_reg, |
---|
644 | we_n => ddr2_we_n_reg, |
---|
645 | dm_rdqs => ddr2_dm_sdram(i downto i), |
---|
646 | ba => ddr2_ba_reg, |
---|
647 | addr => ddr2_address_reg, |
---|
648 | dq => ddr2_dq_sdram((8*(i+1))-1 downto i*8), |
---|
649 | dqs => ddr2_dqs_sdram(i downto i), |
---|
650 | dqs_n => ddr2_dqs_n_sdram(i downto i), |
---|
651 | rdqs_n => open, |
---|
652 | odt => ddr2_odt_reg(ODT_WIDTH*i/DQS_WIDTH) |
---|
653 | ); |
---|
654 | end generate gen; |
---|
655 | end generate gen_cs; |
---|
656 | end generate registered_dimm; |
---|
657 | comp8_mul8: if (REG_ENABLE = 0) generate |
---|
658 | -- if the memory part is component or unbuffered DIMM |
---|
659 | gen_cs: for j in 0 to (CS_NUM - 1) generate |
---|
660 | gen: for i in 0 to DQS_WIDTH - 1 generate |
---|
661 | u_mem0: ddr2_model |
---|
662 | port map ( |
---|
663 | ck => ddr2_clk_sdram(CLK_WIDTH*i/DQS_WIDTH), |
---|
664 | ck_n => ddr2_clk_n_sdram(CLK_WIDTH*i/DQS_WIDTH), |
---|
665 | cke => ddr2_cke_sdram(j), |
---|
666 | cs_n => ddr2_cs_n_sdram(CS_WIDTH*i/DQS_WIDTH), |
---|
667 | ras_n => ddr2_ras_n_sdram, |
---|
668 | cas_n => ddr2_cas_n_sdram, |
---|
669 | we_n => ddr2_we_n_sdram, |
---|
670 | dm_rdqs => ddr2_dm_sdram(i downto i), |
---|
671 | ba => ddr2_ba_sdram, |
---|
672 | addr => ddr2_address_sdram, |
---|
673 | dq => ddr2_dq_sdram((8*(i+1))-1 downto i*8), |
---|
674 | dqs => ddr2_dqs_sdram(i downto i), |
---|
675 | dqs_n => ddr2_dqs_n_sdram(i downto i), |
---|
676 | rdqs_n => open, |
---|
677 | odt => ddr2_odt_sdram(ODT_WIDTH*i/DQS_WIDTH) |
---|
678 | ); |
---|
679 | end generate gen; |
---|
680 | end generate gen_cs; |
---|
681 | end generate comp8_mul8; |
---|
682 | end generate comp_8; |
---|
683 | |
---|
684 | comp_4: if (DEVICE_WIDTH = 4) generate |
---|
685 | -- if the memory part is x4 |
---|
686 | registered_dimm: if (REG_ENABLE = 1) generate |
---|
687 | -- if the memory part is Registered DIMM |
---|
688 | gen_cs: for j in 0 to (CS_NUM - 1) generate |
---|
689 | gen: for i in 0 to (DQS_WIDTH - 1) generate |
---|
690 | u_mem0: ddr2_model |
---|
691 | port map ( |
---|
692 | ck => ddr2_clk_sdram(CLK_WIDTH*i/DQS_WIDTH), |
---|
693 | ck_n => ddr2_clk_n_sdram(CLK_WIDTH*i/DQS_WIDTH), |
---|
694 | cke => ddr2_cke_reg(j), |
---|
695 | cs_n => ddr2_cs_n_reg((CS_WIDTH*i/DQS_WIDTH)), |
---|
696 | ras_n => ddr2_ras_n_reg, |
---|
697 | cas_n => ddr2_cas_n_reg, |
---|
698 | we_n => ddr2_we_n_reg, |
---|
699 | dm_rdqs => ddr2_dm_sdram(i downto i), |
---|
700 | ba => ddr2_ba_reg, |
---|
701 | addr => ddr2_address_reg, |
---|
702 | dq => ddr2_dq_sdram((4*(i+1))-1 downto i*4), |
---|
703 | dqs => ddr2_dqs_sdram(i downto i), |
---|
704 | dqs_n => ddr2_dqs_n_sdram(i downto i), |
---|
705 | rdqs_n => open, |
---|
706 | odt => ddr2_odt_reg(ODT_WIDTH*i/DQS_WIDTH) |
---|
707 | ); |
---|
708 | end generate gen; |
---|
709 | end generate gen_cs; |
---|
710 | end generate registered_dimm; |
---|
711 | comp4_mul4: if (REG_ENABLE = 0) generate |
---|
712 | -- if the memory part is component or unbuffered DIMM |
---|
713 | gen_cs: for j in 0 to (CS_NUM - 1) generate |
---|
714 | gen: for i in 0 to DQS_WIDTH - 1 generate |
---|
715 | u_mem0: ddr2_model |
---|
716 | port map ( |
---|
717 | ck => ddr2_clk_sdram(CLK_WIDTH*i/DQS_WIDTH), |
---|
718 | ck_n => ddr2_clk_n_sdram(CLK_WIDTH*i/DQS_WIDTH), |
---|
719 | cke => ddr2_cke_sdram(j), |
---|
720 | cs_n => ddr2_cs_n_sdram(CS_WIDTH*i/DQS_WIDTH), |
---|
721 | ras_n => ddr2_ras_n_sdram, |
---|
722 | cas_n => ddr2_cas_n_sdram, |
---|
723 | we_n => ddr2_we_n_sdram, |
---|
724 | dm_rdqs => ddr2_dm_sdram(i downto i), |
---|
725 | ba => ddr2_ba_sdram, |
---|
726 | addr => ddr2_address_sdram, |
---|
727 | dq => ddr2_dq_sdram((4*(i+1))-1 downto i*4), |
---|
728 | dqs => ddr2_dqs_sdram(i downto i), |
---|
729 | dqs_n => ddr2_dqs_n_sdram(i downto i), |
---|
730 | rdqs_n => open, |
---|
731 | odt => ddr2_odt_sdram(ODT_WIDTH*i/DQS_WIDTH) |
---|
732 | ); |
---|
733 | end generate gen; |
---|
734 | end generate gen_cs; |
---|
735 | end generate comp4_mul4; |
---|
736 | end generate comp_4; |
---|
737 | |
---|
738 | |
---|
739 | end architecture; |
---|