Lower the uLab FPGA viewer GPMC clock to reduce errors on prototype lashup

Add memory stress tests to GPMC test program
master
Timothy Pearson 10 years ago
parent 0ffb793cb5
commit 32b7b87d3d

@ -34,7 +34,7 @@
#include <sys/mman.h>
#include <fcntl.h>
#define MEMORY_SPACE_ADDRESS_BITS 15
#define MEMORY_SPACE_ADDRESS_BITS 16
#define GPMC_BASE 0x50000000
#define GPMC_REGLEN 0x10000000
@ -119,11 +119,17 @@ static void gpmc_setup(void)
// *(gpmc + displacement + GPMC_CONFIG4) = 0x06020802; // Assert WE on fclk2, deassert WE on fclk6, assert OE on fclk2, deassert OE on fclk8
// *(gpmc + displacement + GPMC_CONFIG5) = 0x00060808; // Data valid on fclk 6, cycle time 8 fclks
// 100MHz compatible SRAM device
*(gpmc + displacement + GPMC_CONFIG2) = 0x00001000; // Assert CS on fclk0, deassert CS on fclk16
// // 100MHz compatible SRAM device
// *(gpmc + displacement + GPMC_CONFIG2) = 0x00001000; // Assert CS on fclk0, deassert CS on fclk16
// *(gpmc + displacement + GPMC_CONFIG3) = 0x00000400; // Assert ADV on fclk 0, deassert ADV on fclk 4
// *(gpmc + displacement + GPMC_CONFIG4) = 0x0c041004; // Assert WE on fclk4, deassert WE on fclk12, assert OE on fclk4, deassert OE on fclk16
// *(gpmc + displacement + GPMC_CONFIG5) = 0x000c1010; // Data valid on fclk 12, cycle time 16 fclks
// 50MHz compatible SRAM device
*(gpmc + displacement + GPMC_CONFIG2) = 0x00001f00; // Assert CS on fclk0, deassert CS on fclk31
*(gpmc + displacement + GPMC_CONFIG3) = 0x00000400; // Assert ADV on fclk 0, deassert ADV on fclk 4
*(gpmc + displacement + GPMC_CONFIG4) = 0x0c041004; // Assert WE on fclk4, deassert WE on fclk12, assert OE on fclk4, deassert OE on fclk16
*(gpmc + displacement + GPMC_CONFIG5) = 0x000c1010; // Data valid on fclk 12, cycle time 16 fclks
*(gpmc + displacement + GPMC_CONFIG4) = 0x1f041f04; // Assert WE on fclk4, deassert WE on fclk31, assert OE on fclk4, deassert OE on fclk31
*(gpmc + displacement + GPMC_CONFIG5) = 0x00101f1f; // Data valid on fclk 16, cycle time 31 fclks
*(gpmc + displacement + GPMC_CONFIG6) = 0x00000000; // No back to back cycle restrictions
*(gpmc + displacement + GPMC_CONFIG7) = 0x00000e50; // CS0: Set base address 0x10000000, 32MB region, and enable CS
@ -180,6 +186,117 @@ static void io_setup(void)
// for (j=0;j<0x3ff; j++) {
// *(gpio + j) = j;
// }
// DEBUG ONLY
// Looping memory test
unsigned int test_base = (MEMORY_SIZE/2);
unsigned int test_length = (MEMORY_SIZE/2);
unsigned int total_errors;
unsigned char error_count[MEMORY_SIZE];
int i;
int loop;
unsigned int overall_total_errors;
overall_total_errors = 0;
for (loop=0; loop<10;loop++) {
printf("Memory test loop %d\n", loop);
for (i=0; i<test_length; i++) {
error_count[i] = 0;
}
printf("\tTesting inversion pattern\n");
// Test with 0xaa
for (i=0;i<test_length; i++) {
*(gpio_char + test_base + i) = 0xaa;
}
for (i=0;i<test_length; i++) {
unsigned char result = *(gpio_char + test_base + i);
if ((result != 0xaa)) {
error_count[i] = error_count[i] + 1;
printf("\terror detected at offset 0x%02x (was 0x%02x, expected 0x%02x, second read attempt returned 0x%02x)\n", i, result, 0xaa, (*(gpio_char + test_base + i)));
}
}
// Test with 0x55
for (i=0;i<test_length; i++) {
*(gpio_char + test_base + i) = 0x55;
}
for (i=0;i<test_length; i++) {
unsigned char result = *(gpio_char + test_base + i);
if ((result != 0x55)) {
error_count[i] = error_count[i] + 1;
printf("\terror detected at offset 0x%02x (was 0x%02x, expected 0x%02x, second read attempt returned 0x%02x)\n", i, result, 0x55, (*(gpio_char + test_base + i)));
}
}
total_errors = 0;
for (i=0; i<test_length; i++) {
total_errors = total_errors + error_count[i];
if (error_count[i] > 0) {
printf("\t%d\terror(s) found at offset 0x%02x\n", error_count[i], i);
}
}
printf("\tTesting all ones/zeros\n");
// Test with 0xff
for (i=0;i<test_length; i++) {
*(gpio_char + test_base + i) = 0xff;
}
for (i=0;i<test_length; i++) {
unsigned char result = *(gpio_char + test_base + i);
if ((result != 0xff)) {
error_count[i] = error_count[i] + 1;
printf("\terror detected at offset 0x%02x (was 0x%02x, expected 0x%02x, second read attempt returned 0x%02x)\n", i, result, 0xff, (*(gpio_char + test_base + i)));
}
}
// Test with 0x00
for (i=0;i<test_length; i++) {
*(gpio_char + test_base + i) = 0x00;
}
for (i=0;i<test_length; i++) {
unsigned char result = *(gpio_char + test_base + i);
if ((result != 0x00)) {
error_count[i] = error_count[i] + 1;
printf("\terror detected at offset 0x%02x (was 0x%02x, expected 0x%02x, second read attempt returned 0x%02x)\n", i, result, 0x00, (*(gpio_char + test_base + i)));
}
}
printf("\tTesting alternating ones/zeros\n");
// Test with 0xff
for (i=0;i<test_length; i=i+2) {
*(gpio_char + test_base + i) = 0xff;
*(gpio_char + test_base + i + 1) = 0x00;
}
for (i=0;i<test_length; i=i+2) {
unsigned char result;
result = *(gpio_char + test_base + i);
if ((result != 0xff)) {
error_count[i] = error_count[i] + 1;
printf("\terror detected at offset 0x%02x (was 0x%02x, expected 0x%02x, second read attempt returned 0x%02x)\n", i, result, 0xff, (*(gpio_char + test_base + i)));
}
result = *(gpio_char + test_base + i + 1);
if ((result != 0x00)) {
error_count[i] = error_count[i] + 1;
printf("\terror detected at offset 0x%02x (was 0x%02x, expected 0x%02x, second read attempt returned 0x%02x)\n", i, result, 0x00, (*(gpio_char + test_base + i)));
}
}
total_errors = 0;
for (i=0; i<test_length; i++) {
total_errors = total_errors + error_count[i];
if (error_count[i] > 0) {
printf("\t%d\terror(s) found at offset 0x%02x\n", error_count[i], i);
}
}
printf("\tTest region size:\t%d\n", test_length);
printf("\tTotal errors found:\t%d\n", total_errors);
fflush(stdout);
overall_total_errors = overall_total_errors + total_errors;
}
for (i=0;i<MEMORY_SIZE; i++) {
*(gpio_char + i) = 0;
}
printf("Total errors found over all loops:\t%d\n", overall_total_errors);
fflush(stdout);
return;
int j;
for (j=0;j<MEMORY_SIZE; j++) {
*(gpio_char + j) = ((unsigned char)j);

@ -106,12 +106,22 @@ void gpmc_setup(void) {
// disable before playing with the registers
*(gpmc + displacement + GPMC_CONFIG7) = 0x00000000;
// *(gpmc + displacement + GPMC_CONFIG) = 0x00000000; // Unlimited address space
// *(gpmc + displacement + GPMC_CONFIG1) = 0x00000000; // No burst, async, 8-bit, non multiplexed
// *(gpmc + displacement + GPMC_CONFIG2) = 0x00001000; // Assert CS on fclk0, deassert CS on fclk16
// *(gpmc + displacement + GPMC_CONFIG3) = 0x00000400; // Assert ADV on fclk 0, deassert ADV on fclk 4
// *(gpmc + displacement + GPMC_CONFIG4) = 0x0c041004; // Assert WE on fclk4, deassert WE on fclk12, assert OE on fclk4, deassert OE on fclk16
// *(gpmc + displacement + GPMC_CONFIG5) = 0x000c1010; // Data valid on fclk 12, cycle time 16 fclks
// *(gpmc + displacement + GPMC_CONFIG6) = 0x00000000; // No back to back cycle restrictions
// *(gpmc + displacement + GPMC_CONFIG7) = 0x00000e50; // CS0: Set base address 0x10000000, 32MB region, and enable CS
// Use slower clocking to reduce errors in wire nest prototype
*(gpmc + displacement + GPMC_CONFIG) = 0x00000000; // Unlimited address space
*(gpmc + displacement + GPMC_CONFIG1) = 0x00000000; // No burst, async, 8-bit, non multiplexed
*(gpmc + displacement + GPMC_CONFIG2) = 0x00001000; // Assert CS on fclk0, deassert CS on fclk16
*(gpmc + displacement + GPMC_CONFIG2) = 0x00001f00; // Assert CS on fclk0, deassert CS on fclk31
*(gpmc + displacement + GPMC_CONFIG3) = 0x00000400; // Assert ADV on fclk 0, deassert ADV on fclk 4
*(gpmc + displacement + GPMC_CONFIG4) = 0x0c041004; // Assert WE on fclk4, deassert WE on fclk12, assert OE on fclk4, deassert OE on fclk16
*(gpmc + displacement + GPMC_CONFIG5) = 0x000c1010; // Data valid on fclk 12, cycle time 16 fclks
*(gpmc + displacement + GPMC_CONFIG4) = 0x1f041f04; // Assert WE on fclk4, deassert WE on fclk31, assert OE on fclk4, deassert OE on fclk31
*(gpmc + displacement + GPMC_CONFIG5) = 0x00101f1f; // Data valid on fclk 16, cycle time 31 fclks
*(gpmc + displacement + GPMC_CONFIG6) = 0x00000000; // No back to back cycle restrictions
*(gpmc + displacement + GPMC_CONFIG7) = 0x00000e50; // CS0: Set base address 0x10000000, 32MB region, and enable CS

@ -369,6 +369,9 @@ void FPGASocket::commandLoop() {
if (m_stateImageRXCounter >= dsp_ram_size) {
m_stateImageRXRequested = false;
m_stateImageTXRequested = true;
// Start user processing
write_gpmc(0x0a, read_gpmc(0x0a) | 0x01);
}
}
else {
@ -398,6 +401,16 @@ void FPGASocket::commandLoop() {
write_gpmc(0x05, buffer[read_offset+4]);
read_offset = read_offset + 6;
}
else if (buffer[read_offset+0] == 'R') {
write_gpmc(0x0c, read_gpmc(0x0c) | 0x01);
usleep(100);
write_gpmc(0x0c, read_gpmc(0x0c) & ~0x01);
read_offset = read_offset + 2;
}
else {
printf("[WARNING] Received invalid command '%c' from client! Dazed and confused, but continuing...\n", buffer[read_offset+0]);
read_offset = read_offset + 2;
}
}
if (m_stateImageTXRequested) {
m_stateImageTXRequested = false;

Loading…
Cancel
Save