Перейти к содержанию
    

Пишем код для отладки платы + азы

Эм... А rand() дает ту же последовательность, если его заново инициализировать (srand) тем же числом?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Эм... А rand() дает ту же последовательность, если его заново инициализировать (srand) тем же числом?

 

Конечно ту же. Он же псевдослучайный.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Эм... А rand() дает ту же последовательность, если его заново инициализировать (srand) тем же числом?

Да, но rand лучше не использовать - медленно. В TRM на ARM7TDMI есть пример генератора псевдослучайной последовательности с использованием barrel shifter'а.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Какой смысл тестить рандом? Лучше всего посмотреть битовые маски в прогах типа memtest и подобных... И потом, если есть ошибки из-за косячного рефреша, записал-прочитал будет нормально.

Имеет смысл делать так -- заполняем всю память нулями, ждем секунду, читаем, снова ждем секунду, читаем.. так несколько раз. Потом заполняем единицами. И снова ждем-читаем.

Для постоянных тестов медленно, но для разовых самое то.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Какой смысл тестить рандом? Лучше всего посмотреть битовые маски в прогах типа memtest и подобных...

Прямой: в противном случае вероятность обнаружения ошибок, связанных с целостностью сигналов, сильно снижается.

 

Имеет смысл делать так -- заполняем всю память нулями, ждем секунду, читаем, снова ждем секунду, читаем.. так несколько раз. Потом заполняем единицами. И снова ждем-читаем.

Для постоянных тестов медленно, но для разовых самое то.

И что? Вы так даже закороток на шинах адреса и данных не найдете.

 

Целью теста является не нахождение ошибок в памяти (хотя и это тоже), а проверка работоспособности интерфейса.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Какой смысл тестить рандом? Лучше всего посмотреть битовые маски в прогах типа memtest и подобных...

Прямой: в противном случае вероятность обнаружения ошибок, связанных с целостностью сигналов, сильно снижается.

 

Имеет смысл делать так -- заполняем всю память нулями, ждем секунду, читаем, снова ждем секунду, читаем.. так несколько раз. Потом заполняем единицами. И снова ждем-читаем.

Для постоянных тестов медленно, но для разовых самое то.

И что? Вы так даже закороток на шинах адреса и данных не найдете.

 

Целью теста является не нахождение ошибок в памяти (хотя и это тоже), а проверка работоспособности интерфейса.

 

При тестировании памяти (нахождение всевозможных ошибок чтения, записи, влияния одних ячеек на других), а так же нахождение ошибок шины к памяти типа закоротко или разрыв, лучше всего использовать маршевые тесты, причем использовать для каждой из возможных ошибок свой тест.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Какой смысл тестить рандом? Лучше всего посмотреть битовые маски в прогах типа memtest и подобных...

Прямой: в противном случае вероятность обнаружения ошибок, связанных с целостностью сигналов, сильно снижается.

Это еще почему? Когда мы гоняем единицы, повреждение линий сразу будет заметно.

 

Имеет смысл делать так -- заполняем всю память нулями, ждем секунду, читаем, снова ждем секунду, читаем.. так несколько раз. Потом заполняем единицами. И снова ждем-читаем.

Для постоянных тестов медленно, но для разовых самое то.

И что? Вы так даже закороток на шинах адреса и данных не найдете.

Если пропала единица, мы этого не заметим? :ohmy:

 

Целью теста является не нахождение ошибок в памяти (хотя и это тоже), а проверка работоспособности интерфейса.

Угу.

 

Да, все нули или единицы может не так хороши для проверки. Тогда можно взять маски 01010101 (55) и 10101010 (АА) и гонять их. Тут видно будет все.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Это еще почему? Когда мы гоняем единицы, повреждение линий сразу будет заметно.

Вам термин Signal Integrity знаком?

 

Если пропала единица, мы этого не заметим? :ohmy:

