İ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.
wiresinyalleri prosedürel blokların dışında sürülür -assignifadeleri tarafından, alt modüllerin çıkışları tarafından veya modül giriş portları tarafından.regsinyalleri prosedürel blokların içinde sürülür -initialveyaalways.
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:
yvez, modüldewireve testbench'te tekrarwireolarak tanımlanır.assignile sürülürler - bu continuous-assignment formudur.='in sağ tarafı içindeki herhangi bir sinyal değiştiğinde tekrar hesaplanır.y'yiwireolarak tutarken biralwaysbloğunun içiney = a & byazamayı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?
assignile 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.) initialveyaalways'ten süreceksen? →reg.- Prosedürel kod tarafından sürülen modül çıkış portu? →
output reg. assignile sürülen modül çıkış portu? →output wire. (Veya sadeceoutput- 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.