Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Need help for interfacing FPGA with SDRAM (MT48LC8M16A2)

Status
Not open for further replies.

myfpga007

Newbie level 2
Joined
Apr 28, 2010
Messages
2
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Activity points
1,363
Hi all,

I am interfacing FPGA spartan3 with the SDRAM memory MT48LC8M16A2. I used the testbench and memory model available on Micron website for which works fine. However, modify the testbench to make it synthesizable and test it on hardware it doesn't work. Although, its still working on the simulator.

The issue is during read operation I always get the same data X"0007"
Could anyone help me find the issue.

Here is the modified code of testbench:

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;


use IEEE.STD_LOGIC_arith.all;
use IEEE.STD_LOGIC_unsigned.all;

ENTITY tb_synthesizable IS
GENERIC (
addr_bits : INTEGER := 12;
data_bits : INTEGER := 16);
PORT(
dip : IN STD_LOGIC_VECTOR (7 downto 0); -- to set the memory (temp_buf)location to be read
ledout : OUT STD_LOGIC_VECTOR (15 downto 0); --16 bit data from memory (temp_buf)
Dq : INOUT STD_LOGIC_VECTOR (data_bits - 1 DOWNTO 0);
Addr : OUT STD_LOGIC_VECTOR (addr_bits - 1 DOWNTO 0);
Ba : OUT STD_LOGIC_VECTOR (1 DOWNTO 0);
sdram_clk : OUT STD_LOGIC ;
Clk : IN STD_LOGIC ; -- 100 MHz external clk
Cke : OUT STD_LOGIC ;
Cs_n : OUT STD_LOGIC ;
Cas_n : OUT STD_LOGIC ;
Ras_n : OUT STD_LOGIC ;
We_n : OUT STD_LOGIC ;
Dqm : OUT STD_LOGIC_VECTOR (1 DOWNTO 0));

END tb_synthesizable;

ARCHITECTURE test OF tb_synthesizable IS
-- CONSTANT tCK : TIME := 10 ns;
-- CONSTANT addr_bits : INTEGER := 12;
-- CONSTANT data_bits : INTEGER := 16;

-- COMPONENT mt48lc8m16a2
-- PORT (
--
-- Dq : INOUT STD_LOGIC_VECTOR (data_bits - 1 DOWNTO 0); --:= (OTHERS => 'Z');
-- Addr : IN STD_LOGIC_VECTOR (addr_bits - 1 DOWNTO 0); --:= (OTHERS => '0');
-- Ba : IN STD_LOGIC_VECTOR (1 DOWNTO 0); --:= "00";
-- Clk : IN STD_LOGIC; --:= '0';
-- Cke : IN STD_LOGIC; --:= '0';
-- Cs_n : IN STD_LOGIC; --:= '1';
-- Cas_n : IN STD_LOGIC; --:= '0';
-- Ras_n : IN STD_LOGIC; --:= '0';
-- We_n : IN STD_LOGIC; --:= '0';
-- Dqm : IN STD_LOGIC_VECTOR (1 DOWNTO 0) --:= "00"
-- );
-- END COMPONENT;

-- FOR ALL : mt48lc8m16a2 USE ENTITY work.mt48lc8m16a2 (behave);

-- SIGNAL pDq : STD_LOGIC_VECTOR (data_bits - 1 DOWNTO 0); -- pDq is replaced with Dq
SIGNAL pAddr : STD_LOGIC_VECTOR (addr_bits - 1 DOWNTO 0);
SIGNAL pBa : STD_LOGIC_VECTOR (1 DOWNTO 0);
-- SIGNAL pClk : STD_LOGIC;
SIGNAL pCke : STD_LOGIC;
SIGNAL pCs_n : STD_LOGIC;
SIGNAL pCas_n : STD_LOGIC;
SIGNAL pRas_n : STD_LOGIC;
SIGNAL pWe_n : STD_LOGIC;
SIGNAL pDqm : STD_LOGIC_VECTOR (1 DOWNTO 0);
SIGNAL stim_done : boolean := false;
SIGNAL clk_done : boolean := false;


--------------------------------MY SIGNALS-----------------------------------------------
SIGNAL count : INTEGER := 0; -- to cycle through various states (which call procedures)
type mem is array (0 to 14) of std_logic_vector(15 downto 0); -- to store data read from SDRAM
signal temp_buf: mem;




