Forum Discussion

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

how to decide read time from SDRAM via SDRAM controller

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?

7 Replies

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

    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 ;)
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    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.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    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.

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

    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.

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

    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 ?
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    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).
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    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.