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

how to decide read time from SDRAM via SDRAM controller

Altera_Forum
Honored Contributor II
2,069 Views

I write my masterthese about the image processing using Altera EP1S40. Because of limitation of on chip memory, the input image should be small. we plan to use the SDRAM which can store the temporary data, and enlarge in input image. It's demanding the we need to know how many clk shoud be taken to read data from SDRAM? How should I write this programme in Quartus II 5.1?

0 Kudos
7 Replies
Altera_Forum
Honored Contributor II
646 Views

It depends on used memory chips. In SDRAM you can set a parameter called latency and it will determine number of clock cycles between read request and data appearance on the memory bus. Usually this takes from two to four clock cycles. If you want fast memory access you can just rise memory clock frequency. Of course, I assume that memory controller will be synthesised in your FPGA :] Another soluction is to use SRAM memory. It is faster than SDRAM, but has less capacity. 

 

If you want to know how to implement SDRAM controller in VHDL I will present here one of possible soluctions ;) 

 

Let us assume that your FPGA has a 50 MHz clock and you want to strobe SDRAM with same 50 MHz clock. So: 

 

SDRAM_ctrl : process (clk,rst) is 

begin 

 

if rst='1' then --assumed reset signal active high 

counter <= "0000000000"; --counter is 10 bit std_logic_vector 

elsif rising_edge(clk) then --you can use falling_edge(clk) if it's more convenient 

 

if counter = 10 then --this is just an example. The point is that counter  

SDRAM_cs <= '0'; --precisely determines moments when RAM control 

end if; --or data signals should change 

 

if counter = 11 then --for precise timing waveforms refer to your SDRAM 

SDRAM_ras <= '0'; --datasheet 

end if; 

 

 

end if; 

 

end process SDRAM_ctrl; 

 

 

Hope, I helped you ;)
0 Kudos
Altera_Forum
Honored Contributor II
646 Views

Thanks for your reply. The whole devices are used for real image processing. The clock i used for FPGA and SDRAM are the same 50MHz. And SDRAM controller is already included in the sysem. Just as you said we set up the parameter as follow: 

CAS latency cycles 2; 

Initilization refresh cycles 2; 

Issue one refreshcommand cycles 7.5 us; 

Delay after powerup, before initilization 100us; 

Duration of refresh command(t_rfc) 66ns; 

Duration of the precharge command(t_rp) 20ns; 

ACTIVE to READ and WRITE delay (t_rcd) 20ns; 

Access time(t_ac) 5.5ns 

Write recovery time (t_wr, No auto precharge) 15ns; 

 

I have to write a User Logic which has the function to write data to SDRAM and read data from SDRAM. For simplicity I just write a 8 bit data to SDRAM and the Data Width of memory profile is 64 bits. I need to write a process to determine how many clocks it will take after I sent the Address to SDRAM controller until the READDATA arrives at User_Logic. By the I am new in VHDL programming.
0 Kudos
Altera_Forum
Honored Contributor II
646 Views

I think You should create a synchronous process in which You have, for example clock with 20 ns period. Then you will be able to determine how many clock cycles takes to read from SDRAM.

0 Kudos
Altera_Forum
Honored Contributor II
646 Views

with your suggestion i can do simulation to determine the delay. But the simulation results are not always right. I want to write a program with pipeline output to determine it.

0 Kudos
Altera_Forum
Honored Contributor II
646 Views

now I have a new problem. I use SDR SDRAM Controller to control SDRAM. The port looks like follows: 

--inputs: 

signal az_addr : IN STD_LOGIC_VECTOR (25 downto 0); 

signal az_be_n : IN STD_LOGIC_VECTOR (7 downto 0); 

signal az_cs : IN STD_LOGIC; 

signal az_data : IN STD_LOGIC_VECTOR (63 downto 0); 

signal az_rd_n : IN STD_LOGIC; 

signal az_wr_n : IN STD_LOGIC; 

signal clk : IN STD_LOGIC; 

signal reset_n : IN STD_LOGIC; 

 

--outputs: 

signal za_data : OUT STD_LOGIC_VECTOR(63 downto 0); 

signal za_valid : OUT STD_LOGIC; 

signal za_waitrequest : OUT STD_LOGIC; 

 

signal zs_addr : OUT STD_LOGIC_VECTOR(12 downto 0); 

