OpenCores
URL https://opencores.org/ocsvn/ddr3_sdram/ddr3_sdram/trunk

Subversion Repositories ddr3_sdram

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /ddr3_sdram/trunk
    from Rev 1 to Rev 2
    Reverse comparison

Rev 1 → Rev 2

/system.ucf
0,0 → 1,174
# For SiOI FG484 Spartan 6 board
# Copyright 2012 SiOI
 
CONFIG VCCAUX=3.3;
 
Net mck62M5 TNM_NET = sys_clk_pin;
TIMESPEC TS_sys_clk_pin = PERIOD sys_clk_pin 16.000 ns HIGH 50% INPUT_JITTER 100.0ps;
 
Net mck62M5 LOC=M3 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50;
Net mled<0> LOC=AB2 | IOSTANDARD=LVCMOS33 | SLEW=QUIETIO;
Net mled<1> LOC=AA2 | IOSTANDARD=LVCMOS33 | SLEW=QUIETIO;
Net mbtn<0> LOC=Y3 | IOSTANDARD=LVCMOS33 | PULLUP;
Net mbtn<1> LOC=AB3 | IOSTANDARD=LVCMOS33 | PULLUP;
 
Net txd LOC=B10 | IOSTANDARD=LVCMOS33;
Net rxd LOC=A10 | IOSTANDARD=LVCMOS33;
 
#Net sda LOC=P2 | IOSTANDARD=SSTL15_II;
#Net scl LOC=L4 | IOSTANDARD=SSTL15_II;
 
# PAR usually gets the following right but use manual placement if it fails:
#INST "*BUFPLLS[0].bufpll_625_18" LOC=BUFPLL_X0Y3;
#INST "*BUFPLLS[1].bufpll_625_18" LOC=BUFPLL_X2Y3;
 
# Ignore the timing of the GPIO outputs from the MicroBlaze:
inst "mcs_0/U0/iomodule_0/IOModule_Core_I1/GPO_I?/gpo_io_i_?" TIG;
 
# Apply TIGs to reset circuitry, allowing it to take multiple clock cycles
inst "drac/rStarted" TIG;
inst "drac/rClrPll" TIG;
 
# It is OK for tristating of the data pins can take multiple clock cycles
inst "drac/READ" TIG;
 
# 20121011; OUT_TERM=UNTUNED_50 is too strong, use OUT_TERM=UNTUNED_25
 
Net ddq<0> LOC=W3 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#LB
Net ddq<1> LOC=W1 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#LB
Net ddq<2> LOC=U3 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#LB
Net ddq<3> LOC=T1 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#LB
Net ddq<4> LOC=Y2 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#LB
Net ddq<5> LOC=V2 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#LB
Net ddq<6> LOC=U1 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#LB
Net ddq<7> LOC=T2 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#LB
Net ddq<8> LOC=T4 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#LB
Net ddq<9> LOC=R3 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#LB
Net ddq<10> LOC=M1 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#LB
Net ddq<11> LOC=L1 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#LB
Net ddq<12> LOC=T3 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#LB
Net ddq<13> LOC=R1 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#LB
Net ddq<14> LOC=M2 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#LB
Net ddq<15> LOC=L3 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#LB
Net ddq<16> LOC=K1 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#LB
Net ddq<17> LOC=K2 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#LB
Net ddq<18> LOC=H2 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#LT
Net ddq<19> LOC=G1 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#LT
Net ddq<20> LOC=M5 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#LB
Net ddq<21> LOC=J3 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#LB
Net ddq<22> LOC=H1 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#LT
Net ddq<23> LOC=G3 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#LT
Net ddq<24> LOC=F1 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#LT
Net ddq<25> LOC=E1 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#LT
Net ddq<26> LOC=C3 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#LT
Net ddq<27> LOC=B2 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#LT
Net ddq<28> LOC=F3 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#LT
Net ddq<29> LOC=F2 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#LT
Net ddq<30> LOC=C1 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#LT
Net ddq<31> LOC=B1 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#LT
Net ddq<32> LOC=C22 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#RT
Net ddq<33> LOC=C20 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#RT
Net ddq<34> LOC=E20 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#RT
Net ddq<35> LOC=F22 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#RT
Net ddq<36> LOC=C19 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#RT
Net ddq<37> LOC=D21 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#RT
Net ddq<38> LOC=E22 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#RT
Net ddq<39> LOC=F21 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#RT
Net ddq<40> LOC=G22 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#RT
Net ddq<41> LOC=H21 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#RT
Net ddq<42> LOC=J20 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#RB
Net ddq<43> LOC=K21 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#RB
Net ddq<44> LOC=F20 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#RT
Net ddq<45> LOC=G20 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#RT
Net ddq<46> LOC=J22 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#RB
Net ddq<47> LOC=K22 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#RB
Net ddq<48> LOC=L20 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#RB
Net ddq<49> LOC=M21 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#RB
Net ddq<50> LOC=P21 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#RB
Net ddq<51> LOC=R22 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#RB
Net ddq<52> LOC=L22 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#RB
Net ddq<53> LOC=M22 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#RB
Net ddq<54> LOC=P22 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#RB
Net ddq<55> LOC=R20 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#RB
Net ddq<56> LOC=T22 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#RB
Net ddq<57> LOC=U20 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#RB
Net ddq<58> LOC=V21 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#RB
Net ddq<59> LOC=W22 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#RB
Net ddq<60> LOC=P19 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#RB
Net ddq<61> LOC=T21 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#RB
Net ddq<62> LOC=V22 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#RB
Net ddq<63> LOC=W20 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#RB
 
Net dqsp<0> LOC=U4 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#LB
Net dqsp<1> LOC=N1 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#LB
Net dqsp<2> LOC=H3 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#LT
Net dqsp<3> LOC=D2 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#LT
Net dqsp<4> LOC=D19 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#RT
Net dqsp<5> LOC=J19 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#RT
Net dqsp<6> LOC=N20 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#RB
Net dqsp<7> LOC=T19 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#RB
 
Net dqsn<0> LOC=V3 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#LB
Net dqsn<1> LOC=N3 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#LB
Net dqsn<2> LOC=H4 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#LT
Net dqsn<3> LOC=D1 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#LT
Net dqsn<4> LOC=D20 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#RT
Net dqsn<5> LOC=H20 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#RT
Net dqsn<6> LOC=N22 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#RB
Net dqsn<7> LOC=T20 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#RB
 
#
# DM signals are outputs during writes and tristated at both ends during reads. We use parallel
# termination during reads on the assumption that it is better for the DM PCB traces not to float.
# It probably is not necessary, but it does not hurt.
#
Net ddm<0> LOC=V1 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#LB
Net ddm<1> LOC=P1 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#LB
Net ddm<2> LOC=J1 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#LB
Net ddm<3> LOC=E3 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#LT
Net ddm<4> LOC=D22 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#RT
Net ddm<5> LOC=H22 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#RT
Net ddm<6> LOC=M19 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#RB
Net ddm<7> LOC=U22 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#RB
 
