2

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;
  • I put an answer to how to get rid of the error. But I'm not sure of your goal here. Your example above does not need `temp`, since you use the return value from the function. Post a more complete example and we can help analyze your use case better. – PlayDough Jun 04 '16 at 12:22
  • You are right. Example above is not clear to point my requirement. I just need a global variable to reach from every function in architecture. – ismylhakkituran Jun 04 '16 at 13:22
  • 3
    What do you need a architecture wide variable as opposed to a `signal`? What are you trying to accomplish by sharing information through a `shared variable`. If you need some sort of state information, I suggest looking at `protected` types in VHDL-2002 and later. – PlayDough Jun 04 '16 at 13:27
  • Thanks for the recommendation. Something about encapsulation is gonna be more useful for future works. – ismylhakkituran Jun 04 '16 at 15:26

2 Answers2

2

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.

Community
  • 1
  • 1
PlayDough
  • 1,116
  • 8
  • 16
1

Shared variable often goes with protected types, which can handle encapsulation of data. An example using protected type is shown below:

architecture SV_example of example is

  signal gct           : std_logic_vector(18 downto 0);

  type temp_t is protected
    impure function register_adder(load_value : std_logic) return std_logic_vector;
  end protected;

  type temp_t is protected body
    variable temp : std_logic_vector(18 downto 0) := (others => '0');
    impure function register_adder(load_value : std_logic) return std_logic_vector is
    begin
      for i in temp'range loop
        temp(i) := load_value;
      end loop;
      return temp;
    end function;
  end protected body;

  shared variable temp_sv : temp_t;

begin

  p1 : process (CLK)
  begin
    if rising_edge(CLK) then
      gct <= temp_sv.register_adder('1');
    end if;
  end process;

end SV_example;

For access to the internal temp data, a function get_temp can be written, if needed.

Morten Zilmer
  • 15,586
  • 3
  • 30
  • 49