nickg / nvc

VHDL compiler and simulator
https://www.nickg.me.uk/nvc/
GNU General Public License v3.0
628 stars 77 forks source link

Generic Type resolving fails when using functions for range #926

Open albydnc opened 2 months ago

albydnc commented 2 months ago

I have an entity with a generic type. If I use a derived type using a function to derive its range (e.g. std_logic_vector(log2ceil(g_N_WORDS) -1 downto 0) I get this error:

** Fatal: expression cannot be folded to an integer constant
     > /home/aperro/Work/colibri/colibri/src/memory/cc_fifo.vhdl:116
     |
 116 |       DATA_T       => std_logic_vector(log2ceil(g_NUM_WORDS) - 1 downto 0),
     |                                        ^^^^^^^^^^^^^^^^^^^^^^^^^

However, if I declare a subtype in the architecture, it succeeds:

subtype derived_t is std_logic_vector(log2ceil(g_NUM_WORDS) - 1 downto 0);

inst : entity work.ent
  generic map(
      data_t => derived_t
  );

It also succeeds if I use attribute subtype:

signal data : std_logic_vector(log2ceil(g_NUM_WORDS) - 1 downto 0);

inst : entity work.ent
  generic map(
      data_t => data'subtype
  );
nickg commented 2 months ago

Where do g_NUM_WORDS and log2ceil come from here? I tried to reproduce this with the following but didn't get any error:

package pack is
    function f (x : integer) return integer;
end package;

package body pack is
    function f (x : integer) return integer is
    begin
        return x;
    end function;
end package body;

-------------------------------------------------------------------------------

entity sub is
    generic (type t);
end entity;

architecture test of sub is
    signal s : t;
begin
end architecture;

-------------------------------------------------------------------------------

use work.pack.all;

entity issue926 is
    generic ( g : integer := 42 );
end entity;

architecture test of issue926 is
begin

    u: entity work.sub
        generic map ( t => bit_vector(f(g) - 1 downto 0) );

end architecture;