Net da<0> LOC=G19 | IOSTANDARD=SSTL15_II | OUT_TERM=UNTUNED_25;#RT
Net da<1> LOC=A21 | IOSTANDARD=SSTL15_II | OUT_TERM=UNTUNED_25;#RT
Net da<2> LOC=A20 | IOSTANDARD=SSTL15_II | OUT_TERM=UNTUNED_25;#RT
Net da<3> LOC=A2 | IOSTANDARD=SSTL15_II | OUT_TERM=UNTUNED_25;#LT
Net da<4> LOC=H8 | IOSTANDARD=SSTL15_II | OUT_TERM=UNTUNED_25;#LT
Net da<5> LOC=G6 | IOSTANDARD=SSTL15_II | OUT_TERM=UNTUNED_25;#LT
Net da<6> LOC=F5 | IOSTANDARD=SSTL15_II | OUT_TERM=UNTUNED_25;#LT
Net da<7> LOC=G4 | IOSTANDARD=SSTL15_II | OUT_TERM=UNTUNED_25;#LT
Net da<8> LOC=H6 | IOSTANDARD=SSTL15_II | OUT_TERM=UNTUNED_25;#LT
Net da<9> LOC=J7 | IOSTANDARD=SSTL15_II | OUT_TERM=UNTUNED_25;#LT
Net da<10> LOC=H19 | IOSTANDARD=SSTL15_II | OUT_TERM=UNTUNED_25;#RT
Net da<11> LOC=H5 | IOSTANDARD=SSTL15_II | OUT_TERM=UNTUNED_25;#LT
Net da<12> LOC=J6 | IOSTANDARD=SSTL15_II | OUT_TERM=UNTUNED_25;#LT
Net da<13> LOC=M20 | IOSTANDARD=SSTL15_II | OUT_TERM=UNTUNED_25;#RB
Net da<14> LOC=K4 | IOSTANDARD=SSTL15_II | OUT_TERM=UNTUNED_25;#LT
Net da<15> LOC=K3 | IOSTANDARD=SSTL15_II | OUT_TERM=UNTUNED_25;#LT
 
Net dba<0> LOC=J17 | IOSTANDARD=SSTL15_II | OUT_TERM=UNTUNED_25;#RT
Net dba<1> LOC=H18 | IOSTANDARD=SSTL15_II | OUT_TERM=UNTUNED_25;#RT
Net dba<2> LOC=J4 | IOSTANDARD=SSTL15_II | OUT_TERM=UNTUNED_25;#LT
 
Net dcmd<2> LOC=K17 | IOSTANDARD=SSTL15_II | OUT_TERM=UNTUNED_25;#RT # RAS
Net dcmd<1> LOC=K18 | IOSTANDARD=SSTL15_II | OUT_TERM=UNTUNED_25;#RB # CAS
Net dcmd<0> LOC=K20 | IOSTANDARD=SSTL15_II | OUT_TERM=UNTUNED_25;#RT # WE
 
Net dce<0> LOC=K5 | IOSTANDARD=SSTL15_II | OUT_TERM=UNTUNED_25;#LT
Net dce<1> LOC=K6 | IOSTANDARD=SSTL15_II | OUT_TERM=UNTUNED_25;#LT
 
Net dcs<0> LOC=K19 | IOSTANDARD=SSTL15_II | OUT_TERM=UNTUNED_25;#RT
Net dcs<1> LOC=L17 | IOSTANDARD=SSTL15_II | OUT_TERM=UNTUNED_25;#RB
 
Net dckp<0> LOC=F18 | IOSTANDARD=SSTL15_II | OUT_TERM=UNTUNED_25;#RT
Net dckp<1> LOC=B21 | IOSTANDARD=SSTL15_II | OUT_TERM=UNTUNED_25;#RT
 
Net dckn<0> LOC=F19 | IOSTANDARD=SSTL15_II | OUT_TERM=UNTUNED_25;#RT
Net dckn<1> LOC=B22 | IOSTANDARD=SSTL15_II | OUT_TERM=UNTUNED_25;#RT
 
Net dodt<0> LOC=L19 | IOSTANDARD=SSTL15_II | OUT_TERM=UNTUNED_25;#RB
Net dodt<1> LOC=P20 | IOSTANDARD=SSTL15_II | OUT_TERM=UNTUNED_25;#RB
 
 
/adapter.v
0,0 → 1,172
/*
MicroBlaze MCS to DDR3 glue
(C) Copyright 2012 Silicon On Inspiration
www.sioi.com.au
86 Longueville Road
Lane Cove 2066
New South Wales
AUSTRALIA
 
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
 
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
 
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
 
`timescale 1ns / 1ps
 
module adapter
(
input ckmb,
input ckdr,
input reset,
 
output srd,
output swr,
output [33:5] sa,
output [255:0] swdat,
output [31:0] smsk,
input [255:0] srdat,
input srdy,
 
output IO_Ready,
input IO_Addr_Strobe,
input IO_Read_Strobe,
input IO_Write_Strobe,
output [31 : 0] IO_Read_Data,
input [31 : 0] IO_Address,
input [3 : 0] IO_Byte_Enable,
input [31 : 0] IO_Write_Data,
input [3 : 0] page,
input [2:0] dbg_out
);
 
reg [31 : 0] rdat;
reg [255 : 0] wdat;
reg [31 : 0] msk;
reg [33 : 2] addr;
reg rdy1;
reg rdy2;
reg read;
reg write;
 
wire [31:0] iowd;
wire [3:0] mask;
 
parameter BADBAD = 256'hBAD0BAD0BAD0BAD0BAD0BAD0BAD0BAD0BAD0BAD0BAD0BAD0BAD0BAD0BAD0BAD0;
 
always @ (posedge ckmb) begin
 
if (IO_Addr_Strobe && IO_Write_Strobe) begin
case (IO_Address[4:2])
0: wdat[31:0] <= iowd;
1: wdat[63:32] <= iowd;
2: wdat[95:64] <= iowd;
3: wdat[127:96] <= iowd;
4: wdat[159:128] <= iowd;
5: wdat[191:160] <= iowd;
6: wdat[223:192] <= iowd;
7: wdat[255:224] <= iowd;
 
// BADBAD markers for bebugging byte masking
// NB: This approach breaks the per-pin IODELAY2 software adjustment on the DQ lines
// 0: wdat <= {BADBAD[255:32], iowd};
// 1: wdat <= {BADBAD[255:64], iowd, BADBAD[31:0]};
// 2: wdat <= {BADBAD[255:96], iowd, BADBAD[63:0]};
// 3: wdat <= {BADBAD[255:128], iowd, BADBAD[95:0]};
// 4: wdat <= {BADBAD[255:160], iowd, BADBAD[127:0]};
// 5: wdat <= {BADBAD[255:192], iowd, BADBAD[159:0]};
// 6: wdat <= {BADBAD[255:224], iowd, BADBAD[191:0]};
// 7: wdat <= {iowd, BADBAD[223:0]};
endcase
case (IO_Address[4:2])
0: msk <= {28'hFFFFFFF, mask};
1: msk <= {24'hFFFFFF, mask, 4'hF};
2: msk <= {20'hFFFFF, mask, 8'hFF};
3: msk <= {16'hFFFF, mask, 12'hFFF};
4: msk <= {12'hFFF, mask, 16'hFFFF};
5: msk <= {8'hFF, mask, 20'hFFFFF};
6: msk <= {4'hF, mask, 24'hFFFFFF};
7: msk <= {mask, 28'hFFFFFFF};
/*
ZZ - write full 256 bits during testing !
0: msk <= {28'h0000000, mask};
1: msk <= {24'h000000, mask, 4'h0};
2: msk <= {20'h00000, mask, 8'h00};
3: msk <= {16'h0000, mask, 12'h000};
4: msk <= {12'h000, mask, 16'h0000};
5: msk <= {8'h00, mask, 20'h00000};
6: msk <= {4'h0, mask, 24'h000000};
7: msk <= {mask, 28'h0000000};
*/
endcase
end
if (IO_Addr_Strobe)
addr <= {page[3:0], IO_Address[29:2]};
end
always @ (posedge ckmb or posedge reset) begin
if (reset) begin
read <= 1'b0;
write <= 1'b0;
rdy2 <= 1'b0;
end else begin
if (IO_Addr_Strobe && IO_Read_Strobe)
read <= 1'b1;
else if (IO_Addr_Strobe && IO_Write_Strobe)
write <= 1'b1;
if (rdy1) begin
read <= 1'b0;
write <= 1'b0;
rdy2 <= 1'b1;
end
if (rdy2)
rdy2 <= 1'b0;
end
end
 
