Skip to content

Slice mismatch results in silent failures (corrupt std_logic_vectors?) instead of warnings / errors #1231

@gfcwfzkm

Description

@gfcwfzkm

I've noticed that some (probably) unintended behavior happens, when a slicing mismatch on a std_logic_vector happens, resulting in the returned std_logic_vector being corrupted. Printing that vector results in non-VHDL-std_signal characters being printed:

Console output:

nvc --version
 nvc 1.16.2 (1.16.2.r0.gb1d6cab4) (Using LLVM 20.1.5)
nvc -a .\testbench\slice_mismatch.vhdl -e slice_mismatch -r
** Note: 0ms+0: Surprise 1 0JÕèèèFO
   Process :slice_mismatch:magic at C:\truncated\slice_mismatch.vhdl:38
** Note: 0ms+0: Surprise 2 1JÕèèèFO
   Process :slice_mismatch:magic at C:\truncated\slice_mismatch.vhdl:38
** Note: 0ms+0: Surprise 3 00JÕèèèF
   Process :slice_mismatch:magic at C:\truncated\slice_mismatch.vhdl:38
** Note: 0ms+0: Surprise 4 01/WUUá0
   Process :slice_mismatch:magic at C:\truncated\slice_mismatch.vhdl:38

ModelSim recognizes the danger and reports the following message, before it aborts the simulation due to it causing an fatal error:

Fatal: (vsim-3607) Slice range direction (downto) does not match slice prefix direction (to).

I'm well aware that this is a mistake and issue on my side with the slice mismatch, but I was left in the dark until I spun up ModelSim. Here is a minimal testbench to replicate the issue:

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

entity slice_mismatch is
end entity slice_mismatch;

architecture rtl of slice_mismatch is
    -- This function should shift a vector left or right by a specific amount.
    -- Due to a slice mismatch occurring in line 29, it instead returns some random characters??
    function expected_shift (
        input_vec : std_logic_vector;
        shift : integer
    ) return std_logic_vector is
        constant len : natural := input_vec'length;
        variable temp : std_logic_vector(len-1 downto 0);
        variable input_vector : std_logic_vector(len-1 downto 0) := input_vec;
        variable abs_shift : natural;
    begin
        abs_shift := abs(shift);
        
        if abs_shift >= len then
            temp := (others => '0');
        else
            if shift >= 0 then  -- Left shift
                temp := input_vec(len-1-abs_shift downto 0) & (abs_shift-1 downto 0 => '0');
            else   -- Right shift
                temp := (abs_shift-1 downto 0 => '0') & input_vec(len-1 downto abs_shift);
            end if;
        end if;
        return temp;
    end function;
begin
    MAGIC : process begin
        -- I assume the directly written std_logic_vector is a "to" instead of "downto" type, thus causing the mismatch
        report "Surprise 1 " & to_string(expected_shift("00000000", 0));
        report "Surprise 2 " & to_string(expected_shift("11111111", 0));
        report "Surprise 3 " & to_string(expected_shift("10101010", -1));
        report "Surprise 4 " & to_string(expected_shift("01010101", 1));
        -- but instead of failing with a loud bang, it results in weird, random characters with no warnings or errors.
        wait;
    end process;
end architecture;

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions