Verilog主要有三种流程控制结构,即case,if-else和“?:”。
本节主要说明了case和if-else结构的实现细节。
1、如何在case语句和嵌套if-else之间进行选择?
case和if-else都是流程控制结构。 两者在功能仿真上是类似的,但是使用场景是不同的。
通常在以下场景选择case语句:
条件是互斥的,只有一个变量控制case语句中的流程。 case变量本身可以是不同信号的拼接。
通常在以下场景中选择多路if语句:
综合优先级编码逻辑,有多个变量控制语句流程。
使用case语句比if-else语句更具可读性,特别是用于状态机时。
在case结构中,如果未指定所有可能的case,并且缺少default语句,则会推断出锁存器。 同样,对于if-else结构,如果缺少最后的else语句,也会推断出锁存器。
2、如何避免if-else树中的优先级编码器?
if-else树可能会综合出优先级编码逻辑。 例如:
module priorityencoder (ino,in1,in2,in3,sel) ;
input in0 , in1,in2,in3 ;
output [1:0] sel ;
always@(in0,in1,in2,in3) begin
sel = 2’b00 ;
if(in0) sel = 2’b00 ;
else (in1) sel = 2’b01 ;
else (in2) sel = 2’b10 ;
else (in3) sel = 2’b11 ;
end
endmodule //priorityencoder
如果在in0和in1都是逻辑真的,in0分支将被采用,因为in0首先计算。EDA工具将综合出优先级编码逻辑。
?:能用在连续赋值里面,而if-else只能用在initial或者always语句块中。
3、Case语句中default子语句的重要性是什么?
case语句中的default子语句表示除case之外的其他情况。如果缺少default子语句,则输出默认会使用保存之前的值,因此会综合出锁存器(latch)。
例如,以下case语句将生成一个latch:
module default_latch(in1,in2,opcode,out1) ;
input [1:0] in1,in2,opcode ;
output [1:0] out1 ;
always@(in1 or in2 or opcode) begin
case(opcode)
2’b00 : out1 = in1 & in2 ;
2’b01: out1 = in1 | in2 ;
2’b10 : out1 = in1 ^ in2 ;
//2’b11 : out1 = in1 % in2 ;
//default : out1 = in1 & in2 ;
endcase
end
endmodule
在上面,通过两行注释,会综合出锁存器。
4、组合逻辑和时序逻辑中的嵌套if-else实现有什么区别?
组合逻辑和时序逻辑中的always语句块中的if-else实现是不同的。
在组合逻辑中,当缺少嵌套if-else语句中的最后一个else子句时,它将推断一个锁存器,因为寄存器必须记住原来的值。例如:
reg latch1 ;
always@(sel ,in1) begin
** if(sel) latch1 <= in1 ;**
end
在一个时序逻辑的always语句块中,如果最后的else语句丢失,仍然会继续推断出触发器。例如:
reg ff1 ;
always@(posedge clk) begin
if(sel1) ff1 <= in1 ;
end
上面的代码将推断出如下逻辑。触发器的D输入端是门控后的输出。
本文转载自公众号:芯片数字实验室
原文链接:https://mp.weixin.qq.com/s?\_\_biz=MzU4ODY5MzkzOA==&mid=2247484625&idx=1&sn=a3ea75a198b5bed9c2a61993be5b157f&chksm=fdd9ac0ccaae251a871654f262d986a66b88f0756372ddd85f81cd4675865c2b1fd64213
未经作者同意,请勿转载!
推荐阅读
想了解更多内容,欢迎关注芯片数字实验室专栏