This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

DSK5510 External SDRAM Memory Read Problem

Other Parts Discussed in Thread: OMAP-L138

Connect external SDRAM (32-bit X 256K) to the DSK5510 via EMIFA bus.  The SDRAM has 2 known bad bits (stuck at 1).  Wrote all 0's to all memory locations. Read back all locations and expect to see all 0's except 2 bad locations should have a 1.  The problem is all 0's were read.   I added a time delay between the write and read, all data were read back correctly. It looks like data written to the memory was cached somewhere, when I tried to read back, the system just returned the cached data instead of the real data from memory.  How can solve this issue beside adding a delay?  Is there a way to disable the cache?

  • Mark,

    There is no data cache on 5510.  So the next thing that comes to mind would potentially be something related to the execution of a write followed by a read.  However, this is specifically addressed by the CPU Reference Guide (spru371f) in Section 1.7.2 Pipeline Protection:

    • If an instruction is supposed to read from a location but a previous
      instruction has not yet written to that location, extra cycles are inserted so
      that the write occurs first.

    Just to be thorough, I had a look at how the EMIF handles prioritization (Section 1.3 of spru590).  A CPU write is always prioritized over a CPU read.

    Given the facts above, it seems far more plausible that the issue is in the SDRAM itself, i.e. perhaps it reports properly in certain conditions.  It seems like you're suggesting that there is some kind of general issue with the 5510 where you end up reading old contents from SDRAM.  If that's the case, then surely that is reproducible on a board with a good SDRAM device.  For example, I would expect that you should be able to fill "pattern1" into SDRAM and verify it is present.  Then follow-up with "pattern2" where you read it back very quickly.  If there is truly some kind of issue here, then I would expect you to read back pattern1 instead of pattern2 in this scenario.

    Brad

  • The goal of the program is to check memory. With a known bad memory chip (2 bad locations always stuck at 1), the program won't be able to detect the bad bit. I wrote a 0 to the bad location, since the bit is bad (stuck at 1), I should read back 1, but I read 0 (pass). If I add a delay between write and read, the program will detect the failure. I am running the program under Code Composer Studio. If I paused the program after the write and look at the memory via the memory browser, I saw an 1 in that location; continued execution detected the failure because it's just like adding a delay between write and read. I have the same problem in the OMAP-L138 processor.
  • The "caching" you are observing is in the DRAM itself. When you open a row the data will be held by the column sense amplifiers. If you open a row, write to it, and then read it back you will be observing the proper data EVEN FOR A BAD DRAM since the data will never actually be written to the array. I believe the delay you're observing relates to the need to deactivate the row in order for the data to be written back to the array. Later when you re-open the row you will observe the bad data.
  • Are you sure you are not just seeing the effect of optimisation in the C compiler? Ensure that you access the memory via a pointer to *volatile* data, else the compiler is justified in not bothering to actually perform a read immediately after a write.
  • I used the codes below to perform write and read. Do you see a problem?

    int MEM_fill(unsigned long int start, unsigned long int len, unsigned long int val)
    {
     unsigned long int i;
     int errorCounter = 0;
     volatile unsigned long int *ptr;

     printf("TEST INFO: Start Memory Flush Test\n");

     ptr = (unsigned long int*) start;

     /* Starting at the lowest address fill memory with a flush pattern */
        for (i = 0; i < len; i++)
        {
         ptr[i] = val;
        }

        /* Verify the data */
        for (i = 0; i < len; i++)
        {
            if (ptr[i] != val)
            {
       /* Error Found */
       errorCounter++;
       printf("TEST ERROR: Reading on Memory Addr[0x%08lX] - Expected: [0x%08lX], Read: [0x%08lX]\n", i, val, ptr[i]);
       UserConfirmation();    //Operator acknowledgment

       if( ERROR_ABORT == errorCounter )
       {
        printf("TEST ERROR: Memory Flush Test Aborted on Memory Addr[0x%08lX] - Too Many Errors\n", i);
        break;
       }
            }
        }

     //---------------------------------------------PASS/FAIL Verification--------------------------------------------

     printf("TEST RESULT: Memory Flush Test (Addr[0x%08lX] to [0x%08lX]) Completed - [%i] Error(s)\n\n", 0x00000000l, len-1, errorCounter);

     return errorCounter;

     //---------------------------------------------END PASS/FAIL Verification-----------------------------------------
    }

  • To what value are you setting len when calling this function?

  • Oh, also, where precisely are you putting the delay that makes things pass, and what value specifically is the delay?
  • Len = 131072 (=128K)
  • /* Starting at the lowest address fill memory with a flush pattern */
    for (i = 0; i < len; i++)
    {
    ptr[i] = val;
    }

    while (i < 10000000) <-----I inserted the delay here
    {
    i=- 1;
    }

    /* Verify the data */
    for (i = 0; i < len; i++)
    {
    if (ptr[i] != val)
  • Given the structure of your code, I don't think this behavior is explained by my previous thoughts about the data being "cached" in the SDRAM's sense amplifiers. Since you write the entire DRAM and then read back the entire DRAM, that would have forced the data to have long been written back to the memory arrays.

    However, I think the fact that you are writing to the entire memory also rules out any kind of problem with the processor itself. In other words, this cannot possibly be related to pipelining, cache, volatiles, or any kind of EMIF prioritization. Even with no additional delay being inserted, there is already many megabytes of data being written and a substantial amount of time passing. The amount of data and time is far too large to possibly relate to any of these items...

    So that said, I believe this issue relates to the specific failure mode of the SDRAM. You say you are writing a value of zero to the bad location and only with a delay do you see it stuck high. I think this suggests that the bit is flipping from 0->1 with the passing of time. That may very well relate to memory refreshes occurring, e.g. that operation is one of the more power consuming operations.