在多个函数中使用一个变量?
Using a variable in more than one funciton?
可能是因为我是新人。无论如何,我想定义一些变量以在多个函数中使用(如 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;
在 VHDL 中(至少对于 VHDL '93 及更高版本),函数默认为 pure
。 pure
函数是一种没有副作用的函数。它仅取决于其输入,不依赖于(非静态)外部信息。
因此,您的解决方法是声明函数 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 的推理模型)。共享变量通常仅用于硬件或测试台建模的一般用途。
共享变量通常与受保护的类型一起使用,可以处理数据的封装。下面是一个使用保护类型的例子:
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
。
可能是因为我是新人。无论如何,我想定义一些变量以在多个函数中使用(如 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;
在 VHDL 中(至少对于 VHDL '93 及更高版本),函数默认为 pure
。 pure
函数是一种没有副作用的函数。它仅取决于其输入,不依赖于(非静态)外部信息。
因此,您的解决方法是声明函数 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 的推理模型)。共享变量通常仅用于硬件或测试台建模的一般用途。
共享变量通常与受保护的类型一起使用,可以处理数据的封装。下面是一个使用保护类型的例子:
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
。