否定函数参数时出现意外的函数输出

时间:2019-03-14 08:42:37

标签: vhdl

我有一个优先级编码功能,该函数返回在输入矢量中找到第一个1的位置处包含1的矢量。该函数将按预期工作,除非我尝试取反输入向量。这是一个演示意外行为的示例:


LIBRARY ieee;
USE ieee.std_logic_1164.ALL;

entity tb IS
end tb;

architecture run of tb is
    constant N : natural := 5;

    function get_first_one_in_vec (vec_in: std_logic_vector) return std_logic_vector is
        variable ret: std_logic_vector(vec_in'high downto vec_in'low);
    begin
        ret := (others => '0');
        for i in vec_in'low to vec_in'high loop
            if vec_in(i)='1' then
                ret(i) := '1';
                exit;
            end if;
        end loop;

        return ret;
    end get_first_one_in_vec;

    signal a            : std_logic_vector(N-1 downto 0);
    signal abar         : std_logic_vector(N-1 downto 0);

    signal first_a      : std_logic_vector(N-1 downto 0);
    signal first_nota   : std_logic_vector(N-1 downto 0);
    signal first_abar   : std_logic_vector(N-1 downto 0);
begin
    process
    begin
        a <= "10100";
        wait for 10 ns;
        a <= "01011";
        wait for 10 ns;
        wait;
    end process;

    abar        <= not(a);
    first_a     <= get_first_one_in_vec(a);
    first_nota  <= get_first_one_in_vec(not(a));
    first_abar  <= get_first_one_in_vec(abar);

end run;

据我了解,first_nota应该与first_abar相同。但是,我的模拟器(ModelSim-Intel FPGA Starter Edition 10.5b,修订版2016.10)认为不是这样,您可以在此处看到:

enter image description here


我在这里想念什么?

1 个答案:

答案 0 :(得分:3)

这可以正常工作:

function get_first_one_in_vec (vec_in: std_logic_vector) return std_logic_vector is
    variable ret: std_logic_vector(vec_in'length downto 1);
    variable inp: std_logic_vector(vec_in'length downto 1) := vec_in;
begin
    ret := (others => '0');
    for i in inp'right to inp'left loop
        if inp(i)='1' then
            ret(i) := '1';
            exit;
        end if;
    end loop;

    return ret;
end get_first_one_in_vec;

https://www.edaplayground.com/x/3zP_

您的为什么不工作?好吧,当您使用not运算符*作为表达式的一部分来调用函数时:

first_nota  <= get_first_one_in_vec(not a);

该函数的输入编号已由1 to运算符更改为not。为什么?这是not运算符的代码,您可以了解原因:

-------------------------------------------------------------------    
-- not
-------------------------------------------------------------------    
FUNCTION "not"  ( l : std_logic_vector ) RETURN std_logic_vector IS
    -- pragma built_in SYN_NOT
-- pragma subpgm_id 204
    --synopsys synthesis_off
    ALIAS lv : std_logic_vector ( 1 TO l'LENGTH ) IS l;
    VARIABLE result : std_logic_vector ( 1 TO l'LENGTH ) := (OTHERS => 'X');
    --synopsys synthesis_on
BEGIN
    --synopsys synthesis_off
    FOR i IN result'RANGE LOOP
        result(i) := not_table( lv(i) );
    END LOOP;
    RETURN result;
    --synopsys synthesis_on
END;
---------------------------------------------------------------------

无论如何,这会破坏您的代码(从单词的另一端开始扫描)。

使功能与输入的编号顺序无关的一种方法是对输入进行标准化,如下所示:

variable inp: std_logic_vector(vec_in'length downto 1) := vec_in;

完成此操作后,您就可以控制了。因此,我们可以更明确地从'high downto 'low 'right循环,而不是从to 'left for i in inp'right to inp'left loop 循环:

not

  • com.intershop.component.rest.capi.resource.AbstractRestResource运算符,而不是 function 。您不需要括号。