Menu

Verilog Wire vs Reg: Hangisini Ne Zaman Kullanmalı (Örneklerle)

Verilog'daki iki ana veri tipi - sürekli bağlantılar için wire ve prosedürel depolama için reg - ve her seferinde aralarında seçim yapma kuralı.

Bu sayfada çalıştırılabilir editörler var - düzenle, çalıştır ve sonucu anında gör.

İki Ad, Bir İş

Verilog'daki her sinyalin bir tipi vardır. İlk karşılaşacağın iki tip wire ve reg'dir. İkisi de bir değer tutabilir. İkisi de tek bitli veya çok bitli olabilir. Fark sinyalin ne olduğu değil - onu kimin sürdüğüdür.

  • wire sinyalleri prosedürel blokların dışında sürülür - assign ifadeleri tarafından, alt modüllerin çıkışları tarafından veya modül giriş portları tarafından.
  • reg sinyalleri prosedürel blokların içinde sürülür - initial veya always.

Tüm kural budur. Anahtar sözcük adları kullanışsızdır çünkü Verilog yazmanın modern yolundan önce gelir. reg, donanımda her zaman bir register olmaz. Nedeni için devam et.

Wire: Sürekli Bağlantı

Bir wire elektriksel bir wire'dır. Sürücüsünün ne ürettiğini sürekli olarak taşır. Bir wire'ın sürülmesinin iki yolu:

Üç şeye dikkat:

  • y ve z, modülde wire ve testbench'te tekrar wire olarak tanımlanır.
  • assign ile sürülürler - bu continuous-assignment formudur. ='in sağ tarafı içindeki herhangi bir sinyal değiştiğinde tekrar hesaplanır.
  • y'yi wire olarak tutarken bir always bloğunun içine y = a & b yazamayız. Derleyici onu reddederdi.

wire anahtar sözcüğünü unutursan, Verilog sinyali senin için tek bitlik bir wire olarak örtük olarak tanımlar - ki bu bazen elverişli, bazen sessiz bir hatadır. Çoğu takım, örtük wire'larda hata veren bir araç seçeneğini etkinleştirir. Açık ol ve tuzağı önle.

Reg: Bir Prosedürel Bloğun İçinde Depolama

Bir reg, initial veya always içinde atama yaptığın bir sinyaldir. Ad, "reg"in "register"a benzer ses çıkardığı dilin erken günlerinden bir kalıntıdır; modern kullanımda bir reg sadece prosedürel kodun yazdığı herhangi bir sinyalin tipidir.

count, modül içinde reg'dir (çünkü always bloğu ona yazar) ve testbench'te wire'dır (çünkü DUT'un çıkış portu onu sürer). Aynı sinyal, farklı roller, her scope'ta farklı tipler.

"Reg" Neden Her Zaman "Register" Anlamına Gelmez

İşte en yaygın başlangıç tuzağı. Bu modül y'yi reg olarak tanımlar - ama sentezlenmiş donanım bir flip-flop içermez:

always @(*) bloğu herhangi bir giriş değişikliğine duyarlıdır. Kombinasyoneldir. Bir sentez aracı o kalıbı görür ve bir AND gate üretir - flip-flop yok, saat yok, sadece mantık. reg anahtar sözcüğü, y'nin bir always içinde atandığı için tamamen sözdizimsel bir gerekliliktir.

Gerçek bir flip-flop elde etmek için, always bloğunun bir saat kenarına duyarlı olması gerekir:

always @(posedge clk) begin
    q <= d;
end

Bu sentez-aracı-lütfen-bir-flip-flop-yap kalıbıdır: saatli sensitivity list, non-blocking atama. Aynı reg anahtar sözcüğü, tamamen farklı donanım. Ayrımı Always Block ve Blocking vs Non-blocking bölümlerinde kapsıyoruz.

Pratikte Karar

