Tek-Atımlık Bir Prosedürel Blok
initial begin ... end, always'in kardeşidir. Fark: initial tam olarak bir kez çalışır, 0 zamanında başlar ve sonra sona erer. Sensitivity list yok, döngü yok.
Tek bir nedenle var: testbench kurulumu. Başlangıç değerleri ayarlama, stimulus başlatma, log dosyaları açma, sabit bir simülasyon süresi sonrası $finish çağırma - bir çalışmanın başında bilinen bir sırada bir kez gerçekleşmesini istediğin her şey.
Simülatörün ne yaptığını adım adım izle:
- Zaman 0'a ilerler.
initialbloğu başlar. İlk$displayyazdırılır.data,8'hA5'e ayarlanır.#10, simüle edilen zamanı 10 birim ilerletir.- İkinci
$displayyazdırılır. $finishsimülasyonu bitirir.
Blok bir kez çalıştı. İkinci bir geçiş yok.
Kanonik Testbench İskeleti
Yazacağın hemen hemen her testbench böyle bir initial bloğu kullanır:
Şekle bak - her seferinde uzanacağın testbench şablonudur:
- VCD dump dosyasını aç (
$dumpfile,$dumpvars) - Dumpfile and VCD bölümünde kapsanır. - Başlangıç değerleri ayarla ve reset'i birkaç döngü tut.
- Stimulus sür,
#gecikmeleriyle araya serpilmiş bir dizi değişiklik aracılığıyla. - Simülasyonu temiz bir şekilde bitirmek için
$finish.
Hepsi bu. Göreceğin her Verilog testi, satıcı örneklerindekiler dahil, bu kalıbı takip eder.
Birden Çok initial Bloğu Paraleldir
Aynı modüldeki birkaç initial bloğu hepsi 0 zamanında aynı anda başlar. Her biri kendi zaman diliminde kendi ifadelerini çalıştırır:
Simülatör her iki bloğu da 0 zamanında başlatır. B bloğunun ilk $display'i hemen çalışır. A bloğu yazdırmadan önce 5 birim bekler. B 2 zamanında tekrar yazdırır. A'nın ikinci yazdırması 15 zamanında ateşlenir. B'nin $finish'i simülasyonu 22 zamanında öldürür.
Kurulumu, saat üretimini ve stimulus'u ayrı initial bloklara bölmek yaygın bir stildir - her blok kısadır ve bir şey yapar.
Tanımlamalarda Inline Initialization
Yaygın bir kompakt form: bir reg'i tanımlama zamanında başlangıçta initialize et. Çoğu simülatör bunu bir initial ile aynı şekilde işler:
reg clk = 0;
reg reset = 1;
reg [7:0] count = 0;
Bu şuna eşdeğerdir:
reg clk;
reg reset;
reg [7:0] count;
initial begin
clk = 0;
reset = 1;
count = 0;
end
Kompakt form testbench'lerde göreceğindir - başlangıç değerini taramayı kolaylaştırdığı tanımlamanın yanına koyar.
initial Yalnızca Simülasyona Özgüdür
Sentez araçları initial bloklarını yok sayar. Gerçek donanımın, kurulum kodunun çalıştığı bir "zaman sıfır" anı yoktur - güç açma, reset sinyalleri ve bunlardan gelen konfigürasyona sahiptir. Gerçek donanımda bir register'ın bilinen bir durumda başlamasına ihtiyacın varsa, onu bir always @(posedge clk) içinde bir reset sinyaliyle sür:
always @(posedge clk) begin
if (reset) state <= IDLE;
else state <= next_state;
end
O if (reset) dalı, initial state = IDLE'ın sentezlenebilir karşılığıdır. Reset, "gerçek donanımda bir register'ı nasıl initialize ederim?" sorusunun cevabıdır.
Bazı FPGA akışları register reset değerleri için kısıtlı bir initial'ı kabul eder (örneğin Xilinx araçları), ama bu satıcıya özgü bir uzantıdır. Taşınabilir kodda buna güvenme.
initial İçinde Göreceğin Şeyler
Standart testbench iskeleti ötesindeki birkaç yaygın kalıp:
Zaman Gecikmeli Sonlandırma
initial begin
#1000 $finish; // güvenlik ağı: 1000 zaman birimi sonra sim'i öldür
end
Tek işi simülasyona sert bir üst sınır koymak olan ayrı bir initial. Ana stimulus bloğun asla gelmeyen bir sinyali beklerken deadlock'a girse bile, bu blok tetiklenir ve çalışmayı bitirir.
Waveform Kurulumu
initial begin
$dumpfile("dump.vcd");
$dumpvars(0, test); // test scope'u altındaki her şeyi dump et
end
Bu iki satır simülatöre test scope'undaki her sinyalle bir VCD dosyası yazmasını söyler. Onlarsız, waveform alamazsın.
İlk Memory İmajı
reg [7:0] memory [0:255];
initial begin
$readmemh("image.hex", memory);
end
$readmemh, hex formatlı bir dosyayı array'e yükler. Instruction memory'yi önceden yüklemek için CPU testbench'lerinde kullanılır. Yalnızca simülasyon.
Yaygın Hatalar
initial'ı sentezlenebilir mantık için kullanmak. Sentezlenmez. Bunun yerine reset sinyallerini kullan.
$finish'i unutmak. Onsuz simülatör başka bir şey durdurana kadar çalışır (varsayılan zaman sınırı, manuel kesinti vb.). Hızlı bir test için iyidir; regression script için her zaman $finish.
Stimulus atamaları arasında #delay'i unutmak. Gecikmesiz a = 0; b = 1; yazarsan, her ikisi de aynı simülasyon zamanında gerçekleşir ve DUT bunları ayrı olaylar olarak değil eşzamanlı olarak görebilir. Ayrı stimulus olayları arasına #1 veya daha uzun ekle.
initial'dan bir wire sürmeye çalışmak. always ile aynı kural: yalnızca reg yasal hedeftir.
Sırada Ne Var
İki prosedürel blok türünü gördün. Bir sonraki doc, başlangıç seviyesi Verilog'daki en kafa karıştırıcı konuyu kapsar: Blocking vs Non-blocking Atama. Ne zaman = ne zaman <= kullanılacağını bilmek, çalışan bir flip-flop ile bir race condition felaketi arasındaki farktır.
Sıkça Sorulan Sorular
Verilog'da initial block nedir?
initial begin ... end, simülasyon başında, 0 zamanında tam olarak bir kez çalışan bir prosedürel bloktur. Testbench state'i kurmak için standart yerdir: sinyalleri initialize etmek, log dosyalarını açmak, $dumpfile/$dumpvars çağırmak, stimulus sürmek ve simülasyonu $finish ile bitirmek. Bir modülde birden çok initial bloğu birlikte var olabilir; hepsi 0 zamanında paralel olarak başlar.
Verilog'da initial ile always arasındaki fark nedir?
initial 0 zamanında bir kez çalışır ve sonra sona erer. always sonsuza kadar tekrar çalışır - bir sensitivity list'i vardır ve listelenen sinyaller değiştiğinde uyanır. initial neredeyse yalnızca testbench'lerde kullanılır. always hem testbench'lerin hem de sentezlenebilir RTL'nin iş atıdır.
Initial block sentezlenebilir mi?
Düz Verilog'da hayır. Sentez araçları initial bloklarını yok sayar çünkü gerçek donanımda kurulum kodunun çalıştığı bir 'zaman sıfır' anı yoktur. Bazı FPGA toolchain'leri register reset değerleri ayarlamak için kısıtlı bir form kabul eder, ama genel durum yalnızca simülasyondur. initial bloklarını testbench'lerde tut; sentezlenebilir mantığı initialize etmek için reset sinyallerini kullan.
Verilog modülünde birden çok initial bloğu olabilir mi?
Evet. Her initial bloğu 0 zamanında başlar ve bağımsız olarak tamamlanır. Kurulumu birden çok bloğa bölmek yaygın bir testbench kalıbıdır - saat üretimi için bir blok, stimulus için bir blok, waveform dump için bir blok. 0 zamanından itibaren eşzamanlı olarak çalışırlar; simülatör zaman ilerledikçe ifadelerini iç içe geçirir.