Mirip Software
Loop for di Verilog adalah salinan dari C:
for (i = 0; i < 8; i = i + 1) begin
// body
end
Tiga bagiannya sama: inisialisasi, kondisi, penambahan. Isinya berjalan ulang selama kondisinya terpenuhi.
Di testbench, loop ini berperilaku persis seperti yang kamu harapkan dari software. Simulator menjalankan setiap iterasi secara bergiliran:
Empat iterasi, empat baris output. Tidak ada kejutan.
Kejutannya muncul saat kamu menaruh loop for di dalam kode yang bisa disintesis.
Pembukaan Loop (Unroll)
Loop for di blok always yang bisa disintesis tidak menjadi loop saat runtime di hardware. Synthesizer membukanya saat elaborasi: loop itu dikembangkan menjadi N salinan isinya, dengan N adalah jumlah iterasinya:
Itu terlihat seperti loop. Di simulasi, simulator memang menjalankan delapan iterasi. Di sintesis, loop itu dibuka menjadi delapan pengecekan paralel dari data[0] sampai data[7], yang semuanya terjadi pada saat yang sama. Synthesizer melihat:
count = 0;
if (data[0]) count = count + 1;
if (data[1]) count = count + 1;
if (data[2]) count = count + 1;
...
if (data[7]) count = count + 1;
…lalu mengubah urutan itu menjadi pohon adder. Perilaku saat berjalannya adalah "lihat kedelapan bit sekaligus dan hitung berapa yang bernilai 1", dalam satu sapuan kombinasional.
Implikasinya: loop for di Verilog yang bisa disintesis tidak gratis. Loop 64 iterasi menjadi 64 salinan isi loop di hardware. Kalau isinya rumit, kamu baru saja membangun blok kombinasional yang besar. Pakai loop saat N kecil (beberapa sampai beberapa puluh). Untuk jumlah yang lebih besar, biasanya kamu butuh counter yang dikendalikan clock dan sebuah state machine.
Batasnya Harus Konstan
Synthesizer hanya bisa membuka loop kalau ia tahu N saat elaborasi. Artinya, batas loop harus berupa konstanta:
// Works - bound is constant
for (i = 0; i < 8; i = i + 1) ...
// Works - bound is a parameter
for (i = 0; i < WIDTH; i = i + 1) ...
// Doesn't synthesize - bound depends on a runtime signal
for (i = 0; i < dynamic_count; i = i + 1) ...
Bentuk terakhir mungkin masih berjalan di simulasi, tapi synthesizer akan menolaknya. Kalau kamu benar-benar butuh loop yang jumlah iterasinya ditentukan saat runtime, bangunlah dengan state machine yang dikendalikan clock dan register counter. Hardware tidak punya loop dengan jumlah putaran variabel seperti di software.
generate for vs for Prosedural
Konstruksi lain yang terpisah tapi berkaitan adalah generate for, yang memakai genvar dan berada di luar blok always:
genvar i;
generate
for (i = 0; i < 8; i = i + 1) begin : g
bit_inverter inv(.x(in[i]), .y(out[i]));
end
endgenerate
Itu mencetak 8 instance dari bit_inverter (dibahas di Instantiasi Module). Sifatnya struktural: kamu sedang mengatakan "buat 8 salinan sub-module ini", bukan menggambarkan perilaku.
Perbedaan singkatnya:
forprosedural (di dalamalways): membuka pernyataan-pernyataan di dalam satu blok behavioral.forgenerate (di luaralways): mereplikasi seluruh konstruksi struktural: instance, pernyataanassign, blok bernama.
Pakai yang sesuai dengan apa yang ingin kamu replikasi.
Saat for Bersinar: Operasi pada Vektor
Loop paling berguna saat kamu melakukan operasi yang sama pada setiap bit sebuah vektor. Menghitung jumlah bit 1 (population count), paritas, membalik urutan byte, membuat tabel lookup:
32 iterasi, masing-masing melakukan satu penugasan bit: jauh lebih mudah dibaca daripada menulis 32 penugasan wire secara manual. Synthesizer membukanya dengan rapi.
while, repeat, forever
Selain for, Verilog punya tiga konstruksi loop lain, kebanyakan untuk testbench:
// Run until a condition fails
while (~done) begin
@(posedge clk);
cycles = cycles + 1;
end
// Run N times - simpler than for when you don't need a counter
repeat (8) @(posedge clk);
// Run forever - clock generators, monitoring loops
always #5 clk = ~clk;
forever begin
@(posedge clk);
$display("count=%0d", count);
end
while, repeat, dan forever hanya bisa disintesis dalam kasus yang sempit (terutama repeat dengan hitungan konstan dan isi yang dikendalikan clock). Di testbench, ketiganya alat yang berguna; di RTL yang bisa disintesis, utamakan for dengan hitungan tetap ditambah state machine yang eksplisit.
for Prosedural di Testbench
Di testbench, loop for berperilaku seperti di software. Pakai sebebasnya:
Loop bersarang ini mencoba setiap kombinasi dari dua input 2-bit. Simulator menjalankan iterasinya secara berurutan. Tidak perlu khawatir soal pembukaan loop, karena testbench tidak disintesis.
Kesalahan yang Umum
Memakai loop for di kode yang bisa disintesis dengan batas yang tidak konstan. Synthesizer akan menolaknya. Kalau batasnya ditentukan saat runtime, bangun counter dan state machine.
Lupa bahwa isi loop menjadi hardware paralel. Loop 64 iterasi dengan pengali di dalamnya berarti 64 pengali paralel, yang kemungkinan besar bukan yang kamu inginkan. Untuk jalur data yang lebar, bangun satu pengali saja dan isi secara berurutan.
Mencampur integer i dan reg bernama i. Keduanya berada di scope yang berbeda; integer-lah yang berlaku di dalam loop. Pilih nama yang jelas untuk menghindari kebingungan.
Selanjutnya
Sekarang kamu sudah punya setiap konstruksi prosedural yang ditawarkan Verilog. Bab berikutnya menyatukan semuanya menjadi pola-pola yang benar-benar dipakai desainer digital: Logika Clocked, yaitu flip-flop, register, dan pipeline, serta Finite State Machine, idiom standar untuk kontroler apa pun yang punya beberapa mode operasi.
Pertanyaan yang sering diajukan
Bagaimana cara kerja loop for di Verilog?
Secara sintaks, loop ini terlihat seperti di C: for (i = 0; i < N; i = i + 1) statement;. Tapi untuk kode yang bisa disintesis, loop-nya dibuka (unrolled) saat elaborasi: synthesizer mengembangkannya menjadi N salinan isi loop. Tidak ada counter loop saat runtime dan tidak ada perulangan di hardware. Di testbench, loop for berperilaku seperti saudaranya di software karena simulator bisa menjalankannya satu per satu secara berurutan.
Apakah loop for bisa disintesis di Verilog?
Bisa, tapi hanya kalau batas loop-nya berupa konstanta yang diketahui saat elaborasi. Synthesizer membuka loop menjadi N salinan paralel dari isinya. Kalau batasnya bergantung pada sinyal saat runtime, loop itu tidak bisa disintesis: kamu harus mengubahnya menjadi desain sekuensial yang dikendalikan clock.
Apa perbedaan for dan generate for di Verilog?
Loop for di dalam blok always adalah konstruksi prosedural yang disintesis dengan cara dibuka. Loop generate for (dengan genvar) adalah konstruksi elaborasi yang eksplisit dan mencetak hardware struktural: banyak instance module, banyak wire, banyak pernyataan assign. Pakai for di dalam blok prosedural; pakai generate for di luarnya untuk mereplikasi struktur.
Apakah Verilog punya loop while?
Punya: while (condition) statement;. Loop ini hanya bisa disintesis kalau synthesizer bisa membuktikan loop-nya berhenti dengan jumlah iterasi yang terbatas. Dalam praktiknya itu jarang, jadi while kebanyakan muncul di testbench dan kode khusus simulasi. Untuk iterasi yang bisa disintesis, pakai loop for dengan hitungan tetap.