Forum Discussion

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

SOPC with SDRAM Contoller

Hy everyone, I am new in building SOPC.

Here is my objection : creating SOPC with SDRAM to write a simple Hello world on NIOS II by using DE0 development board.

I got an error message from NIOS II on address 0_x100_0000 and 0_x100_D727 (notice that it's 9 bits only). (*attached)

My system contains of :

1. CPU (*attached)

2. onchip_memory (not used in this project)

3. sys_timer_clock

4. jtag_uart

5. SDRAM (contoller) (*attached)

6. PLL (*attached)

I think the main problem was coming from my SDRAM contoller setting or PLL setting.

FYI,

For CPU: memory is attached to SDRAM_0 (*pic 1).

For PLL : input clock is 50MHz (from DE0). I created 2 output clock with 50MHz.each for CPU (CPU_clk) and SDRAM(SDRAM_clk).

After getting the error message, I changed the frequency settings to 130MHz, since I realize that the highest frequency for DE0 SDRAM is at 133Mhz for -7 Mode.

I also calculated the phase shift for SDRAM_clk. From user guide, I calculated the phase shift by using below formula :

Read Lag = tOH (SDRAM) - tH(FPGA) = 2.7-(-0.28) = 2.98 ns

Read Lead = tCO_min(FPGA) - tDH(SDRAM) = 0.85-0.8 = 0.05 ns

Phase Shift = (-2.98+0.05)/2 = -1.465ns

I got tOH and tDH from IS42S16400 SDRAM Time Spec (*attached). tH and tDH from "TImeQuest Timing Analyzer" after compiling my project (*attached).

For SDRAM contoller, I set the Address width with 12 Row , 8 Column , 4 Banks, with 16 bit Data Width. (total = 8MBytes). And I also set some timing spec for this controller. FYI, DE0 has IS42S16400 SDRAM.

As i said , I think my main problem came from SDRAM or PLL.

Please help :o

Any reply will be appreciated.

Best regards,

Yuyex :o

20 Replies

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

    If you haven't already done it, please check:

    - pin assignments

    - sdram controller properties in sopc builder; they must match your sdram specifications

    - timing analysis (although I think you shouldn't have problems at 50MHz)

    You can possibly try these:

    - run from onchip memory and perform a sdram test by writing and reading back data

    - keep code in sdram but in Nios properties, set reset and exception vectors to onchip memory
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    If you haven't already done it, please check:

    - pin assignments

    - sdram controller properties in sopc builder; they must match your sdram specifications

    - timing analysis (although I think you shouldn't have problems at 50MHz)

    --- Quote End ---

    I have checked them in these two days :wacko: and I am sure for all of the specs EXCEPT for the WRITE RECOVERY TIME which cant be found from the data sheet, so I leaved it on the default value.

    (FYI, I have attached DE0 SDRAM timing spec on the top of this topic :o)

    --- Quote Start ---

    You can possibly try these:

    - run from onchip memory and perform a sdram test by writing and reading back data

    --- Quote End ---

    Please see the picture, Cris. Thank you :o

    --- Quote Start ---

    - keep code in sdram but in Nios properties, set reset and exception vectors to onchip memory

    --- Quote End ---

    --- Quote End ---

    tested!

    Error Message :

    verifying 00800000 ( 0%)

    verify failed between address 0x800000 and 0x8001af

    leaving target processor paused

    Thank you,

    Yuyex:o
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    - run from onchip memory and perform a sdram test by writing and reading back data

    --- Quote End ---

    If your suggestion is same as I thought on the above picture, I have tested it.

    Error :

    verifying 00800000 ( 0%)

    verify failed between address 0x800000 and 0x801ff3

    leaving target processor paused

    The error ending address is keep on changing :cry:

    What if there are a little difference in the shift phase?(for example : 0.1ns of difference) will it be any error ?
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    If your suggestion is same as I thought on the above picture, I have tested it.

    --- Quote End ---

    I never used the predefined template for ram testing.

    I meant you could test it manually:

    First of all select onchip memory for running code and program data.

    Then in your application set up a loop which writes known data starting from sdram base address. Afterwards read back data and check if is as expected.

    Example:

    for (i=0; i<0x10000; i++) {

    *((int*)SDRAM_BASE_ADDRESS+i) = i;

    }

    error = 0;

    for (i=0; i<0x10000; i++) {

    if ( *((int*)SDRAM_BASE_ADDRESS+i) != i ) {

    error = i;

    break;

    }

    }

    This way you can identify if the problem is always with specific addresses or data, while the jtag debugger simply tells you the address range where the error occurred, but not the exact address neither what the data mismatch was.

    --- Quote Start ---

    What if there are a little difference in the shift phase?(for example : 0.1ns of difference) will it be any error ?

    --- Quote End ---

    A few tenths of ns difference should not matter in your case and with your clock freq.

    Probably your design can work with any shift from -1.0ns to -2.0ns
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    SDRAM Timing Spec

    --- Quote End ---

    The refresh command time t_rfc is not t_ref (marked with nr.1).

    t_ref is the refresh cycle which is 64ms and you correctly used it to calculate refresh command period.

    t_rfc is not reported in datasheet but you can assume it is equal to t_rc, then 70ns.

    Please note that those you used are minimal values. If you want to be conservative, you can rise those values and exclude problems due to any abnormally delayed signal. (clearly you pay the price of slower access to sdram...)

    The only parameter that work the other way is refresh period: this should be reduced to ensure correct operation.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    Example:

    for (i=0; i<0x10000; i++) {

    *((int*)SDRAM_BASE_ADDRESS+i) = i;

    }

    error = 0;

    for (i=0; i<0x10000; i++) {

    if ( *((int*)SDRAM_BASE_ADDRESS+i) != i ) {

    error = i;

    break;

    }

    }

    --- Quote End ---

    Thank you for your reply again Cris :)

    I haven't write C/C++ for about 4 years :shock:

    can you give me the complete C code? # include ... bla bla bla

    void ....bla bla bla

    --- Quote Start ---

    This way you can identify if the problem is always with specific addresses or data, while the jtag debugger simply tells you the address range where the error occurred, but not the exact address neither what the data mismatch was.

    --- Quote End ---

    And if I already know the specific addresses/data of error , what will be the next step?

    --- Quote Start ---

    A few tenths of ns difference should not matter in your case and with your clock freq.

    Probably your design can work with any shift from -1.0ns to -2.0ns

    --- Quote End ---

    I got it .. thank you , Cris :o
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    can you give me the complete C code?

    # include ... bla bla bla

    void ....bla bla bla

    --- Quote End ---

    No need of includes or extra functions.

    Simply add the for loops in your main() and place a breakpoint or print address and data to jtag uart when the code hits the error condition.

    --- Quote Start ---

    And if I already know the specific addresses/data of error , what will be the next step?

    --- Quote End ---

    Error on specific addresses/data can show you the problem is on a single signal.

    For example, if you always write 0x0000 and read 0x0040, write 0x5555 and read 0x5555, write 0xaaaa and read 0xaaea, you can easily understand that problem is with data[6] line which is apparently locked high. Then you can investigate on that specific signal.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Thank you again Cris,

    seems like I need to work on my C to test your suggestion.

    Thank you very much , Cris :o

    Appreciate it so much :o

    Yuyex:o
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    I don't know if you have already finished your project, but based on your last generated sopc builder image, I mean the block diagram figure, I see an error in the Data port (DQ[15..0]). You need to use bidirectional port and not output port.