nickg / nvc

VHDL compiler and simulator
https://www.nickg.me.uk/nvc/
GNU General Public License v3.0
636 stars 80 forks source link

Fail to elaborate when a port map has an interface view broken out as individual associations #1074

Closed Aaron-Hartwig closed 1 week ago

Aaron-Hartwig commented 1 week ago

Example (from here):

A0 : my_component
PORT MAP(
  clk => CLK, 
  data.input_one => IONE, 
  data.input_two => ITWO, 
  data.input_rst => RST, 
  result.output_one => OONE, 
  result.output_dn => ODN
);

When something like that is done nvc fails out like this:

nvc: ../src/lower.c:931: lower_for_each_field_2: Assertion `vcode_reg_kind(rec1_ptr) == VCODE_TYPE_POINTER' failed.

*** Caught signal 6 (SIGABRT) ***

[0x5e52ef3ab32b] ../src/util.c:897 signal_handler
[0x763e5a04251f] (/usr/lib/x86_64-linux-gnu/libc.so.6) 
[0x763e5a0969fc] (/usr/lib/x86_64-linux-gnu/libc.so.6) ./nptl/pthread_kill.c:44 __pthread_kill_implementation
[0x763e5a0969fc] (/usr/lib/x86_64-linux-gnu/libc.so.6) ./nptl/pthread_kill.c:78 __pthread_kill_internal
[0x763e5a0969fc] (/usr/lib/x86_64-linux-gnu/libc.so.6) ./nptl/pthread_kill.c:89 pthread_kill@@GLIBC_2.34
[0x763e5a042475] (/usr/lib/x86_64-linux-gnu/libc.so.6) ../sysdeps/posix/raise.c:26 raise
[0x763e5a0287f2] (/usr/lib/x86_64-linux-gnu/libc.so.6) ./stdlib/abort.c:79 abort
[0x763e5a02871a] (/usr/lib/x86_64-linux-gnu/libc.so.6) ./assert/assert.c:92 __assert_fail_base.cold
[0x763e5a039e95] (/usr/lib/x86_64-linux-gnu/libc.so.6) ./assert/assert.c:101 __assert_fail
[0x5e52ef43f0bc] ../src/lower.c:931 lower_for_each_field_2
[0x5e52ef4652fc] ../src/lower.c:12049 lower_port_map
[0x5e52ef466d0d] ../src/lower.c:12501 lower_ports
[0x5e52ef468cca] ../src/lower.c:13118 lower_instance
[0x5e52ef417a79] ../src/elab.c:1443 elab_lower
[0x5e52ef418207] ../src/elab.c:1560 elab_architecture
[0x5e52ef418d73] ../src/elab.c:1735 elab_instance
[0x5e52ef41a3af] ../src/elab.c:2122 elab_stmts
[0x5e52ef418239] ../src/elab.c:1562 elab_architecture
[0x5e52ef418d73] ../src/elab.c:1735 elab_instance
[0x5e52ef41a3af] ../src/elab.c:2122 elab_stmts
[0x5e52ef418239] ../src/elab.c:1562 elab_architecture
[0x5e52ef41af40] ../src/elab.c:2337 elab
[0x5e52ef3a17fd] ../src/nvc.c:504 elaborate
[0x5e52ef3a57f7] ../src/nvc.c:2185 process_command
[0x5e52ef3a5d37] ../src/nvc.c:2345 main

This is perhaps described in IEEE1076-2019 in 6.5.7.1?

nickg commented 1 week ago

Have you got a more complete example? This does work at least in simple cases. E.g. see test/regress/record24.vhd.

Aaron-Hartwig commented 1 week ago

I was sloppy in my language here. My specific example was utilizing views of records, not raw records. I will get a proper example together. But in the meantime here is something stream of consciousness.

So given an interface definition of

package streaming_if_pkg is
    generic (
        DATA_WIDTH : integer
    );

    type data_channel is record
        data    : std_logic_vector(DATA_WIDTH - 1 downto 0);
        valid   : std_logic;
        ready   : std_logic;
    end record;

    view st_source_if of data_channel is
        valid, data : out;
        ready       : in;
    end view;

    alias st_sink_if is st_source_if'converse;

end package;

package stream8_pkg is new work.streaming_if_pkg generic map (DATA_WIDTH => 8);

If I had an entity like

use work.stream8_pkg;

entity example is
    port (
        clk         : in  std_logic;
        tx_st_if    : view stream8_pkg.st_sink_if;
        rx_st_if    : view stream8_pkg.st_source_if;
    );
end entity;

The following instantiation would break as shown in my initial message

example_inst: example
    port map (
        clk => clk,
        tx_st_if.valid => txd_valid,
        tx_st_if.data => txd,
        tx_st_if.ready => sink_ready,
        rx_st_if.valid => rxd_valid,
        rx_st_if.data => rxd,
        rx_st_if.ready => source_ready
    );
Aaron-Hartwig commented 1 week ago

Here is a reproducer.

test_pkg.vhd

library ieee;
use ieee.std_logic_1164.all;

package test_pkg is

    type test_record is record
        sig1 : std_logic;
        sig2 : std_logic;
    end record;

    view source of test_record is
        sig1 : out;
        sig2 : out;
    end view;

    alias sink is source'converse;

end package;

test.vhd

use work.test_pkg.all;

entity test_source is
    port (
        src : view source
    );
end entity;

architecture rtl of test_source is

begin

end architecture;

use work.test_pkg.all;

entity test_sink is
    port (
        snk : view sink
    );
end entity;

architecture rtl of test_sink is

begin

end architecture;

library ieee;
use ieee.std_logic_1164.all;
use work.test_pkg.all;
use work.test_source;
use work.test_sink;

entity test_top is
end entity;

architecture rtl of test_top is
    signal s1 : std_logic;
    signal s2 : std_logic;
begin
    test_source_inst: entity work.test_source
        port map(
            src.sig1 => s1,
            src.sig2 => s2
        );

    test_sink_inst: entity work.test_sink
        port map(
            snk.sig1 => s1,
            snk.sig2 => s2
        );

end architecture;
> nvc --std=2019 -a test_pkg.vhd test.vhd
> nvc --std=2019 -e TEST_TOP-RTL
nvc: ../src/lower.c:931: lower_for_each_field_2: Assertion `vcode_reg_kind(rec1_ptr) == VCODE_TYPE_POINTER' failed.

