"Unique case violation" 在时间 0 发出警告

"Unique case violation" warning at time 0

我在 FSM 中有一个独特的 case 语句,看起来像这样:

enum logic [1:0] {IDLE = 2'b01,
                  RUN = 2'b10} state, next_state;
always_comb begin
  next_state=state;
  unique case(state)
    IDLE: next_state = RUN;
    RUN: next_state = IDLE
  endcase
end

always_ff @(posedge clk or negedge rstb) begin
  if(!rstb) state <= IDLE;
  else state <= next_state;
end

我在时间 0 收到 "Unique case violation" 警告,大概是因为一切都以 X 启动。我相当确定上面的代码总是只有一个真实情况,所以我想去掉这个警告。

最简单的解决方案是在声明中为 state 分配一个值(例如 IDLE):

enum logic [1:0] {IDLE = 2'b01,
                  RUN = 2'b10} state = IDLE, next_state;

当然您也可以为您的案例添加 default 操作。

你必须记住这只是一个警告。如果你一开始就重置(~rstb)你的模块,忽略它不会有任何问题。

可以通过系统任务$assertcontrol动态转on/off断言,包括unique caseunique if等。请参阅 IEEE Std 1800-2012 § 20.12 断言控制系统任务

请注意,$assertcontrol 是新的(在 IEEE Std 1800-2012 中添加),某些模拟器可能不支持它。还有其他系统任务可以 enable/disable 断言,例如 $asserton$assertoff 自 IEEE1800 之前就存在(我看到它在 Accellera SystemVerilog 3.0 中提到过),但我不确定是否它们包括 unique case

如果您的模拟器已经支持$assertcontrol,那么您可以使用类似下面的代码。我建议在任何使用 unique case 的文件之前编译包含此代码的文件,以降低时间 0.

出现竞争条件的风险
parameter ON=3, OFF=4;
parameter UNIQUE=32, UNIQUE0=64, PRIORITY=128;
initial begin
  // Turn OFF the violation reporting for unique case, unique0 case, priority case, unique if, etc.
  $assertcontrol( OFF , UNIQUE | UNIQUE0 | PRIORITY );

  // Wait some time
  @(negedge rstb) #1ns; // or whatever delay statement you want

  // Turn ON the violation reporting for unique case, unique0 case, priority case, unique if, etc.
  $assertcontrol( ON , UNIQUE | UNIQUE0 | PRIORITY );
end