VHDL:如何处理函数返回的无约束数组作为实体端口的输入?
VHDL: How to handle unconstrained arrays returned by functions as inputs to entity ports?
我正在尝试编写一些相当通用的 VHDL 代码,但我 运行
我不太了解标准的情况。 (我是
使用 VHDL-2008。)
我写了一个函数,可以在不受约束的情况下运行
std_logic_vector(s) 和 returns 一个不受约束的
std_logic_vector。但是,好像我无法使用它
如果我传递两个,则用作我实体中端口的输入
(constrained) std_logic_vectors 到它(参见 test_2 的实例化
我的示例程序)。但是,出于某种原因,如果我
将位字符串文字传递给它(参见 test_1 的实例化)。
有人可以解释为什么不允许我使用 concatenate()
在我被允许的情况下作为 test_2 实例化的输入
在 test_1?
的实例化中使用非常相似的结构
为了用 ModelSim 试用代码,我用 vcom -2008 unconstrained_example.vhd
编译了它
-- test entity/architecture
library ieee;
use ieee.std_logic_1164.all;
entity test is
port (value : in std_logic_vector);
end entity;
architecture a of test is
begin
-- Intentionally empty
end architecture;
library ieee;
use ieee.std_logic_1164.all;
-- Test instantiation
entity testit is
end entity;
architecture a of testit is
signal my_constrained_slv1 : std_logic_vector(5 downto 0);
signal my_constrained_slv2 : std_logic_vector(9 downto 0);
function concatenate(value1 : std_logic_vector; value2 : std_logic_vector) return std_logic_vector is
begin
return value1 & value2;
end function;
begin
process begin
-- Using the function in this context seems to work ok
report "Value is " & to_string(concatenate(my_constrained_slv1, my_constrained_slv2));
wait;
end process;
-- This instantiation seems to work
test_1: entity work.test
port map (
value => concatenate("000000", "1111111111"));
-- For this entity instantiation I'm getting an error from ModelSim:
-- ** Error: unconstrained_example.vhd(43): (vcom-1383) Implicit signal in port map for port "value" is not fully constrained.
test_2: entity work.test
port map (
value => concatenate(my_constrained_slv1, my_constrained_slv2));
end architecture;
您的函数调用不是转换函数,也不满足保留隐式信号声明的要求。
VHDL-2008 允许在端口关联中使用此类复杂表达式。该语言说,在这种情况下,将创建一个隐式信号:
If the actual part of a given association element for a formal signal port of a block is the reserved word inertial followed by an expression, or is an expression that is not globally static, then the given association element
is equivalent to association of the port with an anonymous signal implicitly declared in the declarative region that immediately encloses the block. The signal has the same subtype as the formal signal port and is the target of an implicit concurrent signal assignment statement of the form:
anonymous <= E;
where E is the expression in the actual part of the given association element. The concurrent signal assignment statement occurs in the same statement part as the block.
Source: IEEE-1076-2017 Draft 5a
signal temp : std_logic_vector; -- derived from the formal in the port association list
temp <= concatenate(my_constrained_slv1, my_constrained_slv2);
test_2: entity work.test
port map (
value => temp
);
end block;
问题是,VHDL 需要从端口关联列表 (value : std_logic_vector
) 中的形式推断隐式信号 temp
的类型。它知道,它是一个 std_logic_vector
,但由于端口不受约束,所以不知道约束。
因此,如果实体 test
中的端口 value
受到限制,它应该可以工作:
entity test is
port (
value : in std_logic_vector(15 downto 0)
);
end entity;
我想出了以下解决方法,虽然很丑但是
满足我不必手动指定的主要标准
任何宽度或重复任何信息。通过隐藏函数中的连接调用,我可以
重用该功能以进一步降低范围。一个简短的实验表明 Vivado 2015.4 也接受这个结构。
test_2_helper : block
impure function test_2_help_func return std_logic_vector is
begin
-- This is the only place I have to change in case the assignment has to
-- change in some way. (E.g. use other variables or become more complicated, etc.)
return concatenate(my_constrained_slv1, my_constrained_slv2);
end function;
signal test_2_helper_sig : std_logic_vector(test_2_help_func'range);
begin
test_2: entity work.test
port map (
-- It seems to be syntactically legal to use test_2_help_func(test_2_help_func'range)
-- here. Unfortunately this does not work in simulation. Probably because the
-- test_2_help_func does not have any explicit arguments and this may cause issues
-- with the event driven simulation. As a work around the test_2_helper_sig signal
-- is assigned every clock cycle below instead.
value => test_2_helper_sig);
process
begin
-- Note: If you remove the wait for the clock edge and instead use process(all)
-- test_2_helper_sig does not seem to change during simulation, at least in
-- Modelsim 10.6 where I tested this.
wait until rising_edge(clk);
test_2_helper_sig <= test_2_help_func;
end process;
end block;
注意:这是受以下答案的启发:
我正在尝试编写一些相当通用的 VHDL 代码,但我 运行 我不太了解标准的情况。 (我是 使用 VHDL-2008。)
我写了一个函数,可以在不受约束的情况下运行 std_logic_vector(s) 和 returns 一个不受约束的 std_logic_vector。但是,好像我无法使用它 如果我传递两个,则用作我实体中端口的输入 (constrained) std_logic_vectors 到它(参见 test_2 的实例化 我的示例程序)。但是,出于某种原因,如果我 将位字符串文字传递给它(参见 test_1 的实例化)。
有人可以解释为什么不允许我使用 concatenate() 在我被允许的情况下作为 test_2 实例化的输入 在 test_1?
的实例化中使用非常相似的结构为了用 ModelSim 试用代码,我用 vcom -2008 unconstrained_example.vhd
-- test entity/architecture
library ieee;
use ieee.std_logic_1164.all;
entity test is
port (value : in std_logic_vector);
end entity;
architecture a of test is
begin
-- Intentionally empty
end architecture;
library ieee;
use ieee.std_logic_1164.all;
-- Test instantiation
entity testit is
end entity;
architecture a of testit is
signal my_constrained_slv1 : std_logic_vector(5 downto 0);
signal my_constrained_slv2 : std_logic_vector(9 downto 0);
function concatenate(value1 : std_logic_vector; value2 : std_logic_vector) return std_logic_vector is
begin
return value1 & value2;
end function;
begin
process begin
-- Using the function in this context seems to work ok
report "Value is " & to_string(concatenate(my_constrained_slv1, my_constrained_slv2));
wait;
end process;
-- This instantiation seems to work
test_1: entity work.test
port map (
value => concatenate("000000", "1111111111"));
-- For this entity instantiation I'm getting an error from ModelSim:
-- ** Error: unconstrained_example.vhd(43): (vcom-1383) Implicit signal in port map for port "value" is not fully constrained.
test_2: entity work.test
port map (
value => concatenate(my_constrained_slv1, my_constrained_slv2));
end architecture;
您的函数调用不是转换函数,也不满足保留隐式信号声明的要求。
VHDL-2008 允许在端口关联中使用此类复杂表达式。该语言说,在这种情况下,将创建一个隐式信号:
If the actual part of a given association element for a formal signal port of a block is the reserved word inertial followed by an expression, or is an expression that is not globally static, then the given association element is equivalent to association of the port with an anonymous signal implicitly declared in the declarative region that immediately encloses the block. The signal has the same subtype as the formal signal port and is the target of an implicit concurrent signal assignment statement of the form:
anonymous <= E;
where E is the expression in the actual part of the given association element. The concurrent signal assignment statement occurs in the same statement part as the block.
Source: IEEE-1076-2017 Draft 5a
signal temp : std_logic_vector; -- derived from the formal in the port association list
temp <= concatenate(my_constrained_slv1, my_constrained_slv2);
test_2: entity work.test
port map (
value => temp
);
end block;
问题是,VHDL 需要从端口关联列表 (value : std_logic_vector
) 中的形式推断隐式信号 temp
的类型。它知道,它是一个 std_logic_vector
,但由于端口不受约束,所以不知道约束。
因此,如果实体 test
中的端口 value
受到限制,它应该可以工作:
entity test is
port (
value : in std_logic_vector(15 downto 0)
);
end entity;
我想出了以下解决方法,虽然很丑但是 满足我不必手动指定的主要标准 任何宽度或重复任何信息。通过隐藏函数中的连接调用,我可以 重用该功能以进一步降低范围。一个简短的实验表明 Vivado 2015.4 也接受这个结构。
test_2_helper : block
impure function test_2_help_func return std_logic_vector is
begin
-- This is the only place I have to change in case the assignment has to
-- change in some way. (E.g. use other variables or become more complicated, etc.)
return concatenate(my_constrained_slv1, my_constrained_slv2);
end function;
signal test_2_helper_sig : std_logic_vector(test_2_help_func'range);
begin
test_2: entity work.test
port map (
-- It seems to be syntactically legal to use test_2_help_func(test_2_help_func'range)
-- here. Unfortunately this does not work in simulation. Probably because the
-- test_2_help_func does not have any explicit arguments and this may cause issues
-- with the event driven simulation. As a work around the test_2_helper_sig signal
-- is assigned every clock cycle below instead.
value => test_2_helper_sig);
process
begin
-- Note: If you remove the wait for the clock edge and instead use process(all)
-- test_2_helper_sig does not seem to change during simulation, at least in
-- Modelsim 10.6 where I tested this.
wait until rising_edge(clk);
test_2_helper_sig <= test_2_help_func;
end process;
end block;
注意:这是受以下答案的启发: