From: Philip Pemberton on
Hi guys,
I could really use some help from an SDRAM / FPGA guru here...

I've got an SDRAM controller IP core -- specifically, the sdram_wb core
by Stephen Williams, available from the Git repository
<git://icarus.com/~steve-icarus/sdram_wb.git>. This core works fine on
the Altera DE1, with a 16-bit-wide 64Mbit (1M*16*4bank) PowerChip SDRAM,
P/N A2V64S40CTP. The FPGA is a Cyclone II 2C20, and all I had to do to
make the core work was add a PLL to shift the SDRAM clock by 2ns.

Unfortunately (for me), I hit the limits of what the DE1 could do -- I
got the SoC working, but ran out of space for the LCD controller
(framebuffer) and audio controller. So I've started playing with the
Enterpoint Drigmorn2 board, which uses a Xilinx Spartan3A XC3S700A FPGA,
and a 32Mbyte (2M*32*4bank) 32-bit-wide ISSI SDRAM chip, the IS42S32800B.

The problem is, while all the other SoC logic (CPU, etc.) seems to work
fine, the SDRAM interface just plain won't work. The WISHBONE interface
works great (as in, I can R/W the cache, which stores 32 words, split
into 4 blocks), but if I do a write/readback that requires a RAM access,
the readback returns garbage:

----8<----

SDRAM controller configuration:
Status register: 0x00000833
CAS latency = 3
Column address bits = 9
Enabled and ready
Refresh Timer: 390 clock cycles
CONFIG1: 0x00001010
Trp_clk = 0
Trfc_clk = 1
Trcd_clk = 0
Tras_clk = 1
Cmd> w
Write to memory
Enter address (0x40000000 is added automatically): 0x00000000
Value: 0x55AABBCC
Cmd> q
Read from memory
Enter address (0x40000000 is added automatically): 0x00000000
Value: 0x55AABBCC
Cmd> w
Write to memory
Enter address (0x40000000 is added automatically): 0x00000040
Value: 0xBBCC55AA
Cmd> q
Read from memory
Enter address (0x40000000 is added automatically): 0x00000040
Value: 0xBBCC55AA
Cmd> q
Read from memory
Enter address (0x40000000 is added automatically): 0x00000000
Value: 0x55AABBCC

Cmd> w
Write to memory
Enter address (0x40000000 is added automatically): 0x00000080
Value: 0x12345678
Cmd> q
Read from memory
Enter address (0x40000000 is added automatically): 0x00000000
Value: 0x7AEDB9CC
Cmd> q
Read from memory
Enter address (0x40000000 is added automatically): 0x00000080
Value: 0x7AFFBDFE

----8<----

Interestingly, as long as I only write to data in the address range
[0x00..0x80], the RAM works fine. As soon as I write to address 0x80, all
bets are off. The data is not the same each time, but it does remain
static:

----8<----
Cmd> q
Read from memory
Enter address (0x40000000 is added automatically): 0x00000000
Value: 0xBD2015AA
Cmd> w
Write to memory
Enter address (0x40000000 is added automatically): 0x00000000
Value: 0x12345678
Cmd> w
Write to memory
Enter address (0x40000000 is added automatically): 0x00000080
Value: 0x89ABCDEF
Cmd> q
Read from memory
Enter address (0x40000000 is added automatically): 0x00000000
Value: 0xBD301068
Cmd> q
Read from memory
Enter address (0x40000000 is added automatically): 0x00000000
Value: 0xBD301068
Cmd> q
Read from memory
Enter address (0x40000000 is added automatically): 0x00000080
Value: 0x8830BDFF
Cmd> q
Read from memory
Enter address (0x40000000 is added automatically): 0x00000000
Value: 0xBD301068
----8<----

Ordinarily I'd start by checking for timing issues by soldering wires to
the pins on the RAM IC, then hooking up the logic analyser. This isn't an
option in this case, because the chip is a BGA -- I physically can't get
to the pins/pads/balls/whatever. I'd rather not remove the chip because I
don't have much experience with BGA rework and I'd probably ruin the
(rather expensive) development board.

