I think I was able to reproduce a similar problem in a much smaller example.
Here is the code:
Code: Select all
#include <xs1.h>
#include <platform.h>
//#include <xscope.h>
#include <stdio.h>
#include <stdlib.h>
#include "sdram.h"
#define BITS_IN_BYTE 8
#define TEMP_BUFF_SIZE 2048
#define SERVER_TILE 1
on tile[SERVER_TILE] : out buffered port:32 sdram_dq_ah = XS1_PORT_16B;
on tile[SERVER_TILE] : out buffered port:32 sdram_cas = XS1_PORT_1D;
on tile[SERVER_TILE] : out buffered port:32 sdram_ras = XS1_PORT_1C;
on tile[SERVER_TILE] : out buffered port:8 sdram_we = XS1_PORT_1B;
on tile[SERVER_TILE] : out port sdram_clk = XS1_PORT_1A;
on tile[SERVER_TILE] : clock sdram_cb = XS1_CLKBLK_1;
/*
void xscope_user_init(void){
xscope_register(0);
xscope_config_io(XSCOPE_IO_BASIC);
}
*/
void application(streaming chanend c_server) {
unsigned const numBits = ( 1 << 20 ) * 256; // 256 Megabits is capapcity of sdram chip
unsigned const numBytes = numBits / BITS_IN_BYTE ;
unsigned const numWords = numBytes / sizeof(unsigned);
unsigned remainingWords = numWords;
unsigned address = 0;
int result = 1;
s_sdram_state sdramState;
unsigned localBuffer[TEMP_BUFF_SIZE];
unsigned * movable movPtrLocalBuffer = localBuffer;
unsigned numWrites = numWords / TEMP_BUFF_SIZE;
if (numWords % TEMP_BUFF_SIZE) numWrites++;
unsigned wordsToWrite = TEMP_BUFF_SIZE;
for (int i = TEMP_BUFF_SIZE; i--;) movPtrLocalBuffer[i] = 0xdeadbeef; // Initialize buffer with initial pattern
sdram_init_state(c_server, sdramState);
for (int i = 0; i < numWrites; i++){ //Write inital pattern 0xdeadbeef
result = sdram_write(c_server, sdramState, address, wordsToWrite, move(movPtrLocalBuffer));
if (result == 0) sdram_complete(c_server, sdramState, movPtrLocalBuffer);
else{
printf("sdram_write returned %d while writing inital pattern.\n", result);
return;
}
address += wordsToWrite;
remainingWords -= wordsToWrite;
if (remainingWords < TEMP_BUFF_SIZE) wordsToWrite = remainingWords;
}
// Reset some previouslu used variables
address = 0;
remainingWords = numWords;
wordsToWrite = TEMP_BUFF_SIZE;
// Start write loop
for (int i = 0; i < numWrites; i++){
for (int j = 0; j < TEMP_BUFF_SIZE; j++){
unsigned index = (TEMP_BUFF_SIZE * i) + j;
movPtrLocalBuffer[j] = index; // Fill buffer with index/address
}
result = sdram_write(c_server, sdramState, address, wordsToWrite, move(movPtrLocalBuffer));
if (result == 0) sdram_complete(c_server, sdramState, movPtrLocalBuffer);
else{
printf("sdram_write returned %d while i=%d.\n", result, i);
return;
}
address += wordsToWrite;
remainingWords -= wordsToWrite;
if (remainingWords < TEMP_BUFF_SIZE) wordsToWrite = remainingWords;
}
// Reset the same variables again for read loop
address = 0;
remainingWords = numWords;
wordsToWrite = TEMP_BUFF_SIZE;
// Start the read loop
for (int i = 0; i < numWrites; i++){
result = sdram_read(c_server, sdramState, address, wordsToWrite, move(movPtrLocalBuffer));
if(result == 0) sdram_complete(c_server, sdramState, movPtrLocalBuffer);
else{
printf("sdram_read returned %d while i=%d.\n", result, i);
return;
}
for(int j = 0; j < TEMP_BUFF_SIZE; j++){
unsigned predictedValue = j + (i * TEMP_BUFF_SIZE);
if(movPtrLocalBuffer[j] != predictedValue) printf("ERROR! Read value: %d. Expected %d\n", movPtrLocalBuffer[j], predictedValue);
}
address += wordsToWrite;
remainingWords -= wordsToWrite;
if(remainingWords < TEMP_BUFF_SIZE) wordsToWrite = remainingWords;
}
printf("SDRAM demo completed successfully\n");
}
int main() {
streaming chan c_sdram[1];
par {
on tile[SERVER_TILE]:sdram_server(c_sdram, 1,
sdram_dq_ah,
sdram_cas,
sdram_ras,
sdram_we,
sdram_clk,
sdram_cb,
3, // CAS Latency
256, // Row words
16, // col_bits
9, // col_address_bits
13, // row_address_bits
2, // bank_address_bits
64,
8192,
5);
on tile[SERVER_TILE]: application(c_sdram[0]);
}
return 0;
}
When attempting to write the entire capacity of the chip, I observe the following output during the last loop where the reading and comparing happens:
Code: Select all
ERROR! Read value: 2097152. Expected 0
ERROR! Read value: 2097153. Expected 1
ERROR! Read value: 2097154. Expected 2
ERROR! Read value: 2097155. Expected 3
ERROR! Read value: 2097156. Expected 4
ERROR! Read value: 2097157. Expected 5
ERROR! Read value: 2097158. Expected 6
ERROR! Read value: 2097159. Expected 7
ERROR! Read value: 2097160. Expected 8
ERROR! Read value: 2097161. Expected 9
ERROR! Read value: 2097162. Expected 10
ERROR! Read value: 2097163. Expected 11
So when reading from SDRAM, at address 0 it reads what should have been written at address 2097152. However it looks like during the earlier write loop, when it attempts to write to address 2097152, it loops back to address 0.
Any ideas?