Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
  • Jun 28 16:19
    creiter64 commented #797
  • Jun 28 13:08
    eine labeled #799
  • Jun 28 13:08
    eine labeled #799
  • Jun 28 13:07
    eine review_requested #799
  • Jun 28 13:05
    eine labeled #839
  • Jun 28 13:05
    eine labeled #839
  • Jun 28 10:25
    creiter64 opened #846
  • Jun 27 18:42
    Hardolaf commented #728
  • Jun 27 18:40
    cmarqu commented #728
  • Jun 27 15:38
    Hardolaf commented #728
  • Jun 27 14:50
    Hardolaf commented #728
  • Jun 23 17:14
    GlenNicholls commented #842
  • Jun 23 17:12
    GlenNicholls commented #842
  • Jun 23 13:57
    Hardolaf commented #728
  • Jun 23 13:41
    cmarqu commented #728
  • Jun 23 13:28
    std-max opened #845
  • Jun 23 11:44
    std-max opened #844
  • Jun 23 11:31
    std-max commented #356
  • Jun 23 11:24
    umarcor commented #658
  • Jun 23 11:18
    umarcor commented #842
Adam Vrba
@civec
architecture tb of tb_spi is .... package sb_rl_data is new bitvis_vip_scoreboard.generic_sb_pkg generic map (t_element => t_RL_ARRAY, element_match => slv_array_match, to_string_element => to_string); use sb_rl_data.all; shared variable SB_RL : sb_rl_data.t_generic_sb; ... begin
GlenNicholls
@GlenNicholls
I'm having trouble reading that, can you put your code in a code-block? Use 3 backticks like so:
```
dasHorst99
@dasHorst99

Hi,

I am using vunit now for some weeks now and slowly get a hang of it. Nice little functions are included especially for the integer_array type. Very neet and usefull!
There is now one little task that I have solved but I am curious if some one could say me if there is a function for this or can maybe explain me how it can be done easier.

My task is that I want to read a bmp file. So I read the whole data by using the load_raw function. But I only want a chunk of that data for example the head. Also it must be considered that the bytes are ordered in little endian.

dasHorst99
@dasHorst99
impure function get_header_info(input_arr : integer_array_t; 
                                a   : natural;
                                b   : natural) return natural is

    variable output_value_vector : std_logic_vector(31 downto 0) := (others => '0');
    variable output_value_int    : natural := 0;
    variable output_arr          : integer_array_t := new_1d(4, 8, false);

begin    

    for x in a to b loop
        set(output_arr, x-a, get(input_arr, x));
    end loop;                        

    output_value_vector := std_logic_vector(to_unsigned(get(output_arr, 3), 8)) &
                    std_logic_vector(to_unsigned(get(output_arr, 2), 8)) &
                    std_logic_vector(to_unsigned(get(output_arr, 1), 8)) &
                    std_logic_vector(to_unsigned(get(output_arr, 0), 8));

    output_value_int := to_integer(unsigned(output_value_vector));

    return output_value_int;

end function;

This is not the best code, so maybe there is a better or more convinient way to do this?

Best regards

Oh, I almost forgot to mention something important.
I want these chunks intepreted as whole number. That's why I put the 32 bit vector together from 8 bit pieces.
Patrick Lehmann
@Paebbels
@dasHorst99 Type integer can't hold your data, as it is a signed data type. Thus you have only 0 → 2**31 - 1 as unsigned values.
dasHorst99
@dasHorst99
@Paebbels Yes, you are right. I've tried something to take this fact into accout but till now I couldn't find a proper way to do it.
Patrick Lehmann
@Paebbels
why do you need the RGB color from a BMP file as integer. It's a record of 3 color values not a single value.
Richard Head
@trickyhead_gitlab
RGB in bitmap are only 8 bits per channel. If you are using windows BMP format then the final 8 bits are an alpha channel
But "standard" bitmap is only RGB with no alpha
Patrick Lehmann
@Paebbels
function swap(value : std_logic_vector; size : positive := 8) return std_logic_vector is
  constant segments : natural := value'length / size;
  variable result : std_logic_vector(value'length - 1 downto 0);
begin
  for i in 0 to segments - 1 loop
    result((segments - i) * size - 1 downto (segments - i - 1) * size) := value((i + 1) * size - 1 downto i * size);
  end loop;
  return result;
end function;
dasHorst99
@dasHorst99
@Paebbels This is to read the information of the image header, like for example te header size or the image data offset, which I need to read the image data.
Richard Head
@trickyhead_gitlab
From experience, you can simply ignore alpha - I dont think many tools actually use it
@dasHorst99 why not simply read into arrays of slvs via a char?
using something like this:
procedure read_bytes( file     f :     data_file_t;
                          variable s : out std_logic_vector ) is
        variable c_buf   : character;
    begin
        for i in 0 to (s'length/8) -1 loop
            read(f, c_buf);

            s( (8*i) +7 downto i*8 ) := char_to_slv(c_buf);
        end loop;
    end procedure read_bytes;
you can strip a bitmap header like this:
procedure strip_header( file bmp    : data_file_t;
                                 do_abs : boolean := true;
                                 path   : string  := "";    --only used for reports declaring file is invalid

                                 bpp    : out natural       --only valid values are 8 (greyscale), 24 (RGB) and 32(RGBA)
                           ) is


        variable ret_dims   : image_dimensions_t;

        variable c_buf      : character; --this is the data buffer for reading from the file
        variable slv_buf    : std_logic_vector(31 downto 0);
        variable is_V4      : boolean := false;
        variable bpp_i      : integer;
    begin

        --we take in the first 2 bytes to make sure this is actually a BMP
        read_bytes(bmp, slv_buf(15 downto 0));

        assert slv_buf(15 downto 0) = x"4D42"      --First two bytes should be BM in Ascii
          report "image_file_io_pkg.strip_header : " & path & " is not a valid BMP file."
            severity failure;


        ----------------------------------------------------------------------------------------------
        --throw away the next 12 bytes
        --This is just the filesize, followed by 4 reserved bytes, then data offset
        -----------------------------------------------------------------------------------------------
        for i in 1 to 12 loop
          read(bmp, c_buf);
        end loop;

        -----------------------------------------------------------------------------------------------
        --Next 4 bytes is the header size. Check that it is a supported type, and we can bin the rest
        --if its V4 type.
        -----------------------------------------------------------------------------------------------
        read_bytes(bmp, slv_buf);
        if    slv_buf(7 downto 0) = x"6C" then is_V4 := true;
        elsif slv_buf(7 downto 0) = x"28" then null;          --catch V3 header
        else
            report "image_file_io_pkg.strip_header : " & path & " is not a supported bitmap format."
                  severity failure;
        end if;


        ---------------------------------------
        --Next 32 bit word is the width, followed by height
        ---------------------------------------
        read_bytes(bmp, slv_buf);
        ret_dims.width  := to_integer( signed(slv_buf));

        read_bytes(bmp, slv_buf);
        ret_dims.height := to_integer( signed(slv_buf));

        --if do_abs then
        --    dims.width  := abs ret_dims.width ;
        --    dims.height := abs ret_dims.height;
        --
        --else
        --    dims.width  :=     ret_dims.width ;
        --    dims.height :=     ret_dims.height;
        --end if;

        --report "Width is " & to_string(ret_dims.width) & " height is " & to_string(ret_dims.height) severity note;

        ---------------------------------------
        --Dump the colour planes
        ---------------------------------------
        for i in 1 to 2 loop read(bmp, c_buf); end loop;

        ---------------------------------------
        --Check the bits per pixel
        ---------------------------------------
        slv_buf(31 downto 16)   := x"0000";    --If height was -ve, we would be in trouble if this didnt happen!
        read_bytes(bmp, slv_buf(15 downto 0));

        bpp_i       := to_integer(unsigned(slv_buf));
        bpp         := bpp_i;


        ----------------------------------------------------------------------------------------
        --Dump the next 6 header fields
        --
        --Compression - Not read but if BPP=32 then it is assumed BI_BITFIELDS are set.
        --              See write_header procedure for assumed position of the RGBA bitfields
        --data size   - taken from height and width
        --horizontal physical resolution
        --vertical physical resolution
        --n colours in colour palette
        --all colours are always important
        -----------------------------------------------------------------------------------------
for i in 1 to 6 loop
            read_bytes(bmp, slv_buf);
        end loop;

        ----------------------------------
        --Dump the V4 fields
        ----------------------------------
        if is_v4 then
            for i in 1 to 17 loop
                read_bytes(bmp, slv_buf);
            end loop;
        end if;

        ------------------------------------------------------------------
        --If the bpp is set to 8, then throw away the colour table.
        --It is assumed to be greyscale and binary data read directly
        ------------------------------------------------------------------
        if bpp_i = 8 then
            for i in 0 to 255 loop
                read_bytes(bmp, slv_buf);
            end loop;
        end if;

    end procedure strip_header;
dasHorst99
@dasHorst99

@trickyhead_gitlab

RGB in bitmap are only 8 bits per channel. If you are using windows BMP format then the final 8 bits are an alpha channel

This is then a 24 bit bmp, right?
What do you mean with the last bits? The last bits of the image data?

Richard Head
@trickyhead_gitlab
In bitmap, you can have any of 8, 24 or 32 bits per pixel
8 bits uses a colour table of 24 bit RGB values to specify a map of the 8 bits to a 24bit RGB value. Usually this is used for greyscale images.
24 bits is purely RGB, with 8 bits for each channel. There is no colour table.
32 bits is RGBA, 8 bits per channel. This adds an alpha channel
dasHorst99
@dasHorst99

@trickyhead_gitlab Thank you for your information and your code! I will inspect and try to understand it.

@trickyhead_gitlab

why not simply read into arrays of slvs via a char?

Simply because I don't know what slvs is. ;) I have to look it up.

Richard Head
@trickyhead_gitlab
std_logic_vectors - one of the most used types in VHDL..
dasHorst99
@dasHorst99

Ha, I know std_logic_vectors. I am not so dump after all. ;) Now I am checking slvs was the abbreviation.

My first attempt was exactly this approach, but my code was big and not nice. Now with the vunit functions it is a lot smaller and not so complicated. Therefore I accept the integer conversion with the integer_array.

Lars Asplund
@LarsAsplund
@dasHorst99 I haven't looked into it but this sounds like a case where I would consider using the vast ecosystem of Python to convert the BMP to CSV. Put that code in a preconfig function to your test(s) and load the CSV from your VHDL.
dasHorst99
@dasHorst99
Hi,
nice idea. I did not thought about that. Thank you!
Adam Vrba
@civec
@GlenNicholls sorry for the formating
architecture tb of tb_spi is 
.... 
package sb_rl_data is new bitvis_vip_scoreboard.generic_sb_pkg generic 
map (t_element => t_RL_ARRAY,  element_match => slv_array_match, to_string_element => to_string); 
use sb_rl_data.all; 
shared variable SB_RL : sb_rl_data.t_generic_sb; 
... 
begin
dasHorst99
@dasHorst99
Is it possible that the functions length() and width() or the values associated with them are not the absolute value of the length or width, but represent the highest index?
Because of the naming of the functions I assumed that they give the absolute value back.
Sorry for my dumb question, but I am very new to object oriented programming and I don't know where to look that up.
Richard Head
@trickyhead_gitlab
@dasHorst99 VHDL is not an OO language. which length() and width() functions are you refering to?
dasHorst99
@dasHorst99
Oh, ok, sorry, my bad.
width()
dasHorst99
@dasHorst99

The reason I ask is because I read in an image file (bmp) with the save_raw() function.

shared variable t_whole_image_data : integer_array_t;

t_whole_image_data := load_raw(g_image_filename, 8, false);

Then I ask with the length() for the length

info("length: " & to_string(length(t_whole_image_data)));

and get the result 78840, but my hex editor says that the data goes from 0 to 78840.

Patrick Lehmann
@Paebbels
t_whole_image_data'length
Use an attribute to access meta information of objects and types.
dasHorst99
@dasHorst99

@Paebbels Ok, thank you! I will do

It won't work :
Prefix of attribute "length" must be appropriate for an array object or must denote an array subtype.

dasHorst99
@dasHorst99

@dasHorst99

The reason I ask is because I read in an image file (bmp) with the save_raw() function.

I will take my question back and it gives the absolute value. Sorry for the turmoil.

Lars Asplund
@LarsAsplund
@Paebbels @dasHorst99 integer_array_t is not the data but a reference to the data which is located elsewhere. For that reason you need to use width(). That function returns the actual width. What is the size of your image? What do you expect it to be?
dasHorst99
@dasHorst99
@LarsAsplund
The whole image file has 77840 bytes. Read with the length() function;
The Image data offset is 1078. Read from the header.
So the header is located between 0 to 1077.
The image data therefore has a size of 78840 - 1078 = 77762.
But the resolution of the image is 360*216 which equals to 77760.
So I read in 2 bytes too much according to the calculation.
Why, I don't know.
Lars Asplund
@LarsAsplund
I'm noting that 1078 is not a multiple of 4 so if you read 32 bit chunks the problem may be there
dasHorst99
@dasHorst99
@LarsAsplund
You are right, but I am not always reading 4 bytes. In the header are also 2 byte fields. But I read the 1078 out of the header. I am not calculating them.
Patrick Lehmann
@Paebbels
@dasHorst99 Oh, t_whole_image_data is a protected type instance.
The t_ distracted me ...
then you need to implement a method in the protected type to get the inner value.
Lars Asplund
@LarsAsplund

@/all Following a discussion in another gitter room we added a feature which generates an error if you have a directly instantiated entity like this:

  thing_inst: entity lib.thing
    port map (
      clk => clk,
      rst => rst,
      q => q);

and more than one architecture specified. VHDL rules dictates that the latest successfully compiled architecture shall be used but since you do not (normally) control what order code is compiled this results in an arbitrary selection of architecture. Now you will have an error message like this:

  ERROR - Ambiguous direct entity instantiation of lib.thing in C:\examples\ambiguous_architecture\system.vhd.
  Remove all but one architecture or specify one of:
  1. behavioral (C:\examples\ambiguous_architecture\thing_behavioral.vhd)
  2. rtl (C:\examples\ambiguous_architecture\thing_rtl.vhd)

If you encounter this just follow the instructions, for example

  thing_inst: entity lib.thing(rtl)
    port map (
      clk => clk,
      rst => rst,
      q => q);

and the error will disappear.

Richard Head
@trickyhead_gitlab
Will this work if someone had all architectures in 1 file?
Lars Asplund
@LarsAsplund
Yes, the problem isn't that you have many architectures but that you're not specific about which you're referring to.
svenn71
@svenn71
"arbitrary selected architecture" sounds scary when doing asic design.
Richard Head
@trickyhead_gitlab
@svenn71 I assume its because vunit (and other tools) can determine the compile order for you. With your own scripts you can determine your own compile order
Lars Asplund
@LarsAsplund
@trickyhead_gitlab You can enforce the compile order of two files in VUnit with the add_dependency method but that is not a great solution. Your intent should be expressed in the code and not the in the build script. There are also limitation to what you can do with compile order. If you have several architectures in the same file you can't control order. If you have one instance using one architecture and another instance using the other then both will get the same. This is really a user mistake that VHDL pass silently. Now we have a safety mechanism preventing that.
svenn71
@svenn71
but in an asic project I am never alone, so there is seldom something called "my script" only "my code", and if "my code" is picking up the wrong architecture downstream, I would like to know that early
Lars Asplund
@LarsAsplund
True, and with VUnit you now have that early warning. Another safety measure , if you need multiple architectures, is to use namespaces more. You could for example compile behavioral, rtl, and gate-level models to different libraries.
svenn71
@svenn71
and then hope for the downstream asic workflow to support libraries :)
Lars Asplund
@LarsAsplund
Exactly!