Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
15 years ago

NIOSII addressing for 32 bit wide SDRAM

Hello, first time poster here.

As the title suggests, I have an FPGA accessing a 32 bit wide DDR2 device

(actually 2x 16 bit devices with appropriately shared signals).

Using SOPC builder to generate a simple system with mainly NIOSII/f and one

HPCII DDR2 controller.

The controller is running full rate which means the "local width" is 64 bits.

The DDR2 size is 256MB so the span is 0x10000000 (bytes) and the base

address is 0x20000000 in SOPC.

I am trying to confirm how to access all of the memory.

Should I use IOWR/IORD or IOWR_32DIRECT/IORD_32DIRECT?

If I use IOWR_32DIRECT/IORD_32DIRECT then should I read/write as:

IOWR_32DIRECT(BASE, 0, val);

IOWR_32DIRECT(BASE, 4, val);

IOWR_32DIRECT(BASE, 8, val);

...

IOWR_32DIRECT(BASE, 0xFFFFFFC, val);

else should the address increments be multiples of 8. Else what?

Thank-you.

27 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    A possible epiphany here...

    w.r.t. my last few posts:

    I believe that accesses that involve 0x0F and 0xF0 BE(local_be) values would logically

    necessitate toggling the LSB of the mem column address but since the controller

    datasheet says the LSB of the mem column address is ignored for full rate that this is

    precisely why 0x0F and 0xF0 local_be are ignored thus the only way to see

    all the memory is to ONLY make 0xFF local_be accesses.

    Thoughts?
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Hmmm, not sure that makes complete sense either w.r.t. ignoring LSB col addr bit

    as even if i do a 0xFF 64 bit access that even then I would expect two accesses

    with the col addr LSB toggling.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    So, generating BE = 0xFF transactions from NIOS by using a DMA controller

    by first transferring test data from NIOS to 64 bit onchipmem and then 64-bit DMA'ing this

    to the 64-bit local bus of the DDR2 controller and then reversing the process to get the

    data back to NIOS works fine.

    This creates an acceptable workaround for me.

    The whole BE = 0x0F/0xF0 thing not working properly is probably going to come down

    to the whole partial write support of the controller. Whatever. I have my solution and

    don't want to spend any more time thinking about this.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Sigh. :(

    The next step for me was to go to a half rate implementation which means

    for my 32 bit DDR2 that the local data width is 128-bit operating at 75MHz with

    DDR still at 150MHz. Timing is all met.

    Ok, so I implement a variation of the solution in my last post now using a 128 bit

    onchipmem and also 128 bit DMA controller so now BE = 0xFFFF for all writes/reads.

    Data is getting in and out of onchipmem fine.

    DMA writes look good on the local interface.

    For the DMA reads it looks like the command is correct going to the controller on the local interface but the readdatavalid looks out of whack asserting and deasserting in a periodic

    fashion. seemingly unrelated to the read command just sent to it and this naturally has

    dire consequences to the latched data.

    Searched through the forum, looked at http://www.altera.com/literature/rn/rn_ip.pdf,

    looked at unsupported features.

    Thoughts?
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    >>>>Timing is all met.

    Or is it? <rhetorical>

    Trimmed the system down to bare minimum and it worked.

    Also, characterization showed unreasonable variability in the outcome.

    I believe I have over-constrained the design and will work to properly constrain.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    So, I did a bunch of testing and experimenting and I need help

    to clarify things that may put this thing to rest.

    Firstly, I have only NIOS, DDR, On-chip mem, and JTAG in the system

    and I have reduced the clocks for all possible to the 50MHz sysclk.

    With this, all critical warnings have been removed as previously stated.

    The result with 4x address incrementing is like this:

    1: wrote 00000001, test_addr 00000000, read_val 00000004, device 0

    2: wrote 00000002, test_addr 00000004, read_val 00000004, device 0

    3: wrote 00000004, test_addr 00000008, read_val 00000008, device 0

    4: wrote 00000008, test_addr 0000000c, read_val 00000008, device 0

    5: wrote 00000010, test_addr 00000010, read_val 00000040, device 0

    6: wrote 00000020, test_addr 00000014, read_val 00000040, device 0

    7: wrote 00000040, test_addr 00000018, read_val 00000080, device 0

    8: wrote 00000080, test_addr 0000001c, read_val 00000080, device 0

    ... etc, etc

    and with 8x address incrementing is like this:

    1: wrote 00000001, test_addr 00000000, read_val 00000001, device 0

    2: wrote 00000002, test_addr 00000008, read_val 00000002, device 0

    3: wrote 00000004, test_addr 00000010, read_val 00000004, device 0

    4: wrote 00000008, test_addr 00000018, read_val 00000008, device 0

    5: wrote 00000010, test_addr 00000020, read_val 00000010, device 0

    6: wrote 00000020, test_addr 00000028, read_val 00000020, device 0

    7: wrote 00000040, test_addr 00000030, read_val 00000040, device 0

    8: wrote 00000080, test_addr 00000038, read_val 00000080, device 0

    etc, etc, ...

    8x incrementing looks to provide correct results but that means that

    since we only get 4 bytes per read from NIOS that we are missing

    the other 4 bytes assuming the addresses provided to the _32DIRECT

    RD/WR macros are byte addresses.

    I confirmed that with 8x addr incrementing that I cannot write past the

    span of 0x10000000(256MB which is size of device).

    I used SignalTap to look at the *local* signals and addresses and this

    seems the root of the problem.

    When using 4x incrementing then the local_address increases as

    0,0,1,1,2,2,3,3, etc. for every local_read_req pulse.

    When using 8x incrementing then the local_address increases as

    0,1,2,3, etc.

    So, here, 8x looks correct but then since I can only access up

    to the span 0x10000000 (256MB if byte addr) before NIOS returns

    0xFFFFFFFF as data and the devices are 256MB then half the addresses are not

    available apparently.

    Note for the reads the data for one of the 8x reads on this local_rdata

    bus (64 bits wide) is:

    0x00000002_00000002

    Note for the reads the data for one of the 4x reads on this local_rdata

    bus (64 bits wide) is:

    0x00000004_00000004

    How do I access ____ALL____ 256MB of this device.

    The emi_ddr_ug.pdf by Altera shows local_address

    on page 121 which talks about "LSB of column address on memory side

    is ignored" which may be of some relevance.

    Does this mean we ____WILL____ only see half of our memory???

    Thank-you.

    --- Quote End ---

    Hi,

    How can you test the read/write values ? Did you write a C program to do this ?

    Which kind of tools can we use to write and read data between Nios II et DDR/DDR-2 ?

    I have also NIOS, DDR, On-chip mem, and JTAG

    Thank you in advance.