Skip to content

Multiple sources error while assigning the output ports of a view array #1356

@davidgussler

Description

@davidgussler

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;

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions