1. 程式人生 > >verilogHDL,system Verilog程式碼的多驅動問題

verilogHDL,system Verilog程式碼的多驅動問題

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

以上三種情況,怎麼解決呢? 留待思考。