-
-
Notifications
You must be signed in to change notification settings - Fork 96
Description
I've just started to dive into the new VHDL'19 features, so forgive me if this issue is caused my lack of understanding of the new LRM, rather than a tool bug. I don't have access to any other VHDL'19 simulators, so I can't try to reproduce with a different simulator.
OS: Ubuntu24.04
NVC Version: Compiled from main branch nvc 1.19-devel (1.18.0.r80.gce2345655) (Using LLVM 18.1.3)
Minimal code to reproduce the error:
-- File : axis_pkg.vhd
library ieee;
use ieee.std_logic_1164.all;
package axis_pkg is
-- AXI-Stream element type
type axis_t is record
tready : std_ulogic;
tvalid : std_ulogic;
tdata : std_ulogic_vector;
end record;
-- AXI-Stream array
type axis_arr_t is array (natural range <>) of axis_t;
-- Manager view
view m_axis_v of axis_t is
tready : in;
tvalid : out;
tdata : out;
end view;
-- Subordinate view
alias s_axis_v is m_axis_v'converse;
end package;
-- File: axis_mux.vhd
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.axis_pkg.all;
entity axis_mux is
port (
s_axis : view (s_axis_v) of axis_arr_t;
m_axis : view m_axis_v;
sel : in integer range s_axis'range
);
end entity;
architecture rtl of axis_mux is
begin
select_comb : process(all) begin
m_axis.tvalid <= s_axis(sel).tvalid;
m_axis.tdata <= s_axis(sel).tdata;
for i in s_axis'range loop
-- Removing this line stops the error from printing
s_axis(i).tready <= '1' when m_axis.tready = '1' and (sel = i) else '0';
end loop;
end process;
end architecture;
-- File: axis_mux_tb.vhd
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.axis_pkg.all;
entity axis_mux_tb is
end;
architecture tb of axis_mux_tb is
signal s_axis : axis_arr_t(0 to 3)(tdata(15 downto 0));
signal m_axis : axis_t(tdata(15 downto 0));
signal sel : integer range s_axis'range := 0;
begin
main : process begin
wait for 10 us;
assert false
report "Simulation done"
severity failure;
end process;
u_axis_mux : entity work.axis_mux
port map (
s_axis => s_axis,
m_axis => m_axis,
sel => sel
);
end architecture;
Running this script:
# File: nvc.sh
nvc --std=2019 -a axis_pkg.vhd axis_mux.vhd axis_mux_tb.vhd
nvc --std=2019 -e axis_mux_tb
nvc --std=2019 -r axis_mux_tb
Produces this output:
** Fatal: (init): element TVALID of signal S_AXIS has multiple sources
> axis_mux.vhd:10
|
10 | s_axis : view (s_axis_v) of axis_arr_t;
| ^^^^^^ composite signal S_AXIS declared with unresolved type AXIS_ARR_T
...
20 | select_comb : process(all) begin
| ^ driven by process :axis_mux_tb:u_axis_mux:select_comb
|
= Note: connected to signal S_AXIS
> axis_mux_tb.vhd:14
= Note: element TVALID declared here
> axis_pkg.vhd:11
Which is confusing to me, because the input s_axis(i).tvalid signal is clearly never assigned by the entity, so its hard to see what multiple sources means here.
If I remove this line s_axis(i).tready <= '1' when m_axis.tready = '1' and (sel = i) else '0'; then the error message goes away, which makes it look like nvc does not allow assigning output view elements of record arrays.
As a another test, I created a minimal pass-through module, that only uses one input element, rather than an array of input elements, and nvc ran the design as expected, without any errors:
-- File: axis_passthru.vhd
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.axis_pkg.all;
entity axis_passthru is
port (
s_axis : view s_axis_v;
m_axis : view m_axis_v
);
end entity;
architecture rtl of axis_passthru is
begin
m_axis.tvalid <= s_axis.tvalid;
m_axis.tdata <= s_axis.tdata;
s_axis.tready <= m_axis.tready;
end architecture;