nickg / nvc

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

Missing variable for generic in package instance #815

Closed sean-anderson-seco closed 9 months ago

sean-anderson-seco commented 9 months ago

Elaborating the following program

package bar is
    function gen_baz(l: positive) return bit_vector;
end;

package body bar is
    function gen_baz(l: positive) return bit_vector is begin
        return 10X"240";
    end;
end;

package qux is
    generic (
        X: positive;
        BAZ: bit_vector := work.bar.gen_baz(X)
    );

    subtype baz_t is bit_vector(BAZ'high downto BAZ'low);

    function get_qux(state: baz_t) return baz_t;
end;

package body qux is
    function get_qux(state: baz_t) return baz_t is begin
        return 10D"501";
    end;
end;

entity test is end;

architecture test of test is
    package pkg is new work.qux generic map (X => 10);
    signal s0: pkg.baz_t;
begin
    process begin
        s0 <= pkg.baz_t'value(10D"500");
        s0 <= pkg.get_qux(s0);
        wait;
    end process;
end;

fails with the following error:

$ nvc --std=08 -a test.vhd -e test 

Name       WORK.TEST._P0
Kind       process
Context    WORK.TEST
Blocks     2
Registers  32
Types      19
Variables  0
Begin
   0: r0 := var upref 1, S0             // @<[*] : $<0..1>> => 0..1
      r1 := load indirect r0            // [*] : $<0..1> => 0..1
      r2 := uarray len r1 dim 0         // #
      r3 := unwrap r1                   // $<0..1>
      drive signal r3 count r2
      return 
   1: r4 := var upref 1, S0             // @<[*] : $<0..1>> => 0..1
      r5 := load indirect r4            // [*] : $<0..1> => 0..1
      r6 := uarray len r5 dim 0         // #
      r7 := const 0                     // -2^63..2^63-1 => 0
      r8 := const 48                    // 0..255 => 48
      r9 := const 49                    // 0..255 => 49
      r10 := const [r8,r9,r9,r9,r9,r9,r8,r9,r8,r8] // [10] : 0..255 => 0..255
      r11 := address of r10             // @<0..255> => 0..255
      r12 := const 1                    // -2^31..2^31-1 => 1
      r13 := const 10                   // -2^31..2^31-1 => 10
      r14 := const 0                    // 0..1 => 0
      r15 := wrap r11 [r12 r13 r14]     // [*] : 0..255
      r16 := link package STD.STANDARD  // P<STD.STANDARD>
      r17 := fcall STD.STANDARD.BIT_VECTOR$value r16, r15 // [*] : 0..1 => 0..1
      r18 := debug locus WORK.TEST.elab-78 // D<>
      r19 := uarray len r17 dim 0       // #
      length check left r6 == right r19 locus r18
      r20 := unwrap r17                 // @<0..1> => 0..1
      r21 := unwrap r5                  // $<0..1>
      sched waveform r21 count r6 values r20 reject r7 after r7
      r22 := load indirect r4           // [*] : $<0..1> => 0..1
      r23 := uarray len r22 dim 0       // #
      r24 := link package WORK.TEST.PKG // P<WORK.TEST.PKG>
      r25 := unwrap r22                 // $<0..1>
      r26 := resolved r25               // @<0..1> => 0..1
      r27 := uarray left r22 dim 0      // #
      r28 := uarray right r22 dim 0     // #
      r29 := uarray dir r22 dim 0       // 0..1
      r30 := wrap r26 [r27 r28 r29]     // [*] : 0..1
      r31 := debug locus WORK.TEST.elab-43 // D<>

** Fatal: missing variable for generic BAZ in WORK.TEST-TEST
[0x56268c918028] ../src/diag.c:1015 diag_femit
[0x56268c87adcf] ../src/util.c:585 fatal_trace
[0x56268c8df914] ../src/lower.c:2987 lower_ref
[0x56268c8df914] ../src/lower.c:5280 lower_expr
[0x56268c8e02fe] ../src/lower.c:12349 lower_rvalue
[0x56268c8de41c] ../src/lower.c:4902 lower_attr_ref
[0x56268c8de41c] ../src/lower.c:5300 lower_expr
[0x56268c8e02fe] ../src/lower.c:12349 lower_rvalue
[0x56268c8e041f] ../src/lower.c:355 lower_range_left
[0x56268c8e09c8] ../src/lower.c:491 lower_array_len
[0x56268c8e09c8] ../src/lower.c:477 lower_array_len
[0x56268c8e0fe8] ../src/lower.c:5755 lower_check_array_sizes
[0x56268c8ef316] ../src/lower.c:1134 lower_subprogram_arg
[0x56268c8f0598] ../src/lower.c:2583 lower_fcall
[0x56268c8dd67f] ../src/lower.c:5274 lower_expr
[0x56268c8e02fe] ../src/lower.c:12349 lower_rvalue
[0x56268c8f44a8] ../src/lower.c:6331 lower_sequence
[0x56268c8f724d] ../src/lower.c:11127 lower_process
[0x56268c8bf132] ../src/elab.c:1630 elab_stmts
[0x56268c8c0b04] ../src/elab.c:1823 elab_top_level
[0x56268c8c0d01] ../src/elab.c:1892 elab
[0x56268c87493a] ../src/nvc.c:456 elaborate
[0x56268c87493a] ../src/nvc.c:1905 process_command
[0x56268c873c8d] ../src/nvc.c:1368 interact_cmd
[0x56268c873c8d] ../src/nvc.c:1929 process_command
[0x56268c872034] ../src/nvc.c:2042 main

I think the root of the problem is that tree_container is getting the architecture instead of the package instance:

gdb$ p dump(tree_container(decl))
use STD.STANDARD.all;

architecture WORK.TEST-TEST of TEST is
  package PKG is
    -- Instantiated from WORK.QUX
    generic (
      constant X : in POSITIVE;
      constant BAZ : in BIT_VECTOR := GEN_BAZ(10) );
    generic map (10, GEN_BAZ(10));
    subtype BAZ_T is BIT_VECTOR(BAZ'HIGH downto BAZ'LOW);
    function GET_QUX ( constant STATE : in BAZ_T ) return BAZ_T;
      -- WORK.TEST-TEST.PKG.GET_QUX(24WORK.TEST-TEST.PKG.BAZ_T)24WORK.TEST-TEST.PKG.BAZ_T

    function GET_QUX ( constant STATE : in BAZ_T ) return BAZ_T is
      -- WORK.TEST-TEST.PKG.GET_QUX(24WORK.TEST-TEST.PKG.BAZ_T)24WORK.TEST-TEST.PKG.BAZ_T
    begin
      return "0111110101";
    end function;
  end package;

  signal S0 : BAZ_T;
begin
  process is
  begin
    S0 <= reject 0 ps inertial BAZ_T'VALUE("0111110100");
    S0 <= reject 0 ps inertial GET_QUX(S0);
    wait;
  end process;
end architecture;