Global training solutions for engineers creating the world's electronics

Generic Large-capacity RAM Model

The behavioural code presented in this model will enable you to create a large-capacity RAM model limited only by the virtual memory of your computer.

When modelling large memories using VHDL, many users are disappointed by the limited sizes of RAM that they can create. This is because of the way that simulators “build” the RAM model during elaboration. When modelling fixed-size RAMs, it is often better to use an array variable rather than a signal for the RAM storage. Note that for inference of block RAMs in FPGAs, many tools require the use of signals. In this model, however, we are not going to use an array at all. Instead, we allocate memory space each time a new address is used by using an access type.

On a write, the model looks to see if the address has already been used. If so, the data is overwritten. If not, new storage is allocated for the address and data. On a read, the model searches for the address given, and on finding it returns the data. If the address is not found the memory returns 'U', for "uninitialised". An 'X' may also be a valid choice.

In this model, we show the VHDL for the generic RAM core (entity and architecture) and a 64k word by 16-bit RAM model which instantiates the generic RAM core.

You are welcome to use the source code we provide but you must keep the copyright notice with the code (see the Notices page for details).

-- Generic Large-capacity RAM Model

-- +-----------------------------+
-- | Copyright 1992-2008 DOULOS  |
-- |       Library: memory       |
-- |    designer : Tim Pagden    |
-- +-----------------------------+

--
-- Ram write                    Ram Read
--
--       ___                ___               ___________
-- nCS      \______________/   \_____________/
--       _______     ____________________________________
-- nWE          \___/
--       ____________________________     _______________
-- nOE                               \___/
--       ____ _______________ __________________ ________
-- Addr  ____X_______________X__________________X________
--
--       ____ _______________          __
-- Data  ____X_______________X------- X__X---------------
--

library IEEE;
use IEEE.std_logic_1164.all;
use WORK.RamPack.all;

entity BigRam is
  port (Address: in AddrType;
        Data: inout DataType;
        nCS, nWE, nOE: in Std_logic);
end;

architecture Lists of BigRam is
  -- Model using single linked list
begin
  process (Address, nCS, nWE, nOE)
    type Item;

    type ItemPtr is access Item;

    type Item is
      record
        NextItem: ItemPtr;
        Address:  AddrType;
        Word:     DataType;
      end record;

    variable Head: ItemPtr;

    procedure Get (Addr: in AddrType; Word: out DataType) is
      -- Get the contents of the ram with address = Addr
      variable Ptr: ItemPtr;
    begin
      Ptr := Head;
      while Ptr /= null loop
        if Ptr.Address = Addr then
          Word := Ptr.Word;
          return;
        end if;
        Ptr := Ptr.NextItem;
      end loop;
      Word := (others => 'U');
    end Get;


    procedure Set (Addr: in AddrType; Word: in DataType) is
      -- Set the contents of the ram with address = Addr to Word
      variable Ptr, PreviousPtr: ItemPtr;
    begin
      Ptr := Head;
      PreviousPtr := null;
      while Ptr /= null loop
        if Ptr.Address = Addr then
          if Word = DataType'(others => 'U') then
            -- Delete item from list...
            if PreviousPtr = null then
              Head := Ptr.NextItem;
            else
              PreviousPtr.NextItem := Ptr.NextItem;
            end if;
            DEALLOCATE (Ptr);

          else
            Ptr.Word := Word;
          end if;
          return;
        end if;
        PreviousPtr := Ptr;
        Ptr := Ptr.NextItem;
      end loop;
      if Word /= DataType'(others => 'U') then
        -- Insert new item into list...
        Ptr := new Item'(NextItem => null, Address => Addr, Word => Word);
        if PreviousPtr = null then
          Head := Ptr;
        else
          PreviousPtr.NextItem := Ptr;
        end if;
      end if;
    end Set;

    procedure Diagnose is
      variable Ptr: ItemPtr;
      variable Count: NATURAL := 0;
    begin
      if Diagnostics then
        Ptr := Head;
        while Ptr /= null loop
          Count := Count + 1;
          Ptr := Ptr.NextItem;
        end loop;
        assert FALSE
          report "List length = " & INTEGER'IMAGE(Count)
          severity Note;
      end if;
    end Diagnose;

    variable D: DataType;

  begin
    Data <= (others => 'Z');
    if nCS  = '0' then
      if nOE = '0' then			-- Read operation
        Get(Address, D);
        Data <= D;
        Diagnose;
      elsif nWE = '0' then		-- Write operation
        Set (Address, Data);
        Diagnose;
      end if;
    end if;
  end process;
end;

To download the VHDL source code for this model, click here.

 

Back to VHDL models.

Great training!! Excellent Instructor, Excellent facility ...Met all my expectations.
Henry Hastings
Lockheed Martin

View more references