FPGA, SoC, And CPLD Boards And Kits
FPGA Evaluation and Development Kits
5925 Discussions

SOPC with SDRAM Contoller

Altera_Forum
Honored Contributor II
3,265 Views

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
0 Kudos
20 Replies
Altera_Forum
Honored Contributor II
915 Views

Another attachments.  

Thank you,  

Yuyex:o
0 Kudos
Altera_Forum
Honored Contributor II
915 Views

From Nios properties I see sdram_0 base address is 0x800000 while is loading and verifying addresses 0x1000000 and 0x2008000. 

There's definitely something wrong.  

Are you sure you have associated the Nios project to the right sopc system?
0 Kudos
Altera_Forum
Honored Contributor II
915 Views

Thank you for your reply Cris, 

seems like NIOS didn't take the new SOPC system that i've fixed. So i tried to create a new project file and input the new system once more.  

I got below error : 

 

verifying 01000000 ( 0%) 

verify failed between address 0x1000000 and 0x100d96b 

leaving target processor paused 

 

Besides, I need to ask if i need to assign input/output pin for this SDRAM in this SOPC? 

 

Thank you, 

Yuyex:o
0 Kudos
Altera_Forum
Honored Contributor II
915 Views

 

--- Quote Start ---  

 

seems like NIOS didn't take the new SOPC system that i've fixed. So i tried to create a new project file and input the new system once more.  

I got below error : 

verifying 01000000 ( 0%) 

verify failed between address 0x1000000 and 0x100d96b 

leaving target processor paused 

 

--- Quote End ---  

 

Something has changed but there's still something wrong if sdram base address is really 0x800000. 

Or is it actually 0x1000000? 

Do you mind posting the picture of your sopc? So I can see all bus connections and base address 

 

 

--- Quote Start ---  

Besides, I need to ask if i need to assign input/output pin for this SDRAM in this SOPC? 

 

--- Quote End ---  

 

Sure, you must assign sdram pins. But you must do it in Quartus project, not in sopc builder. 

If you are a beginner, remember the flow is as follows: 

- design the sopc system 

- when you generate it, sopc builder creates a black box block with contains the system and exposes the reuired i/o pins (i.e. clock, reset, sdram i/o, PIOs, ...) 

- add the sopc block in your Quartus project (as HDL or schematic) 

- you must connect the block pins to fpga device pins, adding glue logic if required 

- assign the used pins, based on how the actual fpga is connected to external devices (clock, sdram) on your board. 

- compile quartus project which creates the .sof configuration file 

- create the Nios bsp and application and associate it to your sopc system 

- load the fpga configuration 

- build and load the Nios application 

 

Regards
0 Kudos
Altera_Forum
Honored Contributor II
915 Views

Thank you again Cris, 

Sorry for late reply. 

Here is my SOPC picture.  

 

I have used on-chip mem, and I thought that I can use SDRAM as an on-chip mem, since I dont know where to connect this SDRAM. 

 

I also add some PIO pins in order to make the next LED experiment. 

 

Thank you,  

Yuyex :o
0 Kudos
Altera_Forum
Honored Contributor II
915 Views

Hi Yuyex, 

You MUST connect the Nios2_system sdram pins!! 

Add input or output pins like you have done for clk and LED ports. You can even use the Quartus function which automatically creates port pins: select sopc block, right click and select Generate Pins for Symbol Ports. 

You must change another thing. 

Inside sopc builder, use the same CPU_clk for sdram, too. While SDRAM_clk will be only used externally to connect to the actual sdram chip clock pin. This SDRAM_clk will need a phase shift, in order to meet timing requirements: usually a 1.5ns phase lead relative to CPU_clk is good in most situations. 

 

Cris
0 Kudos
Altera_Forum
Honored Contributor II
915 Views

Thank you Cris ..  

Sorry for my bagga (Japanese) =.= 

I just realize it this morning, and I have connected all of the SDRAM pin here.  

 

Got below message on NIOS II for creating "hello world" project :  

 

verifying 01000000 ( 0%) 

verify failed between address 0x1000000 and 0x100d96b 

leaving target processor paused 

 

The failure address is confusing me :confused: 

 

Thank you,  

Yuyex:o
0 Kudos
Altera_Forum
Honored Contributor II
915 Views

 

--- Quote Start ---  

 

Inside sopc builder, use the same CPU_clk for sdram, too. While SDRAM_clk will be only used externally to connect to the actual sdram chip clock pin. 

--- Quote End ---  

 

 

Do you mean that I cant separate the clock for CPU and the clock for SDRAM? 

I did search for this requirement and it's needed to be separated from the information I have gathered :confused: 

 

 

--- Quote Start ---  

 

This SDRAM_clk will need a phase shift, in order to meet timing requirements: usually a 1.5ns phase lead relative to CPU_clk is good in most situations. 

 

--- Quote End ---  

 

 

I made a calculation based on the formula on the user guide, which lead to -1.46 ... and do you mean minus 1.5ns? 

 

Thank you,  

Yuyex:o
0 Kudos
Altera_Forum
Honored Contributor II
915 Views

 

--- Quote Start ---  

Do you mean that I cant separate the clock for CPU and the clock for SDRAM? 

 

--- Quote End ---  

 

You can use a separate clock for sdram with same or different frequency. 

I meant you however need a separate clock for driving the external sdram clock pin, because you must apply the phase shift. 

So, in a general case you have 3 clocks: 

- cpu_clk 

- sdram_clk, connected to sdram controller inside sopc builder 

- sdram_ext_clk, same freq as sdram_clk but -1.5ns phase shifted; this only connects outside to sdram clk pin. 

 

 

--- Quote Start ---  

 

I made a calculation based on the formula on the user guide, which lead to -1.46 ... and do you mean minus 1.5ns? 

 

--- Quote End ---  

 

Yes. Minus means a phase lead as I told you. 

So my -1.5 guess was good!
0 Kudos
Altera_Forum
Honored Contributor II
915 Views

Thank you for your reply, Cris :o 

 

I did as you suggested me.. I have made 3 different clocks : 

1. 50MHz for CPU_clk 

2. 50MHz with -1.46 phase shift for SDRAM_clk in the SOPC  

3. 50MHZ for SDRAM_clk_ext and connects it to DE0's SDRAM clk (PIN_E5) 

 

I got below error : 

verifying 00800000 ( 0%) 

verify failed between address 0x800000 and 0x8002f3 

leaving target processor paused 

 

FYI, I did an experiment with this system + on-chip memory , and it works.  

It really seems like my SDRAM or PLL doesn't work well, but i dont know what's wrong :eek: 

 

Thank you, 

Yuyex:o
0 Kudos
Altera_Forum
Honored Contributor II
915 Views

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
0 Kudos
Altera_Forum
Honored Contributor II
915 Views

 

--- 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
0 Kudos
Altera_Forum
Honored Contributor II
915 Views

 

--- 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 ?
0 Kudos
Altera_Forum
Honored Contributor II
915 Views

SDRAM Timing Spec 

 

Thank you, 

Yuyex :o
0 Kudos
Altera_Forum
Honored Contributor II
915 Views

 

--- 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
0 Kudos
Altera_Forum
Honored Contributor II
915 Views

 

--- 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.
0 Kudos
Altera_Forum
Honored Contributor II
915 Views

 

--- 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
0 Kudos
Altera_Forum
Honored Contributor II
915 Views

 

--- 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.
0 Kudos
Altera_Forum
Honored Contributor II
915 Views

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
0 Kudos
Altera_Forum
Honored Contributor II
829 Views

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.

0 Kudos
Reply