我有一个包含许多打包结构 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
最佳答案
常量函数有一定的限制 - 它必须是 pure function (即没有副作用,如果使用相同的参数调用,则返回相同的值)。
此限制会传播,因此您的常量函数只能调用同样是纯函数的其他函数。你遇到的问题是next.next()
不是一个纯函数 - 每次调用它时它不会返回相同的值。
遗憾的是,SystemVerilog LRM 似乎没有定义任何 pure
访问枚举值的机制 - 例如,如果可能的话,这将起作用: for (int i=0; i<enum.num(); i++) size=get_message_length(enum.item(i));
我想不出一个巧妙的方法来做到这一点。您可以创建一个 localparam,它是一个枚举值数组并对其进行迭代,但您必须再次写出枚举值。
关于enums - 系统Verilog : How come the enum next() method cannot be used in a constant function?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24788784/