1、一般情况下,综合器将case语句综合成多路选择器,但也可能综合成优先级译码器。
2、case语句中,如果条件列举不完全,将综合出不必要的锁存器。
综合器指令://synopsys parallel_case & //synopsys full_case
使用//synopsys parallel_case可以引导综合器生成多路选择器。
1 always @(cs_state) 2 begin 3 case(cs_state) // synopsys parallel_case 4 2’b00: next_state = 2’b01; 5 2’b01: next_state = 2’b00; 6 2’b10: next_state = 2’b10; 7 default: next_state = 2’b00; 8 endcase 9 end
使用//synopsys full_case则可以避免生成不必要的锁存器。
1 always @(cs_state) 2 begin 3 case(cs_state) // synopsys full_case 4 2’b00: next_state = 2’b01; 5 2’b01: next_state = 2’b00; 6 2’b10: next_state = 2’b10; 7 endcase 8 end
Guideline1:使用if-else-if编码优先级编/译码器,if-else-if的优先级关系更清楚明了。
Guideline2:使用case实现查表类语句,这能提高代码可读性。
Guideline3:一般情况下不要使用”full_case parallel_case”指令在verilog case语句中,其可能造成综合器和仿真器行为的不一致。
Guideline4:3的例外情况,可使用”full_case parallel_case”指令优化状态机编码。原因很简单,未列完的条件,视为don’t care 其赋值由
综合器自动选择0或1。比起人为的赋值0或1,它能简化逻辑,这点可通过卡诺图化简进行解释。
3、避免case语句生成不必要latch的verilog推荐风格:使用default语句赋default值(0或1),或者在进入case语句后立马赋default值,再对各条件做case分析。
4、case代码举例分析。
ex1:
1 module mux3c(y,a,b,c,sel); 2 output y; 3 input [1:0] sel; 4 input a,b,c; 5 reg y; 6 7 always @(a or b or c or sel) 8 case(sel) 9 2'b00: y=a; 10 2'b01: y=b; 11 2'b10; y=c; 12 default: y=1'bx; 13 endcase 14 endmodule
上述代码对综合器:当sel=11时,y为don’t care ,并且综合器使用卡诺图化简的方式进行逻辑优化;
对于仿真器:当sel=11时,y值为x,未知态。因此,这也会导致综合器和仿真器行为不一致(对综合器而言,其效果和使用full_case一样)。
ex2:
1 module mux3c(y,a,b,c,sel); 2 output y; 3 input [1:0] sel; 4 input a,b,c; 5 reg y; 6 7 always @(a or b or c or sel) 8 case(sel) //synopsys full_case 9 2'b00: y=a; 10 2'b01: y=b; 11 2'b10; y=c; 12 endcase 13 endmodule
上述代码对综合器,sel=11时,y为don’t care,但对仿真器会是锁存器(y值保持不变)。
ex3:使用default赋确定的default值(非x值)
1 module mux3c(y,a,b,c,sel); 2 output y; 3 input [1:0] sel; 4 input a,b,c; 5 reg y; 6 7 always @(a or b or c or sel) 8 case(sel) 9 2'b00: y=a; 10 2'b01: y=b; 11 2'b10; y=c; 12 default: y=a;//or y=1'b0; 13 endcase 14 endmodule
通过确定的值避免仿真器出现X值。
ex4:进入case语句后立马赋default值
1 module mux3c(y,a,b,c,sel); 2 output y; 3 input [1:0] sel; 4 input a,b,c; 5 reg y; 6 7 always @(a or b or c or sel) 8 y=1'b0; 9 case(sel) 10 2'b00: y=a; 11 2'b01: y=b; 12 2'b10; y=c; 13 endcase 14 endmodule
通过先赋值的方式,避免忘记写完整个case条件而出现latch。