VHDLで定数の型を明示する方法

# 要約
VHDLで多重定義されている関数に対して定数を入力する場合、
Qualified Expression(型明示式)という構文で定数の型を定義することができます

# 定数の型指定されていない場合

Vunitのcheck_equalのように多重定義された関数に対して
`check_equal(X"AC", X"AC");`のような判定を記述すると
シミュレータが`X"AC"`の型を判別できないためコンパイルエラーとなります

```vhdl:tb_OverloadFunctionFail.vhd
library vunit_lib;
context vunit_lib.vunit_context;
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity tb_OverloadFunctionFail is
    generic (
        runner_cfg : string := runner_cfg_default
    );
end tb_OverloadFunctionFail;

architecture behavior of tb_OverloadFunctionFail is

begin

    test_bench : process
    begin
        test_runner_setup(runner, runner_cfg);
        while test_suite loop

            if run("test") then

                check_equal(X"AC", X"AC");

            end if;
        end loop;
        test_runner_cleanup(runner);
    end process;

end;

```

```:result
=== Test Result ===
Compile failed
=== Command output: ===
can't resolve overload for procedure call
possible interpretations are:
procedure check_equal [string, string, string, log_level_t, natural, string]
procedure check_equal [signed, signed, string, log_level_t, natural, string]
procedure check_equal [std_logic_vector, std_logic_vector, string, log_level_t, natural, string]
procedure check_equal [std_logic_vector, unsigned, string, log_level_t, natural, string]
procedure check_equal [unsigned, std_logic_vector, string, log_level_t, natural, string]
procedure check_equal [unsigned, unsigned, string, log_level_t, natural, string]
```

# Qualified Expression(型明示式)

このような場合、Qualified Expression(型明示式)構文である
`type'(expression)`を使うことで定数の型を明示することができます。

```vhdl:
-- 前後省略
check_equal(unsigned'(X"AC"), std_logic_vector'(X"AC"));
```

`(`の前に`'`が入っていることに注意してください

# 参考

[https://www.ics.uci.edu/~jmoorkan/vhdlref/qualifex.html](https://www.ics.uci.edu/~jmoorkan/vhdlref/qualifex.html)

# おまけ:他の書き方の検証

事前に定数として定義したり、整数から型変換を行ったりしても型が明示されるので問題ないようです

```vhdl:pkg_test.vhd
library vunit_lib;
context vunit_lib.vunit_context;
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity tb_TestCheckEqual is
    generic (
        runner_cfg : string := runner_cfg_default
    );
end tb_TestCheckEqual;

architecture behavior of tb_TestCheckEqual is

    constant UNSIGNED_IN  : unsigned(7 downto 0) := X"AC";
    constant UNSIGNED_ANS : unsigned(7 downto 0) := X"AC";

begin

    test_bench : process
    begin
        test_runner_setup(runner, runner_cfg);
        while test_suite loop

            if run("test") then

                -- エラーになる記述はコメントアウトしています

                -- check_equal(UNSIGNED_IN, X"AC");
                -- -- === Test Result ===
                -- -- failed
                -- -- === Command Output ===
                -- -- can't resolve overload for procedure call
                -- -- possible interpretations are:
                -- -- procedure check_equal [unsigned, std_logic_vector, string, log_level_t, natural, string]
                -- -- procedure check_equal [unsigned, unsigned, string, log_level_t, natural, string]
                -- -- === memo ===
                -- -- X"AC"の型が明示できていません

                -- check_equal(UNSIGNED_IN, unsigned(X"AC"));
                -- -- === Test Result ===
                -- -- failed
                -- -- === Command Output ===
                -- -- string literal cannot be a type conversion operand
                -- -- === memo ===
                -- -- X"AC"がstring型である可能性があるためunsigned()では変換できず型が明示できていません

                check_equal(UNSIGNED_IN, unsigned'(X"AC"));
                -- === Test Result ===
                -- passed
                -- === memo ===
                -- Qualified Expressionで型を明示できています

                check_equal(UNSIGNED_IN, to_unsigned(172, 8));
                -- === Test Result ===
                -- passed
                -- === memo ===
                -- to_signedによって型が明示できています

                check_equal(UNSIGNED_IN, UNSIGNED_ANS);
                -- === Test Result ===
                -- passed
                -- === memo ===
                -- UNSIGNED_ANSの宣言時に型が明示できています

            end if;
        end loop;
        test_runner_cleanup(runner);
    end process;

end;

```