0.起因
最近在项目设计时,遇到了信号多驱动问题。
记录下来,提醒自己,方便他人。
1.现象起源
最近在设计YOLO—V3的模块逻辑。
在准备上FPGA时,综合报错:信号多驱动错误。
2.原因分析
查看代码后,发现是在不同的always@语句中对同一个信号进行了赋值,造成了多驱动问题。
比如:
logic a;
logic b;
logic c;
always @ (posedge clk_1) begin
if(b > 0)
a <= 1'b1;
end
end
always @ (posedge clk_1) begin
if(c > 0 && b < 0) begin
a <= 1'b0;
end
end
如上图所示,因为在两个不同的always块中对信号a进行了赋值,于是造成了多驱动错误。
这个错误,在仿真时并不会报错,但是在综合时,就会报错,一定要避免这个问题。
3.解决办法
明白原因后,解决这个问题,还是不难的。
解决办法:
只在一个always块中对信号a进行赋值。
logic a;
logic b;
logic c;
always @ (posedge clk_1) begin
if(b > 0)
a <= 1'b1;
end
else if(c > 0 && b < 0) begin
a <= 1'b0;
end
end
4.思维拓展
上面只是简单的例子。
实际项目中,代码比这个复杂很多,修改难度也相应大很多。
比如,上面只涉及到一个时钟,而且控制条件互斥,所以很好修改。
但是,很多时候,代码很难修改。比如,出现如下情况。
假如:
(1)两个always块的时钟不同,条件互斥;
logic a;
logic b;
logic c;
always @ (posedge clk_1) begin
if(b > 0)
a <= 1'b1;
end
end
always @ (posedge clk_2) begin
if(c > 0 && b < 0) begin
a <= 1'b0;
end
end
(2)时钟相同,但是条件不互斥,可能发生冲突;
logic a;
logic b;
logic c;
always @ (posedge clk_1) begin
if(b > 0)
a <= 1'b1;
end
end
always @ (posedge clk_1) begin
if(c > 0 ) begin
a <= 1'b0;
end
end
(3)时钟不同,且条件不互斥;
logic a;
logic b;
logic c;
always @ (posedge clk_1) begin
if(b > 0)
a <= 1'b1;
end
end
always @ (posedge clk_2) begin
if(c > 0 ) begin
a <= 1'b0;
end
end
以上三种情况,怎么解决呢?
留待思考。