Menu

Blok Initial Verilog: Menjalankan Kode Persiapan di Awal Simulasi

Apa bedanya blok initial dengan always, kenapa blok ini hanya ada di simulasi, dan pola-pola umum pemakaiannya: stimulus, persiapan waveform, header log.

Halaman ini dilengkapi editor yang bisa dijalankan. Edit, jalankan, dan lihat output-nya seketika.

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:

  1. Waktu maju ke 0.
  2. Blok initial dimulai. $display pertama mencetak.
  3. data diisi 8'hA5.
  4. #10 memajukan waktu simulasi sebanyak 10 satuan.
  5. $display kedua mencetak.
  6. $finish mengakhiri 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:

  1. Buka file dump VCD ($dumpfile, $dumpvars), yang dibahas di Dumpfile dan VCD.
  2. Atur nilai awal dan tahan reset selama beberapa siklus.
  3. Gerakkan stimulus lewat serangkaian perubahan yang diselingi delay #.
  4. $finish untuk 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.

Ilustrasi bahasa pemrograman di Coddy

Belajar coding dengan Coddy

Mulai