BEGIN
-- u1: mt48lc8m16a2
-- PORT MAP(
-- Dq => Dq,
-- Addr => pAddr,
-- Ba => pBa,
-- --Clk => pClk,
-- Clk => sdram_clk1,
-- Cke => pCke,
-- Cs_n => pCs_n,
-- Ras_n => pRas_n,
-- Cas_n => pCas_n,
-- We_n => pWe_n,
-- Dqm => pDqm
-- );
--
--Dq <= pDq ;
Addr <= pAddr ;
Ba <= pBa ;
Cke <= pCke ;
Cs_n <= pCs_n ;
Cas_n <= pCas_n ;
Ras_n <= pRas_n ;
We_n <= pWe_n ;
Dqm <= pDqm ;
sdram_clk <= clk;

ledout<= temp_buf (conv_integer(dip));
-- ledout<= temp_buf(2) when (dip="00000010") else (others => 'Z');
-- ledout<= temp_buf(3) when (dip="00000011") else (others => 'Z');
-- ledout<= temp_buf(4) when (dip="00000100") else (others => 'Z');
-- ledout<= temp_buf(5) when (dip="00000101") else (others => 'Z');
-- ledout<= temp_buf(6) when (dip="00000110") else (others => 'Z');
-- ledout<= temp_buf(7) when (dip="00000111") else (others => 'Z');

stimulator : PROCESS (clk,COUNT)
PROCEDURE ACTIVE (Ba_in : STD_LOGIC_VECTOR (1 DOWNTO 0);
Addr_in : STD_LOGIC_VECTOR (addr_bits - 1 DOWNTO 0);
Dq_in : STD_LOGIC_VECTOR (data_bits - 1 DOWNTO 0)) IS
BEGIN
pCke <= '1';
pCs_n <= '0';
pRas_n <= '0';
pCas_n <= '1';
pWe_n <= '1';
pDqm <= "00";
pBa <= Ba_in;
pAddr <= Addr_in;
Dq <= Dq_in;
-- WAIT FOR tCK;
END;

PROCEDURE AUTO_REFRESH IS
BEGIN
pCke <= '1';
pCs_n <= '0';
pRas_n <= '0';
pCas_n <= '0';
pWe_n <= '1';
pDqm <= "00";
--pBa <= "00";
--pAddr <= (OTHERS => '0');
Dq <= (OTHERS => 'Z');
-- WAIT FOR tCK;
END;

PROCEDURE BURST_TERM IS
BEGIN
pCke <= '1';
pCs_n <= '0';
pRas_n <= '1';
pCas_n <= '1';
pWe_n <= '0';
pDqm <= "00";
--pBa <= "00";
--pAddr <= (OTHERS => '0');
Dq <= (OTHERS => 'Z');
-- WAIT FOR tCK;
END;

PROCEDURE LOAD_MODE_REG (Ba_in : STD_LOGIC_VECTOR (1 DOWNTO 0);
Addr_in : STD_LOGIC_VECTOR (addr_bits - 1 DOWNTO 0)) IS
BEGIN
pCke <= '1';
pCs_n <= '0';
pRas_n <= '0';
pCas_n <= '0';
pWe_n <= '0';
pDqm <= "00";
pBa <= Ba_in;
pAddr <= Addr_in;
Dq <= (OTHERS => 'Z');
-- WAIT FOR tCK;
END;

PROCEDURE NOP (Dq_in : STD_LOGIC_VECTOR (data_bits - 1 DOWNTO 0)) IS
BEGIN
pCke <= '1';
pCs_n <= '0';
pRas_n <= '1';
pCas_n <= '1';
pWe_n <= '1';
pDqm <= "00";
--pBa <= "00";
--pAddr <= (OTHERS => '0');
Dq <= Dq_in;
-- WAIT FOR tCK;
END;

