多个进程驱动一组记录

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