Showing posts with label Memories. Show all posts
Showing posts with label Memories. Show all posts

Wednesday, October 9, 2013

Memory Arrays

One option for modeling memories is the Shelor method. In 1996, Charles Shelor wrote an article in the VHDL Times as part of his "VHDL Designer" column [1], in which he discussed the problem of modeling large memories. He described several possible storage mechanisms. The method presented here is the one he favored.

The Selor Method

Shelor noted that by converting the vector to a number of type natural we can store values in much less space. Of course, there are limitations. The largest integer guaranteed by the VHDL standard is 231 - 1, meaning a 30-bit word is the most you can safely model. It turns out this is not a problem. Few memory components use word sizes larger than 18 bits and most are either 8 or 9 bits wide.

So a range of 0 to 255 is sufficient for an 8-bit word, but that assumes every bit is either 1 or 0. It would be good to also allow words to be uninitialized or corrupted. To do so, just extend the range down to -2.

A generic memory array declaration is:
   - Memory array declaration

   TYPE MemStore IS ARRAY (0 to TotalLOC) OF INTEGER
                    RANGE -2 TO MaxData;                       

where -2 is an uninitialized word, -1 is a corrupt word, and 0 to MaxData are valid data. This method does not lend itself to manipulation of individual bits, but that is rarely called for in a component model.

Simulators tested store integers in 4B, so each word of memory, up to 18 bits, will occupy 4B of simulator memory. This is a considerable improvement over using arrays of std_logic_vector


The VITAL_Memory Package

Another option is to use the VITAL_Memory package released with VITAL2000. This package has an extensive array of features specific to memory modeling, including a method of declaring a memory array that results in a specific form of storage. A memory using the VITAL2000 memory package is declared as follows.

     -- VITAL Memory Declaration 
     VAIABLE Memdat : VitalMemoryDataType :=
          VitalDeclareMemory (
               NoOfWords                   =>  TotalLOC,
               NoOfBitsPerWord             =>  DataWidth,
               NoOfBitsPerSubWord          =>  DataWidth,
               MemoryLoadFile              =>  MemLoadFileName,
               BinaryLoadFile              =>  FALSE
             );

In this memory modeling, a procedure call is used to create the memory array. 

The storage efficiency is very good - a 1B word occupies only 2B of memory - but this holds true only for 8-bit words. A 9-bit word occupies 4B of memory, which is the same as the Shelor Method.


This chapter comes to us from the book ASIC and FPGA Verification by Richard Munden.




References:
- FPGAs World Class Designs, Clive "Max" Maxfield, Elsevier, 2009

Tuesday, October 8, 2013

Modeling Memories: Memory Arrays

Memory
Memories are among the most frequently modeled components. How they are modeled can determine not just the performance, but the very practicality of board-level simulation. 

Many board have memory on them, and FPGA designs frequently interface to one or more types of memory. These are not the old asynchronous static RAMs of more innocent times. These memories are pipelined zero bus turnaround (ZBT) synchronous static RAMs (SSRAM), multibanked synchronous dynamic RAMs (SDRAM), or double data rate (DDR) DRAMs. The list goes on and complexities go up. Verify the interfaces or face the consequences.

Just as the memories have become complex, so have the models. There are several issues specific to memory models. How they are dealt with will determine the accuracy, performance, and resource requirements of the models.

Memory Arrays

There are a number of ways memory arrays can be modeled. The most obvious and commonly used is array of bits. This is the method that most closely resembles the way a memory component is constructed. Because the model's ports are of type std_logic, we can create an array of type std_logic_vector for our memory:

   TYPE MemStore IS ARRAY (0 to 255) OF STD_LOGIC_VECTOR (7 DOWNTO 0);

This has the advantage of allowing reads and writes to the array without any type conversions. However, using an std_logic_vector array is expensive in terms of simulation memory. std_logic is a 9-value type, which is more values than we need or can use. A typical VHDL simulator will use 1B of simulation memory for each std_logic bit. A 1 megabit memory array will consume about 1 MB of computer memory. At that rate, the amount of memory in a design can be too large to simulate.

In real hardware, memory can contain only 1s and 0s. That might suggest the use of type bit_vector, but the point of simulation is to debug and verify a design in an environment that makes it easier than debugging real hardware. It is useful if a read from a memory location that has never been written to give a unique result. Although real hardware may contain random values, 'U' s are more informative for simulation because they make it easy to see that an uninitialized location has been accessed. 

Likewise, if a timing violation occurs during a memory write, the simulation model usually emits a warning message. Ideally that location should also contain an invalid word that is recognizable as such. On reading that corrupt location, the user should see 'X' s.

So it seems type UX01 would provide all the values required. We could declare our memory array:

   TYPE MemStore IS ARRAY (0 to 255) OF UX01_VECTOR (7 DOWNTO 0);

Unfortunately, because UX01 is a subtype of std_logic, most simulators use the same amount of space to store type UX01 as they do to store std_logic.



This chapter comes to us from the book ASIC and FPGA Verification by Richard Munden.


References:
- FPGAs World Class Designs, Clive "Max" Maxfield, Elsevier, 2009
- Source of the picture from http://www.rtcmagazine.com/articles/view/102356