99re热视频这里只精品,久久久天堂国产精品女人,国产av一区二区三区,久久久精品成人免费看片,99久久精品免费看国产一区二区三区

Verilog 競(jìng)爭(zhēng)與冒險(xiǎn)

2022-05-18 09:51 更新

關(guān)鍵字:競(jìng)爭(zhēng),冒險(xiǎn),書(shū)寫(xiě)規(guī)范

產(chǎn)生原因

數(shù)字電路中,信號(hào)傳輸與狀態(tài)變換時(shí)都會(huì)有一定的延時(shí)。

  • 在組合邏輯電路中,不同路徑的輸入信號(hào)變化傳輸?shù)酵稽c(diǎn)門(mén)級(jí)電路時(shí),在時(shí)間上有先有后,這種先后所形成的時(shí)間差稱(chēng)為競(jìng)爭(zhēng)(Competition)。
  • 由于競(jìng)爭(zhēng)的存在,輸出信號(hào)需要經(jīng)過(guò)一段時(shí)間才能達(dá)到期望狀態(tài),過(guò)渡時(shí)間內(nèi)可能產(chǎn)生瞬間的錯(cuò)誤輸出,例如尖峰脈沖。這種現(xiàn)象被稱(chēng)為冒險(xiǎn)(Hazard)。
  • 競(jìng)爭(zhēng)不一定有冒險(xiǎn),但冒險(xiǎn)一定會(huì)有競(jìng)爭(zhēng)。

例如,對(duì)于給定邏輯 ?F = A & A'?,電路如左下圖所示。

由于反相器電路的存在,信號(hào) ?A'? 傳遞到與門(mén)輸入端的時(shí)間相對(duì)于信號(hào) ?A? 會(huì)滯后,這就可能導(dǎo)致與門(mén)最后的輸出結(jié)果 ?F? 會(huì)出現(xiàn)干擾脈沖。如下圖所示。



其實(shí)實(shí)際硬件電路中,只要門(mén)電路各個(gè)輸入端延時(shí)不同,就有可能產(chǎn)生競(jìng)爭(zhēng)與冒險(xiǎn)。

例如一個(gè)簡(jiǎn)單的與門(mén),輸入信號(hào)源不一定是同一個(gè)信號(hào)變換所來(lái),由于硬件工藝、其他延遲電路的存在,也可能產(chǎn)生競(jìng)爭(zhēng)與冒險(xiǎn),如下圖所示。


判斷方法

代數(shù)法

在邏輯表達(dá)式,保持一個(gè)變量固定不動(dòng),將剩余其他變量用 0 或 1 代替,如果最后邏輯表達(dá)式能化簡(jiǎn)成?Y = A + A'?或?Y = A · A'?的形式,則可判定此邏輯存在競(jìng)爭(zhēng)與冒險(xiǎn)。

例如邏輯表達(dá)式 ?Y = AB + A'C?,在 ?B=C=1? 的情況下,可化簡(jiǎn)為 ?Y = A + A'?。顯然,?A? 狀態(tài)的改變,勢(shì)必會(huì)造成電路存在競(jìng)爭(zhēng)冒險(xiǎn)。

卡諾圖法

有兩個(gè)相切的卡諾圈,并且相切處沒(méi)有其他卡諾圈包圍,可能會(huì)出現(xiàn)競(jìng)爭(zhēng)與冒險(xiǎn)現(xiàn)象。

例如左下圖所存在競(jìng)爭(zhēng)與冒險(xiǎn),右下圖則沒(méi)有。


其實(shí),卡諾圖本質(zhì)上還是對(duì)邏輯表達(dá)式的一個(gè)分析,只是可以進(jìn)行直觀(guān)的判斷。

例如,左上圖邏輯表達(dá)式可以簡(jiǎn)化為 ?Y = A'B' + AC?,當(dāng) ?B=0? 且 ?C=1? 時(shí),此邏輯表達(dá)式又可以表示為 ?Y = A' + A?。所以肯定會(huì)存在競(jìng)爭(zhēng)與冒險(xiǎn)。

右上圖邏輯表達(dá)式可以簡(jiǎn)化為 ?Y = A'B' + AB?,顯然 B 無(wú)論等于 1 還是 0,此式都不會(huì)化簡(jiǎn)成 ?Y = A' + A?。所以此邏輯不存在競(jìng)爭(zhēng)與冒險(xiǎn)。

