Home > Mobile >  Multiple processes driving an array of records in VHDL-2008
Multiple processes driving an array of records in VHDL-2008

Time:10-04

The following code showcases an array of records. The particularity is that for each element of the array, the field AR is driven by the process process_AR while the field R is driven by the process process_R.

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;

This code works as (I) expected. Waveform, first code However, change the process_AR by the following (using a for loop now):

-- 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;

When using resolved types (std_ulogic and std_ulogic_vector), this new code fails:

(vsim-3344) Signal "/test_entity/axil_read_channel(0).R.ready" has multiple drivers but is not a resolved signal.

I guess the for loop does not work because the it is sort of a 'dynamical' assignment and therefore axil_read_channel is considered instead of axil_read_channel(i) ? On the other hand, the first version of the code (with hard coded '0' and '1') uses sort of 'static' assignment and therefore considers the two elements axil_read_channel(0) and axil_read_channel(1) as two signals and not element of an array ?

When using non-resolved types (std_logic and std_logic_vector): Waveform, second code, when using non-resolved types (std_logic and std_logic_vector)

What is the reason behind the difference of behavior between the first code and second code ?

Is there a work around not involving for-generate (not applicable to my current design) for synthesis ?

CodePudding user response:

When you use a loop in a process to drive a signal of a composite type (array or record), the elaboration cannot determine which specific objects require a driver at elaboration time, hence it has to assume all objects within the composite type require a driver. This then creates a driver for the entire array/record, rather than each element that would have occured without the loop.

This is what is causing your error when you use resolved/unresolved types. The errors occurs with the unresolved types std_ulogic(_vector) because they are not allowed multiple drivers. The resolved types std_logic(_vector) are allowed multiple drivers and all of the elements undriven by you will have 'U' driven on them.

  • Related