Intel® Quartus® Prime Software
Intel® Quartus® Prime Design Software, Design Entry, Synthesis, Simulation, Verification, Timing Analysis, System Design (Platform Designer, formerly Qsys)
16623 Discussions

Problem SDRAM....Burst Terminate!!!

Altera_Forum
Honored Contributor II
4,064 Views

Hi all, 

 

Ok, I found out that SDRAM keeps writing forever and never stop, when I call IOWR_32DIRECT(...) in SignalTap.  

 

When I look at Dev Board Cyclone II and it does show Write and Burst Terminate in SignalTap. 

 

My board is Cyclone III with MT48LC4M32B2-7. Maybe clock phase shift or something else. 

 

Thanks for read my post and help. 

Sean
0 Kudos
24 Replies
Altera_Forum
Honored Contributor II
1,634 Views

not much info, but yes, you will need to do a clock phase shift between the clock that is driving your SDRAM chip and the clock that is driving your SDRAM controller block. There is some latency though the SDRAM controller. This is not necessarily your problem though. You should be using two seperate clocks. You can have several clocks out of one PLL. They need to be the same clock rate, just delay one of them. You can do it by trial and error and find out what the upper and lower bounds are for proper operation then split the difference. If you give more info like what clock rate and how your SOPC architecture is setup it might help.

0 Kudos
Altera_Forum
Honored Contributor II
1,634 Views

Thanks. I have sys_clk is 100mhz and sdram_clk is 133mhz...my phase shift is -3.5ns.  

 

pll.c0 goes to sys_clk Nios 1/1 and 0deg 

pll.c1 goes to output sdram_clk 4/3 = 133mhz and -3.5ns 

pll.c2 goes to output sys_clk 1/1 and 0deg 

 

Thanks. 

Sean
0 Kudos
Altera_Forum
Honored Contributor II
1,634 Views

You should also constrain your memory interface. It might not be even necessary to phase shift the clock is you provide proper constraints since the fitter might be able to compensate for the offchip timing.

0 Kudos
Altera_Forum
Honored Contributor II
1,634 Views

Ok. Where can I get that information about constrain memory interface? Is there documents online to show me how? I've been looked into TimeQuest, but I don't know where to start... SDC, Create Clock, Set Input Delay... Set Output Delay... 

 

How about I post my design, maybe you could take a look at it? 

 

Thanks, 

Sean
0 Kudos
Altera_Forum
Honored Contributor II
1,634 Views

there is some info on constraining SOPC systems if you search on this blog. I can tell you that the clock phase shift is all that is necessary though.  

 

Have you done a timing analysis? Are you passing timing with the SDRAM controller running at 133?  

 

I could barley get mine to run at 100Mhz on a CIII spd grade 8. Have you tried running all  

 

are you using a custom SDRAM controller or one that is preconfigured in SOPC builder?
0 Kudos
Altera_Forum
Honored Contributor II
1,634 Views

Thanks. 

 

I did try custom and without custom for SDRAM controller in SOPC. In pll, I select Any for speed.  

 

I also tried to set sys_clk to 50mhz and sdram_clk to 50mhz and still no luck. I need to get this SDRAM working... bc my design already works on dev board with SGDMA -> FIFO -> FIFO -> SGDMA 

 

The weird thing is that when I write to sdram. It never stops. 

 

My look like this WRITE –----- -à Gone with the wind 

 

But actual should looks like this WRITE – NOP – PRECHARGE – NOP – ACTIVE 

 

Best regards, 

Sean
0 Kudos
Altera_Forum
Honored Contributor II
1,634 Views

ok, i just looked in sopc, so the memory you are using is already setup, so your controller should be working.  

 

I think you just need to get your clocking right.  

 

Let me understand your system.  

 

You have a Nios II and you have the memory in SOPC builder.  

 

And you have a PLL in SOPC or outside of SOPC?  

 

You basically need to have 1 clock that is driving the SDRAM controller from your PLL and then you need to have another clock that is exported out of your SOPC or top level file off the FPGA to the clock pin of the SDRAM.  

 

The clock that is driving the SDRAM should have a delay of around -3ns.  

 

You need to be doing a timing analysis and putting timing constraints in your design so that at a very minimum, quartus knows what clocks everything is running off of.  

 

