Search code examples
vhdlghdl

GHDL cannot find function defined in package


Using GHDL-4.0.0 I want to compile a VHDL entity which makes a reference to a function that is defined in a separate VHDL package file. I get a compilation error error: no declaration for function_name

Here is a reproducible source:

common.vhd

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.math_real.all;

package common is
    function Bmax_calc(Bin : natural; R : natural; N : natural; M : natural) return natural;
end package;

package body common is
    function Bmax_calc(Bin : natural; R : natural; N : natural; M : natural) return natural is
        constant a : real := real(R*M);
        constant b : real := log2(a);
        constant c : real := real(real(N) * b);
    begin
        return natural(c) + Bin;
    end function;
end package body;

mydesign.vhd

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.std_logic_unsigned.all;

entity mydesign is
    generic (
        Bin : natural := 24;
        R : natural := 8;
        N : natural := 3;
        M : natural := 1
    );
    port (
        clk : in std_logic;
        data_i : in signed(Bin - 1 downto 0);
        data_o : out signed(Bin - 1 downto 0)
    );
end mydesign;

architecture arch of mydesign is
    constant Bmax : integer := Bmax_calc(Bin, R, N, M);
    subtype regsize is signed(Bmax - 1 downto 0);
    signal int_r, int_out : regsize := (others => '0');
begin
    process(clk)
    begin
        if (rising_edge(clk)) then
            data_o <= data_i;
        end if;
    end process;
end arch;

build.sh

#!/usr/bin/bash
mkdir build
cd build
ghdl -a ../common.vhd
ghdl -a --ieee=synopsys ../mydesign.vhd
ghdl -e mydesign

console output

../mydesign.vhd:22:36:error: no declaration for "bmax_calc"
        constant Bmax : integer := Bmax_calc(Bin, R, N, M);
                                   ^

Do I have to specify the package explicitly during compilation? Does GHDL not support referencing functions in a package? Or what else might be the issue?


Solution

  • You need to 'use' your package before you declare mydesign entity to make the package contents visible in the design unit:

    use work.common.all
    

    or you need to make a direct reference to it:

    constant Bmax : integer := work.common.Bmax_calc(Bin, R, N, M);