Search code examples
functionvariablesprocessvhdlmodelsim

Using a variable in more than one funciton?


it is probably because of me being newbe. Anyways, I want to define some variables to use in more than one function (like global variables in C). I decided to go with shared variables but it gives me the error Cannot reference shared variable "x" inside pure function "y". If I define the variable in a process, then it initializes(erases the value) every process activation.

Architecture SV_example of example is

shared variable temp:std_logic_vector(18 downto 0):= "0000000000000000000";
SIGNAL gct: STD_LOGIC_VECTOR(18 DOWNTO 0);

    function register_adder( load_value:std_logic ) return std_logic_vector is      
    begin   
        for i in size downto 0 loop 
            temp(i) := load_value;
        end loop;
     return temp;            
    end register_adder;


    p1 : process (CLK)
    begin
      if rising_edge(CLK) then
        gct <= register_loader('1'); 
   end if;
   end process;
end SV_example;

Solution

  • In VHDL (at least with VHDL '93 and later), functions are pure by default. A pure function is one that has no side effects. It depends only on its inputs, with no dependency on (non-static) outside information.

    So, your fix is to declare the function impure. I had to do some editing to your example to make it an MCVE. The fix:

    library ieee;
    use ieee.std_logic_1164.all;
    
    entity example is
      port
      (
        CLK : in std_logic
      );
    end entity example;
    
    Architecture SV_example of example is
    
    shared variable temp:std_logic_vector(18 downto 0):= "0000000000000000000";
    SIGNAL gct: STD_LOGIC_VECTOR(18 DOWNTO 0);
    
        impure function register_adder( load_value:std_logic ) return std_logic_vector is
        begin
            for i in temp'length-1 downto 0 loop
                temp(i) := load_value;
            end loop;
         return temp;
        end register_adder;
    begin
    
    
        p1 : process (CLK)
        begin
          if rising_edge(CLK) then
            gct <= register_adder('1');
       end if;
       end process;
    end SV_example;
    

    Note this works only in VHDL '93. The use of a shared variable changes significantly in VHDL '02 and later.

    One final note. Shared variables generally are not synthesizable (the only example I can think of is the inference model for a RAM). Shared variables are usually only for general purpose use in hardware or testbench modeling.