signal zs_ba : OUT STD_LOGIC; 

signal zs_cas_n : OUT STD_LOGIC; 

signal zs_cke : OUT STD_LOGIC; 

signal zs_cs_n : OUT STD_LOGIC_VECTOR(3 downto 0); 

signal zs_dq : INOUT STD_LOGIC_VECTOR(63 downto 0); 

signal zs_dqm : OUT STD_LOGIC_VECTOR(7 downto 0); 

signal zs_ras_n : OUT STD_LOGIC; 

signal zs_we_n : OUT STD_LOGIC; 

 

 

 

My ueser logic reads and writes data via SDR SDRAM Controller from and to SDRAM. 

I define follow signals for read operation. 

 

az_addr <= (other 0); 

az_rd_n <= '0'; --read enable 

az_wr_n <='1'; --write disable 

 

clk and reset_n signal are also assigned 

and az_cs <= '1'; 

az_be_n<="11111111" --data mask disable 

 

 

write operation 

az_data<="11111...1" -- 64 bits 

az_rd_n <= '1'; --write enable 

az_wr_n <='0'; --read disable 

 

clk and reset_n signal are also assigned 

and az_cs <= '1'; 

az_be_n<="11111111" --data mask disable 

 

But I can not get back the data. I don't know if in my assignment somewhere is wrong. I have tried for many times. but failed. I am not sure if i have written the data into SDRAM? 

 

can somebody help me ?
0 Kudos
Altera_Forum
Honored Contributor II
646 Views

First of all, you have wrong assigment here : az_addr <= (other 0); . It should look like this : az_addr <= (others => '0'); . I don't know how do you assign values to signals, but you should write a state machine to controll read and write process. From your code I can say, that section:  

 

az_addr <= (other 0); 

az_rd_n <= '0'; --read enable 

az_wr_n <='1'; --write disable 

 

clk and reset_n signal are also assigned 

and az_cs <= '1'; 

az_be_n<="11111111" --data mask disable 

 

 

write operation 

az_data<="11111...1" -- 64 bits 

az_rd_n <= '1'; --write enable 

az_wr_n <='0'; --read disable 

 

clk and reset_n signal are also assigned 

and az_cs <= '1'; 

az_be_n<="11111111" --data mask disable 

 

assigns values at the same time to all signals.  

It would be easier if you could paste your exact code (if the code you have shown isn't the exact code you're using).
0 Kudos
Altera_Forum
Honored Contributor II
646 Views

process (iCLK,iRESET_n) 

 

begin 

if iRESET_n='0' then 

az_addr_to_sdr <=std_logic_vector'("10000000000000000000000000"); 

az_rd_n_to_sdr <= '1'; 

az_wr_n_to_sdr <= '0'; 

elsif iCLK'event and iCLK = '1' then 

if state='1' then 

az_addr_to_sdr <=std_logic_vector'("10000000000000000000000000")+count; 

az_rd_n_to_sdr <= '1'; 

az_wr_n_to_sdr <= '0'; 

az_cs_to_sdr <='1'; 

tDATA_to_sdr <=(DATA_for_test&std_logic_vector'("11111111111111111111111111111111111111111111111111111111")); 

oDATA <= "00001111"; 

 

-- when state='1' write data to SDRAM 

 

 

else  

az_addr_to_sdr <=std_logic_vector'("10000000000000000000000000")+count-std_logic_vector'("01000000000000000000000000");  

az_rd_n_to_sdr <= '0'; 

az_wr_n_to_sdr <= '1'; 

az_cs_to_sdr <='1'; 

oDATA <= data_from_dq(7 downto 0); 

 

-- when state='0' read data from SDRAM 

 

 

 

end if; 

 

 

end if; 

 

end process; 

process (iCLK, iRESET_n) 

begin 

if iRESET_n='0' then 

count <= std_logic_vector'("00000000000000000000000000"); 

elsif iCLK'event and iCLK='1' then  

count <= count + std_logic_vector'("00000000000000000000000001"); 

if count >= std_logic_vector'("01000000000000000000000000") then 

state <= '0'; 

else 

state <= '1'; 

end if; 

end if; 

 

end process; 

That is the whole program I have used. The problem is that i can't read data from SDRAM. 

Output data is supposed to be "11111111" but the vale displayed are always "00000000". I don't know if I haven't written.
0 Kudos
Reply