SVの基本:タスクと機能

概要

 C 言語と同様に、関数 (関数) とタスク (タスク) を使用すると、コードの再利用性とクリーンさを向上させることができます。

その目的は、大きなプロセス ブロックを、読み取り保守が容易な小さな部分に分割することです

機能とタスクの間には類似点と相違点があります。

関数関数

関数の主な目的は、演算式の戻り値を提供することです。これにより、元のコードが簡略化されるだけでなく、大規模なコードのメンテナンスも容易になります。

SV の関数定義と使用法は C と似ています。

  1. 関数は入力変数と出力変数を指定できます
  2. 関数は値を返すことも、値を返さないこともできます (値を返さない場合は void 関数を使用します)。


宣言できる関数の引数の方向

  1. 入力 (デフォルト)
  2. 出力
  3. 入出力
  4. 参照

パラメータリストを宣言する方法は次のとおりです。

1. パラメータ リストでパラメータと方向を宣言します。
2. 関数本体でパラメータと方向を宣言します
。 例:

function logic [15:0] myfunc1(int x, int y);
    ...
endfunction
 
function logic [15:0] myfunc2;
    input int x;
    input int y;
    ...
endfunction

SV の関数の戻りメソッドは      C の関数の戻りメソッドと一致しています。

  1. 値を直接返すには return を使用します (return はすぐに戻ります)
  2. 関数と同じ名前の変数に値を代入します(関数と同じ名前の変数に代入すると、以降のコードが引き続き実行されます)

関数は関数を呼び出すことができますが、すぐに返さなければなりません。つまり、ブロックして待機するという動作は発生しません。  

例:

//myfunc1,返回值经过计算,赋予了与函数同名的变量
function [15:0] myfunc1 (input [7:0] x, y) ;
    myfunc1 = x *y - 1;
endfunction
 
//myfunc2,将计算的返回值,通过return返回,并且立即退出函数
function [15:0] myfunc2 (input [7:0] x, y);
    return x *y - 1;
endfunction

 ボイド関数

void 関数は値を返しません。 

戻り値を使用して関数を呼び出すが、戻り値を使用しない場合は、型変換のために void'() を追加することをお勧めします。[この手順により、コンパイル中に表示される警告メッセージを削除できます]

タスクタスク

関数と同様に、タスクにもパラメータ リストがあります。しかし、タスクは値を返しません。

タスク定義では宣言パラメータを指定できます

  • 入力
  • 出力
  • 入出力
  • 参照

タスク宣言パラメータメソッド(関数と同じ) 

  1.  パラメータリストでパラメータと方向を宣言します。
  2.  タスク本体でパラメータと指示を宣言します

例:  

task mytask1 (output int x, input logic y);
    ...
endtask
 
task mytask2;
    output x;
    input y;
    int x;
    logic y;
    ...
endtask

タスクはシミュレーション時間を消費する可能性があります。いくつかのブロッキング ステートメントを組み込むことができます。(関数とは異なります)

タスクは他のタスクまたは関数を呼び出すことができます。

タスクは値を返しませんが、return を使用してタスクを終了することができます。

例: 

タスク ライトでは、最初にパラメータを取得し、次に待機する必要があるクロック サイクル数を決定し、クロックをオフに設定する必要があります。

Light にはブロック タスクが組み込まれており、そのような操作をカプセル化するには、関数ではなくタスクのみを使用できます。

Always process ブロックで呼び出されるタスク ライトは、最終結果を赤に割り当てます。 

logic red;
parameter red_tics = 100;
always begin //控制灯光
    red = on; //打开红灯
    light(red,red_tics) ; //等待end
//等待‘tics’时钟上升沿的任务
//在关掉‘color’灯之前
task light (output color,input [31:0] tics) ;
    repeat (tics)@ (posedge clock);
    color = off;//关灯
endtask: light