Bir sinyal tanımladığın her sefer kendine sor: onu nasıl süreceğim?

  • assign ile süreceksen? → wire.
  • Bir alt modülün çıkış portuna bağlayacaksan? → wire.
  • Modül giriş portu? → wire. (Girişler her zaman wire'dır.)
  • initial veya always'ten süreceksen? → reg.
  • Prosedürel kod tarafından sürülen modül çıkış portu? → output reg.
  • assign ile sürülen modül çıkış portu? → output wire. (Veya sadece output - yalnızca yön varsayılan olarak wire'dır.)

Bu karar ağacı düz Verilog'da karşılaşacağın her durumu kapsar.

Sürücü Çatışmaları

wire sinyalleri teoride birden çok sürücüye sahip olabilir - tri-state bus'ların çalışma şekli budur, burada birkaç modül aynı wire'ı sürebilir ve inaktif olanlar yüksek empedansa (z) gider. Sıradan mantık için, aynı wire'a yazan iki assign ifadesi tanımsız davranış üretir:

assign y = a;
assign y = b;   // KÖTÜ - y'nin iki sürücüsü var

Simülatör birini seçebilir, sinyali X'leyebilir, araca bağlıdır. Her iki şekilde de bu bir hatadır. Açıkça bir bus kurmuyorsan wire başına bir sürücü.

reg sinyalleri yalnızca bir prosedürel bloktan sürülebilir. İki always bloğunun ikisi de aynı reg'i atadığı bir sentez hatasıdır ve simülasyonda gariptir. Aynı kural: bir sürücü.

SystemVerilog Güncellemesi: logic

SystemVerilog (Verilog'un evrildiği üst küme) her ikisini de değiştiren tek bir anahtar sözcük ekler: logic. Bir logic sinyali assign veya bir prosedürel blok tarafından sürülebilir - ama her ikisi de değil - ve derleyici yanlışlıkla çok-sürücülü bir hata kurmandan seni durdurur.

module modern(input logic a, input logic b, output logic y);
    assign y = a ^ b;
endmodule

Sıfırdan bir proje başlatıyorsan ve aracın SystemVerilog'u destekliyorsa (bu sayfadaki editör, -g2012 ile destekler), her yerde logic kullanmak kuralları basitleştirir. Düz .v dosyaları hala wire/reg bölünmesine ihtiyaç duyar ve her iki stili de sonsuza kadar vahşi doğada göreceksin.

Sırada Ne Var

Bir sonraki doc - Vectors and Arrays - aynı iki tipi alır ve onları çok bitli hale nasıl getireceğini gösterir. Bus genişlikleri, aralıklar, packed boyutlar, bit vector'ı ile vector array'i arasındaki fark. Bir bitlik bir adder'dan daha büyük bir şey kurabilmeden önce ihtiyacın olan her şey.

Sıkça Sorulan Sorular

Verilog'da wire ile reg arasındaki fark nedir?

wire ve reg, ikisi de simülasyonun her anında bir sinyal değeri tutar, ama aralarından sinyali kimin sürdüğüne göre seçim yaparsın. Bir wire bir prosedürel blok dışından sürülür - bir assign veya bir alt modül çıkışı tarafından. Bir reg bir initial veya always bloğunun içinden sürülür. Adlar tarihseldir ve yanıltıcıdır; reg her zaman 'register' anlamına gelmez.

Verilog'da reg bir flip-flop demek midir?

Mutlaka değil. Bir reg yalnızca always bloğu bir saat kenarına duyarlı olduğunda ve non-blocking atama kullandığında bir flip-flop'a sentezlenir. Kombinasyonel bir always @(*) bloğunun içinde atanan bir reg, düz kombinasyonel mantığa sentezlenir. Anahtar sözcük Verilog veri tipini seçer, donanımı değil.

Ne zaman wire ne zaman reg kullanmalıyım?

Pratik kural: sinyali assign ile süreceksen veya bir alt modülün çıkış portuna bağlayacaksan, wire kullan. always veya initial bloğunun içinde atama yapacaksan, reg kullan. Bir modülün girişleri her zaman wire'dır. Çıkışlar, assign ile sürülüyorsa wire, prosedürel bir blok tarafından sürülüyorsa reg'dir.

Bir always bloğunun içinde bir wire'a atama yapabilir misin?

Hayır - bu bir sözdizimi hatasıdır. wire sinyalleri yalnızca continuous assignment'lar (assign) ile veya bir alt modül instance'ının çıkışı olarak bağlanarak sürülebilir. initial veya always içindeki herhangi bir şey bir reg'i (veya SystemVerilog'da bir logic'i) hedeflemelidir. Derleyici bunu yakalar ve 'left-hand side type mismatch' şikayet eder.

SystemVerilog'da logic nedir?

logic, SystemVerilog'un wire ve reg'in birleştirilmesidir. Hem bir continuous assignment hem veya prosedürel bir blok tarafından sürülebilir (ama her ikisi de aynı anda değil). Modern kod her yerde logic kullanma yönünde artıyor ve wire/reg ayrımını unutuyor. Düz Verilog dosyaları hala seçim yapmak zorundadır.

Coddy programming languages illustration

Coddy ile kodlamayı öğren

BAŞLA