Search code examples
variablesvhdlpropagation

VHDL how work variable


i have a question about à strange behaviour,

what the difference between

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;

and

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;

because for me both seem exactly the same... but after i make a test if s_consigne is bigger than an other signal, and the first work correctly, but not the second version... with no more change.

the code around is

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;

the i_triangle and i_sens was made here

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 and i_sens are variable i change with a vjtag and a GUI

and the output of S_H go here

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;

and i see the O_H and O_L on oscilloscope. and in the two case the behaviour was different, and know i understand, thanks Staszek The thing is that in process only the last assignment to signal really happens, and new value will be there after the process completes. It is different to variables, where assignment happens immediately. So in s_cons_prec := s_consigne; s_consigne still has old value.


Solution

  • Well, this is not very well asked question, there is no Minimal Complete Verifable Example, but I guess, you don't know how signals works. The thing is that in process only the last assignment to signal really happens, and new value will be there after the process completes. It is different to variables, where assignment happens immediately. So in s_cons_prec := s_consigne; s_consigne still has old value.