*** Caught signal 6 (SIGABRT) ***

[0x5c6a18d7332b] ../src/util.c:897 signal_handler
[0x72d26ce4251f] (/usr/lib/x86_64-linux-gnu/libc.so.6) 
[0x72d26ce969fc] (/usr/lib/x86_64-linux-gnu/libc.so.6) ./nptl/pthread_kill.c:44 __pthread_kill_implementation
[0x72d26ce969fc] (/usr/lib/x86_64-linux-gnu/libc.so.6) ./nptl/pthread_kill.c:78 __pthread_kill_internal
[0x72d26ce969fc] (/usr/lib/x86_64-linux-gnu/libc.so.6) ./nptl/pthread_kill.c:89 pthread_kill@@GLIBC_2.34
[0x72d26ce42475] (/usr/lib/x86_64-linux-gnu/libc.so.6) ../sysdeps/posix/raise.c:26 raise
[0x72d26ce287f2] (/usr/lib/x86_64-linux-gnu/libc.so.6) ./stdlib/abort.c:79 abort
[0x72d26ce2871a] (/usr/lib/x86_64-linux-gnu/libc.so.6) ./assert/assert.c:92 __assert_fail_base.cold
[0x72d26ce39e95] (/usr/lib/x86_64-linux-gnu/libc.so.6) ./assert/assert.c:101 __assert_fail
[0x5c6a18e070bc] ../src/lower.c:931 lower_for_each_field_2
[0x5c6a18e2d2fc] ../src/lower.c:12049 lower_port_map
[0x5c6a18e2ed0d] ../src/lower.c:12501 lower_ports
[0x5c6a18e30cca] ../src/lower.c:13118 lower_instance
[0x5c6a18ddfa79] ../src/elab.c:1443 elab_lower
[0x5c6a18de0207] ../src/elab.c:1560 elab_architecture
[0x5c6a18de0d73] ../src/elab.c:1735 elab_instance
[0x5c6a18de23af] ../src/elab.c:2122 elab_stmts
[0x5c6a18de0239] ../src/elab.c:1562 elab_architecture
[0x5c6a18de2f40] ../src/elab.c:2337 elab
[0x5c6a18d697fd] ../src/nvc.c:504 elaborate
[0x5c6a18d6d7f7] ../src/nvc.c:2185 process_command
[0x5c6a18d6dd37] ../src/nvc.c:2345 main
nickg commented 1 week ago

Should be fixed now. Can you test again with the latest master branch?

Aaron-Hartwig commented 4 days ago

Sorry for the delay here, but I can confirm it now works on latest master! Thanks again.