nickg / nvc

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

VHDL 93: Unexpected X when concatenating data from generate blocks. #820

Closed aqeelmahroof closed 6 months ago

aqeelmahroof commented 6 months ago

Hi Nick,

I'm currently running a simulation for the following code, where data is concatenated, and the limits are specified through a function. However, during the simulation, I've noticed that the simulator is introducing unexpected 'X' values.

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

entity check_rtl is
generic (
  G_NUM_ARR                     : integer := 4;
  G_WIDTH                      : integer := 4*8
);
port (
  clk                          : in std_logic;
  o_dout                       : out std_logic_vector(G_WIDTH-1 downto 0) := (others => '0')
);
end check_rtl;

architecture rtl of check_rtl is
  type t_arr_property is array (natural range<>) of natural;

  function num_arr (g_num_arr : natural) return t_arr_property is
    variable width_arr : t_arr_property(0 to g_num_arr-1) := (others => 8);
  begin
    return(width_arr);
  end function;

  function f_bit_low (width_arr : t_arr_property) return t_arr_property is
    variable arr_bit_low : t_arr_property(width_arr'range) := (others => 0);
  begin
    for i in width_arr'range loop
      if(i=0) then
        arr_bit_low(i) := 0;
      else
        arr_bit_low(i) := arr_bit_low(i-1) + width_arr(i-1);
      end if;
    end loop;
    return(arr_bit_low);
  end function;

  function f_bit_high (width_arr : t_arr_property) return t_arr_property is
    variable arr_bit_high : t_arr_property(width_arr'range) := (others => 0);
  begin
    for i in width_arr'range loop
      if(i=0) then
        arr_bit_high(i) := -1 + width_arr(i);
      else
        arr_bit_high(i) := arr_bit_high(i-1) + width_arr(i);
      end if;
    end loop;
    --
    return(arr_bit_high);
  end function;  

  constant C_WIDTH_ARR     : t_arr_property := num_arr(G_NUM_ARR);
  constant C_BIT_LOW       : t_arr_property := f_bit_low(C_WIDTH_ARR);
  constant C_BIT_HIGH      : t_arr_property := f_bit_high(C_WIDTH_ARR);

  signal s_clk : std_logic := '0';

begin

  p_clk: process
  begin
    wait for 100 ns;
    s_clk <= '1';
    wait for 100 ns;
    s_clk <= '0';
    wait for 100 ns;
    s_clk <= '1';
    wait for 100 ns;
    s_clk <= '0';
  end process;

  gen_arr: for i in 0 to G_NUM_ARR-1 generate
    signal  data   : unsigned(C_WIDTH_ARR(i)-1 downto 0) := (others => '0');
  begin

    p_dummy: process(s_clk)
      begin
       if (rising_edge(s_clk)) then
        data <= data + 1;
      end if;
    end process;
    --
    gen_reg: if(True) generate
      o_dout(C_BIT_HIGH(i)  downto C_BIT_LOW(i)) <= std_logic_vector(data);
    end generate;
  end generate gen_arr;

end architecture rtl;

Im expecting thease values expected But its resulting in X values observed

Steps to run:

  1. nvc --std=93 -a check_rtl.vhd
  2. nvc -e check_rtl --no-save -O0 -r --format=fst --wave=dump.fst --stop-time=1us

Version nvc --version nvc 1.12-devel (1.11.0.r19.gc739b978) (Using LLVM 14.0.0) (platform Ubuntu 22.04.3 LTS)

Best Regards, Aqeel Mahroof.

nickg commented 6 months ago

Should be fixed now, thanks for reporting.

aqeelmahroof commented 6 months ago

Thanks Nick, That was pretty quick! 👍 . Ran the sims with the fix, its working fine.