├── adapter.v
├── drac_ddr3.v
├── system.ucf
└── top.v
/adapter.v:
--------------------------------------------------------------------------------
1 | /*
2 | MicroBlaze MCS to DDR3 glue
3 | (C) Copyright 2012 Silicon On Inspiration
4 | www.sioi.com.au
5 | 86 Longueville Road
6 | Lane Cove 2066
7 | New South Wales
8 | AUSTRALIA
9 |
10 | This program is free software: you can redistribute it and/or modify
11 | it under the terms of the GNU Lesser General Public License as published by
12 | the Free Software Foundation, either version 3 of the License, or
13 | (at your option) any later version.
14 |
15 | This program is distributed in the hope that it will be useful,
16 | but WITHOUT ANY WARRANTY; without even the implied warranty of
17 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 | GNU Lesser General Public License for more details.
19 |
20 | You should have received a copy of the GNU Lesser General Public License
21 | along with this program. If not, see .
22 | */
23 |
24 | `timescale 1ns / 1ps
25 |
26 | module adapter
27 | (
28 | input ckmb,
29 | input ckdr,
30 | input reset,
31 |
32 | output srd,
33 | output swr,
34 | output [33:5] sa,
35 | output [255:0] swdat,
36 | output [31:0] smsk,
37 | input [255:0] srdat,
38 | input srdy,
39 |
40 | output IO_Ready,
41 | input IO_Addr_Strobe,
42 | input IO_Read_Strobe,
43 | input IO_Write_Strobe,
44 | output [31 : 0] IO_Read_Data,
45 | input [31 : 0] IO_Address,
46 | input [3 : 0] IO_Byte_Enable,
47 | input [31 : 0] IO_Write_Data,
48 | input [3 : 0] page,
49 | input [2:0] dbg_out
50 | );
51 |
52 | reg [31 : 0] rdat;
53 | reg [255 : 0] wdat;
54 | reg [31 : 0] msk;
55 | reg [33 : 2] addr;
56 | reg rdy1;
57 | reg rdy2;
58 | reg read;
59 | reg write;
60 |
61 | wire [31:0] iowd;
62 | wire [3:0] mask;
63 |
64 | parameter BADBAD = 256'hBAD0BAD0BAD0BAD0BAD0BAD0BAD0BAD0BAD0BAD0BAD0BAD0BAD0BAD0BAD0BAD0;
65 |
66 | always @ (posedge ckmb) begin
67 |
68 | if (IO_Addr_Strobe && IO_Write_Strobe) begin
69 | case (IO_Address[4:2])
70 | 0: wdat[31:0] <= iowd;
71 | 1: wdat[63:32] <= iowd;
72 | 2: wdat[95:64] <= iowd;
73 | 3: wdat[127:96] <= iowd;
74 | 4: wdat[159:128] <= iowd;
75 | 5: wdat[191:160] <= iowd;
76 | 6: wdat[223:192] <= iowd;
77 | 7: wdat[255:224] <= iowd;
78 |
79 | // BADBAD markers for bebugging byte masking
80 | // NB: This approach breaks the per-pin IODELAY2 software adjustment on the DQ lines
81 | // 0: wdat <= {BADBAD[255:32], iowd};
82 | // 1: wdat <= {BADBAD[255:64], iowd, BADBAD[31:0]};
83 | // 2: wdat <= {BADBAD[255:96], iowd, BADBAD[63:0]};
84 | // 3: wdat <= {BADBAD[255:128], iowd, BADBAD[95:0]};
85 | // 4: wdat <= {BADBAD[255:160], iowd, BADBAD[127:0]};
86 | // 5: wdat <= {BADBAD[255:192], iowd, BADBAD[159:0]};
87 | // 6: wdat <= {BADBAD[255:224], iowd, BADBAD[191:0]};
88 | // 7: wdat <= {iowd, BADBAD[223:0]};
89 | endcase
90 |
91 | case (IO_Address[4:2])
92 |
93 | 0: msk <= {28'hFFFFFFF, mask};
94 | 1: msk <= {24'hFFFFFF, mask, 4'hF};
95 | 2: msk <= {20'hFFFFF, mask, 8'hFF};
96 | 3: msk <= {16'hFFFF, mask, 12'hFFF};
97 | 4: msk <= {12'hFFF, mask, 16'hFFFF};
98 | 5: msk <= {8'hFF, mask, 20'hFFFFF};
99 | 6: msk <= {4'hF, mask, 24'hFFFFFF};
100 | 7: msk <= {mask, 28'hFFFFFFF};
101 | /*
102 | ZZ - write full 256 bits during testing !
103 | 0: msk <= {28'h0000000, mask};
104 | 1: msk <= {24'h000000, mask, 4'h0};
105 | 2: msk <= {20'h00000, mask, 8'h00};
106 | 3: msk <= {16'h0000, mask, 12'h000};
107 | 4: msk <= {12'h000, mask, 16'h0000};
108 | 5: msk <= {8'h00, mask, 20'h00000};
109 | 6: msk <= {4'h0, mask, 24'h000000};
110 | 7: msk <= {mask, 28'h0000000};
111 | */
112 | endcase
113 | end
114 |
115 | if (IO_Addr_Strobe)
116 | addr <= {page[3:0], IO_Address[29:2]};
117 | end
118 |
119 | always @ (posedge ckmb or posedge reset) begin
120 | if (reset) begin
121 | read <= 1'b0;
122 | write <= 1'b0;
123 | rdy2 <= 1'b0;
124 | end else begin
125 | if (IO_Addr_Strobe && IO_Read_Strobe)
126 | read <= 1'b1;
127 | else if (IO_Addr_Strobe && IO_Write_Strobe)
128 | write <= 1'b1;
129 | if (rdy1) begin
130 | read <= 1'b0;
131 | write <= 1'b0;
132 | rdy2 <= 1'b1;
133 | end
134 | if (rdy2)
135 | rdy2 <= 1'b0;
136 | end
137 | end
138 |
139 | always @ (posedge ckdr or posedge reset) begin
140 | if (reset) begin
141 | rdy1 <= 1'b0;
142 | end else begin
143 | if (srdy)
144 | rdy1 <= 1'b1;
145 | if (rdy2)
146 | rdy1 <= 1'b0;
147 | if (srdy) case (addr[4:2])
148 | 0: rdat <= srdat[31:0];
149 | 1: rdat <= srdat[63:32];
150 | 2: rdat <= srdat[95:64];
151 | 3: rdat <= srdat[127:96];
152 | 4: rdat <= srdat[159:128];
153 | 5: rdat <= srdat[191:160];
154 | 6: rdat <= srdat[223:192];
155 | 7: rdat <= srdat[255:224];
156 | endcase
157 | end
158 | end
159 |
160 | assign iowd = IO_Write_Data;
161 | assign mask = ~IO_Byte_Enable;
162 |
163 | assign IO_Read_Data = rdat;
164 | assign IO_Ready = rdy2;
165 | assign srd = read;
166 | assign swr = write;
167 | assign swdat = wdat;
168 | assign smsk = msk;
169 | assign sa = addr[33:5];
170 |
171 | endmodule
172 |
173 |
--------------------------------------------------------------------------------
/drac_ddr3.v:
--------------------------------------------------------------------------------
1 | /*
2 | DDR3 DRAM controller
3 | (C) Copyright 2012 Silicon On Inspiration
4 | www.sioi.com.au
5 | 86 Longueville Road
6 | Lane Cove 2066
7 | New South Wales
8 | AUSTRALIA
9 |
10 | This program is free software: you can redistribute it and/or modify
11 | it under the terms of the GNU Lesser General Public License as published by
12 | the Free Software Foundation, either version 3 of the License, or
13 | (at your option) any later version.
14 |
15 | This program is distributed in the hope that it will be useful,
16 | but WITHOUT ANY WARRANTY; without even the implied warranty of
17 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 | GNU Lesser General Public License for more details.
19 |
20 | You should have received a copy of the GNU Lesser General Public License
21 | along with this program. If not, see .
22 | */
23 |
24 | `timescale 1ns / 1ps
25 |
26 | module drac_ddr3
27 | (
28 | input ckin,
29 | output ckout,
30 | output ckouthalf,
31 | output reset,
32 |
33 | inout [63:0] ddq,
34 | inout [7:0] dqsp,
35 | inout [7:0] dqsn,
36 | output [7:0] ddm,
37 | output [15:0] da,
38 | output [2:0] dba,
39 | output [2:0] dcmd,
40 | output [1:0] dce,
41 | output [1:0] dcs,
42 | output [1:0] dckp,
43 | output [1:0] dckn,
44 | output [1:0] dodt,
45 |
46 | input srd,
47 | input swr,
48 | input [33:5] sa,
49 | input [255:0] swdat,
50 | input [31:0] smsk,
51 | output [255:0] srdat,
52 | output srdy,
53 |
54 | input [2:0] dbg_out,
55 | output [7:0] dbg_in
56 | );
57 |
58 | reg READ;
59 | reg READ2;
60 |
61 | reg ack;
62 |
63 | reg [15:0] rDDR_Addr;
64 | reg [2:0] rDDR_BankAddr;
65 | reg [1:0] rDDR_CS_n;
66 | reg [2:0] rDDR_Cmd;
67 | reg [1:0] rDDR_CKE;
68 | reg [1:0] rDDR_ODT;
69 |
70 | reg [2:0] STATE;
71 | reg [2:0] RTN;
72 | reg [5:0] DLY;
73 |
74 | reg [10:0] RFCNTR;
75 | reg REFRESH;
76 |
77 | reg RPULSE0;
78 | reg RPULSE1;
79 | reg RPULSE2;
80 | reg RPULSE3;
81 | reg RPULSE4;
82 | reg RPULSE5;
83 | reg RPULSE6;
84 | reg RPULSE7;
85 | reg WPULSE0;
86 | reg [255:0] Q;
87 |
88 | wire [7:0] DM;
89 | wire [7:0] DM_t;
90 | wire [7:0] wDDR_DM;
91 |
92 | wire [7:0] wDDR_DQS;
93 | wire [63:0] DQ_i;
94 | wire [63:0] DQ_i_dly;
95 | wire [255:0] wQ;
96 | wire [63:0] DQ_o;
97 | wire [63:0] DQ_t;
98 | wire [63:0] wDDR_DQ;
99 |
100 | reg [255:0] rWdat;
101 | reg [31:0] rSmsk;
102 |
103 | reg [13:0] rLock = 0;
104 | reg rClrPll = 1;
105 | reg [13:0] rStart = 0;
106 | reg rStarted = 0;
107 |
108 | reg [63:0] rChgDelay;
109 | reg [63:0] rIncDelay;
110 | reg [63:0] rCalDelay;
111 | reg [63:0] rCalDelay2;
112 | reg [63:0] rRstDelay;
113 |
114 | // Set up clocks for DDR3. Use circuitry based on UG382 Ch 1 pp33,34
115 | // Generate the following clocks:
116 | //
117 | // ck600 600MHz clock for DQ IOSERDES2 high speed clock
118 | // ck600_180 600MHz clock for DQS OSERDES2 high speed clock
119 | // DQS clocking lags DQ clocking by half of one bit time
120 | // ck150 1/4 speed clock for IOSERDES2 parallel side and control logic
121 | // ck75 Clock for MicroBlaze CPU
122 | //
123 | // Create two copies of the 600MHz clocks, providing separate copies for
124 | // bank 1 and bank 3. This is necessary as each BUFPLL reaches only a
125 | // single bank. The other clocks are global (BUFG).
126 | wire ck600raw;
127 | wire ck600_180raw;
128 | wire ck150;
129 | wire ck150raw;
130 | wire ck75;
131 | wire ck75raw;
132 | wire [1:0] ck600;
133 | wire [1:0] ck600_180;
134 | wire [1:0] strobe;
135 | wire [1:0] strobe180;
136 |
137 | // DDR3 DIMM byte lane levelling is achieved with these IODELAY2 settings:
138 | parameter LVL_WSLOPE = 3;
139 | parameter LVL_WPHASE = 6;
140 |
141 | BUFG bufg_main
142 | (
143 | .O (ckinb),
144 | .I (ckin)
145 | );
146 |
147 | PLL_BASE
148 | #(
149 | .BANDWIDTH ("OPTIMIZED"),
150 | .CLK_FEEDBACK ("CLKFBOUT"),
151 | .COMPENSATION ("INTERNAL"),
152 | .DIVCLK_DIVIDE (3),
153 | .CLKFBOUT_MULT (29),
154 | .CLKFBOUT_PHASE (0.000),
155 | .CLKOUT0_DIVIDE (1),
156 | .CLKOUT0_PHASE (0.000),
157 | .CLKOUT0_DUTY_CYCLE (0.500),
158 | .CLKOUT1_DIVIDE (1),
159 | .CLKOUT1_PHASE (180.000),
160 | .CLKOUT1_DUTY_CYCLE (0.500),
161 | .CLKOUT2_DIVIDE (4),
162 | .CLKOUT2_PHASE (0.000),
163 | .CLKOUT2_DUTY_CYCLE (0.500),
164 | .CLKOUT3_DIVIDE (8),
165 | .CLKOUT3_PHASE (0.0),
166 | .CLKOUT3_DUTY_CYCLE (0.500),
167 | .CLKOUT4_DIVIDE (8),
168 | .CLKOUT4_PHASE (0.0),
169 | .CLKOUT4_DUTY_CYCLE (0.500),
170 | .CLKOUT5_DIVIDE (8),
171 | .CLKOUT5_PHASE (0.000),
172 | .CLKOUT5_DUTY_CYCLE (0.500),
173 | .CLKIN_PERIOD (16.000)
174 | )
175 | pll_base_main
176 | (
177 | .CLKFBOUT (pllfb0),
178 | .CLKOUT0 (ck600raw),
179 | .CLKOUT1 (ck600_180raw),
180 | .CLKOUT2 (ck150raw),
181 | .CLKOUT3 (ck75raw),
182 | .CLKOUT4 (),
183 | .CLKOUT5 (),
184 | .LOCKED (locked),
185 | .RST (rClrPll),
186 | .CLKFBIN (pllfb0),
187 | .CLKIN (ckinb)
188 | );
189 |
190 | BUFG bufg_150
191 | (
192 | .O (ck150),
193 | .I (ck150raw)
194 | );
195 |
196 | BUFG bufg_75
197 | (
198 | .O (ck75),
199 | .I (ck75raw)
200 | );
201 |
202 | genvar i;
203 | generate
204 | for (i = 0; i <= 1; i = i + 1) begin: BUFPLLS
205 | BUFPLL
206 | #(
207 | .DIVIDE (4),
208 | .ENABLE_SYNC ("TRUE")
209 | )
210 | bufpll_600
211 | (
212 | .IOCLK (ck600[i]),
213 | .LOCK (dbg_in[i]),
214 | .SERDESSTROBE (strobe[i]),
215 | .GCLK (ck150),
216 | .LOCKED (locked),
217 | .PLLIN (ck600raw)
218 | );
219 |
220 | BUFPLL
221 | #(
222 | .DIVIDE (4),
223 | .ENABLE_SYNC ("TRUE")
224 | )
225 | bufpll_600_18
226 | (
227 | .IOCLK (ck600_180[i]),
228 | .LOCK (dbg_in[2 + i]),
229 | .SERDESSTROBE (strobe180[i]),
230 | .GCLK (ck150),
231 | .LOCKED (locked),
232 | .PLLIN (ck600_180raw)
233 | );
234 | end
235 |
236 | // CLOCKS, two
237 | wire [1:0] ckp;
238 | wire [1:0] ckn;
239 | for (i = 0; i <= 1; i = i + 1) begin: DDRO_CLKS
240 | OSERDES2
241 | #(
242 | .DATA_RATE_OQ ("SDR"),
243 | .DATA_RATE_OT ("SDR"),
244 | .TRAIN_PATTERN (0),
245 | .DATA_WIDTH (4),
246 | .SERDES_MODE ("NONE"),
247 | .OUTPUT_MODE ("SINGLE_ENDED")
248 | )
249 | oserdes2_dckp
250 | (
251 | .D1 (1'b0),
252 | .D2 (1'b1),
253 | .D3 (1'b0),
254 | .D4 (1'b1),
255 | .T1 (1'b0),
256 | .T2 (1'b0),
257 | .T3 (1'b0),
258 | .T4 (1'b0),
259 | .SHIFTIN1 (1'b1),
260 | .SHIFTIN2 (1'b1),
261 | .SHIFTIN3 (1'b1),
262 | .SHIFTIN4 (1'b1),
263 | .SHIFTOUT1 (),
264 | .SHIFTOUT2 (),
265 | .SHIFTOUT3 (),
266 | .SHIFTOUT4 (),
267 | .TRAIN (1'b0),
268 | .OCE (1'b1),
269 | .CLK0 (ck600_180[1]),
270 | .CLK1 (1'b0),
271 | .CLKDIV (ck150),
272 | .OQ (ckp[i]),
273 | .TQ (),
274 | .IOCE (strobe180[1]),
275 | .TCE (1'b1),
276 | .RST (reset)
277 | );
278 |
279 | OSERDES2
280 | #(
281 | .DATA_RATE_OQ ("SDR"),
282 | .DATA_RATE_OT ("SDR"),
283 | .TRAIN_PATTERN (0),
284 | .DATA_WIDTH (4),
285 | .SERDES_MODE ("NONE"),
286 | .OUTPUT_MODE ("SINGLE_ENDED")
287 | )
288 | oserdes2_dckn
289 | (
290 | .D1 (1'b1),
291 | .D2 (1'b0),
292 | .D3 (1'b1),
293 | .D4 (1'b0),
294 | .T1 (1'b0),
295 | .T2 (1'b0),
296 | .T3 (1'b0),
297 | .T4 (1'b0),
298 | .SHIFTIN1 (1'b1),
299 | .SHIFTIN2 (1'b1),
300 | .SHIFTIN3 (1'b1),
301 | .SHIFTIN4 (1'b1),
302 | .SHIFTOUT1 (),
303 | .SHIFTOUT2 (),
304 | .SHIFTOUT3 (),
305 | .SHIFTOUT4 (),
306 | .TRAIN (1'b0),
307 | .OCE (1'b1),
308 | .CLK0 (ck600_180[1]),
309 | .CLK1 (1'b0),
310 | .CLKDIV (ck150),
311 | .OQ (ckn[i]),
312 | .TQ (),
313 | .IOCE (strobe180[1]),
314 | .TCE (1'b1),
315 | .RST (reset)
316 | );
317 |
318 | OBUF obuft_ckp
319 | (
320 | .O(dckp[i]),
321 | .I(ckp[i])
322 | );
323 |
324 | OBUF obuf_ckn
325 | (
326 | .O(dckn[i]),
327 | .I(ckn[i])
328 | );
329 | end
330 |
331 | // Address, Bank address
332 | // NB ISIM can't grok parameter arrays, hence the following sim/synth bifurcation
333 | `ifdef XILINX_ISIM
334 | `else
335 | parameter integer bank_a[15:0] = {0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1};
336 | parameter integer bank_ba[2:0] = {0, 1, 1};
337 | `endif
338 |
339 | wire [15:0] wa;
340 | for (i = 0; i <= 15; i = i + 1) begin: DDRO_A
341 | OSERDES2
342 | #(
343 | .DATA_RATE_OQ ("SDR"),
344 | .DATA_RATE_OT ("SDR"),
345 | .TRAIN_PATTERN (0),
346 | .DATA_WIDTH (4),
347 | .SERDES_MODE ("NONE"),
348 | .OUTPUT_MODE ("SINGLE_ENDED")
349 | )
350 | oserdes2_a
351 | (
352 | .D1 (rDDR_Addr[i]),
353 | .D2 (rDDR_Addr[i]),
354 | .D3 (rDDR_Addr[i]),
355 | .D4 (rDDR_Addr[i]),
356 | .T1 (1'b0),
357 | .T2 (1'b0),
358 | .T3 (1'b0),
359 | .T4 (1'b0),
360 | .SHIFTIN1 (1'b1),
361 | .SHIFTIN2 (1'b1),
362 | .SHIFTIN3 (1'b1),
363 | .SHIFTIN4 (1'b1),
364 | .SHIFTOUT1 (),
365 | .SHIFTOUT2 (),
366 | .SHIFTOUT3 (),
367 | .SHIFTOUT4 (),
368 | .TRAIN (1'b0),
369 | .OCE (1'b1),
370 | `ifdef XILINX_ISIM
371 | .CLK0 (ck600_180[0]),
372 | `else
373 | .CLK0 (ck600_180[bank_a[i]]),
374 | `endif
375 | .CLK1 (1'b0),
376 | .CLKDIV (ck150),
377 | .OQ (wa[i]),
378 | .TQ (),
379 | `ifdef XILINX_ISIM
380 | .IOCE (strobe180[0]),
381 | `else
382 | .IOCE (strobe180[bank_a[i]]),
383 | `endif
384 | .TCE (1'b1),
385 | .RST (reset)
386 | );
387 |
388 | OBUF obuf_a
389 | (
390 | .O(da[i]),
391 | .I(wa[i])
392 | );
393 | end
394 |
395 | wire [2:0] wba;
396 | for (i = 0; i <= 2; i = i + 1) begin: DDRO_BA
397 | OSERDES2
398 | #(
399 | .DATA_RATE_OQ ("SDR"),
400 | .DATA_RATE_OT ("SDR"),
401 | .TRAIN_PATTERN (0),
402 | .DATA_WIDTH (4),
403 | .SERDES_MODE ("NONE"),
404 | .OUTPUT_MODE ("SINGLE_ENDED")
405 | )
406 | oserdes2_ba
407 | (
408 | .D1 (rDDR_BankAddr[i]),
409 | .D2 (rDDR_BankAddr[i]),
410 | .D3 (rDDR_BankAddr[i]),
411 | .D4 (rDDR_BankAddr[i]),
412 | .T1 (1'b0),
413 | .T2 (1'b0),
414 | .T3 (1'b0),
415 | .T4 (1'b0),
416 | .SHIFTIN1 (1'b1),
417 | .SHIFTIN2 (1'b1),
418 | .SHIFTIN3 (1'b1),
419 | .SHIFTIN4 (1'b1),
420 | .SHIFTOUT1 (),
421 | .SHIFTOUT2 (),
422 | .SHIFTOUT3 (),
423 | .SHIFTOUT4 (),
424 | .TRAIN (1'b0),
425 | .OCE (1'b1),
426 | `ifdef XILINX_ISIM
427 | .CLK0 (ck600_180[0]),
428 | `else
429 | .CLK0 (ck600_180[bank_ba[i]]),
430 | `endif
431 | .CLK1 (1'b0),
432 | .CLKDIV (ck150),
433 | .OQ (wba[i]),
434 | .TQ (),
435 | `ifdef XILINX_ISIM
436 | .IOCE (strobe180[0]),
437 | `else
438 | .IOCE (strobe180[bank_ba[i]]),
439 | `endif
440 | .TCE (1'b1),
441 | .RST (reset)
442 | );
443 |
444 | OBUF obuf_ba
445 | (
446 | .O(dba[i]),
447 | .I(wba[i])
448 | );
449 | end
450 |
451 | // command, ChipSelect
452 | wire [2:0] wkmd;
453 | for (i = 0; i <= 2; i = i + 1) begin: DDRO_KMD
454 | OSERDES2
455 | #(
456 | .DATA_RATE_OQ ("SDR"),
457 | .DATA_RATE_OT ("SDR"),
458 | .TRAIN_PATTERN (0),
459 | .DATA_WIDTH (4),
460 | .SERDES_MODE ("NONE"),
461 | .OUTPUT_MODE ("SINGLE_ENDED")
462 | )
463 | oserdes2_kmd
464 | (
465 | .D1 (rDDR_Cmd[i]), // Command for 1 cycle
466 | .D2 (rDDR_Cmd[i]),
467 | .D3 (1'b1), // NOP thereafter
468 | .D4 (1'b1),
469 | .T1 (1'b0),
470 | .T2 (1'b0),
471 | .T3 (1'b0),
472 | .T4 (1'b0),
473 | .SHIFTIN1 (1'b1),
474 | .SHIFTIN2 (1'b1),
475 | .SHIFTIN3 (1'b1),
476 | .SHIFTIN4 (1'b1),
477 | .SHIFTOUT1 (),
478 | .SHIFTOUT2 (),
479 | .SHIFTOUT3 (),
480 | .SHIFTOUT4 (),
481 | .TRAIN (1'b0),
482 | .OCE (1'b1),
483 | .CLK0 (ck600_180[1]),
484 | .CLK1 (1'b0),
485 | .CLKDIV (ck150),
486 | .OQ (wkmd[i]),
487 | .TQ (),
488 | .IOCE (strobe180[1]),
489 | .TCE (1'b1),
490 | .RST (reset)
491 | );
492 |
493 | OBUF obuf_kmd
494 | (
495 | .O(dcmd[i]),
496 | .I(wkmd[i])
497 | );
498 | end
499 |
500 | wire [1:0] wcs;
501 | for (i = 0; i <= 1; i = i + 1) begin: DDRO_CS
502 | OSERDES2
503 | #(
504 | .DATA_RATE_OQ ("SDR"),
505 | .DATA_RATE_OT ("SDR"),
506 | .TRAIN_PATTERN (0),
507 | .DATA_WIDTH (4),
508 | .SERDES_MODE ("NONE"),
509 | .OUTPUT_MODE ("SINGLE_ENDED")
510 | )
511 | oserdes2_cs
512 | (
513 | .D1 (rDDR_CS_n[i]),
514 | .D2 (rDDR_CS_n[i]),
515 | .D3 (rDDR_CS_n[i]),
516 | .D4 (rDDR_CS_n[i]),
517 | .T1 (1'b0),
518 | .T2 (1'b0),
519 | .T3 (1'b0),
520 | .T4 (1'b0),
521 | .SHIFTIN1 (1'b1),
522 | .SHIFTIN2 (1'b1),
523 | .SHIFTIN3 (1'b1),
524 | .SHIFTIN4 (1'b1),
525 | .SHIFTOUT1 (),
526 | .SHIFTOUT2 (),
527 | .SHIFTOUT3 (),
528 | .SHIFTOUT4 (),
529 | .TRAIN (1'b0),
530 | .OCE (1'b1),
531 | .CLK0 (ck600_180[1]),
532 | .CLK1 (1'b0),
533 | .CLKDIV (ck150),
534 | .OQ (wcs[i]),
535 | .TQ (),
536 | .IOCE (strobe180[1]),
537 | .TCE (1'b1),
538 | .RST (reset)
539 | );
540 |
541 | OBUF obuf_cs
542 | (
543 | .O(dcs[i]),
544 | .I(wcs[i])
545 | );
546 | end
547 |
548 | // CKE, ODT
549 | wire [1:0] wcke;
550 | for (i = 0; i <= 1; i = i + 1) begin: DDRO_CKE
551 | OSERDES2
552 | #(
553 | .DATA_RATE_OQ ("SDR"),
554 | .DATA_RATE_OT ("SDR"),
555 | .TRAIN_PATTERN (0),
556 | .DATA_WIDTH (4),
557 | .SERDES_MODE ("NONE"),
558 | .OUTPUT_MODE ("SINGLE_ENDED")
559 | )
560 | oserdes2_cke
561 | (
562 | .D1 (rDDR_CKE[i]),
563 | .D2 (rDDR_CKE[i]),
564 | .D3 (rDDR_CKE[i]),
565 | .D4 (rDDR_CKE[i]),
566 | .T1 (1'b0),
567 | .T2 (1'b0),
568 | .T3 (1'b0),
569 | .T4 (1'b0),
570 | .SHIFTIN1 (1'b1),
571 | .SHIFTIN2 (1'b1),
572 | .SHIFTIN3 (1'b1),
573 | .SHIFTIN4 (1'b1),
574 | .SHIFTOUT1 (),
575 | .SHIFTOUT2 (),
576 | .SHIFTOUT3 (),
577 | .SHIFTOUT4 (),
578 | .TRAIN (1'b0),
579 | .OCE (1'b1),
580 | .CLK0 (ck600_180[0]),
581 | .CLK1 (1'b0),
582 | .CLKDIV (ck150),
583 | .OQ (wcke[i]),
584 | .TQ (),
585 | .IOCE (strobe180[0]),
586 | .TCE (1'b1),
587 | .RST (reset)
588 | );
589 |
590 | OBUF obuf_cke
591 | (
592 | .O(dce[i]),
593 | .I(wcke[i])
594 | );
595 | end
596 |
597 | wire [1:0] wodt;
598 | for (i = 0; i <= 1; i = i + 1) begin: DDRO_ODT
599 | OSERDES2
600 | #(
601 | .DATA_RATE_OQ ("SDR"),
602 | .DATA_RATE_OT ("SDR"),
603 | .TRAIN_PATTERN (0),
604 | .DATA_WIDTH (4),
605 | .SERDES_MODE ("NONE"),
606 | .OUTPUT_MODE ("SINGLE_ENDED")
607 | )
608 | oserdes2_odt
609 | (
610 | .D1 (rDDR_ODT[i]),
611 | .D2 (rDDR_ODT[i]),
612 | .D3 (rDDR_ODT[i]),
613 | .D4 (rDDR_ODT[i]),
614 | .T1 (1'b0),
615 | .T2 (1'b0),
616 | .T3 (1'b0),
617 | .T4 (1'b0),
618 | .SHIFTIN1 (1'b1),
619 | .SHIFTIN2 (1'b1),
620 | .SHIFTIN3 (1'b1),
621 | .SHIFTIN4 (1'b1),
622 | .SHIFTOUT1 (),
623 | .SHIFTOUT2 (),
624 | .SHIFTOUT3 (),
625 | .SHIFTOUT4 (),
626 | .TRAIN (1'b0),
627 | .OCE (1'b1),
628 | .CLK0 (ck600_180[1]),
629 | .CLK1 (1'b0),
630 | .CLKDIV (ck150),
631 | .OQ (wodt[i]),
632 | .TQ (),
633 | .IOCE (strobe180[1]),
634 | .TCE (1'b1),
635 | .RST (reset)
636 | );
637 |
638 | OBUF obuf_odt
639 | (
640 | .O(dodt[i]),
641 | .I(wodt[i])
642 | );
643 | end
644 |
645 | // DQ STROBES, 8 differential pairs
646 | wire [7:0] dqso;
647 | wire [7:0] dqso_d;
648 | wire [7:0] dqst;
649 | wire [7:0] dqst_d;
650 | wire [7:0] dqson;
651 | wire [7:0] dqson_d;
652 | wire [7:0] dqstn;
653 | wire [7:0] dqstn_d;
654 | wire [7:0] dummy;
655 | wire [7:0] dummyp;
656 | wire [7:0] dummyn;
657 | for (i = 0; i <= 7; i = i + 1) begin: DDRIO_DQS
658 | OSERDES2
659 | #(
660 | .DATA_RATE_OQ ("SDR"),
661 | .DATA_RATE_OT ("SDR"),
662 | .TRAIN_PATTERN (0),
663 | .DATA_WIDTH (4),
664 | .SERDES_MODE ("NONE"),
665 | .OUTPUT_MODE ("SINGLE_ENDED")
666 | )
667 | oserdes2_dqsp
668 | (
669 | .D1 (1'b0),
670 | .D2 (1'b1),
671 | .D3 (1'b0),
672 | .D4 (1'b1),
673 | .T1 (READ),
674 | .T2 (READ),
675 | .T3 (READ),
676 | .T4 (READ),
677 | .SHIFTIN1 (1'b1),
678 | .SHIFTIN2 (1'b1),
679 | .SHIFTIN3 (1'b1),
680 | .SHIFTIN4 (1'b1),
681 | .SHIFTOUT1 (),
682 | .SHIFTOUT2 (),
683 | .SHIFTOUT3 (),
684 | .SHIFTOUT4 (),
685 | .TRAIN (1'b0),
686 | .OCE (1'b1),
687 | .CLK0 (ck600_180[i >> 2]),
688 | .CLK1 (1'b0),
689 | .CLKDIV (ck150),
690 | .OQ (dqso[i]),
691 | .TQ (dqst[i]),
692 | .IOCE (strobe180[i >> 2]),
693 | .TCE (1'b1),
694 | .RST (reset)
695 | );
696 |
697 | OSERDES2
698 | #(
699 | .DATA_RATE_OQ ("SDR"),
700 | .DATA_RATE_OT ("SDR"),
701 | .TRAIN_PATTERN (0),
702 | .DATA_WIDTH (4),
703 | .SERDES_MODE ("NONE"),
704 | .OUTPUT_MODE ("SINGLE_ENDED")
705 | )
706 | oserdes2_dqsn
707 | (
708 | .D1 (1'b1),
709 | .D2 (1'b0),
710 | .D3 (1'b1),
711 | .D4 (1'b0),
712 | .T1 (READ),
713 | .T2 (READ),
714 | .T3 (READ),
715 | .T4 (READ),
716 | .SHIFTIN1 (1'b1),
717 | .SHIFTIN2 (1'b1),
718 | .SHIFTIN3 (1'b1),
719 | .SHIFTIN4 (1'b1),
720 | .SHIFTOUT1 (),
721 | .SHIFTOUT2 (),
722 | .SHIFTOUT3 (),
723 | .SHIFTOUT4 (),
724 | .TRAIN (1'b0),
725 | .OCE (1'b1),
726 | .CLK0 (ck600_180[i >> 2]),
727 | .CLK1 (1'b0),
728 | .CLKDIV (ck150),
729 | .OQ (dqson[i]),
730 | .TQ (dqstn[i]),
731 | .IOCE (strobe180[i >> 2]),
732 | .TCE (1'b1),
733 | .RST (reset)
734 | );
735 |
736 | IODELAY2
737 | #(
738 | .DATA_RATE ("SDR"),
739 | .ODELAY_VALUE (LVL_WPHASE + i * LVL_WSLOPE),
740 | .IDELAY_VALUE (LVL_WPHASE + i * LVL_WSLOPE),
741 | .IDELAY_TYPE ("FIXED"),
742 | .DELAY_SRC ("IO")
743 | )
744 | iodelay2_dqsp
745 | (
746 | .ODATAIN (dqso[i]),
747 | .DOUT (dqso_d[i]),
748 |
749 | .T (dqst[i]),
750 | .TOUT (dqst_d[i]),
751 |
752 | .IDATAIN (dummyp[i])
753 | );
754 |
755 | IODELAY2
756 | #(
757 | .DATA_RATE ("SDR"),
758 | .ODELAY_VALUE (LVL_WPHASE + i * LVL_WSLOPE),
759 | .IDELAY_VALUE (LVL_WPHASE + i * LVL_WSLOPE),
760 | .IDELAY_TYPE ("FIXED"),
761 | .DELAY_SRC ("IO")
762 | )
763 | iodelay2_dqsn
764 | (
765 | .ODATAIN (dqson[i]),
766 | .DOUT (dqson_d[i]),
767 |
768 | .T (dqstn[i]),
769 | .TOUT (dqstn_d[i]),
770 |
771 | .IDATAIN (dummyn[i])
772 | );
773 |
774 | IOBUF iobuf_dqsp
775 | (
776 | .O(dummyp[i]),
777 | .IO(dqsp[i]),
778 | .I(dqso_d[i]),
779 | .T(dqst_d[i])
780 | );
781 |
782 | IOBUF iobuf_dqsn
783 | (
784 | .O(dummyn[i]),
785 | .IO(dqsn[i]),
786 | .I(dqson_d[i]),
787 | .T(dqstn_d[i])
788 | );
789 |
790 | end
791 |
792 | // DATA MASKS, 8
793 | wire [7:0] dmo;
794 | wire [7:0] dmo_d;
795 | wire [7:0] dmt;
796 | wire [7:0] dmt_d;
797 | for (i = 0; i <= 7; i = i + 1) begin: DDRO_DM
798 | OSERDES2
799 | #(
800 | .DATA_RATE_OQ ("SDR"),
801 | .DATA_RATE_OT ("SDR"),
802 | .TRAIN_PATTERN (0),
803 | .DATA_WIDTH (4),
804 | .SERDES_MODE ("NONE"),
805 | .OUTPUT_MODE ("SINGLE_ENDED")
806 | )
807 | oserdes2_dm
808 | (
809 | .D1 (rSmsk[i]),
810 | .D2 (rSmsk[i + 8]),
811 | .D3 (rSmsk[i + 16]),
812 | .D4 (rSmsk[i + 24]),
813 | .T1 (READ),
814 | .T2 (READ),
815 | .T3 (READ),
816 | .T4 (READ),
817 | .SHIFTIN1 (1'b1),
818 | .SHIFTIN2 (1'b1),
819 | .SHIFTIN3 (1'b1),
820 | .SHIFTIN4 (1'b1),
821 | .SHIFTOUT1 (),
822 | .SHIFTOUT2 (),
823 | .SHIFTOUT3 (),
824 | .SHIFTOUT4 (),
825 | .TRAIN (1'b0),
826 | .OCE (1'b1),
827 | .CLK0 (ck600[i >> 2]),
828 | .CLK1 (1'b0),
829 | .CLKDIV (ck150),
830 | .OQ (dmo[i]),
831 | .TQ (dmt[i]),
832 | .IOCE (strobe[i >> 2]),
833 | .TCE (1'b1),
834 | .RST (reset)
835 | );
836 |
837 | IODELAY2
838 | #(
839 | .DATA_RATE ("SDR"),
840 | .ODELAY_VALUE (LVL_WPHASE + i * LVL_WSLOPE),
841 | .IDELAY_VALUE (LVL_WPHASE + i * LVL_WSLOPE),
842 | .IDELAY_TYPE ("FIXED"),
843 | .DELAY_SRC ("IO")
844 | )
845 | iodelay2_dm
846 | (
847 | .ODATAIN (dmo[i]),
848 | .DOUT (dmo_d[i]),
849 |
850 | .T (dmt[i]),
851 | .TOUT (dmt_d[i]),
852 |
853 | .IDATAIN (dummy[i])
854 | );
855 |
856 | IOBUF iobuf_dm
857 | (
858 | .O(dummy[i]),
859 | .IO(ddm[i]),
860 | .I(dmo_d[i]),
861 | .T(dmt_d[i])
862 | );
863 | end
864 |
865 | // DQ LINES, 64
866 | wire [63:0] dqo;
867 | wire [63:0] dqo_d;
868 | wire [63:0] dqt;
869 | wire [63:0] dqt_d;
870 | wire [63:0] dqi;
871 | wire [63:0] dqi_d;
872 | for (i = 0; i <= 63; i = i + 1) begin: DDRIO_DQ
873 | OSERDES2
874 | #(
875 | .DATA_RATE_OQ ("SDR"),
876 | .DATA_RATE_OT ("SDR"),
877 | .TRAIN_PATTERN (0),
878 | .DATA_WIDTH (4),
879 | .SERDES_MODE ("NONE"),
880 | .OUTPUT_MODE ("SINGLE_ENDED")
881 | )
882 | oserdes2_dq
883 | (
884 | .D1 (rWdat[i]),
885 | .D2 (rWdat[i + 64]),
886 | .D3 (rWdat[i + 128]),
887 | .D4 (rWdat[i + 192]),
888 | .T1 (READ),
889 | .T2 (READ),
890 | .T3 (READ),
891 | .T4 (READ),
892 | .SHIFTIN1 (1'b1),
893 | .SHIFTIN2 (1'b1),
894 | .SHIFTIN3 (1'b1),
895 | .SHIFTIN4 (1'b1),
896 | .SHIFTOUT1 (),
897 | .SHIFTOUT2 (),
898 | .SHIFTOUT3 (),
899 | .SHIFTOUT4 (),
900 | .TRAIN (1'b0),
901 | .OCE (1'b1),
902 | .CLK0 (ck600[i >> 5]),
903 | .CLK1 (1'b0),
904 | .CLKDIV (ck150),
905 | .OQ (dqo[i]),
906 | .TQ (dqt[i]),
907 | .IOCE (strobe[i >> 5]),
908 | .TCE (1'b1),
909 | .RST (reset)
910 | );
911 |
912 | IODELAY2
913 | #(
914 | .DATA_RATE ("SDR"),
915 | .IDELAY_VALUE (0),
916 | .ODELAY_VALUE (LVL_WPHASE + ((i * LVL_WSLOPE) >> 3)),
917 | .IDELAY_TYPE ("VARIABLE_FROM_ZERO"),
918 | .DELAY_SRC ("IO")
919 | )
920 | iodelay2_dq
921 | (
922 | .ODATAIN (dqo[i]),
923 | .DOUT (dqo_d[i]),
924 |
925 | .T (dqt[i]),
926 | .TOUT (dqt_d[i]),
927 |
928 | .IDATAIN (dqi[i]),
929 | .DATAOUT (dqi_d[i]),
930 |
931 | .CE (rChgDelay[i]),
932 | .INC (rIncDelay[i]),
933 | .CLK (ck150),
934 | .CAL (rCalDelay2[i]),
935 | .RST (rRstDelay[i]),
936 | .IOCLK0 (ck600[i >> 5])
937 | );
938 |
939 | IOBUF iobuf_dq
940 | (
941 | .O(dqi[i]),
942 | .IO(ddq[i]),
943 | .I(dqo_d[i]),
944 | .T(dqt_d[i])
945 | );
946 |
947 | ISERDES2
948 | #(
949 | .BITSLIP_ENABLE ("FALSE"),
950 | .DATA_RATE ("SDR"),
951 | .DATA_WIDTH (4),
952 | .INTERFACE_TYPE ("RETIMED"),
953 | .SERDES_MODE ("NONE")
954 | )
955 | iserdes2_dq
956 | (
957 | .Q1 (wQ[i]),
958 | .Q2 (wQ[i + 64]),
959 | .Q3 (wQ[i + 128]),
960 | .Q4 (wQ[i + 192]),
961 | .SHIFTOUT (),
962 | .INCDEC (),
963 | .VALID (),
964 | .BITSLIP (),
965 | .CE0 (READ),
966 | .CLK0 (ck600[i >> 5]),
967 | .CLK1 (1'b0),
968 | .CLKDIV (ck150),
969 | .D (dqi_d[i]),
970 | .IOCE (strobe[i >> 5]),
971 | .RST (reset),
972 | .SHIFTIN (),
973 | .FABRICOUT (),
974 | .CFB0 (),
975 | .CFB1 (),
976 | .DFB ()
977 | );
978 | end
979 | endgenerate
980 |
981 | // DDR commands
982 | parameter K_LMR = 3'h0; // Load Mode Register (Mode Register Set)
983 | parameter K_RFSH = 3'h1; // Refresh (auto or self)
984 | parameter K_CLOSE = 3'h2; // aka PRECHARGE
985 | parameter K_OPEN = 3'h3; // aka ACTIVATE
986 | parameter K_WRITE = 3'h4;
987 | parameter K_READ = 3'h5;
988 | parameter K_ZQCAL = 3'h6; // ZQ calibration
989 | parameter K_NOP = 3'h7;
990 |
991 | // States
992 | parameter S_INIT = 3'h3;
993 | parameter S_INIT2 = 3'h5;
994 | parameter S_IDLE = 3'h0;
995 | parameter S_READ = 3'h1;
996 | parameter S_WRITE = 3'h2;
997 | parameter S_PAUSE = 3'h4;
998 |
999 | // Main DDR3 timings spec @150MHz
1000 | // tRAS RAS time 37.5 ns 6 clks open to close
1001 | // tRC RAS cycle 50.6 ns 8 clks open to next open
1002 | // tRP RAS precharge 13.1 ns 2 clks close to open
1003 | // tRRD RAS to RAS delay 4 clks 4 clks
1004 | // tRCD RAS to CAS delay 13.2 ns 2 clks
1005 | // CL CAS Latency 5 clks 5 clks
1006 | // tWR Write time 15 ns 3 clks Write finished to close issued
1007 | // tWTR Write to Read 4 clks 4 clks Write finished to read issued
1008 | // tRFC Refresh command 1Gb 110ns 17 clks Refresh command time for 1Gb parts
1009 | // tRFC Refresh command 2Gb 160ns 24 clks Refresh command time for 2Gb parts
1010 | // tRFC Refresh command 4Gb 260ns 39 clks Refresh command time for 4Gb parts
1011 | // tREFI Refresh interval 7.8 us 1170 clks
1012 | // tDQSS DQS start +-0.25 clks Time from DDR_Clk to DQS
1013 | parameter tRFC = 39;
1014 | parameter tRCD = 3;
1015 | parameter tRP = 3;
1016 |
1017 | // Provide the PLL with a good long start up reset
1018 | always @ (posedge ckinb) begin
1019 | if (rLock[13] == 1'b1) begin
1020 | rClrPll <= 1'b0;
1021 | end else begin
1022 | rClrPll <= 1'b1;
1023 | rLock <= rLock + 14'b1;
1024 | end
1025 | end
1026 |
1027 | // Hold the rest of the system in reset until the PLL has been locked for
1028 | // a good long while
1029 | always @ (posedge ckinb) begin
1030 | if (rStart[13] == 1'b1) begin
1031 | rStarted <= 1'b1;
1032 | end else begin
1033 | rStarted <= 1'b0;
1034 | if (locked) begin
1035 | rStart <= rStart + 14'b1;
1036 | end else begin
1037 | rStart <= 0;
1038 | end
1039 | end
1040 | end
1041 |
1042 | // Add pipeline delays as required to make it easy for PAR to meet timing
1043 | always @ (posedge ck150) begin
1044 | Q <= wQ;
1045 | rWdat <= swdat;
1046 | rSmsk <= smsk;
1047 | rCalDelay2 <= rCalDelay;
1048 | end
1049 |
1050 | always @ (posedge reset or posedge ck150)
1051 | if (reset) begin
1052 | rDDR_CKE <= 2'b00;
1053 | rDDR_CS_n <= 2'b11;
1054 | rDDR_ODT <= 2'b00;
1055 | rDDR_Cmd <= K_NOP;
1056 |
1057 | STATE <= S_INIT;
1058 | DLY <= 0;
1059 | RTN <= 0;
1060 | RFCNTR <= 0;
1061 | REFRESH <= 0;
1062 |
1063 | ack <= 0;
1064 |
1065 | RPULSE0 <= 0;
1066 | WPULSE0 <= 0;
1067 | rChgDelay <= 64'd0;
1068 | rIncDelay <= 64'd0;
1069 | rCalDelay <= 64'd0;
1070 | rRstDelay <= 64'd0;
1071 | end else begin
1072 | if (RFCNTR[10:7] == 4'b1001) begin // 1153/150Mhz ~7.7us
1073 | RFCNTR <= 0;
1074 | REFRESH <= 1;
1075 | end else
1076 | RFCNTR <= RFCNTR + 11'b1;
1077 |
1078 | RPULSE1 <= RPULSE0;
1079 | RPULSE2 <= RPULSE1;
1080 | RPULSE3 <= RPULSE2;
1081 | RPULSE4 <= RPULSE3;
1082 | RPULSE5 <= RPULSE4;
1083 | RPULSE6 <= RPULSE5;
1084 | RPULSE7 <= RPULSE6;
1085 |
1086 | case (dbg_out[2:0])
1087 | 3'd0: begin
1088 | ack <= WPULSE0 | RPULSE4;
1089 | end
1090 |
1091 | 3'd1: begin
1092 | ack <= WPULSE0 | RPULSE5;
1093 | end
1094 |
1095 | 3'd2: begin
1096 | ack <= WPULSE0 | RPULSE6;
1097 | end
1098 |
1099 | 3'd3: begin
1100 | ack <= WPULSE0 | RPULSE7;
1101 | end
1102 |
1103 | 3'd4: begin
1104 | ack <= WPULSE0 | RPULSE4;
1105 | end
1106 |
1107 | 3'd5: begin
1108 | ack <= WPULSE0 | RPULSE5;
1109 | end
1110 |
1111 | 3'd6: begin
1112 | ack <= WPULSE0 | RPULSE6;
1113 | end
1114 |
1115 | 3'd7: begin
1116 | ack <= WPULSE0 | RPULSE7;
1117 | end
1118 | endcase
1119 |
1120 | case (STATE)
1121 | S_INIT: begin
1122 | rDDR_CKE <= 2'b11;
1123 | READ <= 0;
1124 | rDDR_BankAddr <= sa[15:13];
1125 | rDDR_Addr <= sa[31:16];
1126 | if (swr) begin
1127 | rDDR_CS_n <= sa[32] ? 2'b01 : 2'b10;
1128 | STATE <= S_INIT2;
1129 | rDDR_Cmd <= sa[10:8];
1130 | WPULSE0 <= 1;
1131 | end
1132 | end
1133 |
1134 | S_INIT2: begin
1135 | RTN <= sa[33] ? S_INIT : S_IDLE;
1136 | rDDR_Cmd <= K_NOP;
1137 | STATE <= S_PAUSE;
1138 | DLY <= 20;
1139 | WPULSE0 <= 0;
1140 | end
1141 |
1142 | S_IDLE: begin
1143 | READ <= 0;
1144 | rDDR_ODT <= 2'b00;
1145 | if (swr) begin
1146 | rDDR_Cmd <= K_OPEN;
1147 | STATE <= S_PAUSE;
1148 | RTN <= S_WRITE;
1149 | DLY <= tRCD - 1;
1150 | rDDR_Addr <= sa[31:16];
1151 | rDDR_BankAddr <= sa[15:13];
1152 | rDDR_CS_n <= sa[32] ? 2'b01 : 2'b10;
1153 | end else if (srd) begin
1154 | rDDR_Cmd <= K_OPEN;
1155 | STATE <= S_PAUSE;
1156 | RTN <= S_READ;
1157 | DLY <= tRCD - 1;
1158 | rDDR_Addr <= sa[31:16];
1159 | rDDR_BankAddr <= sa[15:13];
1160 | rDDR_CS_n <= sa[32] ? 2'b01 : 2'b10;
1161 | end else if (REFRESH) begin
1162 | rDDR_Cmd <= K_RFSH;
1163 | STATE <= S_PAUSE;
1164 | RTN <= S_IDLE;
1165 | DLY <= tRFC - 1;
1166 | REFRESH <= 0;
1167 | rDDR_CS_n <= 2'b00;
1168 | end else begin
1169 | rDDR_Cmd <= K_NOP;
1170 | rDDR_CS_n <= 2'b00;
1171 | end
1172 | end
1173 |
1174 | // Address bits
1175 | // ============
1176 | // MB pg Lwd sa Row Col Bnk CS
1177 | // [X] - - - - - - -
1178 | // [X] - - - - - - -
1179 | // 2 - 0 - - - - -
1180 | // 3 - 1 [L] - 0 - -
1181 | // 4 - 2 [L] - 1 - -
1182 | // 5 - - 5 - 2 - -
1183 | // 6 - - 6 - 3 - -
1184 | // 7 - - 7 - 4 - -
1185 | // 8 - - 8 - 5 - -
1186 | // 9 - - 9 - 6 - -
1187 | // 10 - - 10 - 7 - -
1188 | // 11 - - 11 - 8 - -
1189 | // 12 - - 12 - 9 - -
1190 | // 13 - - 13 - [P] 0 -
1191 | // 14 - - 14 - - 1 -
1192 | // 15 - - 15 - - 2 -
1193 | // 16 - - 16 0 - - -
1194 | // 17 - - 17 1 - - -
1195 | // 18 - - 18 2 - - -
1196 | // 19 - - 19 3 - - -
1197 | // 20 - - 20 4 - - -
1198 | // 21 - - 21 5 - - -
1199 | // 22 - - 22 6 - - -
1200 | // 23 - - 23 7 - - -
1201 | // 24 - - 24 8 - - -
1202 | // 25 - - 25 9 - - -
1203 | // 26 - - 26 10 - - -
1204 | // 27 - - 27 11 - - -
1205 | // 28 - - 28 12 - - -
1206 | // 29 - - 29 13 - - -
1207 | // [H] 0 - 30 14 - - -
1208 | // [H] 1 - 31 15 - - -
1209 | // - 2 - 32 - - - 0
1210 | // - 3 - 33 - - - Extra address bit for DRAM init register space
1211 |
1212 | S_WRITE: begin
1213 | rDDR_Cmd <= K_WRITE;
1214 | STATE <= S_PAUSE;
1215 | RTN <= S_IDLE;
1216 | DLY <= 14; // CWL + 2xfer + tWR + tRP
1217 | rDDR_Addr[10:0] <= {1'b1, sa[12:5], 2'b00}; // NB two LSBs ignored by DDR3 during WRITE
1218 | rDDR_Addr[12] <= dbg_out[2];
1219 | rDDR_BankAddr <= sa[15:13];
1220 | rDDR_ODT <= sa[16] ? 2'b10 : 2'b01; // Use ODT only in one rank, otherwise 40R || 40R -> 20R
1221 | WPULSE0 <= 1;
1222 | if (sa[33]) begin
1223 | rChgDelay <= rWdat[63:0];
1224 | rIncDelay <= rWdat[127:64];
1225 | rCalDelay <= rWdat[191:128];
1226 | rRstDelay <= rWdat[255:192];
1227 | end else begin
1228 | rChgDelay <= 64'd0;
1229 | rIncDelay <= 64'd0;
1230 | rCalDelay <= 64'd0;
1231 | rRstDelay <= 64'd0;
1232 | end
1233 | end
1234 |
1235 | S_READ: begin
1236 | rDDR_Cmd <= K_READ;
1237 | STATE <= S_PAUSE;
1238 | RTN <= S_IDLE;
1239 | DLY <= 10; // CL + 2xfer + 1 + tRP
1240 | rDDR_Addr[10:0] <= {1'b1, sa[12:5], 2'b00};
1241 | rDDR_Addr[12] <= dbg_out[2];
1242 | rDDR_BankAddr <= sa[15:13];
1243 | READ <= 1;
1244 | RPULSE0 <= 1;
1245 | end
1246 |
1247 | S_PAUSE: begin
1248 | rDDR_Cmd <= K_NOP;
1249 | DLY <= DLY - 6'b000001;
1250 | if (DLY == 6'b000001)
1251 | STATE <= RTN;
1252 | else
1253 | STATE <= S_PAUSE;
1254 | RPULSE0 <= 0;
1255 | WPULSE0 <= 0;
1256 | rChgDelay <= 64'd0;
1257 | rIncDelay <= 64'd0;
1258 | rCalDelay <= 64'd0;
1259 | rRstDelay <= 64'd0;
1260 | end
1261 | endcase
1262 | end
1263 |
1264 | assign srdat = Q;
1265 | assign srdy = ack;
1266 |
1267 | assign ckouthalf = ck75;
1268 | assign ckout = ck150;
1269 |
1270 | assign reset = ~rStarted;
1271 | assign dbg_in[4] = locked;
1272 | assign dbg_in[7:5] = rDDR_Cmd;
1273 |
1274 | endmodule
1275 |
1276 |
--------------------------------------------------------------------------------
/system.ucf:
--------------------------------------------------------------------------------
1 | # For SiOI FS6484 Spartan 6 board
2 | # Copyright 2012 SiOI
3 |
4 | CONFIG VCCAUX=3.3;
5 |
6 | Net mck62M5 TNM_NET = sys_clk_pin;
7 | TIMESPEC TS_sys_clk_pin = PERIOD sys_clk_pin 16.000 ns HIGH 50% INPUT_JITTER 100.0ps;
8 |
9 | Net mck62M5 LOC=M3 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50;
10 | Net mled<0> LOC=AB2 | IOSTANDARD=LVCMOS33 | SLEW=QUIETIO;
11 | Net mled<1> LOC=AA2 | IOSTANDARD=LVCMOS33 | SLEW=QUIETIO;
12 | Net mbtn<0> LOC=Y3 | IOSTANDARD=LVCMOS33 | PULLUP;
13 | Net mbtn<1> LOC=AB3 | IOSTANDARD=LVCMOS33 | PULLUP;
14 |
15 | Net txd LOC=B10 | IOSTANDARD=LVCMOS33;
16 | Net rxd LOC=A10 | IOSTANDARD=LVCMOS33;
17 |
18 | #Net sda LOC=P2 | IOSTANDARD=SSTL15_II;
19 | #Net scl LOC=L4 | IOSTANDARD=SSTL15_II;
20 |
21 | # PAR usually gets the following right but use manual placement if it fails:
22 | #INST "*BUFPLLS[0].bufpll_625_18" LOC=BUFPLL_X0Y3;
23 | #INST "*BUFPLLS[1].bufpll_625_18" LOC=BUFPLL_X2Y3;
24 |
25 | # Ignore the timing of the GPIO outputs from the MicroBlaze:
26 | inst "mcs_0/U0/iomodule_0/IOModule_Core_I1/GPO_I?/gpo_io_i_?" TIG;
27 |
28 | # Apply TIGs to reset circuitry, allowing it to take multiple clock cycles
29 | inst "drac/rStarted" TIG;
30 | inst "drac/rClrPll" TIG;
31 |
32 | # It is OK for tristating of the data pins can take multiple clock cycles
33 | inst "drac/READ" TIG;
34 |
35 | # 20121011; OUT_TERM=UNTUNED_50 is too strong, use OUT_TERM=UNTUNED_25
36 |
37 | Net ddq<0> LOC=W3 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#LB
38 | Net ddq<1> LOC=W1 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#LB
39 | Net ddq<2> LOC=U3 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#LB
40 | Net ddq<3> LOC=T1 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#LB
41 | Net ddq<4> LOC=Y2 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#LB
42 | Net ddq<5> LOC=V2 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#LB
43 | Net ddq<6> LOC=U1 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#LB
44 | Net ddq<7> LOC=T2 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#LB
45 | Net ddq<8> LOC=T4 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#LB
46 | Net ddq<9> LOC=R3 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#LB
47 | Net ddq<10> LOC=M1 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#LB
48 | Net ddq<11> LOC=L1 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#LB
49 | Net ddq<12> LOC=T3 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#LB
50 | Net ddq<13> LOC=R1 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#LB
51 | Net ddq<14> LOC=M2 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#LB
52 | Net ddq<15> LOC=L3 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#LB
53 | Net ddq<16> LOC=K1 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#LB
54 | Net ddq<17> LOC=K2 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#LB
55 | Net ddq<18> LOC=H2 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#LT
56 | Net ddq<19> LOC=G1 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#LT
57 | Net ddq<20> LOC=M5 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#LB
58 | Net ddq<21> LOC=J3 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#LB
59 | Net ddq<22> LOC=H1 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#LT
60 | Net ddq<23> LOC=G3 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#LT
61 | Net ddq<24> LOC=F1 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#LT
62 | Net ddq<25> LOC=E1 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#LT
63 | Net ddq<26> LOC=C3 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#LT
64 | Net ddq<27> LOC=B2 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#LT
65 | Net ddq<28> LOC=F3 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#LT
66 | Net ddq<29> LOC=F2 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#LT
67 | Net ddq<30> LOC=C1 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#LT
68 | Net ddq<31> LOC=B1 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#LT
69 | Net ddq<32> LOC=C22 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#RT
70 | Net ddq<33> LOC=C20 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#RT
71 | Net ddq<34> LOC=E20 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#RT
72 | Net ddq<35> LOC=F22 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#RT
73 | Net ddq<36> LOC=C19 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#RT
74 | Net ddq<37> LOC=D21 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#RT
75 | Net ddq<38> LOC=E22 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#RT
76 | Net ddq<39> LOC=F21 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#RT
77 | Net ddq<40> LOC=G22 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#RT
78 | Net ddq<41> LOC=H21 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#RT
79 | Net ddq<42> LOC=J20 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#RB
80 | Net ddq<43> LOC=K21 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#RB
81 | Net ddq<44> LOC=F20 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#RT
82 | Net ddq<45> LOC=G20 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#RT
83 | Net ddq<46> LOC=J22 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#RB
84 | Net ddq<47> LOC=K22 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#RB
85 | Net ddq<48> LOC=L20 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#RB
86 | Net ddq<49> LOC=M21 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#RB
87 | Net ddq<50> LOC=P21 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#RB
88 | Net ddq<51> LOC=R22 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#RB
89 | Net ddq<52> LOC=L22 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#RB
90 | Net ddq<53> LOC=M22 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#RB
91 | Net ddq<54> LOC=P22 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#RB
92 | Net ddq<55> LOC=R20 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#RB
93 | Net ddq<56> LOC=T22 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#RB
94 | Net ddq<57> LOC=U20 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#RB
95 | Net ddq<58> LOC=V21 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#RB
96 | Net ddq<59> LOC=W22 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#RB
97 | Net ddq<60> LOC=P19 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#RB
98 | Net ddq<61> LOC=T21 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#RB
99 | Net ddq<62> LOC=V22 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#RB
100 | Net ddq<63> LOC=W20 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#RB
101 |
102 | Net dqsp<0> LOC=U4 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#LB
103 | Net dqsp<1> LOC=N1 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#LB
104 | Net dqsp<2> LOC=H3 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#LT
105 | Net dqsp<3> LOC=D2 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#LT
106 | Net dqsp<4> LOC=D19 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#RT
107 | Net dqsp<5> LOC=J19 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#RT
108 | Net dqsp<6> LOC=N20 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#RB
109 | Net dqsp<7> LOC=T19 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#RB
110 |
111 | Net dqsn<0> LOC=V3 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#LB
112 | Net dqsn<1> LOC=N3 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#LB
113 | Net dqsn<2> LOC=H4 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#LT
114 | Net dqsn<3> LOC=D1 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#LT
115 | Net dqsn<4> LOC=D20 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#RT
116 | Net dqsn<5> LOC=H20 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#RT
117 | Net dqsn<6> LOC=N22 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#RB
118 | Net dqsn<7> LOC=T20 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#RB
119 |
120 | #
121 | # DM signals are outputs during writes and tristated at both ends during reads. We use parallel
122 | # termination during reads on the assumption that it is better for the DM PCB traces not to float.
123 | # It probably is not necessary, but it does not hurt.
124 | #
125 | Net ddm<0> LOC=V1 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#LB
126 | Net ddm<1> LOC=P1 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#LB
127 | Net ddm<2> LOC=J1 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#LB
128 | Net ddm<3> LOC=E3 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#LT
129 | Net ddm<4> LOC=D22 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#RT
130 | Net ddm<5> LOC=H22 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#RT
131 | Net ddm<6> LOC=M19 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#RB
132 | Net ddm<7> LOC=U22 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#RB
133 |
134 | Net da<0> LOC=G19 | IOSTANDARD=SSTL15_II | OUT_TERM=UNTUNED_25;#RT
135 | Net da<1> LOC=A21 | IOSTANDARD=SSTL15_II | OUT_TERM=UNTUNED_25;#RT
136 | Net da<2> LOC=A20 | IOSTANDARD=SSTL15_II | OUT_TERM=UNTUNED_25;#RT
137 | Net da<3> LOC=A2 | IOSTANDARD=SSTL15_II | OUT_TERM=UNTUNED_25;#LT
138 | Net da<4> LOC=H8 | IOSTANDARD=SSTL15_II | OUT_TERM=UNTUNED_25;#LT
139 | Net da<5> LOC=G6 | IOSTANDARD=SSTL15_II | OUT_TERM=UNTUNED_25;#LT
140 | Net da<6> LOC=F5 | IOSTANDARD=SSTL15_II | OUT_TERM=UNTUNED_25;#LT
141 | Net da<7> LOC=G4 | IOSTANDARD=SSTL15_II | OUT_TERM=UNTUNED_25;#LT
142 | Net da<8> LOC=H6 | IOSTANDARD=SSTL15_II | OUT_TERM=UNTUNED_25;#LT
143 | Net da<9> LOC=J7 | IOSTANDARD=SSTL15_II | OUT_TERM=UNTUNED_25;#LT
144 | Net da<10> LOC=H19 | IOSTANDARD=SSTL15_II | OUT_TERM=UNTUNED_25;#RT
145 | Net da<11> LOC=H5 | IOSTANDARD=SSTL15_II | OUT_TERM=UNTUNED_25;#LT
146 | Net da<12> LOC=J6 | IOSTANDARD=SSTL15_II | OUT_TERM=UNTUNED_25;#LT
147 | Net da<13> LOC=M20 | IOSTANDARD=SSTL15_II | OUT_TERM=UNTUNED_25;#RB
148 | Net da<14> LOC=K4 | IOSTANDARD=SSTL15_II | OUT_TERM=UNTUNED_25;#LT
149 | Net da<15> LOC=K3 | IOSTANDARD=SSTL15_II | OUT_TERM=UNTUNED_25;#LT
150 |
151 | Net dba<0> LOC=J17 | IOSTANDARD=SSTL15_II | OUT_TERM=UNTUNED_25;#RT
152 | Net dba<1> LOC=H18 | IOSTANDARD=SSTL15_II | OUT_TERM=UNTUNED_25;#RT
153 | Net dba<2> LOC=J4 | IOSTANDARD=SSTL15_II | OUT_TERM=UNTUNED_25;#LT
154 |
155 | Net dcmd<2> LOC=K17 | IOSTANDARD=SSTL15_II | OUT_TERM=UNTUNED_25;#RT # RAS
156 | Net dcmd<1> LOC=K18 | IOSTANDARD=SSTL15_II | OUT_TERM=UNTUNED_25;#RB # CAS
157 | Net dcmd<0> LOC=K20 | IOSTANDARD=SSTL15_II | OUT_TERM=UNTUNED_25;#RT # WE
158 |
159 | Net dce<0> LOC=K5 | IOSTANDARD=SSTL15_II | OUT_TERM=UNTUNED_25;#LT
160 | Net dce<1> LOC=K6 | IOSTANDARD=SSTL15_II | OUT_TERM=UNTUNED_25;#LT
161 |
162 | Net dcs<0> LOC=K19 | IOSTANDARD=SSTL15_II | OUT_TERM=UNTUNED_25;#RT
163 | Net dcs<1> LOC=L17 | IOSTANDARD=SSTL15_II | OUT_TERM=UNTUNED_25;#RB
164 |
165 | Net dckp<0> LOC=F18 | IOSTANDARD=SSTL15_II | OUT_TERM=UNTUNED_25;#RT
166 | Net dckp<1> LOC=B21 | IOSTANDARD=SSTL15_II | OUT_TERM=UNTUNED_25;#RT
167 |
168 | Net dckn<0> LOC=F19 | IOSTANDARD=SSTL15_II | OUT_TERM=UNTUNED_25;#RT
169 | Net dckn<1> LOC=B22 | IOSTANDARD=SSTL15_II | OUT_TERM=UNTUNED_25;#RT
170 |
171 | Net dodt<0> LOC=L19 | IOSTANDARD=SSTL15_II | OUT_TERM=UNTUNED_25;#RB
172 | Net dodt<1> LOC=P20 | IOSTANDARD=SSTL15_II | OUT_TERM=UNTUNED_25;#RB
173 |
174 |
175 |
--------------------------------------------------------------------------------
/top.v:
--------------------------------------------------------------------------------
1 | /*
2 | MicroBlaze MCS to DDR3 glue
3 | (C) Copyright 2012 Silicon On Inspiration
4 | www.sioi.com.au
5 | 86 Longueville Road
6 | Lane Cove 2066
7 | New South Wales
8 | AUSTRALIA
9 |
10 | This program is free software: you can redistribute it and/or modify
11 | it under the terms of the GNU Lesser General Public License as published by
12 | the Free Software Foundation, either version 3 of the License, or
13 | (at your option) any later version.
14 |
15 | This program is distributed in the hope that it will be useful,
16 | but WITHOUT ANY WARRANTY; without even the implied warranty of
17 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 | GNU Lesser General Public License for more details.
19 |
20 | You should have received a copy of the GNU Lesser General Public License
21 | along with this program. If not, see .
22 | */
23 |
24 | `timescale 1ns / 1ps
25 |
26 | module top
27 | (
28 | input mck62M5,
29 | output [1:0] mled,
30 | input [1:0] mbtn,
31 | output txd,
32 | input rxd,
33 |
34 | inout [63:0] ddq,
35 | inout [7:0] dqsp,
36 | inout [7:0] dqsn,
37 | output [7:0] ddm,
38 | output [15:0] da,
39 | output [2:0] dba,
40 | output [2:0] dcmd,
41 | output [1:0] dce,
42 | output [1:0] dcs,
43 | output [1:0] dckp,
44 | output [1:0] dckn,
45 | output [1:0] dodt
46 | );
47 |
48 | wire Reset;
49 | wire IO_Ready;
50 | wire IO_Addr_Strobe;
51 | wire IO_Read_Strobe;
52 | wire IO_Write_Strobe;
53 | wire [31 : 0] IO_Read_Data;
54 | wire [1 : 0] GPI1;
55 | wire [31 : 0] IO_Address;
56 | wire [3 : 0] IO_Byte_Enable;
57 | wire [31 : 0] IO_Write_Data;
58 | wire [1 : 0] GPO1;
59 | wire [3 : 0] page;
60 |
61 | wire srd;
62 | wire swr;
63 | wire [33:5] sa;
64 | wire [255:0] swdat;
65 | wire [31:0] smsk;
66 | wire [255:0] srdat;
67 | wire srdy;
68 |
69 | wire ck150;
70 | wire ck75;
71 |
72 | wire [0 : 31] Trace_Instruction;
73 | wire [0 : 31] Trace_PC;
74 | wire [0 : 4] Trace_Reg_Addr;
75 | wire [0 : 14] Trace_MSR_Reg;
76 | wire [0 : 31] Trace_New_Reg_Value;
77 | wire [0 : 31] Trace_Data_Address;
78 | wire [0 : 31] Trace_Data_Write_Value;
79 | wire [0 : 3] Trace_Data_Byte_Enable;
80 |
81 | wire [2:0] dbg_out;
82 | wire [7:0] dbg_in;
83 |
84 | drac_ddr3 drac
85 | (
86 | .ckin (mck62M5),
87 | .ckout (ck150),
88 | .ckouthalf (ck75),
89 | .reset (Reset),
90 |
91 | .ddq (ddq),
92 | .dqsp (dqsp),
93 | .dqsn (dqsn),
94 | .ddm (ddm),
95 | .da (da),
96 | .dba (dba),
97 | .dcmd (dcmd),
98 | .dce (dce),
99 | .dcs (dcs),
100 | .dckp (dckp),
101 | .dckn (dckn),
102 | .dodt (dodt),
103 |
104 | .srd (srd),
105 | .swr (swr),
106 | .sa (sa),
107 | .swdat (swdat),
108 | .smsk (smsk),
109 | .srdat (srdat),
110 | .srdy (srdy),
111 |
112 | .dbg_out (dbg_out),
113 | .dbg_in (dbg_in)
114 | );
115 |
116 | adapter glue
117 | (
118 | .ckmb (ck75),
119 | .ckdr (ck150),
120 | .reset (Reset),
121 |
122 | .srd (srd),
123 | .swr (swr),
124 | .sa (sa),
125 | .swdat (swdat),
126 | .smsk (smsk),
127 | .srdat (srdat),
128 | .srdy (srdy),
129 |
130 | .IO_Ready (IO_Ready),
131 | .IO_Addr_Strobe (IO_Addr_Strobe),
132 | .IO_Read_Strobe (IO_Read_Strobe),
133 | .IO_Write_Strobe (IO_Write_Strobe),
134 | .IO_Read_Data (IO_Read_Data),
135 | .IO_Address (IO_Address),
136 | .IO_Byte_Enable (IO_Byte_Enable),
137 | .IO_Write_Data (IO_Write_Data),
138 | .page (page),
139 | .dbg_out (dbg_out)
140 | );
141 |
142 | microblaze_mcs_v1_1 mcs_0
143 | (
144 | .Clk (ck75),
145 | .Reset (Reset),
146 | .IO_Ready (IO_Ready),
147 | .UART_Rx (rxd),
148 | .IO_Addr_Strobe (IO_Addr_Strobe),
149 | .IO_Read_Strobe (IO_Read_Strobe),
150 | .IO_Write_Strobe (IO_Write_Strobe),
151 | .UART_Tx (txdraw),
152 | .IO_Read_Data (IO_Read_Data),
153 | .GPI1 (mbtn),
154 | .GPI2 (dbg_in),
155 | .IO_Address (IO_Address),
156 | .IO_Byte_Enable (IO_Byte_Enable),
157 | .IO_Write_Data (IO_Write_Data),
158 | .GPO1 (mled),
159 | .GPO2 (page),
160 | .GPO3 (dbg_out),
161 | .Trace_Instruction (Trace_Instruction), // Opcode
162 | .Trace_Valid_Instr (Trace_Valid_Instr), // valid opcode y/n
163 | .Trace_PC (Trace_PC), // PC
164 | .Trace_Reg_Write (Trace_Reg_Write), // output Trace_Reg_Write
165 | .Trace_Reg_Addr (Trace_Reg_Addr), // output [0 : 4] Trace_Reg_Addr
166 | .Trace_MSR_Reg (Trace_MSR_Reg), // output [0 : 14] Trace_MSR_Reg
167 | .Trace_New_Reg_Value (Trace_New_Reg_Value), // output [0 : 31] Trace_New_Reg_Value
168 | .Trace_Jump_Taken (Trace_Jump_Taken), // Jump Taken
169 | .Trace_Delay_Slot (Trace_Delay_Slot), // Delay Slot
170 | .Trace_Data_Address (Trace_Data_Address), // Data Address
171 | .Trace_Data_Access (Trace_Data_Access), // Data_Access y/n
172 | .Trace_Data_Read (Trace_Data_Read), // Data Read y/n
173 | .Trace_Data_Write (Trace_Data_Write), // Data Write y/n
174 | .Trace_Data_Write_Value (Trace_Data_Write_Value), // Data Write Value
175 | .Trace_Data_Byte_Enable (Trace_Data_Byte_Enable), // Data Byte Enables
176 | .Trace_MB_Halted (Trace_MB_Halted) // Halted
177 | );
178 |
179 | assign txd = ~txdraw;
180 |
181 | endmodule
182 |
183 |
--------------------------------------------------------------------------------