VHDL如何工作变量

VHDL how work variable

我有一个关于奇怪行为的问题,

有什么区别

process(i_clk) 
variable s_sens_front :STD_LOGIC_VECTOR(1 downto 0):="00";
variable s_cons_prec : STD_LOGIC_VECTOR(9 downto 0):="0000000000";
    begin
    if rising_edge(i_clk) then
        if (s_sens_front = "01" or s_sens_front = "10") then
            s_consigne <= i_consigne;
            s_cons_prec := i_consigne;
        else
            s_consigne <= s_cons_prec;
        end if;
        s_sens_front := s_sens_front(0) & i_sens;
    end if;

end process;

process(i_clk) 
variable s_sens_front :STD_LOGIC_VECTOR(1 downto 0):="00";
variable s_cons_prec : STD_LOGIC_VECTOR(9 downto 0):="0000000000";
    begin
    if rising_edge(i_clk) then
        if (s_sens_front = "01" or s_sens_front = "10") then
            s_consigne <= i_consigne;
        else
            s_consigne <= s_cons_prec;
        end if;
        s_sens_front := s_sens_front(0) & i_sens;

        s_cons_prec := s_consigne;
    end if;

end process;

因为对我来说两者看起来完全一样... 但是在我测试 s_consigne 是否比其他信号大后,第一个工作正常,但第二个版本不工作......没有更多变化。

周围的代码是

process(i_clk) 
variable s_H_prec :STD_LOGIC; 
    begin
    if rising_edge(i_clk) then

            if (i_triangle >= s_consigne) then
                s_H <='0';
            else
                s_H <= '1';
            end if;
    s_H_prec := S_H;
    end if;
end process;

i_triangle 和 i_sens 是在这里制作的

process(i_clk)
variable s_triangle                 : unsigned (9 downto 0):="1000000000";
variable s_triangle_temp        : unsigned (9 downto 0):="1000000000";
variable s_sens_temp        : std_logic;
variable s_ratio_max        : unsigned (9 downto 0):="1111111111";
variable s_sens                 : std_logic; -- Signal qui indique si le triangle doit monter ou descendre

    begin


    if rising_edge(i_clk) then
        if i_reset_n = '0' then -- quand reset on remet tout au valeur du début

            s_sens := i_sens;
            s_triangle := i_init;--valeur du triangle qui va évolué
            s_triangle_temp := i_init;--valeur du triangle du début mémorisé
            s_sens_temp := i_sens;--valeur du sens mémorisé

        else

            if (s_triangle_temp = s_triangle and s_sens = s_sens_temp) then -- si on a fait une période compléte
                                                            -- on donne la nouvelle valeur si elle existe
                if (i_sens = '1') then
                    s_triangle := i_init + 1;
                else
                    s_triangle := i_init -1;
                end if;
                s_sens := i_sens;
                s_triangle_temp := i_init;--valeur du triangle du début mémorisé
                s_sens_temp := i_sens;--valeur du sens mémorisé

            else 

                if s_triangle >= s_ratio_max then --si le compteur est plus grand ou égal au max alors
                    s_sens := '0';              -- on indique qu'il faut décompter
                    s_triangle := s_ratio_max -1; -- on va à la valeur max -1

                elsif s_triangle = "0000000000" then
                    s_sens := '1';
                    s_triangle := "0000000001";

                    s_ratio_max := i_ratio_max;-- on ne le prend que quand on est au minimum
                elsif s_sens = '1' then
                    s_triangle := s_triangle + 1;

                else
                    s_triangle := s_triangle - 1;
                end if;
            end if;
        end if;
        o_sens <= s_sens;
        o_triangle <= s_triangle;
    end if;

end process;

i_init 和 i_sens 是可变的,我用 vjtag 和 GUI 改变

S_H 的输出在此处

process(i_clk) 
variable s_compteurH: UNSIGNED (9 downto 0) := "0000000000";
variable s_compteurL: UNSIGNED (9 downto 0) := "0000000000";
variable S_H            : STD_LOGIC;
variable S_L        : STD_LOGIC;
    begin
        if rising_edge(i_clk) then
            if (i_reset_n = '0') then
                O_L <= '0';
                O_H <= '0';
            else


                if (i_h = '0') then
                    S_H := '0';
                    s_compteurH := "0000000000";

                    if (s_compteurL >= i_retard) then
                        S_L := '1';
                    else
                        s_compteurL := s_compteurL +1;
                    end if;


                else

                    S_L := '0';
                    s_compteurL := "0000000000";

                    if (s_compteurH >= i_retard) then
                        S_H := '1';
                    else
                        s_compteurH := s_compteurH +1 ;
                    end if;

                end if;

            end if;
            o_H <= S_H;
            o_L <= S_L;

        end if;

end process;

我在示波器上看到 O_H 和 O_L。在这两种情况下,行为是不同的,我知道我明白,谢谢 Staszek 问题是在进程中只有最后一次分配给 signal 才真正发生,并且在进程完成后会有新的值。它与变量不同,变量的赋值立即发生。所以在 s_cons_prec := s_consigne; s_consigne 仍然具有旧值。

好吧,这个问题问得不是很好,没有 Minimal Complete Verifable Example,但我想,您不知道信号是如何工作的。问题是在进程中只有最后一次分配给 signal 才真正发生,并且在进程完成后会有新的值。它与变量不同,变量的赋值立即发生。所以在 s_cons_prec := s_consigne; s_consigne 中仍然有旧值。