Sei sulla pagina 1di 17

case Statement

Nesting if past two levels is error prone and possibly inecient. case excels when many tests are performed on the same expression. case works well for muxes, decoders, and next state logic. CASE Statement Structure case (case_expression) case_item1 : case_item_statement1; case_item2 : case_item_statement2; case_item3 : case_item_statement3; case_item4 : case_item_statement4; default : case_item_statement5; endcase case is shorthand to describe a complicated if/then/else structure.

case Statement

U42

U35

U34

//"full case" case statement module case1 ( input [7:0] a_in, b_in, c_in, d_in, input [1:0] sel, output reg [7:0] d_out); always_comb case (sel) 2b00 2b01 2b10 2b11 endcase endmodule

U23 U22

U25 U24

U27 U26

U29 U41 U39 U28

: : : :

d_out d_out d_out d_out

= = = =

a_in; b_in; c_in; d_in;


U38

U31 U30

U33

U32

U40

U37

U36

case Statement
Is the simulation correct?
//"full case" case statement module case1 ( input [7:0] a_in, b_in, c_in, d_in, input [1:0] sel, output reg [7:0] d_out); always_comb case (sel) 2b00 2b01 2b10 2b11 endcase endmodule
/case1/a_in 10 /case1/b_in 20 /case1/c_in 30 /case1/d_in 40 /case1/sel 0 /case1/d_out 10 1 20 2 30 3 40 X

: : : :

d_out d_out d_out d_out

= = = =

a_in; b_in; c_in; d_in;

case Statement
Use default case to propagate x
//"full case" case statement module case1 ( input [7:0] a_in, b_in, c_in, d_in, input [1:0] sel, output reg [7:0] d_out); always_comb case (sel) 2b00 2b01 2b10 2b11 default endcase endmodule
/case1/a_in 10 /case1/b_in 20 /case1/c_in 30 /case1/d_in 40 /case1/sel 0 /case1/d_out 10 1 20 2 30 3 40 X xx

: : : : :

d_out d_out d_out d_out d_out

= = = = =

a_in; b_in; c_in; d_in; 8bx;

case Statement
U17 ...g[6]

//incomplete case statement module case2 ( input [7:0] a_in, b_in, c_in, input [1:0] sel, output reg [7:0] d_out); always_comb case (sel) 2b00 : d_out = a_in; 2b01 : d_out = b_in; 2b10 : d_out = c_in; endcase endmodule
U25

U18 ...g[5]

U19 ...g[4]

U20 ...g[3]

U21 ...g[2]

U22 ...g[1] U27 U26

U23 ...g[0]

U24 U15

...g[7]

U16

Inferred memory devices in process in routine case2 line 6 in file case2.sv. =========================================================================== | Register Name | Type | Width | Bus | MB | AR | AS | SR | SS | ST | =========================================================================== | d_out_reg | Latch | 8 | Y | N | N | N | - | - | - | =========================================================================== Warning: Netlist for always_comb block contains a latch. (ELAB-974) Presto compilation completed successfully.

case Statement
a_in[6] b_in[6] c_in[6] sel[1] sel[0] U11

d_out[7:0]

//incomplete case statement //with default case_item module case2 ( input [7:0] a_in, b_in, c_in, input [1:0] sel, output reg [7:0] d_out); always_comb case (sel) 2b00 2b01 2b10 default endcase endmodule

a_in[5] U12

b_in[5] U13 c_in[5] a_in[4] b_in[4] c_in[4] a_in[3] b_in[3] c_in[3] U14

a_in[2] b_in[2] c_in[2]

U15

: : : :

d_out d_out d_out d_out

= = = =

a_in; b_in; c_in; 8bx;

a_in[1] b_in[1] c_in[1]

U16

sel[1:0]

U18

n3 a_in[0] b_in[0] c_in[0] U17

c_in[7:0]

a_in[7:0] b_in[7:0]

Does RTL and gate simulation dier when sel = 2b11?

sel[1:0]

c_in[7:0] a_in[7] b_in[7] c_in[7] U10 d_out[7:0]

a_in[7:0] b_in[7:0]

case Statement
System Verilog priority Modier SystemVerilog introduced two case and if statement modiers
priority unique

Both give information to synthesis to aid optimization. Both are assertions (simulation error reporting mechanisms) Both imply that there is a case item for all the possible legal values that case expression might assume. Priority
Priority tells the simulator that if all is well, you will nd a match If a match is not found at run-time, emit an error or warning. Since all legal combinations are listed, synthesis is free to optimize any other unlisted case items since they are eectively dont-cares. Priority does not guarantee removal of unintended latches.

