版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/jiang1960034308/article/details/120906198
前言
秋招面试时被问到优化组合逻辑的方法,我说到了消除代码优先级,即在优先级不是必要的时候,用case代替if-else。面试官追问,如果case和if-else都是使用一个查找表实现的,那他们的延迟有区别吗?我突然醒悟,在这里记录一下。
一、Vivado 中的两种Schematic
Vivado中Elaborated Design和Synthesis Design中分别有一个Schematic,为了方便后面的论述,先简单地介绍一下他们的区别(个人理解)。
Elaborated Design中的Schematic显示的是信号之间的逻辑关系。从中我们看不出该逻辑是如何实现的,举个例子,用查找表实现一个乘法器和用DSP实现一个乘法器在这里看不出区别。
Synthesis Design中的Schematic显示的是实现逻辑时使用的器件种类以及器件之间的连接方式。从中我们看不出器件具体实现了什么逻辑,比如用查找表实现一个与运算和用查找表实现一个或运算在这里看不出区别。
当关注的是信号之间的逻辑层数时,应当看后者。
二、例子
比如我要实现一个4-1复用器,用if-else写是这样的:
module mux_test(
output dout ,
input din_a ,
input din_b ,
input din_c ,
input din_d ,
input [ 1:0] sel
);
reg dout_r;
assign dout = dout_r;
always@(*) begin
if(sel == 2'd0)
dout_r = din_a;
else if(sel == 2'd1)
dout_r = din_b;
else if(sel == 2'd2)
dout_r = din_c;
else
dout_r = din_d;
end
endmodule
Elaborated Design里的Schematic是这样的:
Synthesis Design里的Schematic是这样的:
同样是4-1复用器,用case写是这样的:
module mux_test(
output dout ,
input din_a ,
input din_b ,
input din_c ,
input din_d ,
input [ 1:0] sel
);
reg dout_r;
assign dout = dout_r;
always@(*) begin
case(sel)
2'd0: dout_r = din_a;
2'd1: dout_r = din_b;
2'd2: dout_r = din_c;
2'd3: dout_r = din_d;
endcase
end
// always@(*) begin
// if(sel == 2'd0)
// dout_r = din_a;
// else if(sel == 2'd1)
// dout_r = din_b;
// else if(sel == 2'd2)
// dout_r = din_c;
// else
// dout_r = din_d;
// end
endmodule
Elaborated Design里的Schematic是这样的:
Synthesis Design里的Schematic是这样的:
在早期的学习中,我看到过有人说没有优先级比有优先级时序更好,我想了想,脑子里出现了Elaborated Design中的两张图,用if-else最长路径有三级逻辑,而用case只有一级,便接受了这种说法。而实际上我们应该考虑的是Synthesis Design中的两张图。if-else和case都是用查找表实现的,而且在这个例子中两者都是使用一个LUT6,甚至连线都是一样的,也就没有逻辑延迟的差异。
总结
从查找表的角度去考虑,if-else的逻辑延迟未必比case大。但在实际写代码的过程中,仍应遵循当优先级不是必要的时候,用case而不是if-else的原则。