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.
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):
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.