Так Вы ничего не заметите, даже если все линии адреса будут закорочены между собой (и с данными та же картина).

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вот тут вымучил. Явно бажное. Но все мои извраты с платой отлавливает. Вроде. Кроме замыкания адресных линий - эт. сложно. :)

 

 

 

  unsigned int volatile *pSDRAM, *pSDRAM1, *pSDRAM2;
  unsigned int  wCount;
  unsigned int  wRead,
                wWrite,
                wError,
                j,jmax;
  unsigned char bACount,
                nc,nr,nb,i;

  printf ("Main = %d Hz\n",AT91F_CKGR_GetMainClock(AT91C_BASE_CKGR, SLOWCLOCK));
  printf ("CPU = %d Hz\n",AT91F_PMC_GetProcessorClock(AT91C_BASE_PMC, AT91C_BASE_CKGR, SLOWCLOCK));

  printf ("\nSmart :) memory test (only 32 bit)\n");

  #define test_packet_size (8*1024)

  nc = 8 + (AT91C_BASE_SDRC->SDRC_CR & 0x03);          // columns
  nr = 11 + ((AT91C_BASE_SDRC->SDRC_CR >> 2) & 0x03); // rows
  nb = 1 + ((AT91C_BASE_SDRC->SDRC_CR >> 4) & 0x01);  // bancs
  bACount = nc + nr + nb;

  if (AT91C_BASE_SDRC->SDRC_MR & AT91C_SDRC_DBW_16_BITS)
    {
    printf ("Detected %d Mb of 16 bit SDRAM (not supported)\n", 1 << (bACount - 19)); // 16 bit
    while (1) {}
    }
  else
    printf ("Detected %d Mb of 32 bit SDRAM\n", 1 << (bACount - 18)); // 32 bit

//**********ADRESS LINES TEST
  printf("\nAdres lines test...\n");
  for (i = nc; i < bACount; i++)
    {
    if ( (1 << i) > test_packet_size)
      jmax = test_packet_size;
     else
      jmax = (1 << i);
    wError=0;
    srand (1);
    pSDRAM1 = (unsigned int *) BASE_EBI_CS1_ADDRESS;
    pSDRAM2 = (unsigned int *) BASE_EBI_CS1_ADDRESS + (1 << i);
    for (j = 0; j < jmax; j++)
      {
      *pSDRAM1 = rand(); pSDRAM1++;
      *pSDRAM2 = rand(); pSDRAM2++;
      }
    pSDRAM1 = (unsigned int *) BASE_EBI_CS1_ADDRESS;
    pSDRAM2 = (unsigned int *) BASE_EBI_CS1_ADDRESS + (1 << i);
    for (j = 0; j < jmax; j++)
      {
      if (*pSDRAM1 == *pSDRAM2)
        {
        wError++;
        }
      pSDRAM1++;
      pSDRAM2++;
      }
    if (i < nr + nc)
      printf ("A%d ",i-nc);
    else
      printf ("BA%d ",i-nc-nr);
    if (wError == 0)
      printf ("ok\n");
    else
      printf ("unconnected\n");
    }

//***********DATA LINE TEST*****
//***********SHORT**************
  printf("\nData line shorts test...\n");
  for (i = 0; i <= 31; i++)
    {
    wError = 0;
    wWrite = ~(1 << i);
    pSDRAM = (unsigned int *) BASE_EBI_CS1_ADDRESS;
    for (j = 0; j < test_packet_size; j++)
      {
      *pSDRAM = wWrite;
      pSDRAM++;
      }
    pSDRAM = (unsigned int *) BASE_EBI_CS1_ADDRESS;
    for (j = 0; j < test_packet_size; j++)
      {
      wRead = *pSDRAM;
      pSDRAM++;
      wError |= wWrite ^ wRead;
      }
    printf("D%d ",i);
    if (wError == 0)
      printf ("Ok\n");
    else
      {
      printf("shorts with ");
      for (j = 0; j <= 31; j++)
        if (wError & (1 << j))
          printf ("%d ",j);
      printf("\n");
      }
    }
//***********UNCONECT***********
  printf("\nData line uncon test...\n");

  wError = 0;
  pSDRAM = (unsigned int *) BASE_EBI_CS1_ADDRESS;
  for (j = 0; j < test_packet_size; j++)
    {
    *pSDRAM = 0;
    pSDRAM++;
    }
  pSDRAM = (unsigned int *) BASE_EBI_CS1_ADDRESS;
  for (j = 0; j < test_packet_size; j++)
    {
    wRead = *pSDRAM;
    pSDRAM++;
    wError |= wRead;
    }
  for (i = 0; i <= 31; i++)
    {
    printf("D%d ",i);
    if (wError & (1 << i))
      printf("unconect\n");
    else
      printf ("Ok\n");
    }

//***********RAND TEST********
  printf("\nRandom test...\n");
  while (1)
  {
   printf("\n-T WR- 0x00000000\n");
   srand(1);
   printf("First rand = 0x%8X\nStart filling\n",rand());
   pSDRAM = (unsigned int *) BASE_EBI_CS1_ADDRESS;
   for ( wCount = 0;wCount < (1 << (bACount -2)); wCount ++)
    {
    wWrite = rand ();
    *pSDRAM = wWrite;
    pSDRAM++;
    }
   wError = 0;
   srand(1);
   printf("First rand = 0x%8X\nStart testing\n",rand());
   pSDRAM = (unsigned int *) BASE_EBI_CS1_ADDRESS;
   for ( wCount = 0;wCount < (1 << (bACount -2)); wCount ++)
    {
    wRead = *pSDRAM;
    wWrite = rand();
    if (wRead != wWrite )
      {
      printf ("[0x%08X] = 0x%08X ( 0x%08X,0x%08X)\n",wCount,wRead^wWrite,wRead,wWrite );
      wError++;
      }
    pSDRAM++;
    }
   printf("Done. %d errors.\n",wError);
  }

 

