I have here some valid VHDL code, which can be compiled with
GHDL understands this code if option '--std' is not set. When I set '--std' to VHDL-2002 I get errors complaining on the ranges in for-loops. Hmmm in pre 2002 mode this lines throw already a warning :(
So here is my function:
-- create vector-vector from vector (4 bit)
FUNCTION to_slvv_4(slv : STD_LOGIC_VECTOR) RETURN T_SLVV_4 IS
VARIABLE Result : T_SLVV_4((slv'length / 4) - 1 DOWNTO 0);
BEGIN
IF ((slv'length MOD 4) /= 0) THEN
REPORT "to_slvv_4: width mismatch - slv'length is no multiple of 4"
SEVERITY FAILURE;
END IF;
FOR I IN 0 TO (slv'length / 4) - 1 LOOP
Result(I) := slv((I * 4) + 3 DOWNTO (I * 4));
END LOOP;
RETURN Result;
END FUNCTION;
GHDL error message:
D:\VHDL\git\PoC\src\common\vectors.vhdl:249:25:
-> universal integer bound must be numeric literal or attribute
The faulty line 249 is FOR I IN 0 TO (slv'length / 4) - 1 LOOP
. The user defined type T_SLVV_4 is defined as:
type T_SLVV_4 is array(natural range <>) of std_logic_vector(3 downto 0);
My code has 8 errors like that. I could rewrite two of them from 'length
to 'range
so, 6 are left. But some these can not be rewritten...
So why are loop boundary calculations with 'length
not allowed in GHDL and/or VHDL >=2002?
See vhdl - Address of array provided as std_logic_vector - Stack Overflow. This is the same issue.
1 library ieee;
2 use ieee.std_logic_1164.all;
3
4 entity paebbels is
5 end entity;
6
7 architecture foo of paebbels is
8
9 type T_SLVV_4 is array(natural range <>) of std_logic_vector(3 downto 0);
10 -- create vector-vector from vector (4 bit)
11 FUNCTION to_slvv_4(slv : STD_LOGIC_VECTOR) RETURN T_SLVV_4 IS
12 VARIABLE Result : T_SLVV_4((slv'length / 4) - 1 DOWNTO 0);
13 BEGIN
14 IF ((slv'length MOD 4) /= 0) THEN
15 REPORT "to_slvv_4: width mismatch - slv'length is no multiple of 4"
16 SEVERITY FAILURE;
17 END IF;
18
19 FOR I IN 0 TO (slv'length / 4) - 1 LOOP
20 Result(I) := slv((I * 4) + 3 DOWNTO (I * 4));
21 END LOOP;
22 RETURN Result;
23 END FUNCTION;
24
25 begin
26 end architecture;
This is the same issue, but for the range of a loop instead of an a subtype indication:
hdl -a --std=02 paebbels.vhdl
paebbels.vhdl:19:18: universal integer bound must be numeric literal or attribute
ghdl: compilation errorghdl -a --std=93 paebbels.vhdl
paebbels.vhdl:19:18: universal integer bound must be numeric literal or attribute
ghdl: compilation errorghdl -a --std=93c paebbels.vhdl
paebbels.vhdl:19:18:warning: universal integer bound must be numeric literal or attribute
(No error but a warning, which VHDL doesn't actually have. std=93c is what you get when you don't pass a std, it's a relaxed rule.)
See Issue Report IR2073.txt, with the issue raised most recently by Tristan Gingold (the author of ghdl, incidentally).
This resulted in a Language Change Specification (LCS) for P1076-200X (-2008, LCS-2006-32) that also gave permission to interpret the text in the -2002 standard as specified in the Issue Report.
It would seem Tristan never saw that LCS or otherwise implemented it. He added the 93c standard after the the IR was accepted. You could submit a bug report on ghdl-updates on SourceForge or otherwise contact Tristan. There's also nothing that gives authority to interpret the change for the -1993 standard (despite the 93c).
There's also an easy way to evade the issue:
-- FOR I IN 0 TO (slv'length / 4) - 1 LOOP
for i in Result'range loop
Which gives us:
ghdl -a paebbels.vhdl
(No errors, no warnings).
There's also using type conversion to avoid the issue:
-- FOR I IN 0 TO (slv'length / 4) - 1 LOOP
--for i in Result'range loop
for i in 0 to natural(slv'length/4-1) loop
I'd claim the 93c behavior is incorrect, but there's actually a historical dispute whether the LCS changed the meaning of the standard or simply clarified it's interpretation, the intent all along being to allow conversion to universal integer.