2

我有一个包含许多打包结构类型定义的包,我正在尝试编写一个 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 回答