Накосячил. Исправил. :)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В TRM на ARM7TDMI есть пример генератора псевдослучайной последовательности с использованием barrel shifter'а.

 

Носом не ткнете? А то мне что-то не найти...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Носом не ткнете? А то мне что-то не найти...

 

Вот цитата из мануала:

4.18.2 Pseudo-random binary sequence generator
It is often necessary to generate (pseudo-) random numbers and the most efficient
algorithms are based on shift generators with exclusive-OR feedback rather like a
cyclic redundancy check generator. Unfortunately the sequence of a 32 bit generator
needs more than one feedback tap to be maximal length (i.e. 2^32-1 cycles before
repetition), so this example uses a 33 bit register with taps at bits 33 and 20. The basic
algorithm is newbit:=bit 33 eor bit 20, shift left the 33 bit number and put in newbit at
the bottom; this operation is performed for all the newbits needed (i.e. 32 bits). The
entire operation can be done in 5 S cycles:
; Enter with seed in Ra (32 bits),
Rb (1 bit in Rb lsb), uses Rc.
;
TST Rb,Rb,LSR#1; Top bit into carry
MOVS Rc,Ra,RRX; 33 bit rotate right
ADC Rb,Rb,Rb; carry into lsb of Rb
EOR Rc,Rc,Ra,LSL#12; (involved!)
EOR Ra,Rc,Rc,LSR#20; (similarly involved!)
; new seed in Ra, Rb as before

 

И пример использования C + Asm:

extern randtest(u_int *start_addr, u_int word_count, u_int *seed);

void ramtest(u_int address, u_int word_count)
{
    static u_int addr;
    static u_int seed[0x02] = {0xdeadbeef, 0xcafedeca};
    u_int pass = 0x00, fcount = 0x00;

    addr = address;
    while(0x01)
    {
        printf("%d:%d Testing RAM...", pass, fcount);
        if(randtest(&addr, word_count, seed) == 0x00)
        {
            pass++;
            printf ("Passed.\n\r");
        }
        else
        {
            fcount++;
            printf("Failed at 0x%08x, Exp: 0x%08x; Rcv: 0x%08x\n\r", addr, seed[0x00], *(volatile u_int *)addr);
            addr = address;
        }
    }
}

+

        EXPORT    randtest

        AREA    code0, CODE, READONLY

randtest
        stmfd    sp!, {r4-r6, lr}
        ldmia    r2, {r4, r5}
        ldr        r6, [r0]
        mov        r7, r1
0
        tst        r5, r5, lsr #0x01    ; to bit into carry
        movs    r12, r4, rrx        ; 33-bit rotate right
        adc        r5, r5, r5            ; carry into LSB of a2
        eor        r12, r12, r4, lsl #0x0c; (involved!)
        eor        r4, r12, r12, lsr #0x14; (similarly involved!)

        str        r4, [r6], #0x04
        subs    r7, r7, #0x01
        bne        %B0

        ldmia    r2, {r4, r5}
        ldr        r6, [r0]
1
        tst        r5, r5, lsr #0x01    ; to bit into carry
        movs    r12, r4, rrx        ; 33-bit rotate right
        adc        r5, r5, r5            ; carry into LSB of a2
        eor        r12, r12, r4, lsl #0x0c; (involved!)
        eor        r4, r12, r12, lsr #0x14; (similarly involved!)

        ldr        r12, [r6], #0x04
        cmp        r12, r4
        bne        %F2
        subs    r1, r1, #0x01
        bne        %B1
        stmia    r2, {r4, r5}
        mov        r0, #0x00
        ldmfd    sp!, {r4-r6, pc}
2
        sub        r6, r6, #0x04
        str        r6, [r0]
        stmia    r2, {r4, r5}
        mov        r0, #0x01
        ldmfd    sp!, {r4-r6, pc}

        END

 

Только нужно учитывать, что диагностика в этом тесте может не сработать: ошибка будет зафиксирована в любом случае, но при повторном чтении *(volatile u_int *)addr может вернуть правильный результат.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Извините за тупость, но