I have tried routing the clocks and SDRAM data lines onto the LHS and RHS
header pins, then captured the data with my logic analyser -- this shows
that the timing is fine, and also shows that the data being returned is
not the same as that written to the SDRAM. I can do a few screen captures
and put these online if it helps, although I'll openly admit that timing
on the headers =/= timing at the SDRAM (for a start, they're going to be
going through different I/O buffers).

I've also checked the refresh timing -- it's about 15.6 microseconds
(with a 25MHz input clock). I've tried reducing the refresh-timer value
to ~12us but this has no effect on the failure symptoms.

This is how I have the clocking set up:
// Core clock DCM
dcm_core_clock DCM_CoreClockGen (
.CLKIN_IN (CLOCK),
.RST_IN (DCM_RESET),
.CLKFX_OUT (MCLK),
.CLKIN_IBUFG_OUT (CLOCK_B),
.CLK0_OUT (),
.LOCKED_OUT (MCLK_LOCKED)
);

// SDRAM clock DCM -- skews the master clock for the SDRAM
dcm_sdram DCM_SDRAMClockGen (
.CLKIN_IN (MCLK),
// Hold SDRAM DCM in reset until master DCM has locked
.RST_IN (DCM_RESET || !MCLK_LOCKED),
.CLK0_OUT (),
.CLK90_OUT (),
.CLK180_OUT (),
.CLK270_OUT (SDRAM_CLK),
.LOCKED_OUT (SDRAM_CLK_LOCKED)
);

CLOCK is a 25MHz clock input from a crystal oscillator. The Core Clock
DCM is a throwback to an earlier design which ran at 50MHz, but is
currently set up as a "1:1" multiplier (if you can call it that).

The SDRAM DCM is set up to mirror the input clock on the output, with
different phase shifts. At the moment I'm using the 270deg output, but
I've also tried the 0deg and 90deg outputs with no success.

SDRAM_CLK is the output pin for the SDRAM clock.

Can anyone offer any suggestions for other things I could try (or check)?
I'm happy to re-synth the logic or provide logic analyser traces, HDL
source, etc. to help out -- but bear in mind I'm limited to 40 logic
analyser 'bits' at a time (the Drigmorn2 only has 40 user I/Os).

Thanks,
--
Phil.
usenet10(a)philpem.me.uk
http://www.philpem.me.uk/
If mail bounces, replace "10" with the last two digits of the current year
From: Górski Adam on
Hi,

Check system memory map. Maybe somthing is covered with something else.

