Dua Peran untuk Simbol yang Sama
&, |, ^, dan saudara-saudara inversinya muncul dalam dua bentuk yang berbeda:
- Bentuk biner (dua operand):
a & b, yaitu operasi bitwise antara dua vektor yang sama lebarnya. - Bentuk unary (satu operand):
&a, yaitu reduksi semua bitamenjadi satu bit.
Compiler membedakan keduanya dengan menghitung operand. Konvensi penamaannya: "operator bitwise" untuk bentuk biner dan "operator reduksi" untuk bentuk unary.
Bitwise: Satu Bit pada Satu Waktu
Set lengkapnya:
| Operator | Nama | Bit output di posisi N |
|---|---|---|
a & b | AND | a[N] AND b[N] |
a | b | OR | a[N] OR b[N] |
a ^ b | XOR | a[N] XOR b[N] |
a ~& b | NAND | NOT (a[N] AND b[N]) |
a ~| b | NOR | NOT (a[N] OR b[N]) |
a ~^ b | XNOR | NOT (a[N] XOR b[N]) |
~a | NOT | NOT a[N] |
Perhatikan bahwa ~&, ~|, ~^ ditulis dengan tilde dulu, baru operatornya. Masing-masing adalah satu token; tidak ada spasi di antaranya.
Kalau kedua operand lebarnya berbeda, yang lebih sempit di-zero-extend di sebelah kiri agar sama. Kalau ingin sign-extend, pakai operand signed secara eksplisit dengan $signed().
Reduksi: Dari Banyak Bit Menjadi Satu
Bentuk unary dari operator yang sama meringkas sebuah vektor menjadi satu bit:
Arti masing-masing:
&datamengembalikan1kalau semua bitdatabernilai 1, selain itu0. Berguna untuk mengecek "apakah ini semuanya satu?".|datamengembalikan1kalau ada bitdatayang bernilai 1, selain itu0. Berguna untuk mengecek "apakah ini bukan nol?".^datamengembalikan paritas, yaitu XOR dari semua bit.1kalau jumlah angka 1 ganjil,0kalau genap.~&data,~|data,~^dataadalah kebalikan dari ketiganya.
Kamu akan melihatnya di mana-mana di kode sungguhan:
wire empty = ~|fifo_count; // empty iff count is zero
wire all_ones = &mask; // all bits set
wire parity_bit = ^data; // parity of a byte
wire any_request = |request_vector; // is anything requested?
Bentuk reduksi ini ringkas dan disintesis menjadi pohon gerbang yang jelas: & menjadi gerbang AND dengan banyak input, | menjadi OR dengan banyak input, ^ menjadi pohon XOR (yang juga merupakan generator paritas di hardware).
Pola yang Umum
Mengatur dan Menghapus Bit
wire [7:0] data;
wire [7:0] mask = 8'b0000_1000;
wire [7:0] set = data | mask; // forces bit 3 to 1
wire [7:0] cleared = data & ~mask; // forces bit 3 to 0
wire [7:0] toggled = data ^ mask; // flips bit 3
wire [7:0] tested = data & mask; // zero if bit 3 was 0, non-zero otherwise
Ini idiom manipulasi bit yang sama dengan yang kamu pakai di C. Semuanya disintesis menjadi operasi satu gerbang.
Mengecek Apakah Nilainya Semuanya Satu
wire is_max = &counter; // 1 if every bit of counter is 1
Reduksi AND dengan satu gerbang, dibandingkan menulis counter == 8'hFF (yang juga berfungsi; synthesizer biasanya menghasilkan hardware yang identik).
Menghasilkan Bit Paritas
Mendeteksi Sinyal yang Aktif
wire any_pending = |request_vector;
Kalau request_vector lebar (misalnya 64 peminta), reduksi OR meringkasnya menjadi satu sinyal yang bisa kamu masukkan ke priority encoder atau arbiter.
Operator Shift
Selagi membahas operator tingkat bit, ini operator shift-nya:
a << Nmenggeserake kiri sebanyakNposisi bit, mengisi nol di sebelah kanan.a >> Nmenggeserake kanan sebanyakNposisi bit, mengisi nol di sebelah kiri.a <<< Nshift kiri aritmetika (sama dengan<<untuk unsigned).a >>> Nshift kanan aritmetika: mengisi dengan bit tanda saatabertipe signed.
Shift sebanyak nilai konstan gratis di hardware (hanya menyusun ulang kabel). Shift sebanyak variabel saat runtime menghasilkan barrel shifter, yang lebih besar tapi tetap murah.
Selanjutnya
Sekarang kamu sudah melihat setiap operator yang mengembalikan satu nilai. Dokumen berikutnya, Concatenation dan Replikasi, membahas sintaks {} dan {N{...}} yang membangun vektor yang lebih lebar dari potongan-potongan. Kamu akan terus memakainya saat menghubungkan module dengan lebar yang berbeda.
Pertanyaan yang sering diajukan
Apa itu operator bitwise di Verilog?
Operator bitwise menggabungkan dua vektor yang sama lebarnya, posisi demi posisi. a & b meng-AND-kan bit 0 dari a dengan bit 0 dari b, bit 1 dengan bit 1, dan seterusnya, menghasilkan vektor yang sama lebarnya dengan input. Set lengkapnya adalah & (AND), | (OR), ^ (XOR), ~ (NOT), dan bentuk inversi ~&, ~|, ~^ (NAND, NOR, XNOR).
Apa itu operator reduksi di Verilog?
Operator reduksi adalah bentuk unary dari operator bitwise yang meringkas seluruh vektor menjadi satu bit. &data mengembalikan 1 hanya kalau setiap bit data bernilai 1. |data mengembalikan 1 kalau ada bit yang bernilai 1. ^data mengembalikan XOR dari semua bit, yaitu paritasnya. Bentuk reduksi tidak punya operand di kiri, hanya di kanan.
Apa perbedaan & dan && di Verilog?
& adalah AND bitwise: ia memasangkan bit sesuai posisinya dan hasilnya selebar operand-nya. && adalah AND logika: ia memperlakukan setiap operand sebagai boolean (nol vs bukan nol) dan mengembalikan hasil 1-bit. 4'b1100 & 4'b0011 bernilai 4'b0000; 4'b1100 && 4'b0011 bernilai 1.
Bagaimana cara menghitung paritas di Verilog?
Pakai operator reduksi XOR: parity = ^data. Operator ini meng-XOR-kan setiap bit data. Untuk vektor 8-bit, itu sama dengan data[7] ^ data[6] ^ ... ^ data[0]. Hasilnya 1 kalau jumlah bit yang bernilai 1 ganjil, 0 kalau genap. Membaliknya dengan ~^ menghasilkan paritas genap.
Apa fungsi ~ di Verilog?
~ adalah NOT bitwise: ia membalik setiap bit operand-nya. ~4'b1100 bernilai 4'b0011. Jangan tertukar dengan ! (NOT logika), yang meringkas operand menjadi boolean satu bit lalu membaliknya. !4'b1100 bernilai 1'b0 (operand-nya bukan nol, dan membalik nilai benarnya menghasilkan 0).