на плате Rainbow v1.1, как мне кажется, это сделано правильно или я ошибаюсь? Просто тоже начал тестировать память, пробовал описанные здесь методики, но... либо все-таки что-то не правильно на плате, либо я неправильно инициализирую СДРАМ... вот инициализация, которую я подправил из 9200ЕК

void AT91F_InitSDRAM()

{

int i;

volatile int *pSDRAM = (int *)BASE_EBI_CS1_ADDRESS;

 

//* Configure PIOC as peripheral (D16/D31)

AT91F_SDRC_CfgPIO();

 

//* Setup MEMC to support CS1=SDRAM

AT91C_BASE_EBI->EBI_CSA |= AT91C_EBI_CS1A;

AT91C_BASE_EBI->EBI_CFGR = (AT91C_EBI_DBPUC & 0x00) | (AT91C_EBI_EBSEN & 0x00);

 

//* Init SDRAM

 

//* 1. A minimum pause of 200us is provided to precede any signal toggle

/* AT91C_BASE_SDRC->SDRC_CR = AT91C_SDRC_NC_9 | AT91C_SDRC_NR_12 | AT91C_SDRC_NB_4_BANKS | AT91C_SDRC_CAS_2

| 0x100 | 0x4000 | 0x8000

| 0x880000

| 0x21000000;

*/

AT91C_BASE_SDRC->SDRC_CR = AT91C_SDRC_NC_11 | AT91C_SDRC_NR_13 | AT91C_SDRC_NB_4_BANKS | AT91C_SDRC_CAS_2

| 0x100 | 0x4000 | 0x8000

| 0x880000

| 0x21000000;

 

 

//* 2. A Precharge All command is issued to the SDRAM

AT91C_BASE_SDRC->SDRC_MR = AT91C_SDRC_MODE_PRCGALL_CMD;

*pSDRAM = 0;

 

//* 3. Eight Auto-refresh are provided

AT91C_BASE_SDRC->SDRC_MR = AT91C_SDRC_MODE_RFSH_CMD;

for(i=0;i<8;i++)

*pSDRAM = 0;

 

//* 4. A mode register cycle is issued to program the SDRAM parameters

AT91C_BASE_SDRC->SDRC_MR = AT91C_SDRC_MODE_LMR_CMD;

*(pSDRAM+0x80) = 0;

 

//* 5. Write refresh rate into SDRAMC refresh timer COUNT register

AT91C_BASE_SDRC->SDRC_TR = (AT91C_SDRC_COUNT & 0x2E0);

*pSDRAM = 0;

 

//* 6. A Normal Mode Command is provided, 3 clocks after tMRD is set

AT91C_BASE_SDRC->SDRC_MR = AT91C_SDRC_MODE_NORMAL_CMD;

*pSDRAM = 0;

}

У меня запаяно две озухи k4s641632h, по 128 мегабит каждая,
// ***********RAND TEST********

printf("\n\rRandom test...\n\r");

// while (1)

// {

printf("\n\r-T WR- 0x00000000\n\r");

srand(1);

printf("First rand = 0x%8X\n\rStart filling\n\r",rand());

pSDRAM = (unsigned int *) BASE_EBI_CS1_ADDRESS;

// for ( wCount = 0;wCount < (1 << (batemp -2)); wCount ++)

for ( wCount = 0;wCount < 0x80000; wCount ++)

{

wWrite = rand ();

*pSDRAM = wWrite;

pSDRAM++;

}

wError = 0;

srand(1);

printf("First rand = 0x%8X\n\rStart testing\n\r",rand());

pSDRAM = (unsigned int *) BASE_EBI_CS1_ADDRESS;

// for ( wCount = 0;wCount < (1 << (batemp -2)); wCount ++)

for ( wCount = 0;wCount < 0x80000; wCount ++)

{

wRead = *pSDRAM;

wWrite = rand();

if (wRead != wWrite )

{

if (wCount> 0xfffff)

printf ("\n\r sting: %d \n\r", wCount);

printf ("[0x%08X] = 0x%08X ( 0x%08X,0x%08X)\n\r",wCount,wRead^wWrite,wRead,wWrite );

wError++;

}

pSDRAM++;

}

printf("Done. %d errors.\n\r",wError);

// }

 

}

если в этом куске wCount ставить больше, чем 0х7ffff, тоначинает запись идти на первые адреса, т.е. то, что должно быть записано в адрес 0х80000, читается в 0х0, естественно, это есть ошибка.

Подскажите, что неправильно, инициализация, или все-таки надо на плате что-то переделывать и если переделывать, то что?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А вы перекинули А12 и А14? У Вас же память с 13 битами адресации столбцов. Соответственно, реально доступна только половина, если Вы еще не перепаивали.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...