nguthrie
nguthrie

Reputation: 2685

"Unique case violation" warning at time 0

I have a unique case statement inside an FSM that looks something like this:

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

I am getting a "Unique case violation" warning at time 0, presumably because everything starts up as X. I am fairly certain that the above code will always have one and only one true case, so I would like to get rid of this warning.

Upvotes: 1

Views: 2413

Answers (2)

Greg
Greg

Reputation: 19112

You can dynamically turn on/off assertions, including unique case, unique if, etc. with the system task $assertcontrol. Refer to IEEE Std 1800-2012 § 20.12 Assertion control system tasks.

Note that $assertcontrol is new (added in IEEE Std 1800-2012) and some simulators may not support it. There are other system tasks that can enable/disable assertions such as $asserton, $assertoff which been around since pre IEEE1800 (I see it mentioned in Accellera SystemVerilog 3.0), but I'm not sure if they include unique case

If your simulator already supports $assertcontrol then you can use something like the following code. I recommend having the file that contains this code compile before any file that uses unique case to reduce the risk of a race condition at time 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

Upvotes: 1

Qiu
Qiu

Reputation: 5761

The easiest solution would be to assign a value (e.g. IDLE) to state inside declaration:

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

Of course you can also add default action to your case.

You have to remember it's only a warning. If you reset (~rstb) your module at the beginning, nothing wrong will happen if you ignore it.

Upvotes: 0

Related Questions