多个进程驱动一组记录
Multiple processes driving an array of records
以下代码展示了一组记录。特殊之处在于,对于数组的每个元素,字段AR
由进程process_AR
驱动,而字段R
由进程process_R
.[=25驱动=]
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity test_entity is
end entity;
architecture RTL of test_entity is
-- Try with std_ulogic_vector or std_logic_vector
subtype slv is std_logic_vector;
subtype stdl is slv'element;
type AR_record_t is record
valid : stdl;
addr : slv(15 downto 0);
end record;
type R_record_t is record
ready : stdl;
data : slv(31 downto 0);
end record;
type axil_record_t is record
AR : AR_record_t;
R : R_record_t;
end record;
type array_of_axil_record_t is array(natural range <>) of axil_record_t;
signal axil_read_channel : array_of_axil_record_t(0 to 1);
begin
-- Process only deal with the AR channel
process_AR : process
begin
wait for 20 ps;
axil_read_channel(0).AR <= (valid => '1', addr => X"CAFE");
axil_read_channel(1).AR <= (valid => '0', addr => X"DEAD");
end process;
-- Process only deal with the R channel
process_R : process
begin
wait for 20 ps;
axil_read_channel(0).R <= (ready => '0', data => X"12345678");
axil_read_channel(1).R <= (ready => '1', data => X"89ABCDEF");
end process;
end architecture;
此代码按 (I) 预期的方式工作。
但是,通过以下方式更改 process_AR(现在使用 for loop
):
-- Process only deal with the AR channel
process_AR : process
begin
wait for 20 ps;
for i in axil_read_channel'range loop
axil_read_channel(i).AR <= (valid => '1', addr => X"CAFE");
end loop;
end process;
使用未解析类型(std_ulogic 和 std_ulogic_vector)时,此新代码失败:
(vsim-3344) Signal "/test_entity/axil_read_channel(0).R.ready" has multiple drivers but is not a resolved signal.
我猜 for loop
不起作用,因为它是一种 'dynamical' 赋值,因此 axil_read_channel
被考虑而不是 axil_read_channel(i)
?
另一方面,代码的第一个版本(带有硬编码的“0”和“1”)使用某种 'static' 赋值,因此将 axil_read_channel(0)
和 axil_read_channel(1)
这两个元素视为两个信号而不是数组的元素?
使用解析类型时(std_logic 和 std_logic_vector):
第一个代码和第二个代码之间的行为差异背后的原因是什么?
是否有解决方案不涉及用于合成的 for-generate(不适用于我当前的设计)?
当你在进程中使用loop
来驱动复合类型(数组或记录)的信号时,细化无法确定哪些特定对象在细化时需要驱动程序,因此它必须假设复合类型中的所有对象都需要一个驱动程序。然后,这会为整个 array/record 创建一个驱动程序,而不是为没有循环的每个元素创建一个驱动程序。
这就是导致您在使用 resolved/unresolved 类型时出错的原因。未解析的类型 std_ulogic(_vector)
会出现错误,因为它们不允许有多个驱动程序。已解析的类型 std_logic(_vector)
允许有多个驱动程序,所有未由您驱动的元素都将有 'U'
驱动。
针对您的问题,是否有解决方法。大概。您的工具是否支持具有无约束元素的 VHDL-2008 聚合?如果是,以下可能有效(尚未尝试):
-- continuing from your above declarations:
type array_of_AR_record_t is array(natural range <>) of AR_record_t;
type array_of_R_record_t is array(natural range <>) of R_record_t;
type axil_record_t is record
AR : array_of_AR_record_t;
R : array_of_AR_record_t;
end record;
signal axil_read_channel : axil_record_t (AR(0 to 1), R(0 to 1)) ;
. . .
-- Process only deal with the AR channel
process_AR : process
begin
wait for 20 ps;
for i in axil_read_channel.AR'range loop
axil_read_channel.AR(i) <= (valid => '1', addr => X"CAFE");
end loop;
end process;
我们正在研究下一个修订版中的语言更改,以帮助简化声明。参见:https://gitlab.com/IEEE-P1076/VHDL-Issues/-/issues/81
以下代码展示了一组记录。特殊之处在于,对于数组的每个元素,字段AR
由进程process_AR
驱动,而字段R
由进程process_R
.[=25驱动=]
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity test_entity is
end entity;
architecture RTL of test_entity is
-- Try with std_ulogic_vector or std_logic_vector
subtype slv is std_logic_vector;
subtype stdl is slv'element;
type AR_record_t is record
valid : stdl;
addr : slv(15 downto 0);
end record;
type R_record_t is record
ready : stdl;
data : slv(31 downto 0);
end record;
type axil_record_t is record
AR : AR_record_t;
R : R_record_t;
end record;
type array_of_axil_record_t is array(natural range <>) of axil_record_t;
signal axil_read_channel : array_of_axil_record_t(0 to 1);
begin
-- Process only deal with the AR channel
process_AR : process
begin
wait for 20 ps;
axil_read_channel(0).AR <= (valid => '1', addr => X"CAFE");
axil_read_channel(1).AR <= (valid => '0', addr => X"DEAD");
end process;
-- Process only deal with the R channel
process_R : process
begin
wait for 20 ps;
axil_read_channel(0).R <= (ready => '0', data => X"12345678");
axil_read_channel(1).R <= (ready => '1', data => X"89ABCDEF");
end process;
end architecture;
此代码按 (I) 预期的方式工作。
for loop
):
-- Process only deal with the AR channel
process_AR : process
begin
wait for 20 ps;
for i in axil_read_channel'range loop
axil_read_channel(i).AR <= (valid => '1', addr => X"CAFE");
end loop;
end process;
使用未解析类型(std_ulogic 和 std_ulogic_vector)时,此新代码失败:
(vsim-3344) Signal "/test_entity/axil_read_channel(0).R.ready" has multiple drivers but is not a resolved signal.
我猜 for loop
不起作用,因为它是一种 'dynamical' 赋值,因此 axil_read_channel
被考虑而不是 axil_read_channel(i)
?
另一方面,代码的第一个版本(带有硬编码的“0”和“1”)使用某种 'static' 赋值,因此将 axil_read_channel(0)
和 axil_read_channel(1)
这两个元素视为两个信号而不是数组的元素?
使用解析类型时(std_logic 和 std_logic_vector):
第一个代码和第二个代码之间的行为差异背后的原因是什么?
是否有解决方案不涉及用于合成的 for-generate(不适用于我当前的设计)?
当你在进程中使用loop
来驱动复合类型(数组或记录)的信号时,细化无法确定哪些特定对象在细化时需要驱动程序,因此它必须假设复合类型中的所有对象都需要一个驱动程序。然后,这会为整个 array/record 创建一个驱动程序,而不是为没有循环的每个元素创建一个驱动程序。
这就是导致您在使用 resolved/unresolved 类型时出错的原因。未解析的类型 std_ulogic(_vector)
会出现错误,因为它们不允许有多个驱动程序。已解析的类型 std_logic(_vector)
允许有多个驱动程序,所有未由您驱动的元素都将有 'U'
驱动。
针对您的问题,是否有解决方法。大概。您的工具是否支持具有无约束元素的 VHDL-2008 聚合?如果是,以下可能有效(尚未尝试):
-- continuing from your above declarations:
type array_of_AR_record_t is array(natural range <>) of AR_record_t;
type array_of_R_record_t is array(natural range <>) of R_record_t;
type axil_record_t is record
AR : array_of_AR_record_t;
R : array_of_AR_record_t;
end record;
signal axil_read_channel : axil_record_t (AR(0 to 1), R(0 to 1)) ;
. . .
-- Process only deal with the AR channel
process_AR : process
begin
wait for 20 ps;
for i in axil_read_channel.AR'range loop
axil_read_channel.AR(i) <= (valid => '1', addr => X"CAFE");
end loop;
end process;
我们正在研究下一个修订版中的语言更改,以帮助简化声明。参见:https://gitlab.com/IEEE-P1076/VHDL-Issues/-/issues/81