LoginSignup
0
2

More than 3 years have passed since last update.

VHDL備忘録

Posted at

はじめに

いつの間にか知っていたけれど、
あまり説明されない記述をまとめています。

ビット列に区切り文字

VHDLでは進数を明示すれば区切り文字として_が使えます。

constant a : std_logic_vector(9 downto 0) := "11_0010_0001"; -- illegal
constant b : std_logic_vector(9 downto 0) := B"11_0010_0001";

aggregate

全てのビットの値を指定する時にothersをよく使いますが、
一部のビットだけを別の値に指定することができます。

constant data_bits : natural := 8;
constant unsigned_max : unsigned(data_bits - 1 downto 0) := (others => '1');
constant signed_max   : signed(data_bits - 1 downto 0) := (data_bits - 1 => '0', others => '1');

オーバーロード

VHDLのsubprogramではオーバーロードを使うことができます

例えば、自作のrecord_type型の値をチェックする
Vunitのcheck_equalにオーバーロードしたprocedureを作ることで
テストコードの見通しがよくなります。

library vunit_lib;
context vunit_lib.vunit_context;
library ieee;
use ieee.std_logic_1164.all;

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

architecture behavior of tb_sample is

    type record_type is record
        address : std_logic_vector(7 downto 0);
        data : std_logic_vector(15 downto 0);
    end record;

    constant A : record_type := {
        address => (others => '0'),
        data => (others => '0')
    };

    constant B : record_type := {
        address => (others => '0'),
        data => (others => '1')
    };

    -- overload
    procedure check_equal(
        constant got      : in record_type;
        constant expected : in record_type;
        constant msg      : in string
    ) is
    begin
        check_equal(got.address, expected.address, "address : " & msg);
        check_equal(got.data, expected.data, "data : " & msg);
    end;

begin

    test_bench : process
    begin
        test_runner_setup(runner, runner_cfg);
        while test_suite loop
            if run("test") then
                    check_equal('1', '0', "std_logic error");
                    check_equal(A, B, "record_type error"); -- overload
            end if;
        end loop;
        test_runner_cleanup(runner);
    end process;

end;

wait until

wait untilはイベント発生時(値が変化した時)にチェックされるので、
以下のように最初から条件を満たしている場合は待ち続けることになります。

a <= '0';
wait until a ='0';
b <= '0';

対策としては以下の2パターンがあります。

  1. 逆条件をチェックしてから待つ
  2. 適当なクロックと合わせて待つ
1
if a /= '0' then
    wait until a ='0';
end if;
2
    wait until rising_edge(clk) and a ='0';
0
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
2