Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
  • Jul 31 10:23

    LarsAsplund on wait-on

    Added support for immediate ret… (compare)

  • Jul 29 22:36

    LarsAsplund on wait-on

    Added support for wait procedur… (compare)

  • Jul 29 19:47

    LarsAsplund on wait-on

    Added support for wait procedur… (compare)

  • Jul 29 15:11

    LarsAsplund on wait-on

    Added support for wait procedur… (compare)

  • Jul 29 10:37

    LarsAsplund on wait-on

    Added support for wait procedur… (compare)

  • Jul 20 12:13
    eine labeled #818
  • Jul 20 12:13
    eine labeled #818
  • Jul 20 12:12

    eine on master

    OSVVM: bump to 2022.04 (#827) (compare)

  • Jul 20 12:12
    eine closed #827
  • Jul 20 12:11
    eine labeled #842
  • Jul 20 12:11
    eine labeled #842
  • Jul 20 12:11
    eine labeled #846
  • Jul 20 12:11
    eine labeled #846
  • Jul 20 12:10
    eine labeled #848
  • Jul 20 12:10
    eine labeled #851
  • Jul 20 12:10
    eine labeled #856
  • Jul 20 12:09
    eine milestoned #838
  • Jul 20 12:09
    eine labeled #838
  • Jul 20 12:09
    eine labeled #838
  • Jul 20 12:08
    eine milestoned #849
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!
nfrancque
@nfrancque
@LarsAsplund This warning only applies if vunit is provided multiple architectures of the same component, correct? We aren't forced to specify if only one architecture is available?
Lars Asplund
@LarsAsplund
@nfrancque Correct. It's only when there is more than one architecture this becomes a problem and only then we issue an error
if len(primary_unit.architecture_names) > 1:
  self._handle_ambiguous_architecture(source_file, ref, primary_unit)
Lars Asplund
@LarsAsplund
Note that there can still be two architectures in the compiled library but I think that might safe. Let's say you have a behavioral architecture and then add an rtl one without being specific in your instantiation. You will then get the error. If you decide to remove the addition of the behavioral architecture file in your run script the error will go away and the rtl model will be compiled. The behavioral model will still be in the library unless you did a clean compile but since the rtl architecture was compiled last it is the one used
nfrancque
@nfrancque
Yep that all makes sense to me. Personally don't use multiple architectures for much but the people I have seen use it usually leave it unspecified and then change their compile script depending on the target. For these people accidentally including both is almost always a problem, so might be worth adding an option to up it to an error and not allow compile? Doesn't affect me either way but if it did that would sound useful.
Lars Asplund
@LarsAsplund
This will raise a runtime error in Python so you have to fix it or VUnit won't proceed:
if len(primary_unit.architecture_names) > 1:
  self._handle_ambiguous_architecture(source_file, ref, primary_unit)
  raise RuntimeError(f"Ambiguous use of {ref.library}.{ref.design_unit}")
nfrancque
@nfrancque
Ah - perfect! Thanks
dpaul
@dpaul24
@all, First the silly question - Does VUnit based sim using ModelSim run successfully under a Linux Ubuntu Docker image?
Background: I have a Microchip Libero 2021.2 based project for which I run sim using VUnit and ModelSim. I use complete TCL mode. The VUnit based sim run perfectly under Windows10 and a real Linux Ubuntu machine. But the same script fails to run under a Linux Ubuntu docker image. I do not think this is a VUnit problem but has more to do with Libero. Has anyone experience in such a case?
dpaul
@dpaul24
fyi - In Linux I just take care of the paths, and it works. The original project was created on win10.
Adrian Byszuk
@abyszuk
@dpaul24 I have my whole CI setup in Gitlab using Docker images of GHDL/Modelsim with VUnit and it works just fine. There are a few differences wrt. what you ask:
  • Docker image is based on CentOS 8
  • Xilinx Unisim libraries instead of Libero
\o_O/
@nanoeng
@GlenNicholls I came across the same issue @Ahmad-Zaklouta described in his posting on October the 5th. Do you happen to have any advice about what could be wrong with our set up?
GlenNicholls
@GlenNicholls

I think your best bet is to turn off preprocessing and try it again. If that works, re-enable preprocessing and read through the preprocessed file to see if you can figure out what's going on. I can't help much unless you post the problem file before and after VUnit enabled it. I would also suggest using TerosHDL, ghdl_ls, or another VHDL LS that can check your syntax. Those will help uncover errors like this... Now onto some more context

You probably have a syntax error somewhere in that file. Mismatched parenthesis or begin/end were two common cases where I saw that error. To handle preprocessing, VUnit has to move the file to a new location and modify it to add line numbers etc. to the subprogram args. The feature is great and VUnit is nearly perfect from what I've seen at parsing/modifying... BUT, VUnit does not understand semantics (or anything I don't think, I'm pretty sure it uses pure regex parsing), so it'll happily make a modification even though the file has syntax issues. I can't blame it, it's the simulator's job to report errors in the code, VUnit is just the middle man. The simulator sees a critical issue with VUnit's modification because the arguments for the log subprograms aren't correct so it complains about those instead of the real syntax issues. Basically, VUnit unintentionally masks the real error. Maybe changing simulators will help if the other one reports more errors while analyzing the file, but that's a gamble.

I got burned so many times fixing syntax errors with preprocessed files only to see the same or similar error. After digging into them for longer than I'll admit, I found out I accidentally modified the preprocessed file instead of the source file when I found the problem. I don't use the preprocessing feature for this reason. It's great and works 100% of the time, but when your code isn't correct, it can be a huge pain to debug. I think I opened an issue a long time ago on GitHub, but I don't remember. That might have more info about my workaround if there was one.

I love having my logs tell me where a log message is, but until VHDL can provide the extra info like file and line num, it's more headache than it's worth. If you want that feature, check out ActiveHDL >12, RivieraPRO, or ask your simulator vendor to add VHDL2019 support. My workaround for this problem was to write better log messages in the first place, basically something that can be grepped easily. Reference https://github.com/google/styleguide/blob/gh-pages/pyguide.md#3102-error-messages

disclaimer not sure if VUnit supports 2019 so the above suggestion about that might not be feasible yet. I haven't been keeping up with the development for a long while.

Lars Asplund
@LarsAsplund
@GlenNicholls @nanoeng Support for finding line and file location was the reason I joined the work with VHDL 2019. Riviera-PRO supports this so if you use that simulator with the 2019 standard you get location without preprocessing. Active-HDL also supports but there was a bug which caused this feature to fail. Workaround is in the pipe.