PROCEDURE PRECHARGE (Ba_in : STD_LOGIC_VECTOR (1 DOWNTO 0);
Addr_in : STD_LOGIC_VECTOR (addr_bits - 1 DOWNTO 0);
Dq_in : STD_LOGIC_VECTOR (data_bits - 1 DOWNTO 0)) IS
BEGIN
pCke <= '1';
pCs_n <= '0';
pRas_n <= '0';
pCas_n <= '1';
pWe_n <= '0';
pDqm <= "00";
pBa <= Ba_in;
pAddr <= Addr_in;
Dq <= Dq_in;
-- WAIT FOR tCK;
END;

PROCEDURE READ (Ba_in : STD_LOGIC_VECTOR (1 DOWNTO 0);
Addr_in : STD_LOGIC_VECTOR (addr_bits - 1 DOWNTO 0);
Dq_in : STD_LOGIC_VECTOR (data_bits - 1 DOWNTO 0)) IS
BEGIN
pCke <= '1';
pCs_n <= '0';
pRas_n <= '1';
pCas_n <= '0';
pWe_n <= '1';
pDqm <= "00";
pBa <= Ba_in;
pAddr <= Addr_in;
Dq <= Dq_in;
-- WAIT FOR tCK;
END;

-- Write
PROCEDURE WRITE (Ba_in : STD_LOGIC_VECTOR (1 DOWNTO 0);
Addr_in : STD_LOGIC_VECTOR (addr_bits - 1 DOWNTO 0);
Dq_in : STD_LOGIC_VECTOR (data_bits - 1 DOWNTO 0)) IS
BEGIN
pCke <= '1';
pCs_n <= '0';
pRas_n <= '1';
pCas_n <= '0';
pWe_n <= '0';
pDqm <= "00";
pBa <= Ba_in;
pAddr <= Addr_in;
Dq <= Dq_in;
-- WAIT FOR tCK;
END;

BEGIN

if (rising_edge (clk)and count <60) then

count <= count + 1; -- count implements diferent states

case count is

when 0 =>
Dq <= (OTHERS => 'Z');
pAddr <= (OTHERS => '0');
pBa <= "00";
--pClk <= '0';
pCke <= '0';
pCs_n <= '1';
pCas_n <= '0';
pRas_n <= '0';
pWe_n <= '0';
pDqm <= "00";
temp_buf(0) <= X"0000";

-- COMMAND BA ADDR DQ
when 1 =>
NOP ( "ZZZZZZZZZZZZZZZZ");
when 2 =>
NOP ( "ZZZZZZZZZZZZZZZZ");
when 3 =>
NOP ( "ZZZZZZZZZZZZZZZZ");
when 4 =>
NOP ( "ZZZZZZZZZZZZZZZZ");
when 5 =>
NOP ( "ZZZZZZZZZZZZZZZZ");
when 6 =>
NOP ( "ZZZZZZZZZZZZZZZZ");
when 7 =>
NOP ( "ZZZZZZZZZZZZZZZZ");
when 8 =>
NOP ( "ZZZZZZZZZZZZZZZZ");
when 9 =>
NOP ( "ZZZZZZZZZZZZZZZZ");
when 10 =>
NOP ( "ZZZZZZZZZZZZZZZZ");

-- We need 100 us power up sequence. I use 10 NOPs here as a required example.
when 11 =>
PRECHARGE ("00", "010000000000", "ZZZZZZZZZZZZZZZZ");
when 12 =>
NOP ( "ZZZZZZZZZZZZZZZZ");
when 13 =>
NOP ( "ZZZZZZZZZZZZZZZZ");
when 14 =>
NOP ( "ZZZZZZZZZZZZZZZZ");
when 15 =>
NOP ( "ZZZZZZZZZZZZZZZZ");
when 16 =>
AUTO_REFRESH;

when 17 =>
NOP ( "ZZZZZZZZZZZZZZZZ");
when 18 =>
NOP ( "ZZZZZZZZZZZZZZZZ");
when 19 =>
NOP ( "ZZZZZZZZZZZZZZZZ");
when 20 =>
NOP ( "ZZZZZZZZZZZZZZZZ");
when 21 =>
NOP ( "ZZZZZZZZZZZZZZZZ");
when 22 =>
NOP ( "ZZZZZZZZZZZZZZZZ");
when 23 =>
NOP ( "ZZZZZZZZZZZZZZZZ");
when 24 =>
NOP ( "ZZZZZZZZZZZZZZZZ");
when 25 =>
AUTO_REFRESH;

