In SystemVerilog, the case
statement is used to compare an expression against multiple potential values, and based on that, it executes the corresponding block of code. The behavior of the case
statement in SystemVerilog is quite similar to that in Verilog. However, when we use certain keywords like unique
or unique0
, we add extra functionality to ensure that case statements are evaluated without ambiguity. This article will explain how SystemVerilog unique case works, the significance of using unique
and unique0
keywords, and how they affect the evaluation of case items. Additionally, we will provide some practical examples to show how these keywords help in avoiding violations and ensuring proper execution.
What is SystemVerilog Unique Case?
The SystemVerilog unique case statement is an enhanced version of the traditional case
statement. When you use the unique
keyword in a case
statement, it performs a violation check to ensure that no two case
items overlap. If any two items have matching values, a violation is reported, and the first matching value is executed.
This check is important for parallel evaluation and ensures that your code behaves predictably.
How Unique and Unique0 Keywords Work
- unique: The
unique
keyword ensures that only one case item matches the given expression. If multiple items match, it reports a violation. - unique0: This works similarly to
unique
, but it does not report a violation when no case items match the given expression.
Key Differences Between unique
and unique0
Keyword | When Violation Occurs | Behavior on No Match |
---|---|---|
unique | Violation occurs if more than one case item matches | Reports violation on no match |
unique0 | Violation occurs if multiple case items match | No violation if no match occurs |
Example 1: SystemVerilog Unique Case with No Match
Let’s see an example where no case item matches the expression. In this case, SystemVerilog unique case will report a violation.
module tb;
bit [1:0] abc;
initial begin
abc = 1;
// None of the case items match the value in "abc"
// A violation is reported here
unique case (abc)
0 : $display("Found to be 0");
2 : $display("Found to be 2");
endcase
end
endmodule
Simulation Log:
ncsim> run
ncsim: *W,NOCOND: Unique case violation: Every case item expression was false.
File: ./testbench.sv, line = 9, pos = 14
Scope: tb
Time: 0 FS + 1
ncsim: *W,RNQUIE: Simulation is complete.
In this scenario, since no case item matched the value of abc
, a violation is triggered, and the simulation log reflects the error.
Example 2: SystemVerilog Unique Case with Multiple Matches
Next, let’s look at an example where multiple case items match the expression. In this case, SystemVerilog unique case will again report a violation.
module tb;
bit [1:0] abc;
initial begin
abc = 0;
// Multiple case items match the value in "abc"
// A violation is reported here
unique case (abc)
0 : $display("Found to be 0");
0 : $display("Again found to be 0");
2 : $display("Found to be 2");
endcase
end
endmodule
Simulation Log:
ncsim> run
Found to be 0
ncsim: *W,MCONDE: Unique case violation: Multiple matching case item expressions at {line=10:pos=6 and line=11:pos=6}.
File: ./testbench.sv, line = 9, pos = 14
Scope: tb
Time: 0 FS + 1
ncsim: *W,RNQUIE: Simulation is complete.
Here, the value 0
matches two different case items, which causes a violation. The SystemVerilog unique case reports that multiple matches occurred and executes the first one.
Example 3: SystemVerilog Priority Case with No Violations
If you want to avoid violations when multiple case items match, you can use the priority
keyword. This ensures that the first matching case item gets executed without any violations.
module tb;
bit [1:0] abc;
initial begin
abc = 0;
// First match is executed
priority case (abc)
0 : $display("Found to be 0");
0 : $display("Again found to be 0");
2 : $display("Found to be 2");
endcase
end
endmodule
Simulation Log:
ncsim> run
Found to be 0
ncsim: *W,RNQUIE: Simulation is complete.
In this case, even though both 0
values match, priority case ensures that the first one is executed, and no violation is reported.
Conclusion: When to Use SystemVerilog Unique Case
The SystemVerilog unique case statement is essential for avoiding ambiguous behavior in your code. By using the unique
and unique0
keywords, you ensure that no two case items match the given expression at the same time, avoiding confusion and errors.
- Use
unique
when you need to make sure that only one case item matches and want to catch violations if multiple matches occur. - Use
unique0
when you don’t want a violation when no case item matches but still need to avoid overlapping matches.