always @ (posedge ckdr or posedge reset) begin
if (reset) begin
rdy1 <= 1'b0;
end else begin
if (srdy)
rdy1 <= 1'b1;
if (rdy2)
rdy1 <= 1'b0;
if (srdy) case (addr[4:2])
0: rdat <= srdat[31:0];
1: rdat <= srdat[63:32];
2: rdat <= srdat[95:64];
3: rdat <= srdat[127:96];
4: rdat <= srdat[159:128];
5: rdat <= srdat[191:160];
6: rdat <= srdat[223:192];
7: rdat <= srdat[255:224];
endcase
end
end
 
assign iowd = IO_Write_Data;
assign mask = ~IO_Byte_Enable;
 
assign IO_Read_Data = rdat;
assign IO_Ready = rdy2;
assign srd = read;
assign swr = write;
assign swdat = wdat;
assign smsk = msk;
assign sa = addr[33:5];
 
endmodule
 
/top.v
0,0 → 1,182
/*
MicroBlaze MCS to DDR3 glue
(C) Copyright 2012 Silicon On Inspiration
www.sioi.com.au
86 Longueville Road
Lane Cove 2066
New South Wales
AUSTRALIA
 
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
 
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
 
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
 
`timescale 1ns / 1ps
 
module top
(
input mck62M5,
output [1:0] mled,
input [1:0] mbtn,
output txd,
input rxd,
 
inout [63:0] ddq,
inout [7:0] dqsp,
inout [7:0] dqsn,
output [7:0] ddm,
output [15:0] da,
output [2:0] dba,
output [2:0] dcmd,
output [1:0] dce,
output [1:0] dcs,
output [1:0] dckp,
output [1:0] dckn,
output [1:0] dodt
);
wire Reset;
wire IO_Ready;
wire IO_Addr_Strobe;
wire IO_Read_Strobe;
wire IO_Write_Strobe;
wire [31 : 0] IO_Read_Data;
wire [1 : 0] GPI1;
wire [31 : 0] IO_Address;
wire [3 : 0] IO_Byte_Enable;
wire [31 : 0] IO_Write_Data;
wire [1 : 0] GPO1;
wire [3 : 0] page;
 
wire srd;
wire swr;
wire [33:5] sa;
wire [255:0] swdat;
wire [31:0] smsk;
wire [255:0] srdat;
wire srdy;
wire ck150;
wire ck75;
 
wire [0 : 31] Trace_Instruction;
wire [0 : 31] Trace_PC;
wire [0 : 4] Trace_Reg_Addr;
wire [0 : 14] Trace_MSR_Reg;
wire [0 : 31] Trace_New_Reg_Value;
wire [0 : 31] Trace_Data_Address;
wire [0 : 31] Trace_Data_Write_Value;
wire [0 : 3] Trace_Data_Byte_Enable;
 
wire [2:0] dbg_out;
wire [7:0] dbg_in;
 
drac_ddr3 drac
(
.ckin (mck62M5),
.ckout (ck150),
.ckouthalf (ck75),
.reset (Reset),
.ddq (ddq),
.dqsp (dqsp),
.dqsn (dqsn),
.ddm (ddm),
.da (da),
.dba (dba),
.dcmd (dcmd),
.dce (dce),
.dcs (dcs),
.dckp (dckp),
.dckn (dckn),
.dodt (dodt),
.srd (srd),
.swr (swr),
.sa (sa),
.swdat (swdat),
.smsk (smsk),
.srdat (srdat),
.srdy (srdy),
.dbg_out (dbg_out),
.dbg_in (dbg_in)
);
 
adapter glue
(
.ckmb (ck75),
.ckdr (ck150),
.reset (Reset),
.srd (srd),
.swr (swr),
.sa (sa),
.swdat (swdat),
.smsk (smsk),
.srdat (srdat),
.srdy (srdy),
.IO_Ready (IO_Ready),
.IO_Addr_Strobe (IO_Addr_Strobe),
.IO_Read_Strobe (IO_Read_Strobe),
.IO_Write_Strobe (IO_Write_Strobe),
.IO_Read_Data (IO_Read_Data),
.IO_Address (IO_Address),
.IO_Byte_Enable (IO_Byte_Enable),
.IO_Write_Data (IO_Write_Data),
.page (page),
.dbg_out (dbg_out)
);
microblaze_mcs_v1_1 mcs_0
(
.Clk (ck75),
.Reset (Reset),
.IO_Ready (IO_Ready),
.UART_Rx (rxd),
.IO_Addr_Strobe (IO_Addr_Strobe),
.IO_Read_Strobe (IO_Read_Strobe),
.IO_Write_Strobe (IO_Write_Strobe),
.UART_Tx (txdraw),
.IO_Read_Data (IO_Read_Data),
.GPI1 (mbtn),
.GPI2 (dbg_in),
.IO_Address (IO_Address),
.IO_Byte_Enable (IO_Byte_Enable),
.IO_Write_Data (IO_Write_Data),
.GPO1 (mled),
.GPO2 (page),
.GPO3 (dbg_out),
.Trace_Instruction (Trace_Instruction), // Opcode
.Trace_Valid_Instr (Trace_Valid_Instr), // valid opcode y/n
.Trace_PC (Trace_PC), // PC
.Trace_Reg_Write (Trace_Reg_Write), // output Trace_Reg_Write
.Trace_Reg_Addr (Trace_Reg_Addr), // output [0 : 4] Trace_Reg_Addr
.Trace_MSR_Reg (Trace_MSR_Reg), // output [0 : 14] Trace_MSR_Reg
.Trace_New_Reg_Value (Trace_New_Reg_Value), // output [0 : 31] Trace_New_Reg_Value
.Trace_Jump_Taken (Trace_Jump_Taken), // Jump Taken
.Trace_Delay_Slot (Trace_Delay_Slot), // Delay Slot
.Trace_Data_Address (Trace_Data_Address), // Data Address
.Trace_Data_Access (Trace_Data_Access), // Data_Access y/n
.Trace_Data_Read (Trace_Data_Read), // Data Read y/n
.Trace_Data_Write (Trace_Data_Write), // Data Write y/n
.Trace_Data_Write_Value (Trace_Data_Write_Value), // Data Write Value
.Trace_Data_Byte_Enable (Trace_Data_Byte_Enable), // Data Byte Enables
.Trace_MB_Halted (Trace_MB_Halted) // Halted
);
assign txd = ~txdraw;
endmodule
 
/drac_ddr3.v
0,0 → 1,1275
/*
DDR3 DRAM controller
(C) Copyright 2012 Silicon On Inspiration
www.sioi.com.au
86 Longueville Road
Lane Cove 2066
New South Wales
AUSTRALIA
 
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
 
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
 
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
 
`timescale 1ns / 1ps
 
module drac_ddr3
(
input ckin,
output ckout,
output ckouthalf,
output reset,
 
inout [63:0] ddq,
inout [7:0] dqsp,
inout [7:0] dqsn,
output [7:0] ddm,
output [15:0] da,
output [2:0] dba,
output [2:0] dcmd,
output [1:0] dce,
output [1:0] dcs,
output [1:0] dckp,
output [1:0] dckn,
output [1:0] dodt,
input srd,
input swr,
input [33:5] sa,
input [255:0] swdat,
input [31:0] smsk,
output [255:0] srdat,
output srdy,
input [2:0] dbg_out,
output [7:0] dbg_in
);
 
reg READ;
reg READ2;
 
reg ack;
 
reg [15:0] rDDR_Addr;
reg [2:0] rDDR_BankAddr;
reg [1:0] rDDR_CS_n;
reg [2:0] rDDR_Cmd;
reg [1:0] rDDR_CKE;
reg [1:0] rDDR_ODT;
 
reg [2:0] STATE;
reg [2:0] RTN;
reg [5:0] DLY;
 
reg [10:0] RFCNTR;
reg REFRESH;
 
reg RPULSE0;
reg RPULSE1;
reg RPULSE2;
reg RPULSE3;
reg RPULSE4;
reg RPULSE5;
reg RPULSE6;
reg RPULSE7;
reg WPULSE0;
reg [255:0] Q;
 
wire [7:0] DM;
wire [7:0] DM_t;
wire [7:0] wDDR_DM;
 
wire [7:0] wDDR_DQS;
wire [63:0] DQ_i;
wire [63:0] DQ_i_dly;
wire [255:0] wQ;
wire [63:0] DQ_o;
wire [63:0] DQ_t;
wire [63:0] wDDR_DQ;
 
reg [255:0] rWdat;
reg [31:0] rSmsk;
 
reg [13:0] rLock = 0;
reg rClrPll = 1;
reg [13:0] rStart = 0;
reg rStarted = 0;
 
reg [63:0] rChgDelay;
reg [63:0] rIncDelay;
reg [63:0] rCalDelay;
reg [63:0] rCalDelay2;
reg [63:0] rRstDelay;
 
// Set up clocks for DDR3. Use circuitry based on UG382 Ch 1 pp33,34
// Generate the following clocks:
//
// ck600 600MHz clock for DQ IOSERDES2 high speed clock
// ck600_180 600MHz clock for DQS OSERDES2 high speed clock
// DQS clocking lags DQ clocking by half of one bit time
// ck150 1/4 speed clock for IOSERDES2 parallel side and control logic
// ck75 Clock for MicroBlaze CPU
//
// Create two copies of the 600MHz clocks, providing separate copies for
// bank 1 and bank 3. This is necessary as each BUFPLL reaches only a
// single bank. The other clocks are global (BUFG).
wire ck600raw;
wire ck600_180raw;
wire ck150;
wire ck150raw;
wire ck75;
wire ck75raw;
wire [1:0] ck600;
wire [1:0] ck600_180;
wire [1:0] strobe;
wire [1:0] strobe180;
 
// DDR3 DIMM byte lane levelling is achieved with these IODELAY2 settings:
parameter LVL_WSLOPE = 3;
parameter LVL_WPHASE = 6;
 
BUFG bufg_main
(
.O (ckinb),
.I (ckin)
);
 
PLL_BASE
#(
.BANDWIDTH ("OPTIMIZED"),
.CLK_FEEDBACK ("CLKFBOUT"),
.COMPENSATION ("INTERNAL"),
.DIVCLK_DIVIDE (3),
.CLKFBOUT_MULT (29),
.CLKFBOUT_PHASE (0.000),
.CLKOUT0_DIVIDE (1),
.CLKOUT0_PHASE (0.000),
.CLKOUT0_DUTY_CYCLE (0.500),
.CLKOUT1_DIVIDE (1),
.CLKOUT1_PHASE (180.000),
.CLKOUT1_DUTY_CYCLE (0.500),
.CLKOUT2_DIVIDE (4),
.CLKOUT2_PHASE (0.000),
.CLKOUT2_DUTY_CYCLE (0.500),
.CLKOUT3_DIVIDE (8),
.CLKOUT3_PHASE (0.0),
.CLKOUT3_DUTY_CYCLE (0.500),
.CLKOUT4_DIVIDE (8),
.CLKOUT4_PHASE (0.0),
.CLKOUT4_DUTY_CYCLE (0.500),
.CLKOUT5_DIVIDE (8),
.CLKOUT5_PHASE (0.000),
.CLKOUT5_DUTY_CYCLE (0.500),
.CLKIN_PERIOD (16.000)
)
pll_base_main
(
.CLKFBOUT (pllfb0),
.CLKOUT0 (ck600raw),
.CLKOUT1 (ck600_180raw),
.CLKOUT2 (ck150raw),
.CLKOUT3 (ck75raw),
.CLKOUT4 (),
.CLKOUT5 (),
.LOCKED (locked),
.RST (rClrPll),
.CLKFBIN (pllfb0),
.CLKIN (ckinb)
);
 
BUFG bufg_150
(
.O (ck150),
.I (ck150raw)
);
 
BUFG bufg_75
(
.O (ck75),
.I (ck75raw)
);
 
genvar i;
generate
for (i = 0; i <= 1; i = i + 1) begin: BUFPLLS
BUFPLL
#(
.DIVIDE (4),
.ENABLE_SYNC ("TRUE")
)
bufpll_600
(
.IOCLK (ck600[i]),
.LOCK (dbg_in[i]),
.SERDESSTROBE (strobe[i]),
.GCLK (ck150),
.LOCKED (locked),
.PLLIN (ck600raw)
);
BUFPLL
#(
.DIVIDE (4),
.ENABLE_SYNC ("TRUE")
)
bufpll_600_18
(
.IOCLK (ck600_180[i]),
.LOCK (dbg_in[2 + i]),
.SERDESSTROBE (strobe180[i]),
.GCLK (ck150),
.LOCKED (locked),
.PLLIN (ck600_180raw)
);
end
 
// CLOCKS, two
wire [1:0] ckp;
wire [1:0] ckn;
for (i = 0; i <= 1; i = i + 1) begin: DDRO_CLKS
OSERDES2
#(
.DATA_RATE_OQ ("SDR"),
.DATA_RATE_OT ("SDR"),
.TRAIN_PATTERN (0),
.DATA_WIDTH (4),
.SERDES_MODE ("NONE"),
.OUTPUT_MODE ("SINGLE_ENDED")
)
oserdes2_dckp
(
.D1 (1'b0),
.D2 (1'b1),
.D3 (1'b0),
.D4 (1'b1),
.T1 (1'b0),
.T2 (1'b0),
.T3 (1'b0),
.T4 (1'b0),
.SHIFTIN1 (1'b1),
.SHIFTIN2 (1'b1),
.SHIFTIN3 (1'b1),
.SHIFTIN4 (1'b1),
.SHIFTOUT1 (),
.SHIFTOUT2 (),
.SHIFTOUT3 (),
.SHIFTOUT4 (),
.TRAIN (1'b0),
.OCE (1'b1),
.CLK0 (ck600_180[1]),
.CLK1 (1'b0),
.CLKDIV (ck150),
.OQ (ckp[i]),
.TQ (),
.IOCE (strobe180[1]),
.TCE (1'b1),
.RST (reset)
);
OSERDES2
#(
.DATA_RATE_OQ ("SDR"),
.DATA_RATE_OT ("SDR"),
.TRAIN_PATTERN (0),
.DATA_WIDTH (4),
.SERDES_MODE ("NONE"),
.OUTPUT_MODE ("SINGLE_ENDED")
)
oserdes2_dckn
(
.D1 (1'b1),
.D2 (1'b0),
.D3 (1'b1),
.D4 (1'b0),
.T1 (1'b0),
.T2 (1'b0),
.T3 (1'b0),
.T4 (1'b0),
.SHIFTIN1 (1'b1),
.SHIFTIN2 (1'b1),
.SHIFTIN3 (1'b1),
.SHIFTIN4 (1'b1),
.SHIFTOUT1 (),
.SHIFTOUT2 (),
.SHIFTOUT3 (),
.SHIFTOUT4 (),
.TRAIN (1'b0),
.OCE (1'b1),
.CLK0 (ck600_180[1]),
.CLK1 (1'b0),
.CLKDIV (ck150),
.OQ (ckn[i]),
.TQ (),
.IOCE (strobe180[1]),
.TCE (1'b1),
.RST (reset)
);
 
OBUF obuft_ckp
(
.O(dckp[i]),
.I(ckp[i])
);
 
OBUF obuf_ckn
(
.O(dckn[i]),
.I(ckn[i])
);
end
 
// Address, Bank address
// NB ISIM can't grok parameter arrays, hence the following sim/synth bifurcation
`ifdef XILINX_ISIM
`else
parameter integer bank_a[15:0] = {0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1};
parameter integer bank_ba[2:0] = {0, 1, 1};
`endif
 
wire [15:0] wa;
for (i = 0; i <= 15; i = i + 1) begin: DDRO_A
OSERDES2
#(
.DATA_RATE_OQ ("SDR"),
.DATA_RATE_OT ("SDR"),
.TRAIN_PATTERN (0),
.DATA_WIDTH (4),
.SERDES_MODE ("NONE"),
.OUTPUT_MODE ("SINGLE_ENDED")
)
oserdes2_a
(
.D1 (rDDR_Addr[i]),
.D2 (rDDR_Addr[i]),
.D3 (rDDR_Addr[i]),
.D4 (rDDR_Addr[i]),
.T1 (1'b0),
.T2 (1'b0),
.T3 (1'b0),
.T4 (1'b0),
.SHIFTIN1 (1'b1),
.SHIFTIN2 (1'b1),
.SHIFTIN3 (1'b1),
.SHIFTIN4 (1'b1),
.SHIFTOUT1 (),
.SHIFTOUT2 (),
.SHIFTOUT3 (),
.SHIFTOUT4 (),
.TRAIN (1'b0),
.OCE (1'b1),
`ifdef XILINX_ISIM
.CLK0 (ck600_180[0]),
`else
.CLK0 (ck600_180[bank_a[i]]),
`endif
.CLK1 (1'b0),
.CLKDIV (ck150),
.OQ (wa[i]),
.TQ (),
`ifdef XILINX_ISIM
.IOCE (strobe180[0]),
`else
.IOCE (strobe180[bank_a[i]]),
`endif
.TCE (1'b1),
.RST (reset)
);
OBUF obuf_a
(
.O(da[i]),
.I(wa[i])
);
end
wire [2:0] wba;
for (i = 0; i <= 2; i = i + 1) begin: DDRO_BA
OSERDES2
#(
.DATA_RATE_OQ ("SDR"),
.DATA_RATE_OT ("SDR"),
.TRAIN_PATTERN (0),
.DATA_WIDTH (4),
.SERDES_MODE ("NONE"),
.OUTPUT_MODE ("SINGLE_ENDED")
)
oserdes2_ba
(
.D1 (rDDR_BankAddr[i]),
.D2 (rDDR_BankAddr[i]),
.D3 (rDDR_BankAddr[i]),
.D4 (rDDR_BankAddr[i]),
.T1 (1'b0),
.T2 (1'b0),
.T3 (1'b0),
.T4 (1'b0),
.SHIFTIN1 (1'b1),
.SHIFTIN2 (1'b1),
.SHIFTIN3 (1'b1),
.SHIFTIN4 (1'b1),
.SHIFTOUT1 (),
.SHIFTOUT2 (),
.SHIFTOUT3 (),
.SHIFTOUT4 (),
.TRAIN (1'b0),
.OCE (1'b1),
`ifdef XILINX_ISIM
.CLK0 (ck600_180[0]),
`else
.CLK0 (ck600_180[bank_ba[i]]),
`endif
.CLK1 (1'b0),
.CLKDIV (ck150),
.OQ (wba[i]),
.TQ (),
`ifdef XILINX_ISIM
.IOCE (strobe180[0]),
`else
.IOCE (strobe180[bank_ba[i]]),
`endif
.TCE (1'b1),
.RST (reset)
);
OBUF obuf_ba
(
.O(dba[i]),
.I(wba[i])
);
end
 
// command, ChipSelect
wire [2:0] wkmd;
for (i = 0; i <= 2; i = i + 1) begin: DDRO_KMD
OSERDES2
#(
.DATA_RATE_OQ ("SDR"),
.DATA_RATE_OT ("SDR"),
.TRAIN_PATTERN (0),
.DATA_WIDTH (4),
.SERDES_MODE ("NONE"),
.OUTPUT_MODE ("SINGLE_ENDED")
)
oserdes2_kmd
(
.D1 (rDDR_Cmd[i]), // Command for 1 cycle
.D2 (rDDR_Cmd[i]),
.D3 (1'b1), // NOP thereafter
.D4 (1'b1),
.T1 (1'b0),
.T2 (1'b0),
.T3 (1'b0),
.T4 (1'b0),
.SHIFTIN1 (1'b1),
.SHIFTIN2 (1'b1),
.SHIFTIN3 (1'b1),
.SHIFTIN4 (1'b1),
.SHIFTOUT1 (),
.SHIFTOUT2 (),
.SHIFTOUT3 (),
.SHIFTOUT4 (),
.TRAIN (1'b0),
.OCE (1'b1),
.CLK0 (ck600_180[1]),
.CLK1 (1'b0),
.CLKDIV (ck150),
.OQ (wkmd[i]),
.TQ (),
.IOCE (strobe180[1]),
.TCE (1'b1),
.RST (reset)
);
OBUF obuf_kmd
(
.O(dcmd[i]),
.I(wkmd[i])
);
end
wire [1:0] wcs;
for (i = 0; i <= 1; i = i + 1) begin: DDRO_CS
OSERDES2
#(
.DATA_RATE_OQ ("SDR"),
.DATA_RATE_OT ("SDR"),
.TRAIN_PATTERN (0),
.DATA_WIDTH (4),
.SERDES_MODE ("NONE"),
.OUTPUT_MODE ("SINGLE_ENDED")
)
oserdes2_cs
(
.D1 (rDDR_CS_n[i]),
.D2 (rDDR_CS_n[i]),
.D3 (rDDR_CS_n[i]),
.D4 (rDDR_CS_n[i]),
.T1 (1'b0),
.T2 (1'b0),
.T3 (1'b0),
.T4 (1'b0),
.SHIFTIN1 (1'b1),
.SHIFTIN2 (1'b1),
.SHIFTIN3 (1'b1),
.SHIFTIN4 (1'b1),
.SHIFTOUT1 (),
.SHIFTOUT2 (),
.SHIFTOUT3 (),
.SHIFTOUT4 (),
.TRAIN (1'b0),
.OCE (1'b1),
.CLK0 (ck600_180[1]),
.CLK1 (1'b0),
.CLKDIV (ck150),
.OQ (wcs[i]),
.TQ (),
.IOCE (strobe180[1]),
.TCE (1'b1),
.RST (reset)
);
OBUF obuf_cs
(
.O(dcs[i]),
.I(wcs[i])
);
end
// CKE, ODT
wire [1:0] wcke;
for (i = 0; i <= 1; i = i + 1) begin: DDRO_CKE
OSERDES2
#(
.DATA_RATE_OQ ("SDR"),
.DATA_RATE_OT ("SDR"),
.TRAIN_PATTERN (0),
.DATA_WIDTH (4),
.SERDES_MODE ("NONE"),
.OUTPUT_MODE ("SINGLE_ENDED")
)
oserdes2_cke
(
.D1 (rDDR_CKE[i]),
.D2 (rDDR_CKE[i]),
.D3 (rDDR_CKE[i]),
.D4 (rDDR_CKE[i]),
.T1 (1'b0),
.T2 (1'b0),
.T3 (1'b0),
.T4 (1'b0),
.SHIFTIN1 (1'b1),
.SHIFTIN2 (1'b1),
.SHIFTIN3 (1'b1),
.SHIFTIN4 (1'b1),
.SHIFTOUT1 (),
.SHIFTOUT2 (),
.SHIFTOUT3 (),
.SHIFTOUT4 (),
.TRAIN (1'b0),
.OCE (1'b1),
.CLK0 (ck600_180[0]),
.CLK1 (1'b0),
.CLKDIV (ck150),
.OQ (wcke[i]),
.TQ (),
.IOCE (strobe180[0]),
.TCE (1'b1),
.RST (reset)
);
OBUF obuf_cke
(
.O(dce[i]),
.I(wcke[i])
);
end
 
wire [1:0] wodt;
for (i = 0; i <= 1; i = i + 1) begin: DDRO_ODT
OSERDES2
#(
.DATA_RATE_OQ ("SDR"),
.DATA_RATE_OT ("SDR"),
.TRAIN_PATTERN (0),
.DATA_WIDTH (4),
.SERDES_MODE ("NONE"),
.OUTPUT_MODE ("SINGLE_ENDED")
)
oserdes2_odt
(
.D1 (rDDR_ODT[i]),
.D2 (rDDR_ODT[i]),
.D3 (rDDR_ODT[i]),
.D4 (rDDR_ODT[i]),
.T1 (1'b0),
.T2 (1'b0),
.T3 (1'b0),
.T4 (1'b0),
.SHIFTIN1 (1'b1),
.SHIFTIN2 (1'b1),
.SHIFTIN3 (1'b1),
.SHIFTIN4 (1'b1),
.SHIFTOUT1 (),
.SHIFTOUT2 (),
.SHIFTOUT3 (),
.SHIFTOUT4 (),
.TRAIN (1'b0),
.OCE (1'b1),
.CLK0 (ck600_180[1]),
.CLK1 (1'b0),
.CLKDIV (ck150),
.OQ (wodt[i]),
.TQ (),
.IOCE (strobe180[1]),
.TCE (1'b1),
.RST (reset)
);
OBUF obuf_odt
(
.O(dodt[i]),
.I(wodt[i])
);
end
 
// DQ STROBES, 8 differential pairs
wire [7:0] dqso;
wire [7:0] dqso_d;
wire [7:0] dqst;
wire [7:0] dqst_d;
wire [7:0] dqson;
wire [7:0] dqson_d;
wire [7:0] dqstn;
wire [7:0] dqstn_d;
wire [7:0] dummy;
wire [7:0] dummyp;
wire [7:0] dummyn;
for (i = 0; i <= 7; i = i + 1) begin: DDRIO_DQS
OSERDES2
#(
.DATA_RATE_OQ ("SDR"),
.DATA_RATE_OT ("SDR"),
.TRAIN_PATTERN (0),
.DATA_WIDTH (4),
.SERDES_MODE ("NONE"),
.OUTPUT_MODE ("SINGLE_ENDED")
)
oserdes2_dqsp
(
.D1 (1'b0),
.D2 (1'b1),
.D3 (1'b0),
.D4 (1'b1),
.T1 (READ),
.T2 (READ),
.T3 (READ),
.T4 (READ),
.SHIFTIN1 (1'b1),
.SHIFTIN2 (1'b1),
.SHIFTIN3 (1'b1),
.SHIFTIN4 (1'b1),
.SHIFTOUT1 (),
.SHIFTOUT2 (),
.SHIFTOUT3 (),
.SHIFTOUT4 (),
.TRAIN (1'b0),
.OCE (1'b1),
.CLK0 (ck600_180[i >> 2]),
.CLK1 (1'b0),
.CLKDIV (ck150),
.OQ (dqso[i]),
.TQ (dqst[i]),
.IOCE (strobe180[i >> 2]),
.TCE (1'b1),
.RST (reset)
);
 
OSERDES2
#(
.DATA_RATE_OQ ("SDR"),
.DATA_RATE_OT ("SDR"),
.TRAIN_PATTERN (0),
.DATA_WIDTH (4),
.SERDES_MODE ("NONE"),
.OUTPUT_MODE ("SINGLE_ENDED")
)
oserdes2_dqsn
(
.D1 (1'b1),
.D2 (1'b0),
.D3 (1'b1),
.D4 (1'b0),
.T1 (READ),
.T2 (READ),
.T3 (READ),
.T4 (READ),
.SHIFTIN1 (1'b1),
.SHIFTIN2 (1'b1),
.SHIFTIN3 (1'b1),
.SHIFTIN4 (1'b1),
.SHIFTOUT1 (),
.SHIFTOUT2 (),
.SHIFTOUT3 (),
.SHIFTOUT4 (),
.TRAIN (1'b0),
.OCE (1'b1),
.CLK0 (ck600_180[i >> 2]),
.CLK1 (1'b0),
.CLKDIV (ck150),
.OQ (dqson[i]),
.TQ (dqstn[i]),
.IOCE (strobe180[i >> 2]),
.TCE (1'b1),
.RST (reset)
);
 
IODELAY2
#(
.DATA_RATE ("SDR"),
.ODELAY_VALUE (LVL_WPHASE + i * LVL_WSLOPE),
.IDELAY_VALUE (LVL_WPHASE + i * LVL_WSLOPE),
.IDELAY_TYPE ("FIXED"),
.DELAY_SRC ("IO")
)
iodelay2_dqsp
(
.ODATAIN (dqso[i]),
.DOUT (dqso_d[i]),
.T (dqst[i]),
.TOUT (dqst_d[i]),
 
.IDATAIN (dummyp[i])
);
IODELAY2
#(
.DATA_RATE ("SDR"),
.ODELAY_VALUE (LVL_WPHASE + i * LVL_WSLOPE),
.IDELAY_VALUE (LVL_WPHASE + i * LVL_WSLOPE),
.IDELAY_TYPE ("FIXED"),
.DELAY_SRC ("IO")
)
iodelay2_dqsn
(
.ODATAIN (dqson[i]),
.DOUT (dqson_d[i]),
.T (dqstn[i]),
.TOUT (dqstn_d[i]),
 
.IDATAIN (dummyn[i])
);
IOBUF iobuf_dqsp
(
.O(dummyp[i]),
.IO(dqsp[i]),
.I(dqso_d[i]),
.T(dqst_d[i])
);
IOBUF iobuf_dqsn
(
.O(dummyn[i]),
.IO(dqsn[i]),
.I(dqson_d[i]),
.T(dqstn_d[i])
);
end
 
// DATA MASKS, 8
wire [7:0] dmo;
wire [7:0] dmo_d;
wire [7:0] dmt;
wire [7:0] dmt_d;
for (i = 0; i <= 7; i = i + 1) begin: DDRO_DM
OSERDES2
#(
.DATA_RATE_OQ ("SDR"),
.DATA_RATE_OT ("SDR"),
.TRAIN_PATTERN (0),
.DATA_WIDTH (4),
.SERDES_MODE ("NONE"),
.OUTPUT_MODE ("SINGLE_ENDED")
)
oserdes2_dm
(
.D1 (rSmsk[i]),
.D2 (rSmsk[i + 8]),
.D3 (rSmsk[i + 16]),
.D4 (rSmsk[i + 24]),
.T1 (READ),
.T2 (READ),
.T3 (READ),
.T4 (READ),
.SHIFTIN1 (1'b1),
.SHIFTIN2 (1'b1),
.SHIFTIN3 (1'b1),
.SHIFTIN4 (1'b1),
.SHIFTOUT1 (),
.SHIFTOUT2 (),
.SHIFTOUT3 (),
.SHIFTOUT4 (),
.TRAIN (1'b0),
.OCE (1'b1),
.CLK0 (ck600[i >> 2]),
.CLK1 (1'b0),
.CLKDIV (ck150),
.OQ (dmo[i]),
.TQ (dmt[i]),
.IOCE (strobe[i >> 2]),
.TCE (1'b1),
.RST (reset)
);
 
IODELAY2
#(
.DATA_RATE ("SDR"),
.ODELAY_VALUE (LVL_WPHASE + i * LVL_WSLOPE),
.IDELAY_VALUE (LVL_WPHASE + i * LVL_WSLOPE),
.IDELAY_TYPE ("FIXED"),
.DELAY_SRC ("IO")
)
iodelay2_dm
(
.ODATAIN (dmo[i]),
.DOUT (dmo_d[i]),
.T (dmt[i]),
.TOUT (dmt_d[i]),
.IDATAIN (dummy[i])
);
IOBUF iobuf_dm
(
.O(dummy[i]),
.IO(ddm[i]),
.I(dmo_d[i]),
.T(dmt_d[i])
);
end
// DQ LINES, 64
wire [63:0] dqo;
wire [63:0] dqo_d;
wire [63:0] dqt;
wire [63:0] dqt_d;
wire [63:0] dqi;
wire [63:0] dqi_d;
for (i = 0; i <= 63; i = i + 1) begin: DDRIO_DQ
OSERDES2
#(
.DATA_RATE_OQ ("SDR"),
.DATA_RATE_OT ("SDR"),
.TRAIN_PATTERN (0),
.DATA_WIDTH (4),
.SERDES_MODE ("NONE"),
.OUTPUT_MODE ("SINGLE_ENDED")
)
oserdes2_dq
(
.D1 (rWdat[i]),
.D2 (rWdat[i + 64]),
.D3 (rWdat[i + 128]),
.D4 (rWdat[i + 192]),
.T1 (READ),
.T2 (READ),
.T3 (READ),
.T4 (READ),
.SHIFTIN1 (1'b1),
.SHIFTIN2 (1'b1),
.SHIFTIN3 (1'b1),
.SHIFTIN4 (1'b1),
.SHIFTOUT1 (),
.SHIFTOUT2 (),
.SHIFTOUT3 (),
.SHIFTOUT4 (),
.TRAIN (1'b0),
.OCE (1'b1),
.CLK0 (ck600[i >> 5]),
.CLK1 (1'b0),
.CLKDIV (ck150),
.OQ (dqo[i]),
.TQ (dqt[i]),
.IOCE (strobe[i >> 5]),
.TCE (1'b1),
.RST (reset)
);
 
IODELAY2
#(
.DATA_RATE ("SDR"),
.IDELAY_VALUE (0),
.ODELAY_VALUE (LVL_WPHASE + ((i * LVL_WSLOPE) >> 3)),
.IDELAY_TYPE ("VARIABLE_FROM_ZERO"),
.DELAY_SRC ("IO")
)
iodelay2_dq
(
.ODATAIN (dqo[i]),
.DOUT (dqo_d[i]),
.T (dqt[i]),
.TOUT (dqt_d[i]),
 
.IDATAIN (dqi[i]),
.DATAOUT (dqi_d[i]),
.CE (rChgDelay[i]),
.INC (rIncDelay[i]),
.CLK (ck150),
.CAL (rCalDelay2[i]),
.RST (rRstDelay[i]),
.IOCLK0 (ck600[i >> 5])
);
IOBUF iobuf_dq
(
.O(dqi[i]),
.IO(ddq[i]),
.I(dqo_d[i]),
.T(dqt_d[i])
);
ISERDES2
#(
.BITSLIP_ENABLE ("FALSE"),
.DATA_RATE ("SDR"),
.DATA_WIDTH (4),
.INTERFACE_TYPE ("RETIMED"),
.SERDES_MODE ("NONE")
)
iserdes2_dq
(
.Q1 (wQ[i]),
.Q2 (wQ[i + 64]),
.Q3 (wQ[i + 128]),
.Q4 (wQ[i + 192]),
.SHIFTOUT (),
.INCDEC (),
.VALID (),
.BITSLIP (),
.CE0 (READ),
.CLK0 (ck600[i >> 5]),
.CLK1 (1'b0),
.CLKDIV (ck150),
.D (dqi_d[i]),
.IOCE (strobe[i >> 5]),
.RST (reset),
.SHIFTIN (),
.FABRICOUT (),
.CFB0 (),
.CFB1 (),
.DFB ()
);
end
endgenerate
 
// DDR commands
parameter K_LMR = 3'h0; // Load Mode Register (Mode Register Set)
parameter K_RFSH = 3'h1; // Refresh (auto or self)
parameter K_CLOSE = 3'h2; // aka PRECHARGE
parameter K_OPEN = 3'h3; // aka ACTIVATE
parameter K_WRITE = 3'h4;
parameter K_READ = 3'h5;
parameter K_ZQCAL = 3'h6; // ZQ calibration
parameter K_NOP = 3'h7;
 
// States
parameter S_INIT = 3'h3;
parameter S_INIT2 = 3'h5;
parameter S_IDLE = 3'h0;
parameter S_READ = 3'h1;
parameter S_WRITE = 3'h2;
parameter S_PAUSE = 3'h4;
 
// Main DDR3 timings spec @150MHz
// tRAS RAS time 37.5 ns 6 clks open to close
// tRC RAS cycle 50.6 ns 8 clks open to next open
// tRP RAS precharge 13.1 ns 2 clks close to open
// tRRD RAS to RAS delay 4 clks 4 clks
// tRCD RAS to CAS delay 13.2 ns 2 clks
// CL CAS Latency 5 clks 5 clks
// tWR Write time 15 ns 3 clks Write finished to close issued
// tWTR Write to Read 4 clks 4 clks Write finished to read issued
// tRFC Refresh command 1Gb 110ns 17 clks Refresh command time for 1Gb parts
// tRFC Refresh command 2Gb 160ns 24 clks Refresh command time for 2Gb parts
// tRFC Refresh command 4Gb 260ns 39 clks Refresh command time for 4Gb parts
// tREFI Refresh interval 7.8 us 1170 clks
// tDQSS DQS start +-0.25 clks Time from DDR_Clk to DQS
parameter tRFC = 39;
parameter tRCD = 3;
parameter tRP = 3;
 
// Provide the PLL with a good long start up reset
always @ (posedge ckinb) begin
if (rLock[13] == 1'b1) begin
rClrPll <= 1'b0;
end else begin
rClrPll <= 1'b1;
rLock <= rLock + 14'b1;
end
end
 
// Hold the rest of the system in reset until the PLL has been locked for
// a good long while
always @ (posedge ckinb) begin
if (rStart[13] == 1'b1) begin
rStarted <= 1'b1;
end else begin
rStarted <= 1'b0;
if (locked) begin
rStart <= rStart + 14'b1;
end else begin
rStart <= 0;
end
end
end
 
// Add pipeline delays as required to make it easy for PAR to meet timing
always @ (posedge ck150) begin
Q <= wQ;
rWdat <= swdat;
rSmsk <= smsk;
rCalDelay2 <= rCalDelay;
end
 
always @ (posedge reset or posedge ck150)
if (reset) begin
rDDR_CKE <= 2'b00;
rDDR_CS_n <= 2'b11;
rDDR_ODT <= 2'b00;
rDDR_Cmd <= K_NOP;
STATE <= S_INIT;
DLY <= 0;
RTN <= 0;
RFCNTR <= 0;
REFRESH <= 0;
 
ack <= 0;
RPULSE0 <= 0;
WPULSE0 <= 0;
rChgDelay <= 64'd0;
rIncDelay <= 64'd0;
rCalDelay <= 64'd0;
rRstDelay <= 64'd0;
end else begin
if (RFCNTR[10:7] == 4'b1001) begin // 1153/150Mhz ~7.7us
RFCNTR <= 0;
REFRESH <= 1;
end else
RFCNTR <= RFCNTR + 11'b1;
RPULSE1 <= RPULSE0;
RPULSE2 <= RPULSE1;
RPULSE3 <= RPULSE2;
RPULSE4 <= RPULSE3;
RPULSE5 <= RPULSE4;
RPULSE6 <= RPULSE5;
RPULSE7 <= RPULSE6;
 
case (dbg_out[2:0])
3'd0: begin
ack <= WPULSE0 | RPULSE4;
end
3'd1: begin
ack <= WPULSE0 | RPULSE5;
end
3'd2: begin
ack <= WPULSE0 | RPULSE6;
end
3'd3: begin
ack <= WPULSE0 | RPULSE7;
end
3'd4: begin
ack <= WPULSE0 | RPULSE4;
end
3'd5: begin
ack <= WPULSE0 | RPULSE5;
end
3'd6: begin
ack <= WPULSE0 | RPULSE6;
end
3'd7: begin
ack <= WPULSE0 | RPULSE7;
end
endcase
 
case (STATE)
S_INIT: begin
rDDR_CKE <= 2'b11;
READ <= 0;
rDDR_BankAddr <= sa[15:13];
rDDR_Addr <= sa[31:16];
if (swr) begin
rDDR_CS_n <= sa[32] ? 2'b01 : 2'b10;
STATE <= S_INIT2;
rDDR_Cmd <= sa[10:8];
WPULSE0 <= 1;
end
end
S_INIT2: begin
RTN <= sa[33] ? S_INIT : S_IDLE;
rDDR_Cmd <= K_NOP;
STATE <= S_PAUSE;
DLY <= 20;
WPULSE0 <= 0;
end
S_IDLE: begin
READ <= 0;
rDDR_ODT <= 2'b00;
if (swr) begin
rDDR_Cmd <= K_OPEN;
STATE <= S_PAUSE;
RTN <= S_WRITE;
DLY <= tRCD - 1;
rDDR_Addr <= sa[31:16];
rDDR_BankAddr <= sa[15:13];
rDDR_CS_n <= sa[32] ? 2'b01 : 2'b10;
end else if (srd) begin
rDDR_Cmd <= K_OPEN;
STATE <= S_PAUSE;
RTN <= S_READ;
DLY <= tRCD - 1;
rDDR_Addr <= sa[31:16];
rDDR_BankAddr <= sa[15:13];
rDDR_CS_n <= sa[32] ? 2'b01 : 2'b10;
end else if (REFRESH) begin
rDDR_Cmd <= K_RFSH;
STATE <= S_PAUSE;
RTN <= S_IDLE;
DLY <= tRFC - 1;
REFRESH <= 0;
rDDR_CS_n <= 2'b00;
end else begin
rDDR_Cmd <= K_NOP;
rDDR_CS_n <= 2'b00;
end
end
 
// Address bits
// ============
// MB pg Lwd sa Row Col Bnk CS
// [X] - - - - - - -
// [X] - - - - - - -
// 2 - 0 - - - - -
// 3 - 1 [L] - 0 - -
// 4 - 2 [L] - 1 - -
// 5 - - 5 - 2 - -
// 6 - - 6 - 3 - -
// 7 - - 7 - 4 - -
// 8 - - 8 - 5 - -
// 9 - - 9 - 6 - -
// 10 - - 10 - 7 - -
// 11 - - 11 - 8 - -
// 12 - - 12 - 9 - -
// 13 - - 13 - [P] 0 -
// 14 - - 14 - - 1 -
// 15 - - 15 - - 2 -
// 16 - - 16 0 - - -
// 17 - - 17 1 - - -
// 18 - - 18 2 - - -
// 19 - - 19 3 - - -
// 20 - - 20 4 - - -
// 21 - - 21 5 - - -
// 22 - - 22 6 - - -
// 23 - - 23 7 - - -
// 24 - - 24 8 - - -
// 25 - - 25 9 - - -
// 26 - - 26 10 - - -
// 27 - - 27 11 - - -
// 28 - - 28 12 - - -
// 29 - - 29 13 - - -
// [H] 0 - 30 14 - - -
// [H] 1 - 31 15 - - -
// - 2 - 32 - - - 0
// - 3 - 33 - - - Extra address bit for DRAM init register space
 
S_WRITE: begin
rDDR_Cmd <= K_WRITE;
STATE <= S_PAUSE;
RTN <= S_IDLE;
DLY <= 14; // CWL + 2xfer + tWR + tRP
rDDR_Addr[10:0] <= {1'b1, sa[12:5], 2'b00}; // NB two LSBs ignored by DDR3 during WRITE
rDDR_Addr[12] <= dbg_out[2];
rDDR_BankAddr <= sa[15:13];
rDDR_ODT <= sa[16] ? 2'b10 : 2'b01; // Use ODT only in one rank, otherwise 40R || 40R -> 20R
WPULSE0 <= 1;
if (sa[33]) begin
rChgDelay <= rWdat[63:0];
rIncDelay <= rWdat[127:64];
rCalDelay <= rWdat[191:128];
rRstDelay <= rWdat[255:192];
end else begin
rChgDelay <= 64'd0;
rIncDelay <= 64'd0;
rCalDelay <= 64'd0;
rRstDelay <= 64'd0;
end
end
S_READ: begin
rDDR_Cmd <= K_READ;
STATE <= S_PAUSE;
RTN <= S_IDLE;
DLY <= 10; // CL + 2xfer + 1 + tRP
rDDR_Addr[10:0] <= {1'b1, sa[12:5], 2'b00};
rDDR_Addr[12] <= dbg_out[2];
rDDR_BankAddr <= sa[15:13];
READ <= 1;
RPULSE0 <= 1;
end
S_PAUSE: begin
rDDR_Cmd <= K_NOP;
DLY <= DLY - 6'b000001;
if (DLY == 6'b000001)
STATE <= RTN;
else
STATE <= S_PAUSE;
RPULSE0 <= 0;
WPULSE0 <= 0;
rChgDelay <= 64'd0;
rIncDelay <= 64'd0;
rCalDelay <= 64'd0;
rRstDelay <= 64'd0;
end
endcase
end
assign srdat = Q;
assign srdy = ack;
 
assign ckouthalf = ck75;
assign ckout = ck150;
 
assign reset = ~rStarted;
assign dbg_in[4] = locked;
assign dbg_in[7:5] = rDDR_Cmd;
 
endmodule
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.