Casex Archives - Verilog Pro https://www.verilogpro.com/tag/casex/ Verilog and Systemverilog Resources for Design and Verification Mon, 27 Jun 2022 07:43:12 +0000 en-US hourly 1 https://wordpress.org/?v=6.5.2 98068679 Verilog twins: case, casez, casex. Which Should I Use? https://www.verilogpro.com/verilog-case-casez-casex/ https://www.verilogpro.com/verilog-case-casez-casex/#comments Sun, 13 Sep 2015 18:01:11 +0000 http://www.verilogpro.com/?p=96 The Verilog case statement is a convenient structure to code various logic like decoders, encoders, onehot state machines. Verilog defines three versions of the case statement: case, casez, casex. Not only is it easy to confuse them, but there are subtleties between them that can trip up even experienced coders. In this article I will ... Read more

The post Verilog twins: case, casez, casex. Which Should I Use? appeared first on Verilog Pro.

]]>
The Verilog case statement is a convenient structure to code various logic like decoders, encoders, onehot state machines. Verilog defines three versions of the case statement: case, casez, casex. Not only is it easy to confuse them, but there are subtleties between them that can trip up even experienced coders. In this article I will highlight the identifying features of each of the twins, and discuss when each should be used.

Basic Verilog Case Statement

Let’s start by reviewing the basic case statement:

case (case_expression) // case statement header
  case_item_1 : begin
    case_statement_1a;
    case_statement_1b;
  end
  case_item_2 : case_statement_2;
  default     : case_statement_default;
endcase

A case statement has the following parts:

  • Case statement header—consists of the case, casez, or casex keyword followed by case expression
  • Case expression—the expression in parentheses immediately following the case keyword. Valid expressions include constants (e.g. 1’b1), an expression that evaluates to a constant, or a vector
  • Case item—the expression that is compared against the case expression. Note that C-style break is implied following each case item statement
  • Case item statement—one or more statements that is executed if the case item matches the current case expression. If more than one statement is required, they must be enclosed with begin…end
  • Case default—optional, but can include statements to be executed if none of the defined case items match the current case expression

Wildcard Case Statement: casez

The plain case statement is simple but rigid—everything must be explicitly coded. In some situations, you may want to specify a case item that can match multiple case expressions. This is where “wildcard” case expressions casez and casex come in. casez allows “Z” and “?” to be treated as don’t care values in either the case expression and/or the case item when doing case comparison. For example, a case item 2’b1? (or 2’b1Z) in a casez statement can match case expression of 2’b10, 2’b11, 2’b1X, 2’b1Z. It is generally recommended to use “?” characters instead of “Z” characters in the case item to indicate don’t care bits.

Verilog “wildcard” case statements can have overlapping case items. If more than one case item can match a case expression, the first matching case item has priority. Thus, priority logic can be inferred from a case statement. The following code snippet illustrates how casez can be used to code priority logic. It simulates and synthesizes correctly as a priority decoder.

always @(irq) begin
  {int2, int1, int0} = 3'b000;
  casez (irq)
    3'b1?? : int2 = 1'b1;
    3'b?1? : int1 = 1'b1;
    3'b??1 : int0 = 1'b1;
    default: {int2, int1, int0} = 3'b000;
  endcase
end
Verilog casez priority decoder

The logic will look something like this:

Even though this may seem an elegant way to code a priority decoder, the priority intention may only be apparent to the most experienced coders. Therefore, it is generally recommended to code priority logic using the more explicit if…else statement to clearly convey the intention.

While wildcard case comparison can be useful, it also has its dangers. Imagine a potentially dangerous casez statement where the case expression is a vector and one bit resolves to a “Z”, perhaps due to a mistakenly unconnected input. That expression will match a case item with any value for the “Z” bit! To put in more concrete terms, if the LSB of irq in the above code snippet is unconnected such that the case expression evaluates to 3’b00Z, the third case item will still match and int0 will be set to 1, potentially masking a bug!

Even wilder: casex

Now that we understand the usage and dangers of casez, it is straight-forward to extend the discussion to casex. casex allows “Z”, “?”, and “X” to be treated as don’t care values in either the case expression and/or the case item when doing case comparison. That means, everything we discussed for casez also applies for casex, plus “X” is now also a wildcard. In my previous article on Verilog X Optimism I discussed how X’s can propagate around a design and mask design issues. These propagated X’s can easily cause problems when combined with casex statements. To avoid these problems, the recommendation from RTL Coding Styles That Yield Simulation and Synthesis Mismatches is not to use casex at all for synthesizable code.

Verilog case, casez, casex each has its place and use cases. Understanding the differences between them is key to using them correctly and avoiding bugs. It may also help you in your next job interview 🙂

Have you come across any improper usage of these constructs? What are your recommendations for using them, especially casex? Leave a comment below!

SystemVerilog Unique Case

SystemVerilog adds a possible unique modifier to case statements. How does that change the behaviour? Head over to my post SystemVerilog Unique And Priority – How Do I Use Them?

References

  1. RTL Coding Styles That Yield Simulation and Synthesis Mismatches
  2. “full_case parallel_case”, the Evil Twins of Verilog Synthesis

Quiz and Sample Source Code

Now it’s time for a quiz! How will each of the following variations of case statement behave when the case expression

  1. matches one of the non-default case items
  2. does not match any non-default case item
  3. contains all X’s (e.g. if the signal comes from an uninitialized memory)
  4. contains all Z’s (e.g. if the signal is unconnected)
  5. contains a single bit X
  6. contains a single bit Z

Case statement variations:

  1. Plain case statement
  2. Plain case with default case
  3. Casez
  4. Casez with default case
  5. Casex
  6. Casex with default case
  7. Unique case
  8. Unique case with default case
  9. Unique casez
  10. Unique casex

Stumped? Download the executable source code to find out the answer!

[lab_subscriber_download_form download_id=7]

The post Verilog twins: case, casez, casex. Which Should I Use? appeared first on Verilog Pro.

]]>
https://www.verilogpro.com/verilog-case-casez-casex/feed/ 18 96