1

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.

nguthrie
  • 2,615
  • 6
  • 26
  • 43

2 Answers2

1

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
Greg
  • 18,111
  • 5
  • 46
  • 68
  • 2
    So funny story: The version of my simulator I was using doesn't support `$assertcontrol`. I upgraded to the newest version and it supports it. However, it also doesn't suffer from the false warning at time 0, so I don't actually need to deal with it. – nguthrie Apr 21 '16 at 12:51
0

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.

Qiu
  • 5,651
  • 10
  • 49
  • 56
  • I know that I can ignore the warning, but I like to clean up what I can. If I assign `state=IDLE` then I get an error since `state` has multiple drivers. – nguthrie Mar 23 '15 at 17:07
  • @nguthrie: what IDE are you using? It works [just fine](http://www.edaplayground.com/x/GaJ) for me. – Qiu Mar 23 '15 at 18:52
  • Cadence Incisive. Seems like a bug since I found this in section 10.5 of the spec: `The variable declaration assignment is a special case of procedural assignment as it assigns a value to a variable. It allows an initial value to be placed in a variable in the same statement that declares the variable`. Of course, doing this assignment would mask a real problem where there is no reset for some reason. What I really want is a way to suppress the warning at time 0. That is probably tool specific. – nguthrie Mar 23 '15 at 18:57
  • You can use `ncelab -svperf -up` to disable `unique case` warnings. I'm not sure if you can disable warnings only at time 0. – Qiu Mar 23 '15 at 19:40