Modeling an external ram VHDL design

E

Enes Erdin

Hi,

I am trying to simulate my design via ModelSim but my design will use
an external RAM in real environment and I could not manage to
instantiate a model for ram. The actual ram has 19 bits of address bus
and 36 bits of data bus. It is a ZBT ram.

What I tried was creating an signal array of 2^19x36 in the testbench
assuming it as an external ram and use it, however this time "out of
memory" error comes out and my simulation crashes.

Thank in advance for your suggestions.

Regards.

Enes
 
Joined
Mar 29, 2007
Messages
14
Reaction score
0
Have you searched for a simulation model of the RAM? Might be available in VHDL or Verilog from the manufacturer's web page.

Otherwise, you might have to consider the need of simulating the entiry RAM. Isn't possible to limit the height and/or width and still get the confirmation you need?

Good luck
Martin
 
N

Nicolas Matringe

Enes Erdin a écrit :
[...]
What I tried was creating an signal array of 2^19x36 in the testbench
assuming it as an external ram and use it, however this time "out of
memory" error comes out and my simulation crashes.

Hi
A VHDL signal is an object that uses an enormous amount of simulator
memory because of all its attribute. Defining such a big signal is not a
very good idea.
If you want to roll your own simulation model instead of using existing
ones as Brian Drummond suggested, here is a first tip : use a variable
instead of a signal for your memory array.

Hope this helps
Nicolas
 
H

HT-Lab

Enes Erdin said:
Hi,

I am trying to simulate my design via ModelSim but my design will use
an external RAM in real environment and I could not manage to
instantiate a model for ram. The actual ram has 19 bits of address bus
and 36 bits of data bus. It is a ZBT ram.

What I tried was creating an signal array of 2^19x36 in the testbench
assuming it as an external ram and use it, however this time "out of
memory" error comes out and my simulation crashes.

For such a large memory model you might need to use a sparse array which
AFAIK is only supported in Verilog. If you have access to a dual language
license then it is very simple to add this.

Hans
www.ht-lab.com
 
T

Tricky

For such a large memory model you might need to use a sparse array which
AFAIK is only supported in Verilog. If you have access to a dual language
license then it is very simple to add this.

you could do two things to reduce memory:
1. As suggested, use variables instead of signals as they use far less
memory.
2. The really elegant design is to use access types and dynamically
create memory as it is used. You could tie this in with an elegant
shared variable. Heres an example:

type mem_block;
type mem_block_ptr is access mem_block;

type mem_block is array(0 to 1023) of std_logic_vector(35 downto 0);
--this defines a small portion (10 bit addressable) of memory

type mem_storage_t is array(0 to 255) of mem_block_ptr;
--this is the entire memory array type

type memory_t is protected
impure function read( addr : std_logic_vector ) return
std_logic_vector;
procedure write(addr : std_logic_vector;
data : std_logic_vector);
end protected memory_t;
--this stores and gives access to an entire memory
--this memory is broken into rows of 1024 words.

type memory_t is protected body

variable mem_storage : mem_storage_t;

impure function read(addr : std_logic_vector ) return
std_logic_vector is
variable row : integer;
variable col : integer;

variable ret_slv : std_logic_vector(35 downto 0);
begin
row := to_integer(unsigned(addr(18 downto 10) ) );
col := to_integer(unsigned(addr(9 downto 0) ) );
--break down the address so you can index into the 2D array

if mem_storage(row) = null then
ret_slv := (others => 'X');
--no memory allocated here yet
else
ret_slv := mem_storage(row)(col);
--get the memory value
end if;

return ret_slv;
end function read;

procedure write(addr : std_logic_vector;
data : std_logic_vector ) is
variable row : integer;
variable col : integer;
begin
row := to_integer(unsigned(addr(18 downto 10) ) );
col := to_integer(unsigned(addr(9 downto 0) ) );

if mem_storage(row) = null then
mem_storage(row) := new mem_block;
--dynamically create some more ram

--initialise all of the memory that were just allocated
for i in 0 to 1023 loop
mem_storage(row)(i) := (others => 'X');
end loop;
end if;

mem_storage(row)(col) := data;
end procedure write;
end protected body memory_t;

--This is the varaible you actually use.
shared variable my_memory : memory_t;


With the above method, memory is not actually allocated until you
write to it, and should save you some if you only access a small part
of it.
 
M

Mike Treseler

Tricky said:
2. The really elegant design is to use access types and dynamically
create memory as it is used. You could tie this in with an elegant
shared variable. Heres an example: ....

--This is the varaible you actually use.
shared variable my_memory : memory_t;

Cool. Let's try it:
Here's a variable declaration and a test process:
_____________________________________
shared variable my_memory : memory_t;
begin -- architecture mem_demo
p : process is
subtype word_t is std_logic_vector(35 downto 0);
constant all_ones_c : word_t := x"fffffffff";
constant all_zero_c : word_t := x"000000000";
constant pattern1_c : word_t := x"aaaaaaaaa";
constant pattern2_c : word_t := x"555555555";
begin -- process p
my_memory.write(all_zero_c, pattern1_c);
assert my_memory.read( all_zero_c) = pattern1_c;
my_memory.write(all_ones_c, pattern2_c);
assert my_memory.read( all_ones_c) = pattern2_c;

report "Memory test complete. No assertions expected above.";
wait;
end process p;
end architecture mem_demo;
___________________________

Here goes:

vsim -c mem_demo
# Loading work.mem_pkg
# Loading work.mem_demo(mem_demo)
VSIM 1> run
# ** Fatal: (vsim-3421) Value 511 is out of range 0 to 255

Ok, lets try a bigger array:
-- type mem_storage_t is array(0 to 255) of mem_block_ptr;
type mem_storage_t is array(0 to 511) of mem_block_ptr;

Try again:

# vsim -c mem_demo
# Loading work.mem_pkg
# Loading work.mem_demo(mem_demo)
VSIM 1> run
# ** Note: Memory test complete. No assertions expected above.
# Time: 0 ns Iteration: 0 Instance: /mem_demo


Very cool example. Thanks for the posting.

-- Mike Treseler
 
M

Mike Treseler

Jonathan said:
If you need truly random access, something based on
a hash table or a B-tree may be better. But the
Iliffe-vector scheme described by Tricky has the
best speed performance of any such scheme I know,
costing only two table lookups for each simulated
memory access. And it's surprisingly easy to code.

And easier now, given a working example of protected types.
I won't miss seeing this one:
** Warning: some_package.vhd(99): (vcom-1236)
Shared variables must be of a protected type.

Thanks for the comments on access patterns.
A hash-table version, would be nice. Hmmmm.

-- Mike Treseler
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads

ram problem 2
ram 2
pls help me ; vhdl; 0
code vhdl 1
VHDL design flatten compilation 7
need help to design a VHDL code from an algorithm 0
Multiplication VHDL 4
Dual Port RAM Simulation 5

Members online

Forum statistics

Threads
473,995
Messages
2,570,226
Members
46,815
Latest member
treekmostly22

Latest Threads

Top