2

多数のパック構造体 typedef を含むパッケージがあり、これらの構造体の最大ビット幅を教えてくれる CONSTANT 関数を作成しようとしています。各構造体には、列挙された明示的な message_type があります。私が書いた以下の関数はコンパイラによって定数として解釈されるべきだと思いますが、「(vlog-2118) 関数 'get_max_message_length' は有効な定数関数ではありません」というエラーが表示されます (これは ModelSim にあります)。

この関数が一定でない理由を誰か教えてもらえますか? デバッグ後、間違って解釈される原因となっているのは列挙型メソッド「next()」であると判断しました。可能な代替ソリューションはありますか?前もって感謝します!

typedef enum logic [7:0]
{
   MESSAGE_TYPE_0=0,
   MESSAGE_TYPE_1=1,
   MESSAGE_TYPE_2=2
} _MSGTYPE;

function integer get_message_length (_MSGTYPE message_type);
   case (message_type)
      MESSAGE_TYPE_0: return ($bits(message_0));
      MESSAGE_TYPE_1: return ($bits(message_1));
      MESSAGE_TYPE_2: return ($bits(message_2));
      default: return 0;
   endcase
endfunction

function integer get_max_message_length ();
   automatic _MSGTYPE largest = largest.first();
   automatic _MSGTYPE next = next.first();
   next = next.next();
   while (next != next.first()) begin
      largest = get_message_length(largest) > get_message_length(next) ? largest : next;
      next = next.next();
   end
   return get_message_length(largest);
endfunction
4

1 に答える 1

2

定数関数には特定の制限があります。純粋な関数でなければなりません(つまり、同じ引数で呼び出された場合、副作用がなく、同じ値を返す)。

この制限は伝播するため、定数関数は純粋な関数でもある他の関数のみを呼び出すことができます。問題は、それnext.next()が純粋な関数ではないことです。呼び出すたびに同じ値を返すわけではありません。

悲しいことに、SystemVerilog LRM は、列挙値にアクセスするためのメカニズムを定義していないようpureです。たとえば、可能であれば次のように動作します for (int i=0; i<enum.num(); i++) size=get_message_length(enum.item(i));

頭のてっぺんから、これを行うためのきちんとした方法は思いつきません。列挙値の配列である localparam を作成し、それを反復処理することはできますが、列挙値を再度書き出す必要があります。

于 2014-07-17T09:00:01.690 に答える