在多个函数中使用变量?

时间:2016-06-04 09:22:30

标签: function variables process vhdl modelsim

这可能是因为我是新生儿。无论如何,我想定义一些变量用于多个函数(如C中的全局变量)。我决定使用共享变量,但它给了我错误Cannot reference shared variable "x" inside pure function "y"。如果我在进程中定义变量,那么它会在每次进程激活时初始化(擦除值)。

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;

2 个答案:

答案 0 :(得分:2)

在VHDL中(至少使用VHDL '93及更高版本),默认情况下函数为purepure函数是没有副作用的函数。它仅取决于其输入,不依赖于(非静态)外部信息。

因此,您的修复方法是声明函数impure。我必须对你的例子进行一些编辑才能使它成为MCVE。修复:

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;

注意这仅适用于VHDL '93。 shared variable的使用在VHDL '02及更高版本中发生了显着变化。

最后一点说明。共享变量通常不可合成(我能想到的唯一例子是RAM的推理模型)。共享变量通常仅用于硬件或测试平台建模中的通用目的。

答案 1 :(得分:1)

共享变量通常采用受保护类型,可以处理数据封装。使用受保护类型的示例如下所示:

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;

要访问内部temp数据,可以根据需要编写函数get_temp