在使用case语句时,不完备的case语句会导致Vivado综合时推断出锁存器。下面通过实例来详细看看各种情况下的综合结果:
1.完备的case语句
下述的verilog对应的电路结构是一个8选一的多路复用器:
module case_test(
input [2:0]sel,
input data0,
input data1,
input data2,
input data3,
input data4,
input data5,
input data6,
input data7,
output reg data_out
);
always@(*)
begin
case(sel)
3'b000:data_out<=data0;
3'b001:data_out<=data1;
3'b010:data_out<=data2;
3'b011:data_out<=data3;
3'b100:data_out<=data4;
3'b101:data_out<=data5;
3'b110:data_out<=data6;
3'b111:data_out<=data7;
default:data_out<=data_out;
endcase
end
endmodule
综合结果如下:
对于上述的综合结果,每四个输入数据以及sel对应到一个LUT6,之后将二者的输出通过sel[2]控制的选择器进行选择,在完备描述的情况下电路中不会有锁存器。
2.不完备case语句
下面是一个不完备的case语句,只对四种情况进行描述,其余用default描述:
module case_test(
input [2:0]sel,
input data0,
input data1,
input data2,
input data3,
input data4,
input data5,
input data6,
input data7,
output reg data_out
);
always@(*)
begin
case(sel)
3'b000:data_out<=data0;
3'b001:data_out<=data1;
3'b010:data_out<=data2;
3'b011:data_out<=data3;
default:data_out<=data_out;
endcase
end
endmodule
对应的电路结构和综合结果如下图:
我们可以发现,对于default的四种情况,四个输入数据线未连接,将其余四种情况的数据线接入LUT,之后将LUT的输出连接到锁存器的数据输入端D,而将sel[2]连接到使能端,因为G为低电平有效,所以只有到sel[2]为0时锁存器才能将输入端的数据送到输出端,而在sel[2]为1时,Q端保持不变,锁存数据。