In your .SDC file you should have something like this: 

 

create_clock -period 20.000 -name ext_clk [get_ports {clk50}] 

derive_pll_clocks 

derive_clock_uncertainty 

 

where clk50 is the name of your input clock pin that is driving the FPGA. and 20 is the period of that clock. In my case I have a 50Mhz osc hooked to my PLL input.  

 

If you have all of this and still can't get it to work it maybe a software problem or pin mapping problem.
0 Kudos
Altera_Forum
Honored Contributor II
1,634 Views

also, in software, you can do something like this to test your memory.  

 

alt_u32* sdram = (alt_u32*) SDRAM_BASE; 

 

where SDRAM_BASE is the base address of your SDRAM controller. You can find that in your system.h file. 

 

for(i=0;i<10000;i++) 

sdram[i] = i; 

 

 

then in the debugger, you can load sdram variable as an array and verify the result of your for loop.
0 Kudos
Altera_Forum
Honored Contributor II
1,634 Views

Thanks. I will try that and I also include the pictures of my design. 

 

Best regards, 

Sean
0 Kudos
Altera_Forum
Honored Contributor II
1,634 Views

Hi spaugh, 

 

I'm using sys_clk=50mhz, sdram=50mhz, and phase shift=0. When I do Generate SDC File From QSF, I do see the result like this 

 

 

create_clock -name {altera_reserved_tck} -period 100.000 -waveform { 0.000 50.000 } [get_ports {altera_reserved_tck}] 

create_clock -name {sys_clk} -period 10.000 -waveform { 0.000 5.000 } [get_ports {sys_clk}] 

create_clock -name {sdram_clk} -period 7.518 -waveform { 0.000 3.759 } [get_ports {sdram_clk}] 

 

Unconstrained Paths Summary 

Illegal Clocks 0 0 

Unconstrained Clocks 0 0 

Unconstrained Input Ports 35 35 

Unconstrained Input Port Paths 195 195 

Unconstrained Output Ports 56 56 

Unconstrained Output Port Paths 88, 88 

 

Thanks for your help. 

Sean
0 Kudos
Altera_Forum
Honored Contributor II
1,634 Views

Hi all, 

 

I think I got my sys_clk right this time, I set sys_clk is 100mhz and sdram_clk is 133mhz. 

 

In my Nios II 

 

unsigned int i, w, r; 

 

for (i=5; i<8; i++) 

IOWR_32DIRECT(SDRAM_BASE, i, i); 

 

for (i=5; i<8; i++) 

r = IORD_32DIRECT(SDRAM_BASE, i); 

 

I see the write seems to work 5, 6, and 7, but when I read it back. I get 0. When you look at SignalTap, you see CS, RAS, CAS, WE (L, H, L, H) is for read 0. 

 

Geting close ... 

 

Best regards, 

Sean 

0 Kudos
Altera_Forum
Honored Contributor II
1,634 Views

Ok. I have this timing error from TimeQuest. Does anybody know how to fix this error? Thanks for helping. 

 

Sean
0 Kudos
Altera_Forum
Honored Contributor II
1,634 Views

sean, I don't think you will be able to get your system to meet timing with those clock rates. I think you will need to shoot for 100Mhz max on the sdram controller clocks. I tried looking at your pictures that you originally posted of your system, but they were too small to view. If you archive your project I will look at it when I have some free time. But I can tell you that unless you have a speed grade 6 chip, you aren't going to get the sdram controller to meet timing at 133Mhz. The chip is not capable of running that logic at that speed.

0 Kudos
Altera_Forum
Honored Contributor II
1,634 Views

If your system (including the CPU) is clocked at 100MHz and your SDRAM is at 133MHz are you sure you are not hindering your performance? For a 33MHz speed increase is it worth the extra 9-12 clock cycles for the clock crossing that you have inserted? So before trying to tune this memory interface I recommend asking yourself "do I really need my RAM operating this fast???"..... just a thought. The first two chapters go into more detail: http://www.altera.com/literature/hb/nios2/edh_ed5v1_03.pdf

0 Kudos
Altera_Forum
Honored Contributor II
1,634 Views

Thanks spaugh and BadOmen. 

 

