Menu

Operator Verilog: Aritmetika, Perbandingan, Logika, dan Kondisional

Operator inti di Verilog (aritmetika, perbandingan, logika, dan kondisional ?:) beserta aturan dan jebakan seputar lebar yang berbeda-beda dan signedness.

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

Arti "Operator" di Verilog

Operator mengambil ekspresi yang membawa sinyal dan menghasilkan ekspresi baru yang juga membawa sinyal. a + b adalah hardware: synthesizer mengubahnya menjadi adder. a == b adalah hardware: ia membangun komparator. Semua ini bukan "kode yang berjalan", melainkan "rangkaian yang digambarkan oleh operator".

Daftar lengkap operatornya cukup kecil untuk dihafal. Dokumen ini membahas operator aritmetika, perbandingan, logika, dan kondisional. Bitwise dan Reduksi membahas operator tingkat bit yang tidak punya padanan langsung di software.

Aritmetika: + - * / %

Tiga hal yang perlu kamu tahu:

  1. Pembagian adalah pembagian integer. 7/2 bernilai 3, bukan 3.5. Verilog tidak punya tipe float (ya, ada real, tapi itu khusus simulasi).
  2. Pembagian dan modulo mahal di hardware. /4 tidak masalah (synthesizer mengubahnya menjadi shift kanan), tapi /n dengan n yang berubah saat runtime membangun pembagi multi-siklus yang hampir tidak pernah kamu inginkan.
  3. Overflow berputar balik. Menjumlahkan dua nilai unsigned N-bit yang hasilnya melebihi N bit akan terpotong menjadi N bit. Kalau ingin menangkap carry-nya, deklarasikan hasilnya satu bit lebih lebar:
wire [7:0] a, b;
wire [8:0] sum = a + b;   // 9-bit sum captures carry out

Perbandingan: == != < > <= >=

Keenam operator perbandingan mengembalikan hasil satu bit: 1 kalau benar, 0 kalau salah, x kalau salah satu operand punya bit x atau z. Untuk menangani kasus x/z, pakai === dan !== (operator case equality) yang dibahas di Nilai X dan Z.

<= di sini adalah operator perbandingan (kurang dari atau sama dengan). Karakter yang sama juga berarti penugasan non-blocking di dalam blok prosedural (q <= d). Konteks yang membedakannya: di dalam ekspresi, itu perbandingan; di sebelah kiri nilai yang sedang diberikan, itu penugasan. Tumpang tindihnya membingungkan, tapi tidak ambigu bagi parser.

Logika: && || !

Operator logika memperlakukan operand-nya sebagai boolean (apa pun yang bukan nol bernilai benar, nol bernilai salah) dan menghasilkan hasil satu bit:

Perbedaan penting yang harus kamu pahami betul: && logika bukan & bitwise.

4'b1100 && 4'b0011   // 1 (both are non-zero, logical AND is true)
4'b1100 &  4'b0011   // 4'b0000 (no bit positions are 1 in both)

Hal yang sama berlaku untuk || vs |. Pakai operator logika di kondisi if dan predikat ?:; pakai bitwise saat kamu ingin setiap posisi bit di-AND/OR secara independen.

&& dan || bersifat short-circuit seperti di C: sisi kanan tidak dievaluasi kalau hasilnya sudah ditentukan oleh sisi kiri. Ini penting untuk testbench yang memeriksa pointer atau pemanggilan fungsi; jarang penting untuk RTL yang bisa disintesis, karena di sana semuanya memang terjadi paralel.

Operator Kondisional: ?:

Ternary adalah sahabat terbaikmu untuk membangun mux dan ekspresi kondisional:

Pola cond ? a : b di hardware adalah multiplexer 2-ke-1 dengan pemilih 1 bit. Merangkainya tidak masalah untuk pilihan 3 dan 4 arah, tapi lebih dari itu, pernyataan case (dibahas di Pernyataan Case) jauh lebih mudah dibaca.

Operator ?: juga cara standar untuk memberi register nilai default yang hanya sesekali kamu timpa:

next_value = update ? new_data : next_value;

