Skip to content

Commit

Permalink
Correct errors when compiling with GHDL. Add some tests without modif…
Browse files Browse the repository at this point in the history
…ying the old ones. All test with GHDL passes (in 93 and 2008) for all tests in vunit/vhdl (GHDL 3.0.0-dev (v2.0.0-101-g791ff0c1) [Dunoon edition] Compiled with GNAT Version: 9.3.0. GCC back-end code generator)
  • Loading branch information
dalex78 committed Apr 30, 2022
1 parent 4e7fd60 commit 7515a1f
Show file tree
Hide file tree
Showing 3 changed files with 97 additions and 22 deletions.
2 changes: 1 addition & 1 deletion vunit/vhdl/data_types/src/codec.vhd
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ package codec_pkg is
--===========================================================================
-- All data going through the encoding process becomes a string: it
-- basically becomes a sequence of bytes without any overhead for type
-- information. The 'codec' package doesn’t know if four bytes represents an
-- information. The 'codec' package does not know if four bytes represents an
-- integer, four characters or something else. The interpretation of these
-- bytes takes place when the user decodes the data using a type specific
-- 'decode' function.
Expand Down
86 changes: 65 additions & 21 deletions vunit/vhdl/data_types/src/codec_builder.vhd
Original file line number Diff line number Diff line change
Expand Up @@ -1057,8 +1057,6 @@ package body codec_builder_pkg is
-----------------------------------------------------------------------------
procedure encode_string(constant data : in string; variable index : inout code_index_t; variable code : inout code_t) is
begin
-- Note: Modelsim sets data'right to 0 which is out of the positive
-- index range used by strings.
encode_range(data'left, data'right, data'ascending, index, code);
encode_raw_string(data, index, code);
end procedure;
Expand All @@ -1074,12 +1072,13 @@ package body codec_builder_pkg is
-----------------------------------------------------------------------------
procedure encode_raw_bit_array(constant data : in bit_array; variable index : inout code_index_t; variable code : inout code_t) is
constant actual_code_length : natural := code_length_raw_bit_array(data);
variable value : ieee.numeric_bit.unsigned(data'length-1 downto 0) := ieee.numeric_bit.unsigned(data);
constant BYTE_MASK : ieee.numeric_bit.unsigned(data'length-1 downto 0) := resize(to_unsigned(basic_code_nb_values-1, basic_code_length), data'length);
variable value : bit_array(ceil_div(data'length, basic_code_length)*basic_code_length-1 downto 0);
variable byte : bit_array(basic_code_length-1 downto 0);
begin
for i in actual_code_length-1 downto 0 loop
code(index + i) := character'val(to_integer(value and BYTE_MASK));
value := value srl basic_code_length;
value(data'length-1 downto 0) := data;
for i in 0 to actual_code_length-1 loop
byte := value(basic_code_length*(i+1)-1 downto basic_code_length*i);
code(index + actual_code_length - i - 1) := character'val(to_integer(ieee.numeric_bit.unsigned(byte)));
end loop;
index := index + actual_code_length;
end procedure;
Expand Down Expand Up @@ -1123,8 +1122,12 @@ package body codec_builder_pkg is
procedure decode_bit_vector(constant code : in code_t; variable index : inout code_index_t; variable result : out bit_vector) is
variable ret_val : bit_array(result'range);
begin
decode_bit_array(code, index, ret_val);
result := bit_vector(ret_val);
if ret_val'length /= 0 then -- GHDL work-around (see explanation at the end of the file)
decode_bit_array(code, index, ret_val);
result := bit_vector(ret_val);
else
result := "";
end if;
end procedure;

-----------------------------------------------------------------------------
Expand All @@ -1138,8 +1141,12 @@ package body codec_builder_pkg is
procedure decode_numeric_bit_unsigned(constant code : in code_t; variable index : inout code_index_t; variable result : out ieee.numeric_bit.unsigned) is
variable ret_val : bit_array(result'range);
begin
decode_bit_array(code, index, ret_val);
result := ieee.numeric_bit.unsigned(ret_val);
if ret_val'length /= 0 then -- GHDL work-around (see explanation at the end of the file)
decode_bit_array(code, index, ret_val);
result := ieee.numeric_bit.unsigned(ret_val);
else
result := "";
end if;
end procedure;

-----------------------------------------------------------------------------
Expand All @@ -1153,8 +1160,12 @@ package body codec_builder_pkg is
procedure decode_numeric_bit_signed(constant code : in code_t; variable index : inout code_index_t; variable result : out ieee.numeric_bit.signed) is
variable ret_val : bit_array(result'range);
begin
decode_bit_array(code, index, ret_val);
result := ieee.numeric_bit.signed(ret_val);
if ret_val'length /= 0 then -- GHDL work-around (see explanation at the end of the file)
decode_bit_array(code, index, ret_val);
result := ieee.numeric_bit.signed(ret_val);
else
result := "";
end if;
end procedure;

-----------------------------------------------------------------------------
Expand Down Expand Up @@ -1227,8 +1238,12 @@ package body codec_builder_pkg is

procedure decode_std_ulogic_array(constant code : in code_t; variable index : inout code_index_t; variable result : out std_ulogic_array) is
begin
index := index + code_length_integer_range;
decode_raw_std_ulogic_array(code, index, result);
if result'length /= 0 then -- GHDL work-around (see explanation at the end of the file)
index := index + code_length_integer_range;
decode_raw_std_ulogic_array(code, index, result);
else
result := "";
end if;
end procedure;

-----------------------------------------------------------------------------
Expand All @@ -1242,8 +1257,12 @@ package body codec_builder_pkg is
procedure decode_std_ulogic_vector(constant code : in code_t; variable index : inout code_index_t; variable result : out std_ulogic_vector) is
variable ret_val : std_ulogic_array(result'range);
begin
decode_std_ulogic_array(code, index, ret_val);
result := std_ulogic_vector(ret_val);
if ret_val'length /= 0 then -- GHDL work-around (see explanation at the end of the file)
decode_std_ulogic_array(code, index, ret_val);
result := std_ulogic_vector(ret_val);
else
result := "";
end if;
end procedure;

-----------------------------------------------------------------------------
Expand All @@ -1257,8 +1276,12 @@ package body codec_builder_pkg is
procedure decode_numeric_std_unsigned(constant code : in code_t; variable index : inout code_index_t; variable result : out ieee.numeric_std.unsigned) is
variable ret_val : std_ulogic_array(result'range);
begin
decode_std_ulogic_array(code, index, ret_val);
result := ieee.numeric_std.unsigned(ret_val);
if ret_val'length /= 0 then -- GHDL work-around (see explanation at the end of the file)
decode_std_ulogic_array(code, index, ret_val);
result := ieee.numeric_std.unsigned(ret_val);
else
result := "";
end if;
end procedure;

-----------------------------------------------------------------------------
Expand All @@ -1272,8 +1295,12 @@ package body codec_builder_pkg is
procedure decode_numeric_std_signed(constant code : in code_t; variable index : inout code_index_t; variable result : out ieee.numeric_std.signed) is
variable ret_val : std_ulogic_array(result'range);
begin
decode_std_ulogic_array(code, index, ret_val);
result := ieee.numeric_std.signed(ret_val);
if ret_val'length /= 0 then -- GHDL work-around (see explanation at the end of the file)
decode_std_ulogic_array(code, index, ret_val);
result := ieee.numeric_std.signed(ret_val);
else
result := "";
end if;
end procedure;


Expand Down Expand Up @@ -1338,4 +1365,21 @@ package body codec_builder_pkg is
return bit_vector(ret_val);
end function;



--===========================================================================
-- GHDL limitations
--===========================================================================

-- GHDL work-around: GHDL raises an error when casting a null
-- range of type bit_array(-1 downto 0) to bit_vector.
-- Error: 'bound check failure'
-- However:
-- LRM VHDL-2008: '5.2.1 General'
-- > A constraint is compatible with a subtype if each bound of the
-- range belongs to the subtype or if the range constraint defines
-- a null range. Otherwise, the range constraint is not compatible
-- with the subtype.
-- This happens for conversion between array types

end package body;
31 changes: 31 additions & 0 deletions vunit/vhdl/data_types/test/tb_codec.vhd
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ use vunit_lib.path.all;
use vunit_lib.queue_pkg.all;
use vunit_lib.integer_vector_ptr_pkg.all;
use vunit_lib.codec_pkg.all;
use vunit_lib.codec_builder_pkg.all;

library ieee;
use ieee.std_logic_1164.all;
Expand Down Expand Up @@ -94,7 +95,9 @@ begin
variable null_string : string(10 to 9);
variable t1 : time;
variable string_15_downto_4 : string(15 downto 4);
variable bit_array_m3_downto_m5 : bit_array(-3 downto -5);
variable bit_vector_5_downto_3 : bit_vector(5 downto 3);
variable std_ulogic_array_m3_downto_m5 : std_ulogic_array(-3 downto -5);
variable std_ulogic_vector_5_downto_3 : std_ulogic_vector(5 downto 3);
variable numeric_bit_unsigned_5_downto_3 : ieee.numeric_bit.unsigned(5 downto 3);
variable numeric_bit_signed_5_downto_3 : ieee.numeric_bit.signed(5 downto 3);
Expand All @@ -108,12 +111,24 @@ begin
function get_decoded_range_right ( constant vec: string ) return integer is
begin return vec'right; end;

function get_decoded_range_left ( constant vec: bit_array ) return integer is
begin return vec'left; end;

function get_decoded_range_right ( constant vec: bit_array ) return integer is
begin return vec'right; end;

function get_decoded_range_left ( constant vec: bit_vector ) return integer is
begin return vec'left; end;

function get_decoded_range_right ( constant vec: bit_vector ) return integer is
begin return vec'right; end;

function get_decoded_range_left ( constant vec: std_ulogic_array ) return integer is
begin return vec'left; end;

function get_decoded_range_right ( constant vec: std_ulogic_array ) return integer is
begin return vec'right; end;

function get_decoded_range_left ( constant vec: std_ulogic_vector ) return integer is
begin return vec'left; end;

Expand Down Expand Up @@ -219,6 +234,14 @@ begin
check_relation(decode_string(encode_string(string_15_downto_4)) = string'("Hello world!"));
check_relation(get_decoded_range_left(decode_string(encode_string(string_15_downto_4))) = 15);
check_relation(get_decoded_range_right(decode_string(encode_string(string_15_downto_4))) = 4);
elsif run("Test that bit_array can be encoded and decoded") then
bit_array_m3_downto_m5 := "101";
check_relation(decode_bit_array(encode_bit_array("101")) = bit_array'("101"));
check_relation(decode_bit_array(encode_bit_array("1")) = bit_array'("1"));
check_relation(decode_bit_array(encode_bit_array("")) = bit_array'(""));
check_relation(decode_bit_array(encode_bit_array(bit_array_m3_downto_m5)) = bit_array'("101"));
check_relation(get_decoded_range_left(decode_bit_array(encode_bit_array(bit_array_m3_downto_m5))) = -3);
check_relation(get_decoded_range_right(decode_bit_array(encode_bit_array(bit_array_m3_downto_m5))) = -5);
elsif run("Test that bit_vector can be encoded and decoded") then
bit_vector_5_downto_3 := "101";
check_relation(decode_bit_vector(encode_bit_vector("101")) = bit_vector'("101"));
Expand All @@ -227,6 +250,14 @@ begin
check_relation(decode_bit_vector(encode_bit_vector(bit_vector_5_downto_3)) = bit_vector'("101"));
check_relation(get_decoded_range_left(decode_bit_vector(encode_bit_vector(bit_vector_5_downto_3))) = 5);
check_relation(get_decoded_range_right(decode_bit_vector(encode_bit_vector(bit_vector_5_downto_3))) = 3);
elsif run("Test that std_ulogic_array can be encoded and decoded") then
std_ulogic_array_m3_downto_m5 := "XU1";
check_relation(decode_std_ulogic_array(encode_std_ulogic_array("XU1")) = std_ulogic_array'("XU1"));
check_relation(decode_std_ulogic_array(encode_std_ulogic_array("X")) = std_ulogic_array'("X"));
check_relation(decode_std_ulogic_array(encode_std_ulogic_array("")) = std_ulogic_array'(""));
check_relation(decode_std_ulogic_array(encode_std_ulogic_array(std_ulogic_array_m3_downto_m5)) = std_ulogic_array'("XU1"));
check_relation(get_decoded_range_left(decode_std_ulogic_array(encode_std_ulogic_array(std_ulogic_array_m3_downto_m5))) = -3);
check_relation(get_decoded_range_right(decode_std_ulogic_array(encode_std_ulogic_array(std_ulogic_array_m3_downto_m5))) = -5);
elsif run("Test that std_ulogic_vector can be encoded and decoded") then
std_ulogic_vector_5_downto_3 := "XU1";
check_relation(decode_std_ulogic_vector(encode_std_ulogic_vector("XU1")) = std_ulogic_vector'("XU1"));
Expand Down

0 comments on commit 7515a1f

Please sign in to comment.