Adam
> Hi guys,
> I could really use some help from an SDRAM / FPGA guru here...
>
> I've got an SDRAM controller IP core -- specifically, the sdram_wb core
> by Stephen Williams, available from the Git repository
> <git://icarus.com/~steve-icarus/sdram_wb.git>. This core works fine on
> the Altera DE1, with a 16-bit-wide 64Mbit (1M*16*4bank) PowerChip SDRAM,
> P/N A2V64S40CTP. The FPGA is a Cyclone II 2C20, and all I had to do to
> make the core work was add a PLL to shift the SDRAM clock by 2ns.
>
> Unfortunately (for me), I hit the limits of what the DE1 could do -- I
> got the SoC working, but ran out of space for the LCD controller
> (framebuffer) and audio controller. So I've started playing with the
> Enterpoint Drigmorn2 board, which uses a Xilinx Spartan3A XC3S700A FPGA,
> and a 32Mbyte (2M*32*4bank) 32-bit-wide ISSI SDRAM chip, the IS42S32800B.
>
> The problem is, while all the other SoC logic (CPU, etc.) seems to work
> fine, the SDRAM interface just plain won't work. The WISHBONE interface
> works great (as in, I can R/W the cache, which stores 32 words, split
> into 4 blocks), but if I do a write/readback that requires a RAM access,
> the readback returns garbage:
>
> ----8<----
>
> SDRAM controller configuration:
> Status register: 0x00000833
> CAS latency = 3
> Column address bits = 9
> Enabled and ready
> Refresh Timer: 390 clock cycles
> CONFIG1: 0x00001010
> Trp_clk = 0
> Trfc_clk = 1
> Trcd_clk = 0
> Tras_clk = 1
> Cmd> w
> Write to memory
> Enter address (0x40000000 is added automatically): 0x00000000
> Value: 0x55AABBCC
> Cmd> q
> Read from memory
> Enter address (0x40000000 is added automatically): 0x00000000
> Value: 0x55AABBCC
> Cmd> w
> Write to memory
> Enter address (0x40000000 is added automatically): 0x00000040
> Value: 0xBBCC55AA
> Cmd> q
> Read from memory
> Enter address (0x40000000 is added automatically): 0x00000040
> Value: 0xBBCC55AA
> Cmd> q
> Read from memory
> Enter address (0x40000000 is added automatically): 0x00000000
> Value: 0x55AABBCC
>
> Cmd> w
> Write to memory
> Enter address (0x40000000 is added automatically): 0x00000080
> Value: 0x12345678
> Cmd> q
> Read from memory
> Enter address (0x40000000 is added automatically): 0x00000000
> Value: 0x7AEDB9CC
> Cmd> q
> Read from memory
> Enter address (0x40000000 is added automatically): 0x00000080
> Value: 0x7AFFBDFE
>
> ----8<----
>
> Interestingly, as long as I only write to data in the address range
> [0x00..0x80], the RAM works fine. As soon as I write to address 0x80, all
> bets are off. The data is not the same each time, but it does remain
> static:
>
> ----8<----
> Cmd> q
> Read from memory
> Enter address (0x40000000 is added automatically): 0x00000000
> Value: 0xBD2015AA
> Cmd> w
> Write to memory
> Enter address (0x40000000 is added automatically): 0x00000000
> Value: 0x12345678
> Cmd> w
> Write to memory
> Enter address (0x40000000 is added automatically): 0x00000080
> Value: 0x89ABCDEF
> Cmd> q
> Read from memory
> Enter address (0x40000000 is added automatically): 0x00000000
> Value: 0xBD301068
> Cmd> q
> Read from memory
> Enter address (0x40000000 is added automatically): 0x00000000
> Value: 0xBD301068
> Cmd> q
> Read from memory
> Enter address (0x40000000 is added automatically): 0x00000080
> Value: 0x8830BDFF
> Cmd> q
> Read from memory
> Enter address (0x40000000 is added automatically): 0x00000000
> Value: 0xBD301068
> ----8<----
>
> Ordinarily I'd start by checking for timing issues by soldering wires to
> the pins on the RAM IC, then hooking up the logic analyser. This isn't an
> option in this case, because the chip is a BGA -- I physically can't get
> to the pins/pads/balls/whatever. I'd rather not remove the chip because I
> don't have much experience with BGA rework and I'd probably ruin the
> (rather expensive) development board.
>
> I have tried routing the clocks and SDRAM data lines onto the LHS and RHS
> header pins, then captured the data with my logic analyser -- this shows
> that the timing is fine, and also shows that the data being returned is
> not the same as that written to the SDRAM. I can do a few screen captures
> and put these online if it helps, although I'll openly admit that timing
> on the headers =/= timing at the SDRAM (for a start, they're going to be
> going through different I/O buffers).
>
> I've also checked the refresh timing -- it's about 15.6 microseconds
> (with a 25MHz input clock). I've tried reducing the refresh-timer value
> to ~12us but this has no effect on the failure symptoms.
>
> This is how I have the clocking set up:
> // Core clock DCM
> dcm_core_clock DCM_CoreClockGen (
> .CLKIN_IN (CLOCK),
> .RST_IN (DCM_RESET),
> .CLKFX_OUT (MCLK),
> .CLKIN_IBUFG_OUT (CLOCK_B),
> .CLK0_OUT (),
> .LOCKED_OUT (MCLK_LOCKED)
> );
>
> // SDRAM clock DCM -- skews the master clock for the SDRAM
> dcm_sdram DCM_SDRAMClockGen (
> .CLKIN_IN (MCLK),
> // Hold SDRAM DCM in reset until master DCM has locked
> .RST_IN (DCM_RESET || !MCLK_LOCKED),
> .CLK0_OUT (),
> .CLK90_OUT (),
> .CLK180_OUT (),
> .CLK270_OUT (SDRAM_CLK),
> .LOCKED_OUT (SDRAM_CLK_LOCKED)
> );
>
> CLOCK is a 25MHz clock input from a crystal oscillator. The Core Clock
> DCM is a throwback to an earlier design which ran at 50MHz, but is
> currently set up as a "1:1" multiplier (if you can call it that).
>
> The SDRAM DCM is set up to mirror the input clock on the output, with
> different phase shifts. At the moment I'm using the 270deg output, but
> I've also tried the 0deg and 90deg outputs with no success.
>
> SDRAM_CLK is the output pin for the SDRAM clock.
>
> Can anyone offer any suggestions for other things I could try (or check)?
> I'm happy to re-synth the logic or provide logic analyser traces, HDL
> source, etc. to help out -- but bear in mind I'm limited to 40 logic
> analyser 'bits' at a time (the Drigmorn2 only has 40 user I/Os).
>
> Thanks,
From: Philip Pemberton on
On Fri, 21 May 2010 13:40:04 +0200, Górski Adam wrote:
> Check system memory map. Maybe somthing is covered with something else.

