Waktu di Software vs Waktu di Hardware
Dalam sebuah program, waktu maju satu instruksi demi satu instruksi. CPU menyelesaikan baris 1, lalu menjalankan baris 2. Kalau kamu ingin dua hal terjadi bersamaan, kamu memakai thread, async, atau mesin kedua.
Di hardware, semuanya terjadi sekaligus. Rangkaian tidak bergiliran. Adder selalu menjumlahkan, multiplexer selalu memilih, flip-flop selalu mengawasi clock. Tidak ada program counter. Tidak ada "baris saat ini".
Verilog harus menggambarkan dunia itu dalam bentuk teks. Cara Verilog melakukannya adalah sumber semua kebingungan di bab ini.
Dua Lapis Konkurensi
Saat membaca sebuah module Verilog, kamu sedang melihat dua hal yang berbeda sekaligus:
- Deskripsi statis dari rangkaian. Kabel, register, instance gerbang, instance sub-module, penugasan kontinu. Semua ini ada secara bersamaan. Urutannya di dalam file tidak penting.
- Blok prosedural, yaitu
initialdanalways, yang terlihat seperti program kecil yang dijalankan simulator langkah demi langkah. Di dalam salah satu blok ini, pernyataan memang berjalan dengan semacam urutan. Tapi beberapa blokalwaysbisa aktif sekaligus, masing-masing di "thread" kecil waktu simulasinya sendiri.
module example(input wire a, input wire b, output wire y, output wire z);
assign y = a & b; // exists at all times
assign z = a | b; // also exists at all times, in parallel
always @(posedge a) begin
// a separate "always-on" reactor that wakes up on each
// rising edge of `a`
end
endmodule
Dua baris assign itu bukan urutan. Keduanya menggambarkan dua potong logika kombinasional yang bisa ditata berdampingan oleh tool sintesis. Blok always adalah hal ketiga yang terjadi secara paralel.
Arti "Sinyal"
Di software, variabel menyimpan nilai sampai kamu mengubahnya. Di Verilog, sinyal menyimpan nilai terus-menerus, dan di setiap saat nilainya bergantung pada apa pun yang menggerakkannya.
wire digerakkan dari luar (sebuah assign, port output dari sub-module, koneksi inout). reg digerakkan dari dalam blok prosedural. Keduanya punya nilai setiap saat. Tidak ada yang namanya "belum diinisialisasi" dalam arti C: sinyal bisa digerakkan ke nilai yang jelas, ke nilai khusus tidak diketahui x, atau ke impedansi tinggi z. Dua yang terakhir dibahas di Nilai X dan Z.
Clock Mengubah Segalanya
Begitu clock masuk, waktu mulai berpengaruh. Flip-flop adalah potongan hardware kecil yang menangkap nilai input-nya pada tepi naik (atau tepi turun) clock dan menahannya sampai tepi berikutnya. Yang memungkinkanmu membangun counter, state machine, pipeline, apa pun yang punya memori, adalah clock.
Perhatikan q <= d, bukan q = d. Itu adalah penugasan non-blocking, andalan utama logika yang dikendalikan clock. Artinya "di tepi clock berikutnya, jadwalkan q agar bernilai sama dengan d saat ini". Aturannya dibahas lebih dalam di Blocking vs Non-blocking; untuk sekarang, cukup sadari bahwa penugasan itu tidak sedang berpura-pura menjadi pernyataan software.
RTL: Model Berpikir Register Transfer
Kebanyakan Verilog yang bisa disintesis ditulis dengan gaya yang disebut Register Transfer Level, atau RTL. Idenya sederhana:
- Tentukan state apa yang dibutuhkan rangkaianmu (register-nya).
- Untuk setiap register, gambarkan dua hal: apa yang membuatnya reset, dan logika kombinasional apa yang menghitung nilai berikutnya.
- Hubungkan output logika kombinasional ke input register, dan kamu punya rangkaian yang berfungsi.
always @(posedge clk) begin
if (reset) state <= IDLE;
else state <= next_state;
end
always @(*) begin
case (state)
IDLE: next_state = start ? RUNNING : IDLE;
RUNNING: next_state = done ? IDLE : RUNNING;
default: next_state = IDLE;
endcase
end
Itu adalah mesin dua state. Blok always pertama dikendalikan clock: itu flip-flop. Yang kedua murni kombinasional: itu hanya sebuah persamaan. Hampir setiap state machine, counter, dan pipeline yang akan kamu tulis mengikuti bentuk itu.
Kebiasaan yang Membuatmu Tersandung
Kalau kamu datang dari dunia software, ini daftar singkat kebiasaan yang perlu kamu tinggalkan:
- "Variabel berubah saat aku memberinya nilai." Tidak di tepi clock: penugasan non-blocking menjadwalkan perubahannya di akhir langkah waktu.
- "Pernyataan dijalankan dari atas ke bawah." Di luar blok prosedural, tidak. Di dalam blok yang dikendalikan clock, kurang lebih begitu, tapi blocking vs non-blocking mengubah arti "berurutan" yang sebenarnya.
- "Aku akan mengalokasikan ini saat dibutuhkan." Hardware tidak mengalokasikan. Setiap register dan gerbang harus sudah ada saat sintesis. Ukuran setiap vektor sudah tetap.
- "Loop ini cepat, cuma satu operasi." Loop
fordi Verilog yang bisa disintesis dibuka (unrolled) menjadi hardware paralel. Loop 64 iterasi menjadi 64 salinan isi loop, bukan instruksi CPU yang berjalan 64 kali.
Kamu tidak sedang belajar menulis program. Kamu sedang belajar menggambarkan rangkaian. Naluri membaca dari atas ke bawah justru yang salah, dan butuh waktu untuk melatihnya ulang.
Selanjutnya
Dokumen berikutnya membahas cara menyiapkan toolchain lokal (opsional, editor browser sudah cukup), lalu menulis module pertamamu dari nol. Kita akan kembali ke perbandingan hardware vs software setiap kali ada yang terlihat aneh, karena sebagian besar bagian yang "aneh" punya akar masalah yang sama: ini bukan software.
Pertanyaan yang sering diajukan
Apa perbedaan hardware dan software dalam konteks Verilog?
Software adalah urutan instruksi yang dijalankan CPU, satu per satu. Hardware, yaitu hal yang digambarkan Verilog, adalah jaringan gerbang logika dan kabel yang semuanya membawa sinyal pada waktu yang sama. File Verilog menggambarkan jaringan itu. Simulator meniru perilaku paralelnya; tool sintesis mengubahnya menjadi silikon sungguhan.
Apakah kode Verilog berjalan dari atas ke bawah seperti C?
Tidak, dan memperlakukannya seperti itu adalah kesalahan pemula yang paling umum. Pernyataan di tingkat atas (assign, instance module, blok always) semuanya 'ada' sekaligus. Hanya di dalam blok prosedural, yaitu initial dan always, terjadi sesuatu yang mirip eksekusi berurutan, dan bahkan di sana penugasan non-blocking mematahkan ilusi itu.
Apa arti 'concurrent' di Verilog?
Artinya beberapa pernyataan menggambarkan bagian-bagian rangkaian yang semuanya bekerja pada waktu yang sama. Dua pernyataan assign di module yang sama bukan 'baris 1 lalu baris 2'. Keduanya adalah dua potong hardware yang berjalan paralel dan terus-menerus bereaksi terhadap input-nya.
Apa itu desain RTL?
RTL adalah singkatan dari Register Transfer Level. Ini gaya menulis Verilog di mana kamu menggambarkan rangkaian sebagai register (flip-flop) dan logika kombinasional yang menghitung nilai berikutnya. Kebanyakan Verilog yang bisa disintesis adalah RTL. Tingkat di atasnya adalah behavioral; tingkat di bawahnya adalah gate-level.