nickg / nvc

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

External name to not-yey-elaborated signal with unconstrained complex type causes fatal: variable and stored value do not have same type : #860

Closed avelure closed 6 months ago

avelure commented 6 months ago

I understand the following code is not completely valid as the two signals are pointing to a signal in an entity that has not yet been elaborated. NVC gives an error on the two signals, but it looks like it still tries to parse the type after the error and fails due to the type being defined by the generics which are not completely elaborated. Modelsim gives a warning in this case, but is able to pass simulation.

The test requires UVVM, but it could probably be recreated without.

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

library uvvm_util;
context uvvm_util.uvvm_util_context;

library bitvis_vip_sbi;
context bitvis_vip_sbi.vvc_context;

entity ethernet_th is
  generic(
    GC_SBI_ADDR_WIDTH : positive := 8;
    GC_SBI_DATA_WIDTH : positive := 8
  );
end entity ethernet_th;

architecture struct_sbi of ethernet_th is
  signal clk       : std_logic;
  signal i1_sbi_if : t_sbi_if(addr(GC_SBI_ADDR_WIDTH - 1 downto 0), wdata(GC_SBI_DATA_WIDTH - 1 downto 0), rdata(GC_SBI_DATA_WIDTH - 1 downto 0));
begin
end architecture struct_sbi;

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

library uvvm_util;
context uvvm_util.uvvm_util_context;

library bitvis_vip_sbi;
context bitvis_vip_sbi.vvc_context;

entity test is
  generic(
    GC_DATA_WIDTH : positive := 8);
end entity;

architecture tb of test is
  constant C_ADDR_WIDTH : positive := 8;

  alias clk is << signal .test.i_test_harness.clk : std_logic >>;
  alias i1_sbi_if is << signal .test.i_test_harness.i1_sbi_if : t_sbi_if(addr(C_ADDR_WIDTH - 1 downto 0), wdata(GC_DATA_WIDTH - 1 downto 0), rdata(GC_DATA_WIDTH - 1 downto 0)) >>;
begin

  i_test_harness : entity work.ethernet_th(struct_sbi)
    generic map(
      GC_SBI_ADDR_WIDTH => C_ADDR_WIDTH,
      GC_SBI_DATA_WIDTH => GC_DATA_WIDTH
    );

  p_main: process
  begin
    wait;
  end process p_main;
end architecture;
$ nvc -L~/.nvc/lib --std=08 -a test_uvvm_ethernet.vhd
$ nvc -L~/.nvc/lib --std=08 -e test -r
** Error: external name CLK not found
    > C:\proj\public\minimal\test_uvvm_ethernet.vhd:42
    |
 42 |   alias clk is << signal .test.i_test_harness.clk : std_logic >>;
    |                           ^^^^^^^^^^^^^^^^^^^ name I_TEST_HARNESS not found inside TEST
    |
    = Note: an object cannot be referenced by an external name until it has been elaborated
** Error: external name I1_SBI_IF not found
    > C:\proj\public\minimal\test_uvvm_ethernet.vhd:43
    |
 43 |   alias i1_sbi_if is << signal .test.i_test_harness.i1_sbi_if : t_sbi_if(addr(C_ADDR_WIDTH - 1 downto 0), wdata(GC_DATA_WIDTH - 1 downto 0), rdata(GC_DATA_WIDTH - 1 downto 0)) >>;
    |                                 ^^^^^^^^^^^^^^^^^^^ name I_TEST_HARNESS not found inside TEST
    |
    = Note: an object cannot be referenced by an external name until it has been elaborated

Name       WORK.TEST
Kind       instance
Blocks     1
Registers  10
Types      18
  BITVIS_VIP_SBI.SBI_BFM_PKG.T_SBI_IF$  {$<0..8>, [*] : $<0..8>, $<0..8>, $<0..8>, [*] : $<0..8>, $<0..8>, [*] : $<0..8>}
  BITVIS_VIP_SBI.SBI_BFM_PKG.T_SBI_IF   {0..8, [*] : 0..8, 0..8, 0..8, [*] : 0..8, 0..8, [*] : 0..8}
Variables  4
  GC_DATA_WIDTH                         // -2^31..2^31-1 => 1..2^31-1, constant
  C_ADDR_WIDTH                          // -2^31..2^31-1 => 1..2^31-1, constant
  CLK                                   // $<0..8> => 0..8
  I1_SBI_IF                             // @<BITVIS_VIP_SBI.SBI_BFM_PKG.T_SBI_IF${}> => BITVIS_VIP_SBI.SBI_BFM_PKG.T_SBI_IF{}
Begin
   0: r0 := package init STD.STANDARD   // P<STD.STANDARD>
      r1 := package init BITVIS_VIP_SBI.SBI_BFM_PKG // P<BITVIS_VIP_SBI.SBI_BFM_PKG>
      r2 := package init IEEE.STD_LOGIC_1164 // P<IEEE.STD_LOGIC_1164>
      r3 := package init IEEE.NUMERIC_STD // P<IEEE.NUMERIC_STD>
      r4 := const 8                     // -2^31..2^31-1 => 8
      r5 := const 1                     // -2^31..2^31-1 => 1
      r6 := const 2147483647            // -2^31..2^31-1 => 2^31-1
      r7 := const 0                     // 0..1 => 0
      GC_DATA_WIDTH := store r4
      C_ADDR_WIDTH := store r4
      r8 := undefined                   // $<0..8> => 0..8
      CLK := store r8
      r9 := undefined                   // BITVIS_VIP_SBI.SBI_BFM_PKG.T_SBI_IF${} => BITVIS_VIP_SBI.SBI_BFM_PKG.T_SBI_IF{}
      I1_SBI_IF := store r9      <----

** Fatal: variable and stored value do not have same type
[00007FF6C0912970]
[00007FF6C09BBD46]
[00007FF6C0911943]
[00007FF6C0A4DDD0] vhpi_is_printable+0x53fb0
[00007FF6C0984C63]
[00007FF6C09B6389]
[00007FF6C096737A]
[00007FF6C096E42D]
[00007FF6C0964869]
[00007FF6C0908AE9]
[00007FF6C0902D78]
[00007FF6C08F1315]
[00007FF6C08F1366]
[00007FFD00E1257D] BaseThreadInitThunk+0x1d
[00007FFD01B2AA58] RtlUserThreadStart+0x28

Please report this bug at https://github.com/nickg/nvc/issues