Help us understand the problem. What is going on with this article?

VHDLのfunctionとprocedureについて

はじめに

VHDLではprocedureとfunctionによってsubprogramを定義できます。
それぞれの使い分けを把握していなかったのでまとめました。

functionのほうが制約が厳しいのでどちらでもいい場合はfunctionを使うほうがよさそうです。

function

functionは以下の特徴を持ちます。

  • ディレイやイベント制御は使えない(wait文は使えない)
  • 常に1つの値を返す
  • inputの引数をもてる(もたなくてもよい)
  • outputやinoutの引数はもてない
  • non-blockingは使用できない

以上の特徴からfunctionは主に組合せ回路の実装に使用できます。

例えば以下のようにandリダクション演算をfunctionで定義できます。

function and_reduce (arg : std_logic_vector ) return std_logic is
    variable var : std_logic;
begin
    var = '1';
    for i in arg'range loop
        var := var and arg(i);
    end loop;
    return var;
end function;

procedure

procedureは以下の特徴を持ちます

  • ディレイやイベント制御ができる(wait文が使える)
  • 複数の値を返すことができる
  • inputの引数をもてる(もたなくてもよい)
  • outputやinoutの引数をもてる
  • ノンブロッキング代入も使用できる

以上のようにfunctionでできなかったことができるようになっています。

procedureでは複数の出力とwait文を使うことができるため
以下のようにSPI通信のマスタの動作を定義できます。

ただし、wait文を使った場合は回路として論理合成することはできません
wait文を使わない場合はこちらの記事のように論理合成することもできます。

constant data_bits : natural := 8;

procedure send_spi (
    signal data : in std_logic_vector(data_bits - 1 downto 0);
    signal sdo : out std_logic;
    signal sclk : out std_logic;
    signal ss : out std_logic
) is
    constant sclk_period : time := 1 us; -- 1MHz
begin
    ss <= '0';
    for i in 0 to data'length - 1 loop
        sclk <= '0';
        wait for sclk_period / 2;
        sclk <= '1';
        sdo <= data(i);
        wait for sclk_period / 2;
    end loop;
    sclk <= '0';
    ss <= '1';
end procedure;

上記のprocedureを使えばスレーブのテストコードは以下のように簡単になります。
この処理をさらにprocedureとして定義することもできます。

master_data := X"AC";
send_spi (data => master_data, sdo => sdi, sclk => sclk, ss => ss);
wait for clk_period;
check_equal(receive_data, master_data, "data error"); -- VUnit

並列procedure?順次procedure?

FPGAの部屋では入力信号にsignal宣言を書かないことで順次procedureとして扱うことができるとされている。

内容を読む限りはsignal宣言の有無ではなく
wait文の有無で並列procedureか順次procedureが決まるように思えますが
参考にされている図書を持っていないので詳細については不明です。

参考

[pdf] Functions, Procedures, and Testbenches - Xilinx
vhdlwhiz.com - HOW TO USE A PROCEDURE IN VHDL
vhdlwhiz.com - HOW TO USE A FUNCTION IN VHDL
Qiita - VHDL で ビット幅を可変にできる Priority Encoder を書く
FPGAの部屋 - procedureを使うときの注意点

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away