Even I tried (sys_clk=25mhz and sdram_clk=33mhz), I still couldn't get it working.  

 

In my Nios 

unsigned int i, w, r; 

 

for (i=5; i<8; i++) 

IOWR_32DIRECT(SDRAM_BASE, i, i); 

usleep(20); 

 

for (i=5; i<8; i++) 

r = IORD_32DIRECT(SDRAM_BASE, i); 

 

I see in signaltap...  

write 5 .... wait (20) 

write 6 .... wait (20) 

write 7 .... wait (20) ... So I think the write method seems working right.  

 

But when I read 5, 6, 7... I got 0, but I do see (CS, RAS, CAS, WE) L H L H on the lines. 

 

Thanks, 

Sean
0 Kudos
Altera_Forum
Honored Contributor II
1,634 Views

You are performing unaligned accesses. The 'i' variable you are using as an offset in the 32-bit read/write IO macros needs to be multiples of 4 (bytes). I think you meant to access word offset 5, 6, 7 which means the offset for the macro needs to be 20, 24, 28 

 

The fabric doesn't support unaligned accesses so I'm guessing you were actually accessing byte address 4 when you passed in 5, 6, 7. If you want to populate the SDRAM with an increment pattern and read it back try this: 

 

volatile unsigned long r; // you don't want the compiler to optimize out the read loop 

 

for (i = 0; i < SOMETHING; i++) 

IOWR_32DIRECT(SDRAM_BASE, i*4; i); 

 

for (i = 0; i < SOMETHING; i++) 

r = IORD_32DIRECT(SDRAM_BASE, i*4);
0 Kudos
Altera_Forum
Honored Contributor II
1,634 Views

Thanks BadOMen. I'm still the same problem. The zs_dq_to_and_from_sdram[0..31] always retuns 0 when I call read. But the write ok. 

 

I also include the capture Write and Read 

Write CS, RAS, CAS, WE = L H L L 

Read CS, RAS, CAS, WE = L H L H 

 

In Nios 

i = 5; 

IOWR_32DIRECT(SDRAM_BASE, i*4, i); 

printf("Write: %x\n", i); 

 

usleep(10); 

i = 5; 

r = IORD_32DIRECT(SDRAM_BASE, i*4); 

printf(" Read: %x\n", r); 

 

Output 

Write: 5 

Read: 0 

 

 

~Sean 

0 Kudos
Altera_Forum
Honored Contributor II
1,634 Views

Opps.. I forgot to include signal tap...

0 Kudos
Altera_Forum
Honored Contributor II
1,634 Views

Just updated. 

 

I just got a brand new board from hardware engineer. It seems to work with limit time, but it still fails. 

 

Nios code: 

volatile unsigned long w, r; 

unsigned int i; 

 

for (i=5; i<10; i++) 

IOWR_32DIRECT(SDRAM_BASE, i*4, i); 

printf("Write: %x\n", i);  

usleep(1000); // Note: it only works with 1000. Not 10000 

r = IORD_32DIRECT(SDRAM_BASE, i*4); 

printf(" Read: %x\n\n", r); 

 

nios2-terminal: connected to hardware target using JTAG UART on cable 

nios2-terminal: "USB-Blaster [USB-0]", device 1, instance 0 

nios2-terminal: (Use the IDE stop button or Ctrl-C to terminate) 

 

Write: 5 

Read: 5 

 

Write: 6 

Read: 6 

 

Write: 7 

Read: 7 

 

Write: 8 

Read: 8 

 

Write: 9 

Read: 9 

 

 

With usleep(10000) 

nios2-terminal: connected to hardware target using JTAG UART on cable 

nios2-terminal: "USB-Blaster [USB-0]", device 1, instance 0 

nios2-terminal: (Use the IDE stop button or Ctrl-C to terminate) 

 

Write: 5 

Read: ffffffff 

 

Write: 6 

Read: ffffffff 

 

Write: 7 

Read: ffffffff 

 

Write: 8 

Read: ffffffff 

 

Write: 9 

Read: ffffffff 

 

~Sean 

0 Kudos
Altera_Forum
Honored Contributor II
1,598 Views

sean, why do you want to run your cpu and sdram at different rates?

0 Kudos
Reply