Skip to content

Unused, undefined foreign function makes elaboration fail #793

@umarcor

Description

@umarcor

Is your feature request related to a problem? Please describe.

In the MWE below, both get_param and get_addr are defined as foreign functions (VHPIDIRECT). Both of them have placeholder assertions that are expected to make the execution fail at runtime, if no C implementation is provided during elaboration. However, it fails during elaboration, not at runtime.

Describe the solution you'd like

These are the use cases I am trying to evaluate:

  • C implementations are not provided and functions are not used in the testbench. No error should be produced. Although I'd expect two warnings to be shown during elaboration.
  • C implementations are not provided and functions are used in the testbench. I'd expect two warnings to be shown during elaboration and an (assertion) error to be produced at runtime.
  • C implementations are provided (no matter if functions are used or not). No warnings should be shown during elaboration and no assertion error should be produced at runtime.

Describe alternatives you've considered

Note that the error during elaboration is produced by get_addr, because GHDL expects it to be used in buffet_t_prot.init(i: integer), even though this is not true. However, get_param does not produce any error, because GHDL is sure about it not being used at all. I think that none of them should fail.

Alternative I have considered are:

  • Provide two different sources, one without foreign functions at all, and another one that includes them along with the 'default' version. However, I'd lke to avoid it, as this would require recompiling multiple sources that depend on this.
  • Provide a stubs.c file. I'd also like to avoid this, since it would required to compile it.

Additional context

The context of this request is VUnit/vunit#462. In order to support different implementations of certain functions, some relying on foreign functions and some not, a variable is checked in an if-then-else statement. If the value implies that the design was elaborated with C implementations, the foreign functions are used. Otherwise, they are not. Therefore, I need GHDL to let the user elaborate a design with foreign functions without an actual C implementation, as long as he/she knows that those functions will not be used.


#>> run.sh

cat > pkg_c.vhd <<-EOF
package pkg_c is
  function get_param(f: integer) return integer;
    attribute foreign of get_param :
      function is "VHPIDIRECT get_param";

  type buffer_t is array(integer range <>) of integer;
  type buffer_p is access buffer_t;

  impure function get_addr(f: integer) return buffer_p;
    attribute foreign of get_addr :
      function is "VHPIDIRECT get_addr";

  type buffet_t_prot is protected
    procedure init ( i: integer );
  end protected buffet_t_prot;
end pkg_c;

package body pkg_c is
  function get_param(f: integer) return integer is begin
    assert false report "VHPI" severity failure;
  end get_param;

  impure function get_addr(f: integer) return buffer_p is begin
    assert false report "VHPI" severity failure;
  end get_addr;

  type buffet_t_prot is protected body
    variable var: buffer_p;
    procedure init ( i: integer ) is begin
      var := get_addr(i);
    end procedure;
  end protected body buffet_t_prot;
end pkg_c;
EOF

cat > tb.vhd <<-EOF
use work.pkg_c.all;

entity test is
end entity;

architecture tb of test is begin
  main: process begin
    report "HELLO" severity warning;
    wait;
  end process;
end architecture;
EOF

docker run --rm -tv /$(pwd)://src -w //src ghdl/ghdl:ubuntu18-llvm-5.0 bash -c "\
  ghdl -a --std=08 pkg_c.vhd tb.vhd &&\
  ghdl -e --std=08 test"

#>> end

Output with mcode:

# curl -L https://raw.githubusercontent.com/1138-4EB/issue-runner/master/runner.sh | sh -s ghdl/ghdl#793
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   980  100   980    0     0   7101      0 --:--:-- --:--:-- --:--:--  7101
mkdir: created directory 'run-ghdl--ghdl--793'
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   147  100   147    0     0    124      0  0:00:01  0:00:01 --:--:--   124
100  2206  100  2206    0     0   1715      0  0:00:01  0:00:01 --:--:--  1715
cmd: /usr/bin/python3 extract_sources.py ghdl/ghdl#793
Get run.sh
Unable to find image 'ghdl/ghdl:buster-mcode' locally
buster-mcode: Pulling from ghdl/ghdl
ae11a5913a58: Pulling fs layer
4122fa923d65: Pulling fs layer
62a798bdb871: Pulling fs layer
62a798bdb871: Verifying Checksum
62a798bdb871: Download complete
ae11a5913a58: Verifying Checksum
ae11a5913a58: Download complete
ae11a5913a58: Pull complete
4122fa923d65: Verifying Checksum
4122fa923d65: Download complete
4122fa923d65: Pull complete
62a798bdb871: Pull complete
Digest: sha256:85d6a172b1d30cccb13474487786a2db7e5fd8c16cbb4feb3665f090503979c6
Status: Downloaded newer image for ghdl/ghdl:buster-mcode
pkg_c.vhd:9:19:error: unknown foreign VHPIDIRECT 'get_addr'

Output with LLVM:

pkg_c.o: In function `work__pkg_c__buffet_t_prot__init':
ortho:(.text+0x151): undefined reference to `get_addr'
collect2: error: ld returned 1 exit status
ghdl:error: compilation error

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions