Jump to content
  • 0

How to use the on board 16MB memory of nexys 3 via VHDL. Any help is appreciated .


devchandil

Question

6 answers to this question

Recommended Posts

There is also block RAM available within every FPGA chip.  You could use that as well.  In that case, a controller isn't really needed--you just need to follow the HDL synthesis standards given by (in this case) Xilinx.

Dan

Link to comment
Share on other sites

Hi Devchandil,

Agreed you can also use block ram. Here is some generic code in VHDL that shows how to use block ram.

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

ENTITY myMem IS

     PORT ( Addr : IN std_logic_vector (9 DOWNTO 0);

                Data : IN std_logic_vector (7 DOWNTO 0);

                MemRead, MemWrite, Clk : IN std_logic;

                Instr : OUT std_logic_vector (7 DOWNTO 0));

END myMem;

 

ARCHITECTURE myMem_arch OF myMem IS

     SUBTYPE byte IS std_logic_vector (7 DOWNTO 0);

     TYPE t_1KB IS ARRAY (0 TO 1023) OF byte;

     SIGNAL mem : t_1KB;

BEGIN

   PROCESS (Clk)

      VARIABLE ind : unsigned (9 DOWNTO 0);

  BEGIN

       IF rising_edge (Clk) THEN

           ind := unsigned (Addr);

           IF (MemRead = ‘1’) THEN

                  Instr <= mem (to_integer(ind));

           ELSIF (MemWrite = ‘1’) THEN

                 mem(to_integer(ind)) <= Data;

          END IF;

   END IF;

 END PROCESS;

END myMem_arch;

 

Link to comment
Share on other sites

You can actually find several different examples in the XST manual for how to implement block RAM.  There are several subtleties to be aware of, such as if you are reading and writing the same address on the same clock, which result will be read?  The new one or the old?