when 26 =>
NOP ( "ZZZZZZZZZZZZZZZZ");
when 27 =>
NOP ( "ZZZZZZZZZZZZZZZZ");
when 28 =>
NOP ( "ZZZZZZZZZZZZZZZZ");
when 29 =>
NOP ( "ZZZZZZZZZZZZZZZZ");
when 30 =>
NOP ( "ZZZZZZZZZZZZZZZZ");
when 31 =>
NOP ( "ZZZZZZZZZZZZZZZZ");
when 32 =>
NOP ( "ZZZZZZZZZZZZZZZZ");
when 33 =>
LOAD_MODE_REG ("00", "000000110011");
when 34 =>
NOP ( "ZZZZZZZZZZZZZZZZ");
when 35 =>
NOP ( "ZZZZZZZZZZZZZZZZ");
when 36 =>
ACTIVE ("00", "000000000000", "ZZZZZZZZZZZZZZZZ");
when 37 =>
NOP ( "ZZZZZZZZZZZZZZZZ");
when 38 =>
WRITE ("00", "000000000000", "0000000000000000"); --"010000000000"
when 39 =>
NOP ( "0000000000000001");
when 40 =>
ACTIVE ("01", "000000000000", "0000000000000010");
when 41 =>
NOP ( "0000000000000011");
when 42 =>
NOP ( "0000000000000100");
when 43 =>
NOP ( "0000000000000101");
when 44 =>
NOP ( "0000000000000110");
when 45 =>
NOP ( "0000000000000111");


when 46 =>
READ ("00", "010000000000", "ZZZZZZZZZZZZZZZZ");
temp_buf (1) <= dq;
when 47 =>
NOP ( "ZZZZZZZZZZZZZZZZ");
temp_buf (2) <= dq;
when 48 =>
ACTIVE ("01", "000000000000", "ZZZZZZZZZZZZZZZZ");
temp_buf (3) <= dq;
when 49 =>
NOP ( "ZZZZZZZZZZZZZZZZ");
temp_buf (4) <= dq;
when 50 =>
NOP ( "ZZZZZZZZZZZZZZZZ");
temp_buf (5) <= dq;

when 51 =>
NOP ( "ZZZZZZZZZZZZZZZZ");
temp_buf (6) <= dq;
when 52 =>
NOP ( "ZZZZZZZZZZZZZZZZ");
temp_buf (7) <= dq;
when 53 =>
NOP ( "ZZZZZZZZZZZZZZZZ");


when 54 =>
NOP ( "ZZZZZZZZZZZZZZZZ");
when 55 =>
NOP ( "ZZZZZZZZZZZZZZZZ");
when 56 =>
NOP ( "ZZZZZZZZZZZZZZZZ");
when 57 =>

when others =>
null;

END CASE;
-- ASSERT false
-- REPORT "End of Stimulation Detected!"
-- SEVERITY note;
-- stim_done <= true;
-- WAIT;

END IF;
END PROCESS;

-- clock : PROCESS
-- VARIABLE done_time : time;
-- BEGIN
-- pclk <= '0';
-- WAIT for tCK/2;
-- WHILE not stim_done loop
-- pclk <= '1';
-- WAIT for tCK/2;
-- pclk <= '0';
-- WAIT for tCK/2;
-- END LOOP;
-- done_time := now + tCK;
-- WHILE now < done_time LOOP -- one last clock to finish last command
-- pclk <= '1';
-- WAIT for tCK/2;
-- pclk <= '0';
-- WAIT for tCK/2;
-- END LOOP;
-- ASSERT false
-- REPORT "Suspending clock activity"
-- SEVERITY note;
-- clk_done <= true;
-- WAIT;
-- END PROCESS;
END test;

Thanks in advance

Code:
 

If I understand correctly that testbench is made by Micron for the purpose of verification, right? As in not for the purpose of synthesis. If so, then I would not be surprised if it doesn't do what you want when synthesized.

To interface the spartan3 to sdram you need some sdram controller IP from xilinx, or from places like opencores.

hope that helps.
 

    myfpga007

    Points: 2
    Helpful Answer Positive Rating
Its just sometimes easier spending some time reading the data sheet and writing your own code.

Its harsh but true
 

Thanks for your reply guys.......
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top