Altera の Quartus で引数の有無が混在した多重定義関数をVHDLで記述する際の注意点

#はじめに

VHDLはポリモーフィズムな型システムを持つので同じ名前で型の異なる関数を定義することが出来ます。

ところが、Altera 社の Quartus で何故かエラーが発生してしまいました。他の処理系(Vivado や GHDL)はちゃんと通ります。
どうやら、パッケージ内に同じ名前で引数有りの関数と引数無しの関数が混在していると、引数無し関数をパッケージ名.関数名という形で呼び出したときにうまく見つけられないみたいです。

ちょっと前提条件がピンポイントすぎるのですが、何かの参考にしてください。

#トラブルが発生した環境

- Altera 社 Quartus Prime Verion 15.1.0 Build 185 10/21/2015 SJ Lite Edition 

#トラブルが発生した VHDL 記述

次のように、パッケージ内に同じ名前で引数有りと引数無しの関数を定義しておきます。

````VHDL:sample_code.vhd
library ieee;
use     ieee.std_logic_1164.all;
use     ieee.numeric_std.all;
package Sample_Code is
    subtype   Code_Type   is std_logic_vector(3 downto 0);
    type      Code_Vector is array (integer range <>) of Code_Type;
    function  New_Code(DATA:std_logic_vector) return Code_Type;
    function  New_Code(DATA:unsigned        ) return Code_Type;
    function  New_Code(DATA:integer         ) return Code_Type;
    function  New_Code                        return Code_Type;
end Sample_Code;

library ieee;
use     ieee.std_logic_1164.all;
use     ieee.numeric_std.all;
package body Sample_Code is
    function  New_Code(DATA:std_logic_vector) return Code_Type is begin
        return DATA(Code_Type'range);
    end function;
    function  New_Code(DATA:unsigned        ) return Code_Type is begin
        return New_Code(std_logic_vector(DATA));
    end function;
    function  New_Code(DATA:integer         ) return Code_Type is begin
        return New_Code(to_unsigned(DATA, 4));
    end function;
    function  New_Code                        return Code_Type is begin
        return New_Code(0);
    end function;
end Sample_Code;
````

で、パッケージで定義した関数のうち、引数無しの関数をパッケージ名.関数名という形で呼び出します。

````VHDL:sample_1_ng.vhd
library ieee;
use     ieee.std_logic_1164.all;
use     ieee.numeric_std.all;
use     work.Sample_Code;
entity  Sample is
    port (O: out Sample_Code.Code_Type);
end     Sample;
architecture RTL of Sample is
begin
    O <= Sample_Code.New_Code;
end RTL;
````

#トラブル内容

すると、何故か、関数呼び出しのところでエラーが発生します。

````
Info: *******************************************************************
Info: Running Quartus Prime Analysis & Synthesis
	Info: Version 15.1.0 Build 185 10/21/2015 SJ Lite Edition
	Info: Processing started: Sat Feb 06 00:10:09 2016
	Info: Version 15.1.0 Build 185 10/21/2015 SJ Lite Edition
	Info: Processing started: Sat Feb 06 00:10:09 2016
Info: Command: quartus_map --read_settings_files=on --write_settings_files=off sample_altera -c sample_altera
Warning (20028): Parallel compilation is not licensed and has been disabled
Info (12021): Found 2 design units, including 1 entities, in source file sample_1_ng.vhd
	Info (12022): Found design unit 1: Sample-RTL
	Info (12023): Found entity 1: Sample
	Info (12022): Found design unit 1: Sample-RTL
	Info (12023): Found entity 1: Sample
Info (12021): Found 2 design units, including 0 entities, in source file sample_code.vhd
	Info (12022): Found design unit 1: Sample_Code
	Info (12022): Found design unit 2: Sample_Code-body
	Info (12022): Found design unit 1: Sample_Code
	Info (12022): Found design unit 2: Sample_Code-body
Error (10404): VHDL error at sample_1_ng.vhd(10): can't determine object and type associated with indexed name or signature name near text "New_Code" -- found 4 possible objects and types
Info (10797): VHDL info at sample_code.vhd(7): first match for 'New_Code' found here
Info (10797): VHDL info at sample_code.vhd(8): another match for 'New_Code' found here
Info (10797): VHDL info at sample_code.vhd(9): another match for 'New_Code' found here
Info (10797): VHDL info at sample_code.vhd(10): another match for 'New_Code' found here
Error: Quartus Prime Analysis & Synthesis was unsuccessful. 1 error, 1 warning
	Error: Peak virtual memory: 855 megabytes
	Error: Processing ended: Sat Feb 06 00:10:34 2016
	Error: Elapsed time: 00:00:25
	Error: Total CPU time (on all processors): 00:01:01
	Error: Peak virtual memory: 855 megabytes
	Error: Processing ended: Sat Feb 06 00:10:34 2016
	Error: Elapsed time: 00:00:25
	Error: Total CPU time (on all processors): 00:01:01
````

#解決策１

次のように sample_1_ng.vhd を修正すると通ります。どうやらパッケージ名.関数名だとダメで、関数名だけだといいみたいです。

````VHDL:sample_1_ok_1.vhd
library ieee;
use     ieee.std_logic_1164.all;
use     ieee.numeric_std.all;
use     work.Sample_Code.all;
entity  Sample is
    port (O: out Code_Type);
end     Sample;
architecture RTL of Sample is
begin
    O <= New_Code;
end RTL;
````

#解決策2

次のようにしても通ります。引数無しだと見つけられないけど、引数をつけると見つけられるようです。

````VHDL:sample_1_ok_2.vhd
library ieee;
use     ieee.std_logic_1164.all;
use     ieee.numeric_std.all;
use     work.Sample_Code;
entity  Sample is
    port (O: out Sample_Code.Code_Type);
end     Sample;
architecture RTL of Sample is
begin
    O <= Sample_Code.New_Code(0);
end RTL;
````

#その後の経過

Altera Forum にこの件を報告しました。

[Thread: Error (10404) VHDL error occured when function call by\<package_name\>.\<function_name\>](http://www.alteraforum.com/forum/showthread.php?t=51340)

このアドバイスに従い、Altera 社の Service Request に報告しました。

##さらにその後

Altera 社の Service Request にあげたところ、バグとして報告されたそうです。
修正は 16.1 の予定だそうです。