Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

[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 :p) didnt work.

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

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 :p) 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
 
  • Like
Reactions: 153rd

    153rd

    Points: 2
    Helpful Answer Positive Rating
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.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top