Blok Prosedural Sekali Jalan
initial begin ... end adalah saudara dari always. Bedanya: initial berjalan tepat satu kali, mulai pada waktu 0, lalu berhenti. Tidak ada sensitivity list dan tidak ada perulangan.
Blok ini ada untuk satu alasan: persiapan testbench. Mengatur nilai awal, memulai stimulus, membuka file log, memanggil $finish setelah waktu simulasi tertentu: semua hal yang ingin kamu lakukan sekali di awal sebuah run, dengan urutan yang jelas.
Ikuti apa yang dilakukan simulator langkah demi langkah:
- Waktu maju ke 0.
- Blok
initialdimulai.$displaypertama mencetak. datadiisi8'hA5.#10memajukan waktu simulasi sebanyak 10 satuan.$displaykedua mencetak.$finishmengakhiri simulasi.
Blok itu berjalan sekali. Tidak ada putaran kedua.
Kerangka Testbench yang Baku
Hampir setiap testbench yang akan kamu tulis memakai blok initial seperti ini:
Perhatikan bentuknya: inilah templat testbench yang akan selalu kamu pakai:
- Buka file dump VCD (
$dumpfile,$dumpvars), yang dibahas di Dumpfile dan VCD. - Atur nilai awal dan tahan reset selama beberapa siklus.
- Gerakkan stimulus lewat serangkaian perubahan yang diselingi delay
#. $finishuntuk mengakhiri simulasi dengan rapi.
Itu saja. Setiap pengujian Verilog yang akan kamu lihat, termasuk yang ada di contoh vendor, mengikuti pola ini.
Beberapa Blok initial Berjalan Paralel
Beberapa blok initial di module yang sama semuanya mulai pada waktu 0 secara bersamaan. Masing-masing menjalankan pernyataannya sendiri di potongan waktunya sendiri:
Simulator memulai kedua blok pada waktu 0. $display pertama di blok B langsung berjalan. Blok A menunggu 5 satuan sebelum mencetak. Blok B mencetak lagi pada waktu 2. Cetakan kedua blok A muncul pada waktu 15. $finish di blok B menghentikan simulasi pada waktu 22.
Memecah persiapan, pembangkitan clock, dan stimulus ke blok initial yang terpisah adalah gaya yang umum: setiap blok pendek dan hanya mengerjakan satu hal.
Inisialisasi Langsung di Deklarasi
Bentuk ringkas yang umum: inisialisasi reg langsung saat deklarasi. Kebanyakan simulator memperlakukannya sama dengan initial:
reg clk = 0;
reg reset = 1;
reg [7:0] count = 0;
Itu setara dengan:
reg clk;
reg reset;
reg [7:0] count;
initial begin
clk = 0;
reset = 1;
count = 0;
end
Bentuk ringkas inilah yang akan kamu lihat di testbench: nilai awalnya langsung berada di sebelah deklarasi, sehingga mudah dibaca sekilas.
initial Khusus Simulasi
Tool sintesis mengabaikan blok initial. Hardware sungguhan tidak punya "momen nol" saat kode persiapan dijalankan; yang ada adalah saat dinyalakan, sinyal reset, dan konfigurasi yang datang dari peristiwa-peristiwa itu. Kalau kamu butuh register yang mulai dari state yang jelas di hardware sungguhan, gerakkan dengan sinyal reset di dalam always @(posedge clk):
always @(posedge clk) begin
if (reset) state <= IDLE;
else state <= next_state;
end
Cabang if (reset) itu adalah padanan initial state = IDLE yang bisa disintesis. Reset adalah jawaban untuk "bagaimana cara menginisialisasi register di hardware sungguhan?"
Beberapa alur FPGA memang menerima initial terbatas untuk nilai reset register (misalnya tool Xilinx), tapi itu ekstensi milik vendor tertentu. Jangan mengandalkannya di kode yang harus portabel.
Hal-Hal yang Akan Kamu Lihat di Dalam initial
Beberapa pola umum selain kerangka testbench standar:
Penghentian dengan Delay Waktu
initial begin
#1000 $finish; // safety net: kill the sim after 1000 time units
end
Sebuah initial terpisah yang tugasnya hanya memberi batas atas yang pasti pada simulasi. Bahkan kalau blok stimulus utamamu macet menunggu sinyal yang tidak pernah datang, blok ini tetap berjalan dan mengakhiri run.
Persiapan Waveform
initial begin
$dumpfile("dump.vcd");
$dumpvars(0, test); // dump everything under the `test` scope
end
Dua baris ini menyuruh simulator menulis file VCD berisi setiap sinyal di scope test. Tanpanya, kamu tidak mendapat waveform.
Isi Awal Memori
reg [7:0] memory [0:255];
initial begin
$readmemh("image.hex", memory);
end
$readmemh memuat file berformat hex ke dalam array. Dipakai di testbench CPU untuk mengisi memori instruksi lebih dulu. Khusus simulasi.
Kesalahan yang Umum
Memakai initial untuk logika yang akan disintesis. Ia tidak akan tersintesis. Pakai sinyal reset sebagai gantinya.
Lupa $finish. Tanpanya, simulator berjalan sampai ada hal lain yang menghentikannya (batas waktu default, interupsi manual, dan lain-lain). Untuk tes cepat itu tidak masalah; untuk skrip regresi, selalu pakai $finish.
Lupa #delay di antara penugasan stimulus. Kalau kamu menulis a = 0; b = 1; tanpa delay, keduanya terjadi pada waktu simulasi yang sama dan DUT mungkin melihatnya bersamaan, bukan sebagai event terpisah. Sisipkan #1 atau lebih di antara event stimulus yang berbeda.
Mencoba menggerakkan wire dari initial. Aturannya sama dengan always: hanya reg yang menjadi target yang sah.
Selanjutnya
Kamu sudah melihat dua jenis blok prosedural. Dokumen berikutnya membahas topik yang paling sering membingungkan pemula Verilog: Penugasan Blocking vs Non-blocking. Tahu kapan memakai = dan kapan memakai <= adalah pembeda antara flip-flop yang berfungsi dan kekacauan race condition.
Pertanyaan yang sering diajukan
Apa itu blok initial di Verilog?
initial begin ... end adalah blok prosedural yang berjalan tepat satu kali di awal simulasi, pada waktu 0. Ini tempat standar untuk menyiapkan state testbench: menginisialisasi sinyal, membuka file log, memanggil $dumpfile/$dumpvars, menggerakkan stimulus, dan mengakhiri simulasi dengan $finish. Beberapa blok initial bisa ada bersamaan dalam satu module; semuanya mulai pada waktu 0 secara paralel.
Apa perbedaan initial dan always di Verilog?
initial berjalan sekali pada waktu 0 lalu berhenti. always berjalan ulang selamanya: ia punya sensitivity list dan bangun setiap kali sinyal yang tercantum berubah. initial hampir hanya dipakai di testbench. always adalah andalan utama baik di testbench maupun di RTL yang bisa disintesis.
Apakah blok initial bisa disintesis?
Tidak di Verilog biasa. Tool sintesis mengabaikan blok initial karena hardware sungguhan tidak punya momen 'waktu nol' saat kode persiapan dijalankan. Beberapa toolchain FPGA menerima bentuk terbatas untuk mengatur nilai reset register, tapi pada umumnya blok ini khusus simulasi. Simpan blok initial di testbench; pakai sinyal reset untuk menginisialisasi logika yang bisa disintesis.
Bisakah satu module Verilog punya beberapa blok initial?
Bisa. Setiap blok initial mulai pada waktu 0 dan berjalan sampai selesai secara independen. Memecah persiapan ke beberapa blok adalah pola testbench yang umum: satu blok untuk membangkitkan clock, satu untuk stimulus, satu untuk menyimpan waveform. Semuanya berjalan bersamaan sejak waktu 0; simulator menyelang-nyelingi pernyataan-pernyataannya seiring waktu berjalan.