├── 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 | --------------------------------------------------------------------------------