• Top
    • Documentation
    • Books
    • Boolean-reasoning
    • Projects
    • Debugging
    • Std
    • Proof-automation
    • Macro-libraries
    • ACL2
    • Interfacing-tools
    • Hardware-verification
      • Gl
      • Esim
      • Vl2014
        • Warnings
        • Primitives
        • Use-set
        • Syntax
        • Getting-started
        • Utilities
        • Loader
        • Transforms
          • Expression-sizing
          • Occform
          • Oprewrite
          • Expand-functions
          • Delayredux
          • Unparameterization
          • Caseelim
            • Vl-casezx-stmt-elim
            • Vl-casezx-matchexpr
            • Vl-modulelist-caseelim
            • Vl-casezx-match-any-expr
            • Vl-casestmt-elim
            • Vl-casestmt-size-warnings
            • Vl-casezx-elim-aux
            • Vl-stmt-caseelim
            • Case-statement-problems
            • Vl-casestmt-compare-expr
            • Vl-initiallist-caseelim
            • Vl-alwayslist-caseelim
            • Vl-casestmt-elim-aux
            • Vl-initial-caseelim
            • Vl-always-caseelim
            • Vl-casestmt-sizes-agreep
            • Vl-module-caseelim
            • Vl-design-caseelim
          • Split
          • Selresolve
          • Weirdint-elim
          • Vl-delta
          • Replicate-insts
          • Rangeresolve
          • Propagate
          • Clean-selects
          • Clean-params
          • Blankargs
          • Inline-mods
          • Expr-simp
          • Trunc
          • Always-top
          • Gatesplit
          • Gate-elim
          • Expression-optimization
          • Elim-supplies
          • Wildelim
          • Drop-blankports
          • Clean-warnings
          • Addinstnames
          • Custom-transform-hooks
          • Annotate
          • Latchcode
          • Elim-unused-vars
          • Problem-modules
        • Lint
        • Mlib
        • Server
        • Kit
        • Printer
        • Esim-vl
        • Well-formedness
      • Sv
      • Fgl
      • Vwsim
      • Vl
      • X86isa
      • Svl
      • Rtl
    • Software-verification
    • Math
    • Testing-utilities
  • Transforms

Caseelim

Replace vl-casestmts with equivalent vl-ifstmts.

This rewrite rewrites case statements into if statements. It requires that sizes have been computed that the test expressions and match expressions agree on their sizes. If these conditions are not met, it may issue non-fatal warnings and fail to rewrite the case statements.

This transform is practically useful for supporting designs that involve case statements and we believe it is basically reasonable. But Verilog's case statements have significant problems with regards to the handling of X and Z values. There are, therefore, many cases where this translation will change a module's simulation semantics. More information about these problems can be found in case-statement-problems.

The basic idea of the transform is just to rewrite, e.g., for plain case statements:

case (<test>)
 <match-1>: <body-1>
 <match-2>: <body-2>
 ...
 <match-n>: <body-N>
 default:   <default-body>
endcase

   -->

if (<test> === <match-1>)      <body-1>
else if (<test> === <match-2>) <body-2>
...
else if (<test> === <body-n>)  <body-n>
else                           <default-body>

This rewrite is intuitively correct, and appears to produce identical results in some test simulations on NCVerilog and Verilog-XL.

This transform isn't quite correct if test can cause side-effects. The Verilog standard says that test should be evaluated only once, before the match expressions. In our transformed code, test may be evaluated multiple times. This is not a problem for back-end tools like esim where there is no such notion of evaluation.

We considered doing something more sophisticated to avoid replicating the test expression, which would avoid this problem. It would be easy enough to simply assign the test expression to some temporary wire, then check temp against each match expression. But we might then need to also include this new wire in the sensitivity list for the always block, which could become tricky/messy. So for now, our transform really is just as naive as the above suggests.

Our support for casex and casez statements is somewhat more limited. Here, we require that each match expression be some simple, atomic vl-constint-p or vl-weirdint-p expression. These constraints allow us to carry out the following transform e.g.,:

casez (in)
  4'b001?: <body-1>
  4'b01??: <body-2>
  4'b1???: <body-3>
  default: <default-body>
endcase
   -->
if      ( (in & 4'b1110) === (4'b001z & 4'b1110) )    <body-1>
else if ( (in & 4'b1100) === (4'b01zz & 4'b1100) )    <body-2>
else if ( (in & 4'b1000) === (4'b1zzz & 4'b1000) )    <body-2>
else if (in[3] === 1'b0 & in[2] === 1'b1)              <body-2>
else if (in[3] === 1'b1)                               <body-3>
else                                                   <default-body>

That is, our if statement conditions simply mask out the x/z/? bits as appropriate, and check that the other bits are matched.

Unfortunately, this transformation is completely wrong in the case where data has X or Z bits, because in the Verilog semantics these bits are not to be tested. On the other hand, these are terrible, non-conservative semantics, and we think our behavior is about as reasonable as possible.

Subtopics

Vl-casezx-stmt-elim
Rewrite an casez or casex statement into if statements.
Vl-casezx-matchexpr
Creates, e.g., the expression (data & 4'b1100) === 4'b1000 for handling casez(data) ... 4'b10??: ... endcase.
Vl-modulelist-caseelim
(vl-modulelist-caseelim x ss) maps vl-module-caseelim across a list.
Vl-casezx-match-any-expr
Handles situations like casez(foo) ... 3'bxx1, 3'bx10: ... endcase, i.e., where we have multiple match expressions associated with the same body.
Vl-casestmt-elim
Rewrite an ordinary case statement into if statements.
Vl-casestmt-size-warnings
Check case statements for compatible sizes, and issue warnings if we find any incompatible sizes.
Vl-casezx-elim-aux
Vl-stmt-caseelim
Recursively eliminate case, casez, and casex statements within a statement.
Case-statement-problems
The official behavior of case, casez and casex is problematic with respect to X and Z values.
Vl-casestmt-compare-expr
Creates, e.g., the expression foo === 3'b110 | foo === 3'b111, for handling case(foo) ... 3'b110, 3'b111: ... endcase.
Vl-initiallist-caseelim
Vl-alwayslist-caseelim
Vl-casestmt-elim-aux
Vl-initial-caseelim
Vl-always-caseelim
Vl-casestmt-sizes-agreep
Make sure all match expressions have been sized and that their sizes are compatible with the test expression.
Vl-module-caseelim
Vl-design-caseelim