需要注意的是,卡諾圖是首尾相臨的。如下圖所示,雖然看起來(lái)兩個(gè)卡諾圈并沒(méi)有相切,但實(shí)際上,m6 與 m4 也是相鄰的,所以下面卡諾圖所代表的數(shù)字邏輯也會(huì)產(chǎn)生競(jìng)爭(zhēng)與冒險(xiǎn)。


其他較為復(fù)雜的情況,可能需要采用 "計(jì)算機(jī)輔助分析 + 實(shí)驗(yàn)" 的方法。

消除方法

對(duì)數(shù)字電路來(lái)說(shuō),常見(jiàn)的避免競(jìng)爭(zhēng)與冒險(xiǎn)的方法主要有 4 種。

  1. 增加濾波電容,濾除窄脈沖
  2. 此種方法需要在輸出端并聯(lián)一個(gè)小電容,將尖峰脈沖的幅度削弱至門(mén)電路閾值以下。

    此方法雖然簡(jiǎn)單,但是會(huì)增加輸出電壓的翻轉(zhuǎn)時(shí)間,易破壞波形。

  3. 修改邏輯,增加冗余項(xiàng)
  4. 利用卡諾圖,在兩個(gè)相切的圓之間,增加一個(gè)卡諾圈,并加在邏輯表達(dá)式之中。

    如下圖所示,對(duì)數(shù)字邏輯 ?Y = A'B' + AC? 增加冗余項(xiàng) ?B'C?,則此電路邏輯可以表示為 ?Y = A'B' + AC + B'C?。此時(shí)電路就不會(huì)再存在競(jìng)爭(zhēng)與冒險(xiǎn)。


  5. 使用時(shí)鐘同步電路,利用觸發(fā)器進(jìn)行打拍延遲
  6. 同步電路信號(hào)的變化都發(fā)生在時(shí)鐘邊沿。對(duì)于觸發(fā)器的 D 輸入端,只要毛刺不出現(xiàn)在時(shí)鐘的上升沿并且不滿(mǎn)足數(shù)據(jù)的建立和保持時(shí)間,就不會(huì)對(duì)系統(tǒng)造成危害,因此可認(rèn)為 D 觸發(fā)器的 D 輸入端對(duì)毛刺不敏感。 利用此特性,在時(shí)鐘邊沿驅(qū)動(dòng)下,對(duì)一個(gè)組合邏輯信號(hào)進(jìn)行延遲打拍,可消除競(jìng)爭(zhēng)冒險(xiǎn)。

    延遲一拍時(shí)鐘時(shí),會(huì)一定概率的減少競(jìng)爭(zhēng)冒險(xiǎn)的出現(xiàn)。實(shí)驗(yàn)表明,最安全的打拍延遲周期是 3 拍,可有效減少競(jìng)爭(zhēng)冒險(xiǎn)的出現(xiàn)。

    當(dāng)然,最終還是需要根據(jù)自己的設(shè)計(jì)需求,對(duì)信號(hào)進(jìn)行合理的打拍延遲。

    為說(shuō)明對(duì)信號(hào)進(jìn)行打拍延遲可以消除競(jìng)爭(zhēng)冒險(xiǎn),我們建立下面的代碼模型。

    module competition_hazard
        (
          input             clk ,
          input             rstn ,
          input             en ,
          input             din_rvs ,
          output reg        flag
        );
    
        wire    condition = din_rvs & en ;  //combination logic
        always @(posedge clk or negedge !rstn) begin
            if (!rstn) begin
                flag   <= 1'b0 ;
            end
            else begin
                flag   <= condition ;
            end
        end
    
    endmodule

    testbench 描述如下:

    `timescale 1ns/1ns
    
    module test ;
        reg          clk, rstn ;
        reg          en ;
        reg          din_rvs ;
        wire         flag_safe, flag_dgs ;
    
        //clock and rstn generating
        initial begin
            rstn              = 1'b0 ;
            clk               = 1'b0 ;
            #5 rstn           = 1'b1 ;
            forever begin
                #5 clk = ~clk ;
            end
        end
    
        initial begin
            en        = 1'b0 ;
            din_rvs   = 1'b1 ;
            #19 ;      en        = 1'b1 ;
            #1 ;       din_rvs   = 1'b0 ;
        end
    
        competition_hazard         u_dgs
         (
          .clk              (clk           ),
          .rstn             (rstn          ),
          .en               (en            ),
          .din_rvs          (din_rvs       ),
          .flag             (flag_dgs      ));
    
        initial begin
            forever begin
                #100;
                if ($time >= 1000)  $finish ;
            end
        end
    
    endmodule // test

    仿真結(jié)果如下:

    由圖可知,信號(hào) ?condition ?出現(xiàn)了一個(gè)尖峰脈沖,這是由于信號(hào) ?din_rvs ?與信號(hào) ?en ?相對(duì)于模塊內(nèi)部時(shí)鐘都是異步的,所以到達(dá)內(nèi)部門(mén)電路時(shí)的延時(shí)是不同的,就有可能造成競(jìng)爭(zhēng)冒險(xiǎn)。

    雖然最后的仿真結(jié)果 ?flag ?一直為 0,似乎是我們想要的結(jié)果。但是實(shí)際電路中,這個(gè)尖峰脈沖在時(shí)間上非??拷鼤r(shí)鐘邊沿,就有可能被時(shí)鐘采集到而產(chǎn)生錯(cuò)誤結(jié)果。


    下面我們對(duì)模型進(jìn)行改進(jìn),增加打拍延時(shí)的邏輯,如下:

    module clap_delay
        (
          input             clk ,
          input             rstn ,
          input             en ,
          input             din_rvs ,
          output reg        flag
        );
    
        reg                  din_rvs_r ;
        reg                  en_r ;
        always @(posedge clk or !rstn) begin
            if (!rstn) begin
                din_rvs_r      <= 1'b0 ;
                en_r           <= 1'b0 ;
            end
            else begin
                din_rvs_r      <= din_rvs ;
                en_r           <= en ;
            end
        end
    
        wire                 condition = din_rvs_r & en_r ;
        always @(posedge clk or negedge !rstn) begin
            if (!rstn) begin
                flag   <= 1'b0 ;
            end
            else begin
    
                flag   <= condition ;
            end
        end // always @ (posedge clk or negedge !rstn)
    
    endmodule

    將此模塊例化到上述 testbench 中,得到如下仿真結(jié)果。

    由圖可知,信號(hào) ?condition ?沒(méi)有尖峰脈沖的干擾了,仿真結(jié)果中 ?flag ?為 0 也如預(yù)期。

    其實(shí),輸入信號(hào)與時(shí)鐘邊沿非常接近的情況下,時(shí)鐘對(duì)輸入信號(hào)的采樣也存在不確定性,但是不會(huì)出現(xiàn)尖峰脈沖的現(xiàn)象。對(duì)輸入信號(hào)多打 2 拍,是更好的處理方式,對(duì)競(jìng)爭(zhēng)與冒險(xiǎn)有更好的抑制作用。


  7. 采用格雷碼計(jì)數(shù)器
  8. 遞加的多 bit 位計(jì)數(shù)器,計(jì)數(shù)值有時(shí)候會(huì)發(fā)生多個(gè) bit 位的跳變。

    例如計(jì)數(shù)器變量 counter 從 5 計(jì)數(shù)到 6 時(shí), 對(duì)應(yīng)二進(jìn)制數(shù)字為 4'b101 到 4'b110 的轉(zhuǎn)換。因?yàn)楦?nbsp;bit 數(shù)據(jù)位的延時(shí),counter 的變換過(guò)程可能是: ?4'b101 -> 4'b111 -> 4'b110?。如果有以下邏輯描述,則信號(hào) cout 可能出現(xiàn)短暫的尖峰脈沖,這顯然是與設(shè)計(jì)相悖的。

    cout = counter[3:0] == 4'd7 ;     

    而格雷碼計(jì)數(shù)器,計(jì)數(shù)時(shí)相鄰的數(shù)之間只有一個(gè)數(shù)據(jù) bit 發(fā)生了變化,所以能有效的避免競(jìng)爭(zhēng)冒險(xiǎn)。

    好在 Verilog 設(shè)計(jì)時(shí),計(jì)數(shù)器大多都是同步設(shè)計(jì)。即便計(jì)數(shù)時(shí)存在多個(gè) bit 同時(shí)翻轉(zhuǎn)的可能性,但在時(shí)鐘驅(qū)動(dòng)的觸發(fā)器作用下,只要信號(hào)間滿(mǎn)足時(shí)序要求,就能消除掉 100% 的競(jìng)爭(zhēng)與冒險(xiǎn)。

小結(jié)

一般來(lái)說(shuō),為消除競(jìng)爭(zhēng)冒險(xiǎn),增加濾波電容和邏輯冗余,都不是 Verilog 設(shè)計(jì)所考慮的。

計(jì)數(shù)采用格雷碼計(jì)數(shù)器,大多數(shù)也是應(yīng)用在高速時(shí)鐘下減少信號(hào)翻轉(zhuǎn)率來(lái)降低功耗的場(chǎng)合。

利用觸發(fā)器在時(shí)鐘同步電路下對(duì)異步信號(hào)進(jìn)行打拍延時(shí),是 Verilog 設(shè)計(jì)中經(jīng)常用到的方法。

除此之外,為消除競(jìng)爭(zhēng)冒險(xiǎn),Verilog 編碼時(shí)還需要注意一些問(wèn)題,詳見(jiàn)下一小節(jié)。

Verilog 書(shū)寫(xiě)規(guī)范

在編程時(shí)多注意以下幾點(diǎn),也可以避免大多數(shù)的競(jìng)爭(zhēng)與冒險(xiǎn)問(wèn)題。

  1. 時(shí)序電路建模時(shí),用非阻塞賦值。
  2. 組合邏輯建模時(shí),用阻塞賦值。
  3. 在同一個(gè) always 塊中建立時(shí)序和組合邏輯模型時(shí),用非阻塞賦值。
  4. 在同一個(gè) always 塊中不要既使用阻塞賦值又使用非阻塞賦值。
  5. 不要在多個(gè) always 塊中為同一個(gè)變量賦值。
  6. 避免 latch 產(chǎn)生。

下面,對(duì)以上注意事項(xiàng)逐條分析。

  1. 時(shí)序電路建模時(shí),用非阻塞賦值
  2. 前面講述非阻塞賦值時(shí)就陳述過(guò),時(shí)序電路中非阻塞賦值可以消除競(jìng)爭(zhēng)冒險(xiǎn)。

    例如下面代碼描述,由于無(wú)法確定 a 與 b 阻塞賦值的操作順序,就有可能帶來(lái)競(jìng)爭(zhēng)冒險(xiǎn)。

    always @(posedge clk) begin
        a = b ;
        b = a ;
    end

    而使用非阻塞賦值時(shí),賦值操作是同時(shí)進(jìn)行的,所以就不會(huì)帶來(lái)競(jìng)爭(zhēng)冒險(xiǎn),如以下代碼描述。

    always @(posedge clk) begin
        a <= b ;
        b <= a ;
    end
  3. 組合邏輯建模時(shí),用阻塞賦值
  4. 例如,我們想實(shí)現(xiàn) C = A&B, F=C&D 的組合邏輯功能,用非阻塞賦值語(yǔ)句如下。

    兩條賦值語(yǔ)句同時(shí)賦值,F(xiàn) <= C & D 中使用的是信號(hào) C 的舊值,所以導(dǎo)致此時(shí)的邏輯是錯(cuò)誤的,F(xiàn) 的邏輯值不等于 A&B&D。

    而且,此時(shí)要求信號(hào) C 具有存儲(chǔ)功能,但不是時(shí)鐘驅(qū)動(dòng),所以 C 可能會(huì)被綜合成鎖存器(latch),導(dǎo)致競(jìng)爭(zhēng)冒險(xiǎn)。

    always @(*) begin
        C <= A & B ;
        F <= C & D ;
    end

    對(duì)代碼進(jìn)行如下修改,F(xiàn) = C & D 的操作一定是在 C = A & B 之后,此時(shí) F 的邏輯值等于 A&B&D,符合設(shè)計(jì)。

    always @(*) begin
        C = A & B ;
        F = C & D ;
    end
  5. 在同一個(gè) always 塊中建立時(shí)序和組合邏輯模型時(shí),用非阻塞賦值
  6. 雖然時(shí)序電路中可能涉及組合邏輯,但是如果賦值操作使用非阻塞賦值,仍然會(huì)導(dǎo)致如規(guī)范 1 中所涉及的類(lèi)似問(wèn)題。

    例如在時(shí)鐘驅(qū)動(dòng)下完成一個(gè)與門(mén)的邏輯功能,代碼參考如下。

    always @(posedge clk or negedge rst_n)
        if (!rst_n) begin
            q <= 1'b0;
        end
        else begin
            q <= a & b;  //即便有組合邏輯,也不要寫(xiě)成:q = a & b
         end
    end
  7. 在同一個(gè) always 塊中不要既使用阻塞賦值又使用非阻塞賦值
  8. always 涉及的組合邏輯中,既有阻塞賦值又有非阻塞賦值時(shí),會(huì)導(dǎo)致意外的結(jié)果,例如下面代碼描述。

    此時(shí)信號(hào) C 阻塞賦值完畢以后,信號(hào) F 才會(huì)被非阻塞賦值,仿真結(jié)果可能正確。

    但如果 F 信號(hào)有其他的負(fù)載,F(xiàn) 的最新值并不能馬上傳遞出去,數(shù)據(jù)有效時(shí)間還是在下一個(gè)觸發(fā)時(shí)刻。此時(shí)要求 F 具有存儲(chǔ)功能,可能會(huì)被綜合成 latch,導(dǎo)致競(jìng)爭(zhēng)冒險(xiǎn)。

    always @(*) begin
        C = A & B ;
        F <= C & D ;
    end

    如下代碼描述,仿真角度看,信號(hào) C 被非阻塞賦值,下一個(gè)觸發(fā)時(shí)刻才會(huì)有效。而 F = C & D 雖然是阻塞賦值,但是信號(hào) C 不是阻塞賦值,所以 F 邏輯中使用的還是 C 的舊值。

    always @(*) begin
        C <= A & B ;
        F = C & D ;
    end

    下面分析假如在時(shí)序電路里既有阻塞賦值,又有非阻塞賦值會(huì)怎樣,代碼如下。

    假如復(fù)位端與時(shí)鐘同步,那么由于復(fù)位導(dǎo)致的信號(hào) q 為 0,是在下一個(gè)時(shí)鐘周期才有效。

    而如果是信號(hào) a 或 b 導(dǎo)致的 q 為 0,則在當(dāng)期時(shí)鐘周期內(nèi)有效。

    如果 q 還有其他負(fù)載,就會(huì)導(dǎo)致 q 的時(shí)序特別混亂,顯然不符合設(shè)計(jì)需求。

    always @(posedge clk or negedge rst_n)
        if (!rst_n) begin  //假設(shè)復(fù)位與時(shí)鐘同步
            q <= 1'b0;
        end
        else begin
            q = a & b;  
        end
    end

    需要說(shuō)明的是,很多編譯器都支持這么寫(xiě),上述的分析也都是建立在仿真角度上。實(shí)際中如果阻塞賦值和非阻塞賦值混合編寫(xiě),綜合后的電路時(shí)序?qū)⑹清e(cuò)亂的,不利于分析調(diào)試。

  9. 不要在多個(gè) always 塊中為同一個(gè)變量賦值
  10. 與 C 語(yǔ)言有所不同,Verilog 中不允許在多個(gè) always 塊中為同一個(gè)變量賦值。此時(shí)信號(hào)擁有多驅(qū)動(dòng)端(Multiple Driver),是禁止的。當(dāng)然,也不允許 assign 語(yǔ)句為同一個(gè)變量進(jìn)行多次連線(xiàn)賦值。 從信號(hào)角度來(lái)講,多驅(qū)動(dòng)時(shí),同一個(gè)信號(hào)變量在很短的時(shí)間內(nèi)進(jìn)行多次不同的賦值結(jié)果,就有可能產(chǎn)生競(jìng)爭(zhēng)冒險(xiǎn)。

    從語(yǔ)法來(lái)講,很多編譯器檢測(cè)到多驅(qū)動(dòng)時(shí),也會(huì)報(bào) Error。

  11. 避免 latch 產(chǎn)生
  12. 具體分析見(jiàn)下一章:《避免 Latch》

點(diǎn)擊這里下載源碼


以上內(nèi)容是否對(duì)您有幫助:
在線(xiàn)筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)