SystemVerilog|functionの使い方

Systemverilog
田中太郎
田中太郎

SystemVerilogのfuctionの使い方を紹介します

functionの基本的な使い方

functionは以下のように定義します(入力1と入力2を加算するfunction)

function 関数名(
    input 入力1,
    input 入力2
);
    関数名 = 入力1 + 入力2;
endfunction

moduleを定義するように、関数を定義します

moduleと違うのは、出力はoutput で宣言するのではなく
関数名に代入した値が出力となります

定義した関数は以下のように使用します

always_ff @(posedge clk, negedge rst_n) begin
    if (!rst_n) begin
        data <= 1'b0;
    end
    else begin
        data <= 関数名(1'b0, 1'b1);
    end
end

引数にはもちろん信号も代入できます

出力を複数ビットにしたいときは、以下のように宣言します

function [1:0] 関数名(
    input 入力1,
    input 入力2
);
    関数名 = 入力1 + 入力2;
endfunction
functionを使用したサンプルコード
module sample1 (
    input clk,
    input rst_n,
    input in1,
    input in2,
    output logic [1:0] dout
);
    function [1:0] func(
        input in1,
        input in2
    );
        func = in1 + in2;
    endfunction

    always_ff @(posedge clk, negedge rst_n) begin
        if (!rst_n) begin
            dout <= 2'b00;
        end
        else begin
            dout <= func(in1, in2);
        end
    end
endmodule

if文とfunction

function文内でif文を使用できます

function 関数名(
    input 入力1,
    input 入力2
);
    if (入力1) begin
       関数名 = 入力2;
    end
    else begin
        関数名 = 1'b0;
    end
endfunction

このとき、if文の条件はelseを使用するなどして網羅的に分岐を作成しましょう

function内でif文を使用したサンプルコード
module sample2 (
    input clk,
    input rst_n,
    input in1,
    input in2,
    output logic dout
);
    function func(
        input in1,
        input in2
    );
        if (in1) begin
            func = in2;
        end
        else begin
            func = 1'b0;
        end
    endfunction

    always_ff @(posedge clk, negedge rst_n) begin
        if (!rst_n) begin
            dout <= 1'b0;
        end
        else begin
            dout <= func(in1, in2);
        end
    end
endmodule

case文とfunction

function文内ではcase文も使用できます

function 関数名(
    input 入力1,
    input 入力2
);
    case(入力1)
        1'b1   : 関数名 = 入力2;
        default: 関数名 = 1'b0;
    endcase
endfunction
function内でcase文を使用したサンプルコード
module sample3 (
    input clk,
    input rst_n,
    input in1,
    input in2,
    output logic dout
);
    function func(
        input in1,
        input in2,
    );
        case(in1)
            1'b1   : func = in2;
            default: func = 1'b0;
        endcase
    endfunction

    always_ff @(posedge clk, negedge rst_n) begin
        if (!rst_n) begin
            dout <= 1'b0;
        end
        else begin
            dout <= func(in1, in2);
        end
    end
endmodule

まとめ

SystemVerilogのfunctionの使い方を紹介しました。

コメント

タイトルとURLをコピーしました