cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
nfogh
Contributor
Contributor
5,580 Views
Registered: ‎02-12-2009

DDR2 MPMC behaves a bit weird

I am having some weird problems with my Spartan3A DSP-3400 board which uses DDR2 RAM. The wiring and hardware configuration I am using is the same as for the spartan demo board. The MPMC is connected to the microblaze using PLB.

If I write less than 33 integers to it, it works fine. So, this code:

    #define NUM 32
    unsigned int str[255];
    unsigned int* ddrstr = (unsigned int*)DDR2_BASEADDR;
    int i;
    for (i = 0; i < NUM; i++)
        str[i] = i;
       
    for (i = 0; i < NUM; i++)
        ddrstr[i] = i;
   
    cdl_printf("DDR: ");
    for (i = 0; i < NUM; i++)
        cdl_printf("%d ", (unsigned int) ddrstr[i]);
    cdl_printf("\r\n");

    cdl_printf("BRAM: ");
    for (i = 0; i < NUM; i++)
        cdl_printf("%d ", (unsigned int) str[i]);
    cdl_printf("\r\n");

will output:
DDR: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
BRAM: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31

as expected. However, if I increase NUM to 33, I get the following:

DDR: 32 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
BRAM: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32

As if the first data was overwritten by the last.

Have anyone got a clue about what might cause this?

Another thing is if I change from reading/writing ints to reading/writing chars and increase NUM to 130. Like this:

    unsigned char str[255];
    unsigned char* ddrstr = (unsigned char*)DDR2_BASEADDR;
    #define NUM 130
    int i;
    for (i = 0; i < NUM; i++)
        str[i] = i;
       
    for (i = 0; i < NUM; i++)
        ddrstr[i] = i;
   
    cdl_printf("DDR: ");
    for (i = 0; i < NUM; i++)
        cdl_printf("%d ", (unsigned char) ddrstr[i]);
    cdl_printf("\r\n");

    cdl_printf("BRAM: ");
    for (i = 0; i < NUM; i++)
        cdl_printf("%d ", (unsigned char) str[i]);
    cdl_printf("\r\n");

I get this:
DDR: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129
BRAM: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129

Again, increasing NUM to 131 gives wrong results:

DDR: 0 1 130 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 2
0 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130
BRAM: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130

But it is the 3rd char that is overwritten. It really is quite puzzling.

I am not initializing the DDR or anything. Do I need to run a calibration procedure before DDR works or something? I have not enabled static PHY, ECC or Performance Monitoring. I don't really need much speed, so if it can be resolved quickly by decreasing performance, it is OK.

Cheers,
  Nikolaj Fogh
0 Kudos
6 Replies
dylan
Xilinx Employee
Xilinx Employee
5,562 Views
Registered: ‎07-30-2007

The Spartan-3 demo boards were built before MIG pinout guidelines were determined.  The result is that the read capture delays are hard coded, and won't work with a custom board unless all traces are matched to the demo board.

 

The best workaround is to use the static phy, especially if you don't need a high clock rate.  There is information in the mpmc datasheet on the static phy and there is a calibration software example in the mpmc driver example directory.

0 Kudos
nfogh
Contributor
Contributor
5,530 Views
Registered: ‎02-12-2009

I have tried to get the static PHY implemented as described in the mpmc datasheet.

 

I have added a DCM to my design and connected the PSINCDEC, PSEN and PSDONE to the mpmc, as described in the datasheet. Now, I try to use the calibration code from the mpmc driver. However, it seems to loop endlessly after setting the static PHY register in MpmcDecDcmPhaseShift()

 

     while ((XMpmc_GetStaticPhyReg(InstancePtr) &
                    XMPMC_SPIR_DCM_DONE_MASK) == 0);

 

It is as if the DCM never finishes, or that it is not really connected to the mpmc. I have attached the .mhs file.

 

What frequency range can I expect to achieve with a static PHY? I have tried to get 128 MHz and 64 MHz, but none of them worked. I don't really need a lot of speed, but as far as I know, DDR2 has a minimum frequency it will work at.

0 Kudos
dylan
Xilinx Employee
Xilinx Employee
5,507 Views
Registered: ‎07-30-2007

Attached is a static PHY design that runs on the ML410 that you can use as a reference.
nfogh
Contributor
Contributor
5,337 Views
Registered: ‎02-12-2009

I have made up the static PHY design based on the design you sent, and it finds the calibration tab values ok. It is performing pretty badly (4MB/s), but thats the least of my concerns. My results are pretty much the same as in the first post. Depending on what amount of data (and what data types) I send to the RAM, the first data gets corrupted (the same stuff that happened in my first post). Is there anything that could cause that behavior. I'm thinking buffering, bursts or simply hardware mistakes?
0 Kudos
dylan
Xilinx Employee
Xilinx Employee
5,335 Views
Registered: ‎07-30-2007

I have not seen any issues like that with the static phy.  Have the timing constraints from the UCF been added?  What happens if the MPMC memory test is used, from the MPMC driver/examples directory?
0 Kudos
nfogh
Contributor
Contributor
5,304 Views
Registered: ‎02-12-2009

I didn't really find a memory test in the driver/examples dir, I have tried to run the memtests in xutil.h

 

It says:

 

p, li { white-space: pre-wrap; }

Starting MemoryTest for DDR2_SDRAM:

Running 32-bit test...

FAILED!

Running 16-bit test...

FAILED!

Running 8-bit test...

PASSED!

Memtest done!

 

Weirdly enough. The 8-bit test passes.

 

The only timing constraints i have are these:

 

NET DDR2/*rd_data_rise_in* MAXDELAY = 1000 ps;
NET DDR2/*rd_data_fall_in* MAXDELAY = 1000 ps;

0 Kudos