Warning about getting "X"es for 4-valued logic VHDL

100 Views Asked by At

I am getting a warning that an arithmetic operation have X so the result is will always be X, although I am initializing my signals to 0s. Can anyone help?

N.B. I am getting X for Z_count and RC_count_var

--RC counter
LIBRARY ieee ;
USE ieee.std_logic_1164.all;
USE ieee.std_logic_unsigned.all;

Entity RC_counter2 is
    Port(load, Cplus, Cminus : In Std_logic;
        X: In std_logic_vector (3 downto 0) :="0000";
        Z_count: Out std_logic_vector (3 downto 0) :="0000");
end Entity;

Architecture behav of RC_counter2 is
    signal RC_count_var: std_logic_vector(3 downto 0):="0000";
    Begin
    process(Cplus, load)
        --variable RC_count_var: std_logic_vector(3 downto 0):="0000";

        Begin
            if load = '1' then
                RC_count_var <= X;
            end if;

            if (Cplus'EVENT and Cplus = '1') then
                RC_count_var <= RC_count_var + 1;
            else
                RC_count_var <= RC_count_var;
            end if;

        end process;

    process(Cminus, load)
        Begin

          if load = '1' then
                      RC_count_var <= X;
              end if;

         if (Cminus'EVENT and Cminus = '1') then
                    RC_count_var <= RC_count_var - 1; 
             else
                    RC_count_var <=RC_count_var;
             end if;

    end process;
 Z_count <= RC_count_var;
 end Architecture; 
1

There are 1 best solutions below

0
On BEST ANSWER

The value of RC_Count_var becomes invalid because it has multiple conflicting drivers.

In VHDL, whenever a signal is assigned in more than one process, it implies multiple drivers. These are usually not supported for synthesis and not recommended altogether. To make sure you do not have multiple drivers, simply makes all assignations to a signal in a single process.

Moreover, while not exactly wrong or problematic, I suggest you modify the following code:

if load = '1' then
    RC_count_var <= X;
end if;

if (Cplus'EVENT and Cplus = '1') then
    RC_count_var <= RC_count_var + 1;
else
    RC_count_var <= RC_count_var;
end if;

This doesn't gives multiple drivers, but has several problems. First, successive assignments to the same signal in a process overrides previous one. Thus, if cplus is rising and load is '1', the value doesn't get loaded. It is much better and cleaner to use elsif or else. Also, synthesis target doesn't usually support asynchronous load. Asynchronous set/reset is fine, but asynchronous load to the value X, in your case, is likely problematic.