タスクと機能の違い

  1.  関数はシミュレーション時間を消費しませんが、タスクはシミュレーション時間を消費します。(最大の違い)
  2. 関数からタスクを呼び出すことはできませんが、タスクから関数を呼び出すことはできます。(関数はすぐに戻る必要があり、組み込みのブロッキング ステートメントやブロック動作を持つタスクはないため、関数は関数のみを呼び出すことができ、タスクは呼び出すことはできません。逆に、タスクは関数を呼び出すことができ、タスクはまた、関数を呼び出すこともできます。タスクは組み込みのブロッキング ステートメントである可能性があるため、タスクを呼び出します)
  3. 関数は値のみを返すことができますが、タスクは値を返しません。(関数に void 戻り値以外の戻り値がある場合、関数呼び出しの結果を式のオペランドとして使用できます)
  4.  関数は式のオペランドとして使用でき、オペランドの値は関数の戻り値になります

パラメータの受け渡し

パラメータタイプ 
1、入力パラメータ

 入力パラメータの方向は、メソッドの呼び出し時に値によって渡されます。

 つまり、転送プロセス中に、外部変数の値がコピーされ、入力パラメータに割り当てられます。

2. 出力、入出力パラメータ

入力パラメータと同様に、出力および入出力も、渡されるときまたは渡されるときに値の転送プロセスを受けます。

 値の受け渡しのプロセスは、メソッドが呼び出されて返されたときにのみ発生します。

3. refパラメータ

 前の 3 つのパラメータとは異なります。 

 ref パラメータを渡すと、値のコピーは行われませんが、変数ポインタがメソッドに渡され、メソッド内のパラメータに対する操作が同時に外部変数に影響を与えます。

外部から渡された ref パラメーターがメソッドによって変更されるのを防ぎたい場合は、変数が読み取り専用変数であることを示す const 修飾子を追加できます。

 パラメータの受け渡し方法

  1. メソッド呼び出し時にパラメータ位置でパラメータを渡す
  2. パラメータはパラメータ名のマッピングを通じて渡されます。(SV ではモジュールと同様のインスタンス化が可能)

位置に応じてパラメータを渡す 

パラメータのデフォルト値を指定します

SV では、メソッドが入力パラメーターを宣言するときに、そのデフォルト値を指定できます。

        パラメーターのデフォルト値を持つメソッドが呼び出されたときに、これらのパラメーターに値が渡されない場合、コンパイラーはこれらのパラメーターに対応するデフォルト値を渡します。

例:  

read() 関数を呼び出すときにパラメータを渡す方法はたくさんあります。簡単な要約:

2 つの入力パラメータにはデフォルト値を使用できますが、呼び出すときは、少なくとも 1 つのパラメータ値を渡す必要があり、3 つのパラメータの位置に従う必要があります。

//没有指定方向的情况下,参数都是输入方向
//为参数j 、data指定了默认值
task read(int j = 0, int k, int data = 1 );
    ...
endtask
 
read( , 5 );//等同于read ( 0,5,1 );
read ( 2,5 );//等同于read( 2,5,1 );
read( , 5,);//等同于read ( 0,5,1 );
read( , 5,7 );//等同于read( 0,5,7 );
read( 1,5,2 );//等同于read( 1,5,2 );
read ( );//错误;k没有默认值
read( 1,, 7 );//错误;k没有默认值

パラメータ名マッピングを使用してパラメータを渡す

        SV では、モジュールのインスタンス化と同様に、メソッド呼び出し時にパラメーターの場所によってパラメーターを渡すことができ、パラメーター名マッピングによってパラメーターを渡すこともできます。

例:  

function int fun( int j = 1,string s = "no”);
    ...
endfunction
fun( .j(2),.s("yes") ) ; //fun( 2,"yes");
fun( .s("yes") ); //fun( 1,"yes" );
fun( , "yes" );  //fun( 1,"yes" ) ;
fun( . j(2) );  //fun( 2,“no”);
fun( .s("yes"),.j(2));  // fun( 2, "yes");
fun( .s(),.j() );  // fun( 1, "no”);
fun( 2 ); //fun( 2, "no”);
fun( );  //fun


著作権に関する声明: この記事は CSDN ブロガー「Tong Tonghua」のオリジナル記事であり、CC 4.0 BY-SA 著作権規約に準拠しています。転載する場合は、オリジナルのソースリンクとこの声明を添付してください。
元のリンク: https://blog.csdn.net/weixin_41788560/article/details/124057717

おすすめ

転載: blog.csdn.net/Arvin_ing/article/details/127224779