Aturan Lebar: Jebakan Pemula

Aturan lebar Verilog untuk operator aritmetika terkenal sering mengejutkan. Versi singkatnya:

  • Lebar hasilnya adalah lebar maksimum dari input-input-nya.
  • Kalau hasilnya diberikan ke sesuatu yang lebih lebar, hasilnya di-zero-extend (atau di-sign-extend kalau signed).
  • Lebar perhitungan perantara juga sama dengan lebar hasilnya, artinya overflow terjadi di perhitungan perantara.

Perkalian pertama mengalami overflow karena lebar kedua operand 8 bit, sehingga lebar hasilnya juga 8 bit, dan 40000 tidak muat. Yang kedua berhasil karena kita secara eksplisit melebarkan a sebelum mengalikan.

Teknik perbaikannya:

  • Pakai operator concatenation {8'b0, a} untuk zero-extend.
  • Pakai $unsigned(a) atau $signed(a) untuk memengaruhi cara nilainya dibaca.
  • Lebarkan ekspresi perantara kalau ragu.

Prioritas Operator

Kamu tidak akan menghafal tabelnya, tapi kamu akan mengandalkan beberapa aturan:

  • *, /, % mengikat lebih kuat daripada +, -.
  • Perbandingan mengikat lebih kuat daripada operator logika (&&, ||).
  • Operator kondisional ?: punya prioritas sangat rendah, jadi biasanya cabang-cabangnya perlu diberi tanda kurung di ekspresi yang lebih besar.
  • Kalau ragu, beri tanda kurung. Simulator tidak menagih per karakter.
out = (mode == 2'd0) ? a + b : a - b;   // clearer with parens

Selanjutnya

Kamu sudah membahas setiap operator yang mirip dengan saudaranya di software. Dokumen berikutnya, Bitwise dan Reduksi, membahas operator yang tidak punya padanan langsung di software: AND/OR/XOR bitwise per bit, ditambah bentuk reduksi yang meringkas seluruh vektor menjadi satu bit.

Pertanyaan yang sering diajukan

Operator apa saja yang didukung Verilog?

Verilog punya empat kelompok besar operator: aritmetika (+, -, *, /, %), perbandingan (==, !=, <, >, <=, >=), logika (&&, ||, !), dan bitwise/reduksi (&, |, ^, ~, ~&, ~|, ~^). Ditambah operator shift (<<, >>, <<<, >>>), concatenation {}, replikasi {N{...}}, dan kondisional ?:.

Apa perbedaan && dan & di Verilog?

&& adalah AND logika: ia memperlakukan setiap operand sebagai boolean (nol atau bukan nol) dan mengembalikan hasil 1-bit. & adalah AND bitwise: ia memasangkan bit sesuai posisinya. 4'b1100 && 4'b0011 bernilai 1 (keduanya bukan nol); 4'b1100 & 4'b0011 bernilai 4'b0000. Pakai && di kondisi, & untuk operasi tingkat bit.

Bagaimana cara kerja pembagian di Verilog?

Pembagian integer: bagian pecahannya dibuang. 7 / 2 bernilai 3, bukan 3.5. Operator % memberi sisa bagi: 7 % 2 bernilai 1. Pembagian dengan nol menghasilkan x (tidak diketahui) di simulasi. Secara teknis kedua operator itu bisa disintesis, tapi menghasilkan hardware yang sangat besar dan lambat di FPGA dan ASIC; hindari di jalur yang akan disintesis kecuali pembaginya pangkat 2.

Apa itu operator kondisional di Verilog?

?: adalah operator ternary atau kondisional, disalin dari C. cond ? a : b menghasilkan a kalau cond bernilai benar (bukan nol) dan b kalau tidak. Ini konstruksi yang paling sering dipakai untuk logika mirip multiplexer: out = sel ? in1 : in0 membangun mux 2-ke-1. Rantai ?: membangun mux yang lebih lebar, meskipun case biasanya lebih jelas kalau inputnya lebih dari dua.

Ilustrasi bahasa pemrograman di Coddy

Belajar coding dengan Coddy

Mulai