ghdl / ghdl

VHDL 2008/93/87 simulator
GNU General Public License v2.0
2.27k stars 352 forks source link

Generic parameters treated strictly when -frelaxed selected #2651

Open Araneidae opened 2 months ago

Araneidae commented 2 months ago

Description When analysing with the -frelaxed flag the treatment of generic size parameters is stricter than expected, in particular others cannot be used.

Expected behaviour It would be useful to support the relaxed behaviour implemented by ModelSim/QuestaSim and by Vivado. These tools treat generic size parameters more like global constants and allow more flexible aggregate constructions.

How to reproduce? The code below fails with ghdl, but only produces warnings with ModelSim and with Vivado

library ieee;
use ieee.std_logic_1164.all;                                                    

entity test_others is                                                           
    generic (                                                                   
        WIDTH_IN : natural;                                                     
        WIDTH_OUT : natural
    );                                                                          
    port (                                                                      
        data_i : in std_ulogic_vector(WIDTH_IN-1 downto 0);                     
        data_o : out std_ulogic_vector(WIDTH_OUT-1 downto 0)                    
    );                                                                          
end;                                                                            

architecture arch of test_others is                                             
begin                                                                           
    data_o <= (WIDTH_IN-1 downto 0 => data_i, others => '0');
end;             

built with command

ghdl -a --std=08 -frelaxed test_others.vhd

generates errors

others.vhd:17:15:error: not static choice exclude others choice
    data_o <= (WIDTH_IN-1 downto 0 => data_i, others => '0');
              ^
others.vhd:17:15:error: non-locally static choice for an aggregate is allowed only if only choice
    data_o <= (WIDTH_IN-1 downto 0 => data_i, others => '0');
              ^

With ModelSim the following warning is generated:

# ** Warning: test_others.vhd(18): (vcom-1048) Non-locally static choice (association #1, choice #1) is allowed only if it is the only choice of the only association.

Context Please, provide the following information:

tgingold commented 2 months ago

This one is not easy to support as aggregate are analyzed before elaboration. I don't plan to work on it soon, but I will try to do all the preliminary work.

Araneidae commented 2 months ago

I'm not surprised this is harder, I was quite surprised at just how small commit https://github.com/ghdl/ghdl/commit/ae75c96f408bce8cf058f3506346c5b493470b92 is!

Just for reference, this issue doesn't just apply to explicit generic parameters, but also to locally calculated constants, the following code also fails in essentially the same way:

library ieee;
use ieee.std_logic_1164.all;

entity test_others is
    port (
        data_i : in std_ulogic_vector;
        data_o : out std_ulogic_vector
    );
end;

architecture arch of test_others is
    constant WIDTH_IN : natural := data_i'LENGTH;
begin
    data_o <= (WIDTH_IN-1 downto 0 => data_i, others => '0');
end;
Araneidae commented 2 months ago

Think I'll also add this as a note here: experimenting with replacing the data_o assignment with a function call (which of course does work), I encountered the following slightly unexpected error message:

library ieee;
use ieee.std_logic_1164.all;

entity test_others is
    port (
        data_i : in std_ulogic_vector;
        data_o : out std_ulogic_vector
    );
end;

architecture arch of test_others is
    constant WIDTH_IN : natural := data_i'LENGTH;
    constant WIDTH_OUT : natural := data_o'LENGTH;
    function extend(data : std_ulogic_vector) return std_ulogic_vector
    is
        variable result : data_o'SUBTYPE;
--         variable result : std_ulogic_vector(WIDTH_OUT-1 downto 0);
    begin
        result(WIDTH_IN-1 downto 0) := data;
        result(WIDTH_OUT-1 downto WIDTH_IN) := (others => '0');
        return result;
    end;
begin
--     data_o <= (WIDTH_IN-1 downto 0 => data_i, others => '0');
    data_o <= extend(data_i);
end;

fails with message

others.vhd:16:27:warning: reference to port "data_o" violate pure rule for function "extend" [-Wpure]
        variable result : data_o'SUBTYPE;
                          ^

Again it seems plausible to me that the pedantry of the VHDL standard (😬) does indeed forbid this, but this definitely seems another candidate for -frelaxed to accept.

However ... in this case I'm not going to claim that ModelSim does it better ... instead, it produces the message

# -- Compiling architecture arch of test_others
# ** Fatal: Unexpected signal: 11.
# ** Note: others.vhd(20): VHDL Compiler exiting

Cool!

My experience seems to be that 'SUBTYPE tickles lots of language tool bugs.

tgingold commented 2 months ago

The subtype attribute doesn't generate anymore an error in that case.