Comb Logic

You might also like

Download as pdf or txt
Download as pdf or txt
You are on page 1of 17

case Statement

Nesting if past two levels is error prone and possibly inefficient.

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

//"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);

U34

U23
U22

U25
U24

U27
U26

always_comb
case (sel)
2b00
2b01
2b10
2b11
endcase
endmodule

U29
U41

:
:
:
:

d_out
d_out
d_out
d_out

=
=
=
=

U39

a_in;
b_in;
c_in;
d_in;

U28

U31
U30

U33

U32

U40

U37
U38

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

:
:
:
:

d_out
d_out
d_out
d_out

=
=
=
=

a_in;
b_in;
c_in;
d_in;

/case1/a_in 10
/case1/b_in 20
/case1/c_in 30
/case1/d_in 40
/case1/sel 0
/case1/d_out 10

20

30

40

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

:
:
:
:
:

d_out
d_out
d_out
d_out
d_out

=
=
=
=
=

a_in;
b_in;
c_in;
d_in;
8bx;

/case1/a_in 10
/case1/b_in 20
/case1/c_in 30
/case1/d_in 40
/case1/sel 0
/case1/d_out 10

20

30

40

xx

case Statement
U17
...g[6]

U18

//incomplete case statement


module case2 (
input
[7:0] a_in, b_in, c_in,
input
[1:0] sel,
output reg [7:0] d_out);

...g[5]

U19
...g[4]

U20
...g[3]

U21

always_comb
case (sel)
2b00
: d_out = a_in;
2b01
: d_out = b_in;
2b10
: d_out = c_in;
endcase
endmodule

U25

...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]

U11

d_out[7:0]

sel[1]
sel[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);

a_in[5]
U12

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

U14

a_in[3]
b_in[3]
c_in[3]

:
:
:
:

d_out
d_out
d_out
d_out

=
=
=
=

a_in;
b_in;
c_in;
8bx;

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

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

sel[1:0]

U18

U15

U16

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

sel[1:0]

always_comb
case (sel)
2b00
2b01
2b10
default
endcase
endmodule

c_in[7:0]

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

U17

c_in[7:0]

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

a_in[7]
b_in[7]
c_in[7]

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

U10
d_out[7:0]

case Statement
System Verilog priority Modifier
I SystemVerilog introduced two case and if statement modifiers
I
I

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
I
I
I

Priority tells the simulator that if all is well, you will find 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 effectively dont-cares.
Priority does not guarantee removal of unintended latches.

case Statement
a_in[6]
b_in[6]
c_in[6]

U11

//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);

d_out[7:0]

sel[1]
sel[0]

a_in[5]
U12

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

U14

a_in[3]
b_in[3]
c_in[3]

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

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

sel[1:0]

U18

U15

U16

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

sel[1:0]

always_comb
priority case (sel)
2b00
: d_out = a_in;
2b01
: d_out = b_in;
2b10
: d_out = c_in;
endcase
endmodule

c_in[7:0]

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

U17

c_in[7:0]

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

a_in[7]
b_in[7]
c_in[7]

U10
d_out[7:0]

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

case Statement

System Verilog priority Modifier


I

OK, so what happens in simulation with 2b11 ?

No x propagation in RTL simulation, but warning is emitted

Go back, fix the error that caused the unallowed case to occur.

After fixing, 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 Modifier


I Bottom line...
I
I

If case is full, use default expression.


If case is not full, use priority modifier.

casez Statement
I
I
I
I
I

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;

1b1;
1b1;
1b1;

//default

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

n3

irq[2:0]
n4

U6

int0
int0

irq[2:0]

irq[0]

U5
irq[1]

U8

int1
int1

irq[2]
int2

casez Statement

Parallel or Unique encoding


I

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 modifier 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]

int0
U8

int0

U6

int1

int2,irq[1]

int1
irq[2:1]
U7

n2
int2
int2

irq[0]

SYNTHESIS RESULTS ARE INCORRECT!

casez Statement

Now what?
I

Further work has shown unique to be of at most little benefit.

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.

You might also like