Nope -- replacing it with a Block RAM (the same WISHBONE RAM core I use
for the "safe zone" boot RAM at 0x30000000) makes the RAM test work ("RAM
OK, 8KiB detected"). That would seem to suggest that the problem is
either:
- in the SDRAM controller logic
- in the SDRAM clock drive logic / IOBs
- on the PCB itself

:-/

--
Phil.
usenet10(a)philpem.me.uk
http://www.philpem.me.uk/
If mail bounces, replace "10" with the last two digits of the current year
From: Górski Adam on
Philip Pemberton pisze:
> On Fri, 21 May 2010 13:40:04 +0200, Górski Adam wrote:
>> Check system memory map. Maybe somthing is covered with something else.
>
> Nope -- replacing it with a Block RAM (the same WISHBONE RAM core I use
> for the "safe zone" boot RAM at 0x30000000) makes the RAM test work ("RAM
> OK, 8KiB detected"). That would seem to suggest that the problem is
> either:
> - in the SDRAM controller logic
> - in the SDRAM clock drive logic / IOBs
> - on the PCB itself
>
> :-/
>
Check timings on both boards in result log file and then make proper
constraints.

Best regards

Adam Górski
From: Brian Drummond on
On 21 May 2010 11:15:11 GMT, Philip Pemberton <usenet10(a)philpem.me.uk>
wrote:

>Hi guys,
>I could really use some help from an SDRAM / FPGA guru here...
>
>I've got an SDRAM controller IP core -- specifically, the sdram_wb core
>by Stephen Williams, available from the Git repository
><git://icarus.com/~steve-icarus/sdram_wb.git>. This core works fine on
>the Altera DE1, with a 16-bit-wide 64Mbit (1M*16*4bank) PowerChip SDRAM,
>P/N A2V64S40CTP. The FPGA is a Cyclone II 2C20, and all I had to do to
>make the core work was add a PLL to shift the SDRAM clock by 2ns.

>Unfortunately (for me), I hit the limits of what the DE1 could do -- I
>got the SoC working, but ran out of space for the LCD controller
>(framebuffer) and audio controller. So I've started playing with the
>Enterpoint Drigmorn2 board, which uses a Xilinx Spartan3A XC3S700A FPGA,
>and a 32Mbyte (2M*32*4bank) 32-bit-wide ISSI SDRAM chip, the IS42S32800B.

What happens in simulation?

Simulating SDRAM should be OK - use the simulation model for the nearest
equivalent chip from Micron if you can't get one from ISSI.

Simulating DDR devices gets messy because the vendors don't supply VHDL
models, so you need a mixed-language capable sim, unless you're using
Verilog.

If it's as simple as clock phase timing you may get away with
experiments on the hardware, using the DCM variable phase shift, but I
would recommend simulation first.

- Brian