nickg / nvc

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

** Fatal: cannot rewrite generic DIM to tree kind T_FCALL #831

Closed smaslovski closed 8 months ago

smaslovski commented 8 months ago

Hi,

I've found that NVC crashes when elaborating the code given below. Here is the crash backtrace:

$ nvc --std=08 -a bug.vhd
$ nvc --std=08 -e fft    
** Fatal: cannot rewrite generic DIM to tree kind T_FCALL
[0x55b14efb493f] ../src/diag.c:1015 diag_femit
[0x55b14ef00e5f] ../src/util.c:585 fatal_trace
[0x55b14ef5f2b3] ../src/simp.c:441 simp_ref
[0x55b14ef5f2b3] ../src/simp.c:1552 simp_tree.lto_priv.0
[0x55b14ef71bc8] ../src/object.c:675 object_rewrite
[0x55b14ef71c3d] ../src/object.c:738 object_rewrite
[0x55b14ef71afc] ../src/object.c:749 object_rewrite
[0x55b14ef71c3d] ../src/object.c:738 object_rewrite
[0x55b14ef71afc] ../src/object.c:749 object_rewrite
[0x55b14ef71c3d] ../src/object.c:738 object_rewrite
[0x55b14ef71afc] ../src/object.c:749 object_rewrite
[0x55b14ef71afc] ../src/object.c:749 object_rewrite
[0x55b14ef71c3d] ../src/object.c:738 object_rewrite
[0x55b14ef71afc] ../src/object.c:749 object_rewrite
[0x55b14ef5aeb2] ../src/tree.c:1288 tree_rewrite
[0x55b14ef5aeb2] ../src/tree.c:1697 simplify_global
[0x55b14ef5d8c0] ../src/elab.c:1807 elab_top_level.lto_priv.0
[0x55b14eef995c] ../src/elab.c:1886 elab
[0x55b14eef995c] ../src/elab.c:456 elaborate
[0x55b14eefb033] ../src/nvc.c:1905 process_command
[0x55b14eef574e] ../src/nvc.c:2042 main

Here is the VHDL code

-- fft_types --------------------------------------------------------------------------
library ieee;
use ieee.math_complex.all;
use std.textio.all;

package fft_types is
  subtype fft_data_type is complex;
  type fft_data_vector is array (natural range <>) of fft_data_type;
  pure function "+" (a, b : fft_data_vector) return fft_data_vector;
  pure function "*" (a, b : fft_data_vector) return fft_data_vector;
end package fft_types;

package body fft_types is
  pure function "+" (a, b : fft_data_vector) return fft_data_vector is
    variable res : fft_data_vector (a'range);
  begin
    for i in a'range loop
      res(i) := a(i) + b(i);
    end loop;
    return res;
  end function;

  pure function "*" (a, b : fft_data_vector) return fft_data_vector is
    variable res : fft_data_vector (a'range);
  begin
    for i in a'range loop
      res(i) := a(i) * b(i);
    end loop;
    return res;
  end function;
end package body fft_types;

-- fft --------------------------------------------------------------------------------
library ieee;
use ieee.math_complex.all;
use work.fft_types.all;

entity fft is
  generic (
    POW : natural  := 4;
    DIM : positive := 2**POW);
  port (
    x, w : in  fft_data_vector (0 to DIM-1);
    y    : out fft_data_vector (0 to DIM-1) := (others => fft_data_type'(0.0,0.0)));
end entity fft;

architecture recursive of fft is
  subtype half_array is fft_data_vector (0 to DIM/2-1);
  signal even, odd, x_e, x_o, w_e : half_array := (others => fft_data_type'(0.0,0.0));
  alias w_b : half_array is w(0 to DIM/2-1);
  alias w_t : half_array is w(DIM/2 to DIM-1);
begin
  stage :
  if base_case: POW = 1 generate
    y(0) <= x(0) + x(1);
    y(1) <= x(0) - x(1);
  else general_case: generate
    split_even_odd :
    for i in half_array'range generate
      x_e(i) <= x(2*i);
      x_o(i) <= x(2*i+1);
      w_e(i) <= w(2*i);
    end generate;

    even_fft :
      entity fft
        generic map (
          POW => POW-1)
        port map (
          x => x_e, w => w_e, y => even);

    odd_fft :
      entity fft
        generic map (
          POW => POW-1)
        port map (
          x => x_o, w => w_e, y => odd);

    y(0 to DIM/2-1)   <= even + odd*w_b;
    y(DIM/2 to DIM-1) <= even + odd*w_t;
  end generate stage;
end architecture recursive;

With best regards, Stanislav