2012-06-13 15 views
6

Ostatnio widziałem jakiś przerzutnik D kod RTL w Verilog tak:lepszy sposób kodowania przerzutnik D

module d_ff(
      input d, 
      input clk, 
      input reset, 
      input we, 
      output q 
    ); 

    always @(posedge clk) begin 
      if (~reset) begin 
        q <= 1'b0; 
      end 
      else if (we) begin 
        q <= d; 
      end 
      else begin 
        q <= q; 
      end 
    end 
    endmodule 

Czy oświadczenie q <= q; konieczne?

+2

Być może trzeba ustawić wyjścia w ramach _wszystkich okoliczności? – paxdiablo

Odpowiedz

7

Czy instrukcja q < = q; niezbędny?

Nie, nie jest, aw przypadku ASIC może faktycznie zwiększyć powierzchnię i zużycie energii. Nie jestem pewien, jak radzą sobie z tym nowoczesne układy FPGA. Podczas syntezy narzędzie zobaczy tę instrukcję i wymaga, aby q było aktualizowane na każdym dodatnim zboczu zegara. Bez tej ostatniej klauzuli else narzędzie może zaktualizować tylko q, gdy tylko zostaną spełnione określone warunki.

W ASIC oznacza to, że narzędzie do syntezy może wstawić bramkę zegarową (o ile ma taką bibliotekę) zamiast mux. W przypadku pojedynczego DFF może to być faktycznie gorsze, ponieważ bramka zegarowa zwykle jest znacznie większa niż mux, ale jeśli q ma 32 bity, to oszczędności mogą być bardzo znaczące. Nowoczesne narzędzia mogą automatycznie wykryć, czy liczba DFF używających udostępnionego zezwolenia spełnia określony próg, a następnie odpowiednio wybrać bramkę zegarową lub mux.

With final else clause

W tym przypadku narzędzie potrzebuje 3 muxes Dodatkowo, polecane trasy

always @(posedge CLK or negedge RESET) 
    if(~RESET) 
    COUNT <= 0; 
    else if(INC) 
    COUNT <= COUNT + 1; 
    else 
    COUNT <= COUNT; 

Without final else clause

Tutaj narzędzie wykorzystuje pojedynczą bramę zegara dla wszystkich DFFs

always @(posedge CLK or negedge RESET) 
    if(~RESET) 
    COUNT <= 0; 
    else if(INC) 
    COUNT <= COUNT + 1; 

Images from here

+0

To wydaje się być rodzajem optymalizacji, którą syntezator może zrobić dla dowolnego fragmentu kodu, ponieważ zachowanie jest takie samo –

+1

Uważaj na bramkowanie zegara. Może to doprowadzić do usterki. – N8TRO

1

Jeśli chodzi o symulację, usunięcie tej instrukcji nie powinno niczego zmieniać, ponieważ q powinno być typu reg (lub logiczne w SystemVerilog) i powinno utrzymywać jego wartość.

Ponadto większość narzędzi do syntezy powinno generować ten sam obwód w obu przypadkach, ponieważ q jest aktualizowane przy użyciu zadania nieblokującego. Być może lepszym kodem byłoby użycie always_ff zamiast zawsze (jeśli twoje narzędzie to obsługuje). W ten sposób kompilator sprawdzi, czy q jest zawsze aktualizowane przy użyciu nieblokującego przypisania i generowana jest sekwencyjna logika.

Powiązane problemy