目录
一、基本RTL模型
1.if的模型
2.if-else if的模型
3.else 的模型
二、避免产生锁存-latch
1.latch的产生
2.消除latch
三、避免综合过度优化
1.过度优化的产生
2.避免过度优化的方法
一、基本RTL模型
1.if的模型
always@(*)begin
if(cmd==2'b10)begin
done <= 2'b10
end
end
RTL模型为一个比较器
2.if-else if的模型
always@(*)begin
if(cmd==2'b00)begin
done = 2'b00;
end else if(cmd==2'b01)begin
done = 2'b01;
end if(cmd==2'b10)begin
done = 2'b10;
end if(cmd==2'b11) begin
done = 2'b11;
end
end
RTL模型为多个比较器,每个比较器的参考电压值为if-else if语句内比较的值
3.else 的模型
always@(*)begin
if(cmd==2'b00)begin
done = 2'b00;
end else if(cmd==2'b01)begin
done = 2'b01;
end else begin
done = 2'b11;
end
end
可将电路分为两级,第一级为N个比较器,当进入else的状况时,N路比较器输出全为0,再用这N路0进行组合逻辑产生else内部需要的结果
以上述代码为例,当cmd= =2’b0 | cmd= =2’b1 均不满足时,两路比较器输出均为0,可看作第一级电路;
然后,二号比较器的输出结果取反,接到done[0]=1’b1;
同时,二号比较器的输出结果作为mux的选通信号,地址0输出,输出内容为一号比较器的输出结果取反,即输出1,done[1]=1’b;
于是两路比较器的输出结果经过组合逻辑电路实现
else begin done =2’b11; end
二、避免产生锁存-latch
1.latch的产生
使用条件选择电路,如果不设置冗余项,会产生锁存,即latch
if(cmd==2'b00)begin
done = 2'b00;
end else if(cmd==2'b01)begin
done = 2'b01;
end if(cmd==2'b10)begin
done = 2'b10;
end
锁存器可以理解为带复位与置位的寄存器,复位输出为0,置位输出为pre端连接值
2.消除latch
(1)if加else,case加default
if(cmd==2'b00)begin
done = 2'b00;
end else if(cmd==2'b01)begin
done = 2'b01;
end else begin
done = 2'b11;
end
(2)赋初值
done =2'b0;
if(cmd==2'b00)begin
done = 2'b00;
end else if(cmd==2'b01)begin
done = 2'b01;
end if(cmd==2'b10)begin
done = 2'b10;
end
三、避免综合过度优化
1.过度优化的产生
在if-else if电路中有一种情况,综合时会被过度优化。当if -else if列举出所有的情况,并按照消除latch的思路加上冗余的else项后,会产生以下结果
if(cmd==2'b00)begin
done = 2'b00;
end else if(cmd==2'b01)begin
done = 2'b01;
end if(cmd==2'b10)begin
done = 2'b10;
end if(cmd==2'b11) begin
done = 2'b11;
end else begin
done = 2’b00;
end
此时仿真出来的结果已经不正常了,说明电路被过度优化。
产生优化的原因,猜测如下:根据生成else 电路的思路,四路比较器输出均为0,则需要用这4个0产生组合逻辑,得到done = 2’b00;
但是,done = 2’b00是if(cmd==2’b00)的结果,于是中间的三个比较器均被优化掉了。综合电路优化的规则是从第一级输入到输出,我们所需要的中间几个比较器反而被判定为冗余逻辑,而被优化掉了。
2.避免过度优化的方法
将带有优先级的if -else if改为多个并行的if块
if(cmd==2'b00)begin
done <= 2'b00;
end
if(cmd==2'b01)begin
done <= 2'b01;
end
if(cmd==2'b10)begin
done <= 2'b10;
end
if(cmd==2'b11)begin
done <= 2'b11;
end
但这样一来,由于无法使用else设置冗余项,又会产生latch.
于是引用消除latch的思路2:赋初值
done <= 2’b00;
if(cmd==2'b00)begin
done <= 2'b00;
end
if(cmd==2'b01)begin
done <= 2'b01;
end
if(cmd==2'b10)begin
done <= 2'b10;
end
if(cmd==2'b11)begin
done <= 2'b11;
end
成功避免了过度优化与latch的问题。