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;
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;
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;
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.
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
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.
@/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.
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.