[SOLVED] How to make 3D RAM in VHDL

Status
Not open for further replies.

153rd

Member level 1
Joined
Mar 4, 2011
Messages
34
Helped
5
Reputation
10
Reaction score
5
Trophy points
1,288
Activity points
1,545
Hey guys,

I have a question regarding RAM.

I want to show something on a VGA monitor( in 320 x 240).

I have to make a video driver, and I use 3 bits for color( 1 red, 1 green, 1 blue).
The video driver reads data from the RAM memory.

What I can do, is make an array of (320 x 3) x (240) ==> 960 x 240.

But this is a bit cumbersome if I'd want to change the image, I'd have to change each bit manually.

The only way I know to make RAM is : type RAMTYPE is array( x downto 0) of std_logic_vector(y downto 0);
I tried to use array(x downto 0) of array(y downto 0) of std_logic_vector(z downto 0),
wich (as expected ) didnt work.

Is there a way to make a 3D array in VHDL?
 


A 3D array can be defined as...
type t_3D_ARRAY is array(0 to 319, 0 to 239, 0 to 2) of std_logic; -- If you want std_logic types
type t_3D_ARRAY is array(0 to 319, 0 to 239, 0 to 2) of integer; -- If you want an integer type
signal Image: t_3D_ARRAY;

Then you would access a particular color element 'c' of pixel 'x,y' as Image(x,y,c);

I might also suggest that since each pixel consists of and RGB triple, that it might be better to define types like this
type t_PIXEL_ELEMENTS is (Red, Green, Blue);
type t_PIXEL is array (t_PIXEL_ELEMENTS) of integer range 0 to 255; -- Assuming that you want RGB 24 bit
type t_IMAGE is array(0 to 319, 0 to 239) of t_PIXEL;
signal Image: t_IMAGE;

Then you would access a particular color element of pixel 'x,y' as Image(x,y)(Red), or Image(x,y)(Green) or Image(x,y)(Blue) and each would have a value from 0 to 255.

Which is better for you would depend on how exactly you want to access the data in the rest of your program

Kevin Jennings
 
Last edited:
Remember:
3D RAM is unsynthesizable
 

Kevin, thank you very much for your help. But shaiko, is there a workaround to make 3d ram then?
 

Not with RAM
You have to think hardware when designing with VHDL
Do you know of any FPGA memory that is 3D ?
I don't...
 
Remember:
3D RAM is unsynthesizable
Good point for the size of memory in question...even the 2D RAM of the size that was listed is also unsynthesizable without a lot-o-memory internal. I assumed the OP was asking from a testbench type of perspective, but after re-reading I don't think so.

In any case memory is always a 1D array and can only be abstracted to appear to be a 2D or 3D. However, it is not difficult to create this abstraction, the only thing that makes it not synthesizable is the size. To create the linear memory address you simply concatenate the individual elements. If X and Y denote a pixel address and C denotes the pixel color element then the memory address can be X & Y & C simply concatenated together. In the case of the OP, if X ranges from 0 to 319, Y from 0 to 239 and C from 0 to 2, then you would need 9 bits for X, 8 bits for Y and 2 bits for C which implies a 19 bit address. Not many parts with 1/2 MB of internal memory, but that address can still be used to access external memory.

Kevin Jennings

---------- Post added at 11:10 ---------- Previous post was at 11:07 ----------

Kevin, thank you very much for your help. But shaiko, is there a workaround to make 3d ram then?
See my later post for more details. 3D RAM is not inherently un-synthesizable, what makes it difficult is the resulting memory size. So yes 3D is synthesizable as is 2D...but that is an abstraction (and a useful one at that) to access conventional linear 1D memory.

Kevin Jennings
 
Reactions: 153rd

    153rd

    Points: 2
    Helpful Answer Positive Rating
thanks a lot guys!
 

thanks a lot guys!
I forgot to add in the last post, that a simpler way to then implement this 3D abstraction would be with a record type

t_PIXELS is record
X: natural range 0 to 319
Y: natural range 0 to 239
C: natural range 0 to 2; -- Or use the 'Red/Green/Blue' type I mentioned in earlier post
end record;

Create a function that converts a signal of this record type into a single linear address number like this
Addr <= C + 4*(Y + 256*X);

Kevin Jennings
 

Remember:
3D RAM is unsynthesizable

Not strictly true:

Quartus allows 3D rams (well, 3 x 1D array) style to allow the inference of dual port mixed width ram:

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

entity test_ram is
  
  port (
    
    ------------------------------------------------------------
    --Clock and reset
    ------------------------------------------------------------
    clk                       : in  std_logic;
    reset                     : in  std_logic;
    
    
    addr_in                   : in  integer range 0 to 255;
    d_in                      : in  std_logic_vector(31 downto 0);
    w_en                      : in  std_logic;
    
    addr_out                  : in  integer range 0 to 1023;
    d_out                     : out std_logic_vector(7 downto 0)
    
  );
end entity;
  
architecture rtl of test_ram is
  
  type bytes_t is array(0 to 3) of std_logic_vector(7 downto 0);
  type ram_3d_t is array(0 to 255) of bytes_t;
  signal ram_3d     : ram_3d_t;
begin
  
  
  process(clk)
  begin
    if rising_edge(clk) then
      
      
      if w_en = '1' then
        ram_3d( addr_in ) <= ( d_in(31 downto 24),d_in(23 downto 16), d_in(15 downto 8), d_in(7 downto 0) );
      end if;
      
      d_out <= ram_3d( addr_out/4 )(addr_out rem 4);
    end if;
  end process;
  
end rtl;
 

Status
Not open for further replies.
Cookies are required to use this site. You must accept them to continue using the site. Learn more…