verilogHDL,system Verilog程式碼的多驅動問題
阿新 • • 發佈:2018-12-12
0.起因
最近在專案設計時,遇到了訊號多驅動問題。
記錄下來,提醒自己,方便他人。
1.現象起源
最近在設計YOLO—V3的模組邏輯。 在準備上FPGA時,綜合報錯:訊號多驅動錯誤。
2.原因分析
檢視程式碼後,發現是在不同的[email protected]語句中對同一個訊號進行了賦值,造成了多驅動問題。 比如:
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
以上三種情況,怎麼解決呢? 留待思考。