dynamic memory allocation for images in a test bench

Discussion in 'VHDL' started by wallge, Feb 16, 2007.

  1. wallge

    wallge Guest

    Say I to implement the following C language constructs in my VHDL
    testbench:
    I want to have a generic image struct:

    typedef struct {
    unsigned int height;
    unsigned int width;
    unsigned char *pixels;
    } Image_Type;

    I think something like this can be done with a VHDL record type.

    Then initialize it with the following function:

    int init_image_struct(unsigned int height, unsigned int width,
    Image_Type *image)
    {
    image->height = height;
    image->width = width;
    image->pixels = (unsigned char*) malloc(sizeof(unsigned char) *
    height * width);
    return 0;
    }


    I would like to pass my vhdl functions constants or parameters read
    from files at some point during the course of my simulation run.

    I want to be able to do this so I can handle images of various sizes
    without knowing the size ahead of time.
    This would prevent the need for hard coded images sizes (need a new
    type for each different image size).

    Can anyone tell me how to do this in VHDL?

    Also how to prevent memory leaks?
    wallge, Feb 16, 2007
    #1
    1. Advertising

  2. wallge

    KJ Guest

    "wallge" <> wrote in message
    news:...
    > Say I to implement the following C language constructs in my VHDL
    > testbench:
    > I want to have a generic image struct:
    >
    > typedef struct {
    > unsigned int height;
    > unsigned int width;
    > unsigned char *pixels;
    > } Image_Type;
    >
    > I think something like this can be done with a VHDL record type.
    >
    > Then initialize it with the following function:
    >
    > int init_image_struct(unsigned int height, unsigned int width,
    > Image_Type *image)
    > {
    > image->height = height;
    > image->width = width;
    > image->pixels = (unsigned char*) malloc(sizeof(unsigned char) *
    > height * width);
    > return 0;
    > }
    >
    >
    > I would like to pass my vhdl functions constants or parameters read
    > from files at some point during the course of my simulation run.


    Good approach.

    I'd also suggest also since you're dealing with images that it would be
    handy to directly work with .BMP, .TIF, .JPG files, whatever native image
    file format is convenient for your project. Just code up some VHDL to
    read/write these types of files directly. Once you've got that down, it
    will be a snap to integrate that all in with the rest of your testbench.

    >
    > I want to be able to do this so I can handle images of various sizes
    > without knowing the size ahead of time.
    > This would prevent the need for hard coded images sizes (need a new
    > type for each different image size).
    >
    > Can anyone tell me how to do this in VHDL?


    You need to use the 'new' keyword. It is similar to 'malloc' in C or 'new'
    in C++ i.e.

    Image_Type_variable := new Image_Type.

    You can allocate an array of your type with

    Image_Type_variable := new Image_Type(Number_Of_Things);

    This will come in handy for allocating the chunk of memory that you'll need
    for your image as an array of pixels.

    You deallocate the memory using the deallocate function i.e.
    deallocate(Image_Type_variable);

    >
    > Also how to prevent memory leaks?
    >

    Make sure that every call to 'new' eventually results in a call to
    'deallocate'. There is no magic that will help you out here, it's more like
    C in this regard where every 'malloc' needs a 'free'.

    Experiment with it a bit and google if needed but it's pretty
    straightforward.

    Kevin Jennings
    KJ, Feb 16, 2007
    #2
    1. Advertising

  3. wallge

    wallge Guest

    I've already got the image opening procedures built.
    I just use pgm and ppm images since they are just text based files, no
    complex
    headers or compression schemes to deal with...

    Is there a way to use shared variable or something along these lines
    to be able to access my dynamically allocated memory
    in multiple processes or procedures.

    Also, can the various elements of allocated data types
    be accessed with standard array(index) notation?

    For instance in the Image_Type_variable := new
    Image_Type(Number_Of_Things);
    declaration, can i write:
    Image_Type(5)
    to assign or access that particular array value?

    or if I am using a for-loop:

    Image_Type(i) := some_value;

    to assign to that array value?

    On Feb 16, 4:22 pm, "KJ" <> wrote:
    > "wallge" <> wrote in message
    >
    > news:...
    >
    >
    >
    > > Say I to implement the following C language constructs in my VHDL
    > > testbench:
    > > I want to have a generic image struct:

    >
    > > typedef struct {
    > > unsigned int height;
    > > unsigned int width;
    > > unsigned char *pixels;
    > > } Image_Type;

    >
    > > I think something like this can be done with a VHDL record type.

    >
    > > Then initialize it with the following function:

    >
    > > int init_image_struct(unsigned int height, unsigned int width,
    > > Image_Type *image)
    > > {
    > > image->height = height;
    > > image->width = width;
    > > image->pixels = (unsigned char*) malloc(sizeof(unsigned char) *
    > > height * width);
    > > return 0;
    > > }

    >
    > > I would like to pass my vhdl functions constants or parameters read
    > > from files at some point during the course of my simulation run.

    >
    > Good approach.
    >
    > I'd also suggest also since you're dealing with images that it would be
    > handy to directly work with .BMP, .TIF, .JPG files, whatever native image
    > file format is convenient for your project. Just code up some VHDL to
    > read/write these types of files directly. Once you've got that down, it
    > will be a snap to integrate that all in with the rest of your testbench.
    >
    >
    >
    > > I want to be able to do this so I can handle images of various sizes
    > > without knowing the size ahead of time.
    > > This would prevent the need for hard coded images sizes (need a new
    > > type for each different image size).

    >
    > > Can anyone tell me how to do this in VHDL?

    >
    > You need to use the 'new' keyword. It is similar to 'malloc' in C or 'new'
    > in C++ i.e.
    >
    > Image_Type_variable := new Image_Type.
    >
    > You can allocate an array of your type with
    >
    > Image_Type_variable := new Image_Type(Number_Of_Things);
    >
    > This will come in handy for allocating the chunk of memory that you'll need
    > for your image as an array of pixels.
    >
    > You deallocate the memory using the deallocate function i.e.
    > deallocate(Image_Type_variable);
    >
    >
    >
    > > Also how to prevent memory leaks?

    >
    > Make sure that every call to 'new' eventually results in a call to
    > 'deallocate'. There is no magic that will help you out here, it's more like
    > C in this regard where every 'malloc' needs a 'free'.
    >
    > Experiment with it a bit and google if needed but it's pretty
    > straightforward.
    >
    > Kevin Jennings
    wallge, Feb 16, 2007
    #3
  4. wallge

    KJ Guest

    "wallge" <> wrote in message
    news:...
    > Is there a way to use shared variable or something along these lines
    > to be able to access my dynamically allocated memory
    > in multiple processes or procedures.

    Like any other variable, a pointer can be a shared variable.

    One detail I left out of the first post is the definition of the pointer
    type and might have been confusing about which were pointers and which were
    not.

    If you have type 'Image_Type' (presumably a record type along the lines of
    your C 'struct') then you define yet another type which is a pointer to
    something of that type
    type ptr_Image_Type is access Image_Type;

    Now you would declare a variable (shared if you'd prefer) of that pointer
    type
    variable A_ptr_Image_Type_variable: ptr_Image_Type;

    and then you would get a new thing of that type with the 'new' statement
    like...
    A_ptr_Image_Type_variable := new Image_Type;

    The assignment could also have combined with the declaration like this...
    variable A_ptr_Image_Type_variable: ptr_Image_Type := new Image_Type;

    Then access elements of that record like this...

    A_ptr_Image_Type_variable.element1 := 123;

    and lastly deallocate it and free memory with
    deallocate(A_ptr_Image_Type_variable);

    >
    > Also, can the various elements of allocated data types
    > be accessed with standard array(index) notation?
    >

    Yes

    > For instance in the Image_Type_variable := new
    > Image_Type(Number_Of_Things);
    > declaration, can i write:
    > Image_Type(5)
    > to assign or access that particular array value?
    >

    Yes.

    > or if I am using a for-loop:
    >
    > Image_Type(i) := some_value;
    >
    > to assign to that array value?

    Yes.

    The notation when accessing the variable is identical whether the
    'Image_Type' variable is a pointer or a plain old fixed type that you're
    used to. It's different than C in that regard in that with C the notation
    you use is different based on whether the variable is a pointer or not.

    Kevin Jennings
    KJ, Feb 17, 2007
    #4
  5. wallge

    wallge Guest

    I guess what I would like is a type that Would not have to be
    initialized
    before compile time.

    Does the following code work?
    if not, why not?


    --architecture of our testbench
    architecture behavior of testbench is

    --component I/O
    signal data_in, data_out : std_logic_vector(7 downto 0);
    signal counter : natural;

    -- Images read in from file
    signal height, width : natural;

    -- test bench start switch,
    --so we only read data from file once at start of sim
    signal init : boolean := false;

    type pixel is natural range 0 to 255;
    type pixel_ptr is access pixel;

    -- this should be a global variable accessible by any process
    shared variable Image : pixel_ptr;


    begin

    init_ptrs : process(init)
    if init = false then
    --get image dimensions from file
    height <= get_image_height("image.pgm");
    width <= get_image_width("image.pgm");
    --allocate memory
    Image := new pixel_ptr(height * width);
    -- get pixel data from file, and put into pointer
    get_image_pixels("image.pgm", Image);
    init <= true;
    end if;
    end process;

    -- access our pixels in a clocked process...
    access_pix : process(clk, rst, data_in, counter
    if rst = '1' then
    counter <= 0;
    data_in <= (others => '0');
    elsif rising_edge(clk) then
    data_in <= std_logic_vector(to_unsigned(Image(counter),
    data_in'length));
    counter <= counter + 1;
    end if;
    end process;


    ---rest of test bench occurs below...
    uut : some_component
    port map
    (
    rst => rst,
    clk => clk,
    data_in => data_in,
    data_out => data_out
    );

    end architecture;




    On Feb 16, 9:12 pm, "KJ" <> wrote:
    > "wallge" <> wrote in message
    >
    > news:...> Is there a way to use shared variable or something along these lines
    > > to be able to access my dynamically allocated memory
    > > in multiple processes or procedures.

    >
    > Like any other variable, a pointer can be a shared variable.
    >
    > One detail I left out of the first post is the definition of the pointer
    > type and might have been confusing about which were pointers and which were
    > not.
    >
    > If you have type 'Image_Type' (presumably a record type along the lines of
    > your C 'struct') then you define yet another type which is a pointer to
    > something of that type
    > type ptr_Image_Type is access Image_Type;
    >
    > Now you would declare a variable (shared if you'd prefer) of that pointer
    > type
    > variable A_ptr_Image_Type_variable: ptr_Image_Type;
    >
    > and then you would get a new thing of that type with the 'new' statement
    > like...
    > A_ptr_Image_Type_variable := new Image_Type;
    >
    > The assignment could also have combined with the declaration like this...
    > variable A_ptr_Image_Type_variable: ptr_Image_Type := new Image_Type;
    >
    > Then access elements of that record like this...
    >
    > A_ptr_Image_Type_variable.element1 := 123;
    >
    > and lastly deallocate it and free memory with
    > deallocate(A_ptr_Image_Type_variable);
    >
    >
    >
    > > Also, can the various elements of allocated data types
    > > be accessed with standard array(index) notation?

    >
    > Yes
    >
    > > For instance in the Image_Type_variable := new
    > > Image_Type(Number_Of_Things);
    > > declaration, can i write:
    > > Image_Type(5)
    > > to assign or access that particular array value?

    >
    > Yes.
    >
    > > or if I am using a for-loop:

    >
    > > Image_Type(i) := some_value;

    >
    > > to assign to that array value?

    >
    > Yes.
    >
    > The notation when accessing the variable is identical whether the
    > 'Image_Type' variable is a pointer or a plain old fixed type that you're
    > used to. It's different than C in that regard in that with C the notation
    > you use is different based on whether the variable is a pointer or not.
    >
    > Kevin Jennings
    wallge, Feb 18, 2007
    #5
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Joseph A. Zammit

    Xilinx test bench and user group

    Joseph A. Zammit, Feb 25, 2004, in forum: VHDL
    Replies:
    3
    Views:
    2,143
  2. Pete Fraser
    Replies:
    4
    Views:
    6,762
    Mike Treseler
    Nov 4, 2004
  3. s.subbarayan

    Dynamic memory allocation and memory leak...

    s.subbarayan, Mar 18, 2005, in forum: C Programming
    Replies:
    10
    Views:
    675
    Eric Sosman
    Mar 22, 2005
  4. Ken
    Replies:
    24
    Views:
    3,831
    Ben Bacarisse
    Nov 30, 2006
  5. chris
    Replies:
    6
    Views:
    970
    chris
    Oct 28, 2005
Loading...

Share This Page