lpcware

SDRAM performance at 120MHz vs 60MHz

Discussion created by lpcware Employee on Jun 15, 2016
Latest reply on Jun 15, 2016 by lpcware
Content originally posted in LPCWare by wella-tabor on Fri Jul 24 04:03:07 MST 2015
Hello,

I just did some "not so perfect" tests to compare SDRAM when clocking 120MHz and 60 Mhz. The cpu-LPC1788 ran at 120Mhz,  SDRAM MT48LC4M32B2B5, NOR FLASH S29GL256P.

The numbers are in ms.
SDRAM, NOR @120MHz
Overall 13782
Burst read16 1957
Nor burst read 10066


SDRAM, NOR @60MHz
Overall 15576
Burst read16 2236
Nor burst read 11744


My interest was to find out the speed impact at 60MHz. I could let 120MHz but this is not a valid freq (according to the datasheet, max ~80MHz). The speed decrease ratio is about ~1,3 so the memory is not two times faster when at 120MHz. I could speed it up to 80 MHz but it causes lowering the CPU to 80 MHz.

Why I am posting this?
Because nobody did it yet. And if yes, I did not find it. Until this test I was a clock hunter :).

BR
Martin





#include <stdint.h>
// Compile without optimisation
int memperf(uint32_t sdram_base_address, uint32_t sdram_size,uint32_t nor_base_address, uint32_t nor_size)
{
StopWatch_Init();
uint32_t start;
uint32_t elapsed;
uint32_t elapsed_ms;

uint8_t *ram8 = (uint8_t *) sdram_base_address;
uint16_t *ram16 = (uint16_t *) sdram_base_address;
uint32_t *ram32 = (uint32_t *) sdram_base_address;

uint8_t *rom8 = (uint8_t *) nor_base_address;
uint16_t *rom16 = (uint16_t *) nor_base_address;
uint32_t *rom32 = (uint32_t *) nor_base_address;

uint32_t count = 0;

start = StopWatch_Start();
// write

// Fill with pattern
for (count = 0; count < sdram_size; count++)
{
ram8[count] = 0xAA;
}

// Fill with pattern
for (count = 0; count < sdram_size / sizeof(uint16_t); count++)
{
ram16[count] = 0x5555;
}

// Fill with pattern
for (count = 0; count < sdram_size / sizeof(uint32_t); count++)
{
ram32[count] = 0xAAAAAAAAUL;
}

// read
for (count = 0; count < sdram_size; count++)
{
if (ram8[count] != 0xAA)
{
return 0;
}
}

for (count = 0; count < sdram_size / sizeof(uint16_t); count++)
{
if (ram16[count] != 0xAAAA)
{
return 0;
}
}

for (count = 0; count < sdram_size / sizeof(uint32_t); count++)
{
if (ram32[count] != 0xAAAAAAAAUL)
{

}
}

// clear
for (count = 0; count < sdram_size / sizeof(uint32_t); count++)
{
ram32[count] = 0;
}

// write with stride
#define STRIDE 16

// Fill with pattern
for (count = 0; count < sdram_size; count += STRIDE)
{
ram8[count] = 0xAA;
}

// Fill with pattern
for (count = 0; count < sdram_size / sizeof(uint16_t); count += STRIDE)
{
ram16[count] = 0xAAAA;
}

// Fill with pattern
for (count = 0; count < sdram_size / sizeof(uint32_t); count += STRIDE)
{
ram32[count] = 0xAAAAAAAAUL;
}

// read with stride
for (count = 0; count < sdram_size; count += STRIDE)
{
if (ram8[count] != 0xAA)
{
return -1;
}
}

for (count = 0; count < sdram_size / sizeof(uint16_t); count += STRIDE)
{
if (ram16[count] != 0xAAAA)
{
return -1;
}
}

for (count = 0; count < sdram_size / sizeof(uint32_t); count += STRIDE)
{
if (ram32[count] != 0xAAAAAAAAUL)
{
return -1;
}
}


// write /read

// Fill with pattern
for (count = 0; count < sdram_size / sizeof(uint32_t) / 2; count++)
{
// write to beginning
ram32[count] = 0xAAAAAAAAUL;

// read from end with write back
ram32[count] = ram32[sdram_size / sizeof(uint32_t) - count  - 1];
}

elapsed = StopWatch_Elapsed(start);
elapsed_ms = StopWatch_TicksToMs(elapsed);
debug_print_text("Overall ");
debug_print_number(elapsed_ms);
debug_print_newline(1);

// Rom test
start = StopWatch_Start();
for (count = 0; count < sdram_size / sizeof(uint16_t); count++)
{
volatile uint16_t a;
a = ram16[count];

}
elapsed = StopWatch_Elapsed(start);
elapsed_ms = StopWatch_TicksToMs(elapsed);
debug_print_text("Burst read16 ");
debug_print_number(elapsed_ms);
debug_print_newline(1);


start = StopWatch_Start();
// read
for (count = 0; count < nor_size; count++)
{
volatile uint32_t a;
a = rom8[count];
}

for (count = 0; count < sdram_size / sizeof(uint16_t); count++)
{
volatile uint32_t a;
a = rom16[count];
}
for (count = 0; count < sdram_size / sizeof(uint32_t); count++)
{
volatile uint32_t a;
a = rom32[count];
}
elapsed = StopWatch_Elapsed(start);
elapsed_ms = StopWatch_TicksToMs(elapsed);
debug_print_text("Nor burst read ");
debug_print_number(elapsed_ms);
debug_print_newline(1);

return 0;
}

Outcomes