(I was actually going to post the Verilog example code from the XST manual for what jpeyron posted above, but ... then got lost in the details and subtleties and figured I'd just post a link.  :P)

Link to comment
Share on other sites

11 hours ago, jpeyron said:

Hi Devchandil,

I've seen others online have used the Onboard Memory controller reference design in VHDL for the nexys 2 here https://reference.digilentinc.com/nexys/nexys2/nexys2.

to work with the onboard memory for the Nexys 3. 

thank you,

Jon

 

 

onboardmemcfg.zip

Thank you jpeyron,

 

10 hours ago, jpeyron said:

Hi Devchandil,

Agreed you can also use block ram. Here is some generic code in VHDL that shows how to use block ram.

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

ENTITY myMem IS

     PORT ( Addr : IN std_logic_vector (9 DOWNTO 0);

                Data : IN std_logic_vector (7 DOWNTO 0);

                MemRead, MemWrite, Clk : IN std_logic;

                Instr : OUT std_logic_vector (7 DOWNTO 0));

END myMem;

 

ARCHITECTURE myMem_arch OF myMem IS

     SUBTYPE byte IS std_logic_vector (7 DOWNTO 0);

     TYPE t_1KB IS ARRAY (0 TO 1023) OF byte;

     SIGNAL mem : t_1KB;

BEGIN

   PROCESS (Clk)

      VARIABLE ind : unsigned (9 DOWNTO 0);

  BEGIN

       IF rising_edge (Clk) THEN

           ind := unsigned (Addr);

           IF (MemRead = ‘1’) THEN

                  Instr <= mem (to_integer(ind));

           ELSIF (MemWrite = ‘1’) THEN

                 mem(to_integer(ind)) <= Data;

          END IF;

   END IF;

 END PROCESS;

END myMem_arch;

 

Thank you Jpeyron,

I tried to implement the code you provided, but was unsuccessful in doing so, for input I took the 8 switches provided on my nexys3 board and the address lines I used are 

ADDR25: F15 ADDR16: G13 ADDR7: H15 
ADDR24: F16 ADDR15: E16 ADDR6: H16

ADDR23: C17 ADDR14: E18 ADDR5: G16 
ADDR22: C18 ADDR13: K12 ADDR4: G18 
ADDR21: F14 ADDR12: K13 ADDR3: J16 
ADDR20: G14 ADDR11: F17 ADDR2: J18 
ADDR19: D17 ADDR10: F18 ADDR1: K17
ADDR18: D18 ADDR9: H13 ADDR0: K18 

ADDR17: H12 ADDR8: H14

 

The code I made :

 

entity memstr is
    Port ( addr : in  STD_LOGIC_VECTOR (25 downto 0);
           data : in  STD_LOGIC_VECTOR (7 downto 0);
           memread : in  STD_LOGIC;
           memwrite : in  STD_LOGIC;
           clk : in  STD_LOGIC;
           instr : out  STD_LOGIC_VECTOR (7 downto 0));
end memstr;

architecture Behavioral of memstr is
    --SUBTYPE byte IS std_logic_vector (7 DOWNTO 0);

     TYPE t_2KB IS ARRAY (0 TO 2047) OF std_logic_vector (7 DOWNTO 0);
    
     SIGNAL mem : t_2KB;
      
begin

      PROCESS (clk)
VARIABLE ind : unsigned (25 DOWNTO 0);

       BEGIN
IF rising_edge (clk) THEN

           ind := unsigned (Addr);

           IF (memread = '1') THEN

                  instr <= mem (to_integer(ind));
                        END LOOP;

           ELSIF (memwrite = '1') THEN

                 mem(to_integer(ind)) <= data;

          END IF;

   END IF;
      

     END PROCESS;

end Behavioral;

The UCF file is as follows:

NET "addr(0)" LOC = "K18" ;
NET "addr(0)" LOC = "K17" ;
NET "addr(0)" LOC = "J18" ;
NET "addr(0)" LOC = "J16" ;
NET "addr(0)" LOC = "G18" ;
NET "addr(0)" LOC = "G16" ;
NET "addr(0)" LOC = "H16" ;
NET "addr(0)" LOC = "H15" ;
NET "addr(0)" LOC = "H14" ;
NET "addr(0)" LOC = "H13" ;
NET "addr(0)" LOC = "F18" ;
NET "addr(0)" LOC = "F17" ;
NET "addr(0)" LOC = "K13" ;
NET "addr(0)" LOC = "K12" ;
NET "addr(0)" LOC = "E18" ;
NET "addr(0)" LOC = "E16" ;
NET "addr(0)" LOC = "G13" ;
NET "addr(0)" LOC = "H12" ;
NET "addr(0)" LOC = "D18" ;
NET "addr(0)" LOC = "D17" ;
NET "addr(0)" LOC = "G14" ;
NET "addr(0)" LOC = "F14" ;
NET "addr(0)" LOC = "C18" ;
NET "addr(0)" LOC = "C17" ;
NET "addr(0)" LOC = "F16" ;
NET "addr(0)" LOC = "F15" ;
NET "data(0)" LOC = "T10" ;
NET "data(0)" LOC = "T9" ;
NET "data(0)" LOC = "V9" ;
NET "data(0)" LOC = "M8" ;
NET "data(0)" LOC = "N8" ;
NET "data(0)" LOC = "U8" ;
NET "data(0)" LOC = "V8" ;
NET "data(0)" LOC = "T5" ;


NET "memread" LOC = "C9" ;
NET "memwrite" LOC = "D9" ;
NET "clk" LOC = "V10" ;
NET "instr(0)" LOC = "U16" ;
NET "instr(1)" LOC = "V16" ;
NET "instr(2)" LOC = "U15" ;
NET "instr(3)" LOC = "V15" ;
NET "instr(4)" LOC = "M11" ;
NET "instr(5)" LOC = "N11" ;
NET "instr(6)" LOC = "R11" ;
NET "instr(7)" LOC = "T11" ;

Link to comment
Share on other sites

It looks like @jpeyron and I may have confused you in our zeal to try to answer your question.  Let's start at the top, "onboard memory" can be ambiguous.  The Nexys 2 documentation describes 16MB SDRAM as onboard memory, however the Spartan3E chip also has memory onboard and even "onchip".  This latter memory is further split into two categories, "block RAM" which we described above and "distributed RAM" which is accessed in a similar fashion.  There are differences between the two: "Block RAM" is limited by the FPGA chip.  It's not likely that you will have 16MB of it.  The wires for block RAM never leave the chip, so you don't need to mention them in any UCF file.  "SDRAM", however, is different.  This one takes a bit more logic to access properly, the controller is harder to build and easier to copy someone elses, and the wires do leave the chip and hence need to be in a UCF file.

That said, here are some things I noticed:

If you are trying to use block RAM on your FPGA,

1. The address should not appear on any NET's

2. The size is not likely to require 26 bits of address

3. By registering "ind" and then reading/writing the memory on the next clock, you may well be placing your memory value at the last address, not the address that comes with it

If, on the other hand, you are hoping to use the 16MB SDRAM on your board, then you will instead wish to download and use the SDRAM controller found here.  This controller will require quite a few lines between your FPGA and the memory, and it should be clear from the controller what lines those are.  Still, you can't have multiple addr(0) lines in your netlist. 

You may notice that I'm talking around the details of the SDRAM, but giving details of the block RAM interface.  That is on purpose.  The SDRAM isn't as simple to use.  If that's what you wish to use, however, just say so and I (we) will taylor our responses to your purpose.

Also, next time you write to tell us things aren't working, please include an explanation of why, or what error message you are getting.  It'll make this process easier.  In this case I can imagine several errors you might have gotten with your code above, but as you get closer to working code that's not likely to remain that way.

Thanks,

Dan

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...