Paebbels
Paebbels

Reputation: 16221

Why is GHDL and/or VHDL-2002 so restrictive on ranges in loops?

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?

Upvotes: 1

Views: 508

Answers (1)

user1155120
user1155120

Reputation:

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 error

ghdl -a --std=93 paebbels.vhdl
paebbels.vhdl:19:18: universal integer bound must be numeric literal or attribute
ghdl: compilation error

ghdl -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.

Upvotes: 2

Related Questions