Hi InfiniteImprobability,
We have started testing with lib_sdram running on our hardware without success so far. As previously posted, our hardware uses port 16B on tile 1 for the ADQ bus and ports 1A-1D for the control bus. The SDRAM part number is a Micron MT48LC16M16A2P-6A:G (167MHZ, CL = 3, tAC = 5.4ns max, tOH = 3ns min).
During testing, several clock dividers (4, 5, & 6), CAS values (2, 3, & 4), #define N values (0, 1, & 2) in io.S, set_pad_delay(dq_ah, n) values (0, 1, & 2) in server.xc were tested with no observable differences in behavior.
Scoping the SDRAM chip at the package with a spring ground instead of a ground clip wire, the power supply rails are clean, as well as SD_CLK, WE#, CAS#, RAS# and DQM signals. The ADQ bus signals look clean as well, but only a few can be scoped at a time without a logic analyzer; that also makes it difficult to know if signals are in the right place (I suspect it's quite a task even with an analyzer!).
Our test code was adapted from the github example, and set_pad_delay(dq_ah, 0) was used along with #define N (1). Based on the timing spreadsheet, these values provided plenty of margin with a 50MHz clock:
Code: Select all
#include <xs1.h>
#include <platform.h>
#include <stdio.h>
#include <stdlib.h>
#include "sdram.h"
#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;
#define ADDR_START 0x0
void application(streaming chanend c_server) {
#define BUF_WORDS (8)
unsigned read_buffer[BUF_WORDS];
unsigned write_buffer[BUF_WORDS];
unsigned * movable read_buffer_pointer = read_buffer;
unsigned * movable write_buffer_pointer = write_buffer;
s_sdram_state sdram_state;
sdram_init_state(c_server, sdram_state);
printf("Start SDRAM Demo\n");
//Fill the memory initially with known pattern
for(unsigned i=0;i<BUF_WORDS;i++){
write_buffer_pointer[i] = 0xdeadbeef;
}
sdram_write(c_server, sdram_state, ADDR_START, BUF_WORDS, move(write_buffer_pointer));
sdram_complete(c_server, sdram_state, write_buffer_pointer);
// Read back starting from the same address
sdram_read (c_server, sdram_state, ADDR_START, BUF_WORDS, move(read_buffer_pointer));
sdram_complete(c_server, sdram_state, read_buffer_pointer);
for(unsigned i=0;i<BUF_WORDS;i++){
if(read_buffer_pointer[i] != write_buffer_pointer[i])
printf(" Failure at word %d: Value written = %08x Value read = %08x \n", i, write_buffer_pointer[i], read_buffer_pointer[i]);
else
printf(" Success at word %d: Value written = %08x Value read = %08x \n", i, write_buffer_pointer[i], read_buffer_pointer[i]);
}
printf("SDRAM demo complete.\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, 256, 16, 9, 13, 2, 64, 8192, 5); //IS45S16160D 256Mb option (Note: we're using Micron MT48LC16M16A2P-6A:G)
on tile[SERVER_TILE]: application(c_sdram[0]);
}
return 0;
}
If ADDR_START is set to 0x0, the following output is produced:
Start SDRAM Demo
Failure at word 0: Value written = deadbeef Value read = 00000000
Failure at word 1: Value written = deadbeef Value read = 00000000
Failure at word 2: Value written = deadbeef Value read = 00000000
Failure at word 3: Value written = deadbeef Value read = 00000000
Failure at word 4: Value written = deadbeef Value read = 00000000
Failure at word 5: Value written = deadbeef Value read = 00000000
Failure at word 6: Value written = deadbeef Value read = 00000000
Failure at word 7: Value written = deadbeef Value read = 00000000
SDRAM demo complete.
Setting ADDR_START to 0xe produces garbage with every word the same value:
Start SDRAM Demo
Failure at word 0: Value written = deadbeef Value read = 001c001c
Failure at word 1: Value written = deadbeef Value read = 001c001c
Failure at word 2: Value written = deadbeef Value read = 001c001c
Failure at word 3: Value written = deadbeef Value read = 001c001c
Failure at word 4: Value written = deadbeef Value read = 001c001c
Failure at word 5: Value written = deadbeef Value read = 001c001c
Failure at word 6: Value written = deadbeef Value read = 001c001c
Failure at word 7: Value written = deadbeef Value read = 001c001c
SDRAM demo complete.
When it's set to 0xf:
Start SDRAM Demo
Failure at word 0: Value written = deadbeef Value read = 001e001e
Failure at word 1: Value written = deadbeef Value read = 001e001e
Failure at word 2: Value written = deadbeef Value read = 001e001e
Failure at word 3: Value written = deadbeef Value read = 001e001e
Failure at word 4: Value written = deadbeef Value read = 001e001e
Failure at word 5: Value written = deadbeef Value read = 001e001e
Failure at word 6: Value written = deadbeef Value read = 001e001e
Failure at word 7: Value written = deadbeef Value read = 001e001e
SDRAM demo complete.
Any idea what might be going on?
- Tony