case Statement
a_in[6] b_in[6] c_in[6] sel[1] sel[0] U11

d_out[7:0]

//incomplete case statement //with systemverilog priority modifier module case2 ( input [7:0] a_in, b_in, c_in, input [1:0] sel, output reg [7:0] d_out); always_comb priority case (sel) 2b00 : d_out = a_in; 2b01 : d_out = b_in; 2b10 : d_out = c_in; endcase endmodule

a_in[5] U12

b_in[5] U13 c_in[5] a_in[4] b_in[4] c_in[4] a_in[3] b_in[3] c_in[3] U14

a_in[2] b_in[2] c_in[2]

U15

a_in[1] b_in[1] c_in[1]

U16

sel[1:0]

U18

n3 a_in[0] b_in[0] c_in[0] U17

c_in[7:0]

a_in[7:0] b_in[7:0]

Warning: case2.sv:7: Case statement marked priority does not cover all possible conditions. (VER-504)

sel[1:0]

c_in[7:0] a_in[7] b_in[7] c_in[7] U10 d_out[7:0]

a_in[7:0] b_in[7:0]

case Statement

System Verilog priority Modier OK, so what happens in simulation with 2b11 ? No x propagation in RTL simulation, but warning is emitted Go back, x the error that caused the unallowed case to occur. After xing, the RTL and gate simulation should match.

case Statement
//incomplete case statement //with systemverilog priority modifier module case2 ( input [7:0] a_in, b_in, c_in, input [1:0] sel, output reg [7:0] d_out); always_comb priority case (sel) 2b00 : d_out = a_in; 2b01 : d_out = b_in; 2b10 : d_out = c_in; endcase endmodule

** Warning: (vsim-8315) case2.sv(7): No condition is true in the unique/priority if/case statement. ** Warning: (vsim-8315) case2.sv(7): No condition is true in the unique/priority if/case statement.

case Statement

System Verilog priority Modier Bottom line...


If case is full, use default expression. If case is not full, use priority modier.

casez Statement
casez is a special version of the case expression Allows dont care bits in the comparison Uses ? or Z values as dont care instead of as a logic value (weird!) Recommendation: use ? as dont care Use caution when using this statement casez Example
module interrupt_ctl1 ( output reg int2, int1, int0, input [2:0] irq ); always_comb begin {int2, int1, int0} casez (irq) 3b1?? : int2 = 3b?1? : int1 = 3b??1 : int0 = endcase end endmodule

3b0;

//default

1b1; 1b1; 1b1;

casez Statement
casez Example
U7

module interrupt_ctl1 ( output reg int2, int1, int0, input [2:0] irq ); always_comb begin {int2, int1, int0} = 3b0; //default casez (irq) 3b1?? : int2 = 1b1; 3b?1? : int1 = 1b1; 3b??1 : int0 = 1b1; endcase end

irq[2:0] n4 irq[2:0] irq[0]

n3 U6 int0 int0

U5 irq[1] U8

int1 int1

irq[2] int2

casez Statement

Parallel or Unique encoding If the irq bus has any of the values: 3b011, 3b101, 3b110 or 3b111, more than one case item could match the irq value. This is known as a non-parallel case statement. Synthesis will produce a priority encoder structure. If code could be rewritten to have parallel or unique case items, no priority structure would be needed. Thus, faster/smaller implementation. We indicate this situation with the modier unique.

casez Statement
Parallel or Unique Encoding
module interrupt_ctl2a ( output reg int2, int1, int0, input [2:0] irq ); always_comb begin {int2, int1, int0} = 3b0; //default unique casez (irq) 3b1?? : int2 = 1b1; 3b01? : int1 = 1b1; 3b001 : int0 = 1b1; endcase end
irq[1] U8 int2,irq[1] int0 int0

int1 irq[2:1] U7 n2 int2 int2 U6 int1

irq[0]

SYNTHESIS RESULTS ARE INCORRECT!

casez Statement

Now what? Further work has shown unique to be of at most little benet. I only got it to work properly once. Synthesis does not stick strictly to priority encoding, its smarter. Using unique, I get about 10% decrease in delay and area at best. At this point, until I can bet a better handle on it, avoid unique.

casex Statement

One more case expression exists: casex. Can be useful for testbenches. Current recommendations are to not use it in synthesizible code.

Potrebbero piacerti anche