⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ftahbram.c

📁 The GRLIB IP Library is an integrated set of reusable IP cores, designed for system-on-chip (SOC) de
💻 C
字号:
/****************************************************************************** *Tests the on-chip ram and returns an error code if an error is detected. *Do not enable MULTIPLEERROR since it will halt the cpu unless a modified *traptable is used. AUTOSCRUB and ERRCNT must not be enabled unless EDACEN *is enabled ******************************************************************************/#include "ftahbram.h"#include "ftlib.h"#include <stdio.h>#define RAMADDR 0xa0000000   //Address to the RAM under test#define CONFADDR 0x80000b00  //Address to the configuration register of the RAM#define AHBSTATADR 0x80000d00 //Address to AHB Status Module //Testcontrol #define AUTOSCRUB 1 //Autoscrubbing enabled#define ERRCNT 1    //Error counter enabled#define EDACEN 1    //EDAC Enabled#define CNTBITS 1   //Number of bits used for the single error counter (1 - 8)#define MULTIPLEERROR 0 //Do multiple error test (Requires modified traptable)#define AHBSTATAV 1   //AHB status register availablestruct control_reg {  unsigned reserved : 19 - CNTBITS; //currently unused  unsigned sec      : CNTBITS; //Single error counter  unsigned memsize  : 3;  //memorysize  unsigned wb       : 1;  //write diagnostics enable  unsigned rb       : 1;  //read diagnostics enable  unsigned en       : 1;  //edac enable  unsigned tcb      : 7;  //checkbits used for diagnostics};extern void *catch_interrupt(void func(int irq), int irq);void irq_handler(int irq);static int irqcnt = 0;static int irqerror = 0;static int *creg_val;static volatile int *creg_pnt = (int *) CONFADDR;static volatile int *ahbstat = (int *) AHBSTATADR; int ftahbram_test(void) {  volatile int *iram = (int *) RAMADDR;  volatile char *cram = (char *) RAMADDR;  volatile short int *sram = (short int *) RAMADDR;   int size;  int i;  int temp1;  int temp4;  int temp5;  unsigned int temp6;  int ctrl;  int cachectrl;  short int temp2;  char temp3;  struct control_reg creg;   struct control_reg *read;  read = (struct control_reg *) &ctrl;  int countmax;   creg_val = (int *) &creg;  size = 1024 * pow2( (int)( (*creg_pnt >> 9) & 7) );  countmax = pow2(CNTBITS) - 1;    //initialization   creg.tcb = 0;  creg.rb = 0;  creg.wb = 0;  creg.memsize = 0;  creg.sec = countmax;  creg.reserved = 0;      *creg_pnt = *creg_val;    //Disable caches  cachectrl = cache_disable();    /* printf("write test words\n"); */  i = 0;while(i < 2) {   //test all memory locations with word accesses  for(i = 0; i < (size / 4); i++) {    *(iram + i) = i;  }    /* printf("read test words\n"); */  for(i = 0; i < (size / 4); i = i++) {    if ( *(iram + i) != i ) {      //word has been read or written incorrectly      return 1;    }  }    /* printf("write test halfwords\n"); */  //test all memory locations with halfword accesses  for(i = 0; i < (size / 2); i = i++) {    *(sram + i) = i;  }  /* printf("read test halfwords\n"); */  for(i = 0; i < (size / 2) ; i = i++ ) {    if ( *(sram + i) != i ) {    //halfword has been read or written incorrectly      return 2;    }  }/*   printf("write test bytes\n"); */  //test all memory locations with halfword accesses  for(i = 0; i < size; i = i++) {    *(cram + i) = (char)i;  }  /* printf("read test bytes\n"); */  for(i = 0; i < size ; i = i++ ) {    if ( *(cram + i) != (char) i ) {    //halfword has been read or written incorrectly      return 3;    }  }  /* printf("word read after write test\n"); */  for(i = 0; i < (size / 4); i++) {    *(iram + i) = i;    temp1 = *(iram + i);    if (temp1 != i) {      //read after write error      return 4;    }  }    /* printf("halfword read after write test\n"); */  for(i = 0; i < (size / 2); i++) {    *(sram + i) = i;    temp2 = *(sram + i);    if (temp2 != i) {      //read after write error      return 5;    }  }    /* printf("byte read after write test\n"); */  for(i = 0; i < size; i++) {    *(cram + i) = (char)i;    temp3 = *(cram + i);    if (temp3 != (char)i) {      //read after write error      return 6;    }  }#if EDACEN == 1  i++;  creg.en = 0;  *creg_pnt = *creg_val;#else  i = 2;#endif}#if EDACEN == 1 creg.en = 1; *creg_pnt = *creg_val;    //Single error tests  /* printf("checkbit test\n"); */  creg.rb = 1;  *creg_pnt = *creg_val;  ctrl = *creg_pnt;  for(i = 0; i < 1024; i++) {    temp4 = rand();    *iram = temp4;    temp1 = *iram;    temp1 = encode(temp4);    ctrl = *creg_pnt;    /* printf("Value: %i\n", temp4); */    /* printf("Calc check: %x\n", temp1); */    /* printf("Read check: %x\n", read->tcb); */    if(read->tcb != temp1) {      //checkbit mismatch      /* printf("Checkbit error in iteration : %i\n", i); */      return 7;    }  }  /* printf("Single error correction test\n"); */  creg.wb = 1;  creg.rb = 0;  *creg_pnt = *creg_val;  temp1 = 0xdbac8754;  /* printf("Data: %x\n", temp1); */  temp4 = encode(temp1);  /* printf("Checkbits : %x\n", temp4); */  for(i = 0; i < 32; i++) {    /* printf("Iteration : %i\n", i); */    creg.tcb = scramble(temp4, i, 0);    /* printf("Scrambled cbits: %x\n", creg.tcb); */    *creg_pnt = *creg_val;    *iram = temp1;    temp5 = *iram;    /* printf("Read data: %x\n", temp5); */    if(temp5 != (temp1 ^ (1 << i))) {      //data not corrected properly      return 8;    }  }  //Single error counter and Interrupt tests#if ERRCNT == 1  *creg_pnt = *creg_val;  temp1 = 0x9b304d24;  temp4 = scramble(encode(temp1), 0, 0);  creg.sec = 0;  creg.tcb = temp4;  *creg_pnt = *creg_val;  /* printf("Single error counter and interrupt test\n"); */  for(i = 0; i < countmax; i++) {    *iram = temp1;    temp5 = *iram;    ctrl = *creg_pnt;    /* printf("sec: %i\n", read->sec); */    if (read->sec != i + 1) {      //Single error counter error      //printf("iteration: %i\n", i);      return 9;    }  }  *iram = temp1;  temp5 = *iram;  ctrl = *creg_pnt;  if(read->sec != countmax) {    //Single error counter saturation error    return 10;  }    creg.sec = countmax;  *creg_pnt = *creg_val;  *ahbstat = 0;#if AHBSTATAV == 1  catch_interrupt(irq_handler, IRQ);  enable_irq(IRQ);  while(irqcnt < 100) {    *(iram + irqcnt) = temp1;    temp5 = *(iram + irqcnt);  }  disable_irq(IRQ);  if(irqerror != 0) {    //interrupt error    if (irqerror == 1) {      return 11;    } else {      return 21;    }  }#endif  *creg_pnt = *creg_val;  *iram = temp1;  creg.wb = 0;  *creg_pnt = *creg_val;  *cram = (char) 0x01;  ctrl = *creg_pnt;  if(read->sec != 1) {    //Incorrect single error detection    return 12;  }  *creg_pnt = *creg_val;  temp5 = *iram;  ctrl = *creg_pnt;  if(read->sec != 0) {    //Incorrect single error correction    return 13;  }#endif    //Autoscrub tests#if AUTOSCRUB == 1  creg.wb = 1;  *creg_pnt = *creg_val;  *iram = temp1;  temp5 = *iram;  ctrl = *creg_pnt;  if(read->sec != 1) {    //Incorrect single error detection    return 14;  }  *creg_pnt = *creg_val;  temp5 = *iram;  ctrl = *creg_pnt;  if(read->sec != 0) {    //Autoscrub error    return 15;  }#endif#if MULTIPLEERROR == 1      //Multiple error tests  creg.sec = countmax;  creg.rb = 1;  *creg_pnt = *creg_val;  creg.sec = 0;  temp1 = 0x30a9c15b;  temp4 = encode(temp1);  for(i = 0; i < 88; i++) {    //printf("Iteration : %i\n", i);    creg.tcb = scramble(temp4, i, 1);    *creg_pnt = *creg_val;    ctrl = *creg_pnt;    *iram = temp1;    creg.tcb = 0;    *creg_pnt = *creg_val;    temp5 = *iram;    ctrl = *creg_pnt;    if(read->sec != 0) {      //printf("Iteration : %i\n", i);      //Multiple error detected as single error      return 16;    }  } #endif#if ERRCNT == 1  //Single error on checkbits test  /* printf("Single error on checkbits test\n"); */  creg.sec = countmax;  creg.wb = 1;  creg.rb = 0;  *creg_pnt = *creg_val;  temp1 = 0x1234567;  for(i = 32; i < 39; i++) {    temp4 = scramble(encode(temp1), i, 0);    creg.tcb = temp4;    *creg_pnt = *creg_val;    *iram = temp1;    creg.wb = 0;    *creg_pnt = *creg_val;    temp5 = *iram;    ctrl = *creg_pnt;    if(read->sec != 1 || temp5 != temp1) {      //Incorrect checkbit error handling      return 17;    }    creg.wb = 1;    *creg_pnt = *creg_val;#if AUTOSCRUB == 1    temp5 = *iram;    ctrl = *creg_pnt;    if(read->sec != 0 || temp5 != temp1) {      //Autoscrub handles checkbit error incorrectly      return 18;    } #endif  }#endif  creg.wb = 0;  creg.rb = 0;  creg.sec = countmax;  *creg_pnt = *creg_val;  //Mixed size reads and writes  *iram = 0xaabbccdd;  *(cram + 2) = 0xee;  temp1 = *iram;  *(cram + 3) = 0xff;  temp4 = *iram;  *(iram + 1) = 0xffffeeee;  *(sram + 2) = 0x1111;  temp2 = *(sram + 2);  *(cram + 6) = 0x22;  temp3 = *(cram + 7);  temp5 = (int)temp3;  if( (temp1 != 0xaabbeedd) || (temp4 != 0xaabbeeff) || ( (temp5 & 0xff) != 0xee) ||      (temp2 != 0x1111) ) {    //Write error, read error     return 19;  }  //Mixed size with single errors   creg.wb = 1;  temp1 = 0xaabbccdd;  creg.tcb = scramble(encode(temp1), 8, 0);  *creg_pnt = *creg_val;  *iram = temp1;  *(iram + 1) = temp1;  *(iram + 2) = temp1;  creg.wb = 0;  *creg_pnt = *creg_val;  *(cram + 1) = 0x22;  temp4 = *iram;  *(sram + 2) = 0x4455;  temp2 = *(sram + 2);  temp5 = *(iram + 2);  temp3 = *(cram + 1);  if( (temp2 != 0x4455) || ((int) temp3 != 0x22) || (temp4 != 0xaa22cddd) ||      (temp5 != 0xaabbcddd) ) {    //Write error, read error    return 20;  }#endif  //Set caches to old state  cache_reset(cachectrl);    //no errors   return 0;}void irq_handler(int irq) {  int ctrl;  int temp;  struct control_reg *reg;  reg = (struct control_reg *) &ctrl;  ctrl = *creg_pnt;  if(reg->sec != 1) {    irqerror = 1;  }  *creg_pnt = *creg_val;  temp = *(ahbstat + 1);  if ( temp != (RAMADDR + irqcnt * 4)) {    //ahb stat error    irqerror = 2;  }   *ahbstat = 0;  irqcnt++;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -