はじめに
VHDLはポリモーフィズムな型システムを持つので同じ名前で型の異なる関数を定義することが出来ます。
ところが、Altera 社の Quartus で何故かエラーが発生してしまいました。他の処理系(Vivado や GHDL)はちゃんと通ります。
どうやら、パッケージ内に同じ名前で引数有りの関数と引数無しの関数が混在していると、引数無し関数をパッケージ名.関数名という形で呼び出したときにうまく見つけられないみたいです。
ちょっと前提条件がピンポイントすぎるのですが、何かの参考にしてください。
トラブルが発生した環境
- Altera 社 Quartus Prime Verion 15.1.0 Build 185 10/21/2015 SJ Lite Edition
トラブルが発生した VHDL 記述
次のように、パッケージ内に同じ名前で引数有りと引数無しの関数を定義しておきます。
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;
で、パッケージで定義した関数のうち、引数無しの関数をパッケージ名.関数名という形で呼び出します。
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
解決策1
次のように sample_1_ng.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
次のようにしても通ります。引数無しだと見つけられないけど、引数をつけると見つけられるようです。
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>
このアドバイスに従い、Altera 社の Service Request に報告しました。
さらにその後
Altera 社の Service Request にあげたところ、バグとして報告されたそうです。
修正は 16.1 の予定だそうです。