
田中太郎
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の使い方を紹介しました。
コメント