Menu

Operator Bitwise dan Reduksi di Verilog

Operator tingkat bit di Verilog: AND/OR/XOR bitwise, bentuk inversinya, dan operator reduksi yang meringkas seluruh vektor menjadi satu bit.

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

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 bit a menjadi 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:

OperatorNamaBit output di posisi N
a & bANDa[N] AND b[N]
a | bORa[N] OR b[N]
a ^ bXORa[N] XOR b[N]
a ~& bNANDNOT (a[N] AND b[N])
a ~| bNORNOT (a[N] OR b[N])
a ~^ bXNORNOT (a[N] XOR b[N])
~aNOTNOT 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:

  • &data mengembalikan 1 kalau semua bit data bernilai 1, selain itu 0. Berguna untuk mengecek "apakah ini semuanya satu?".
  • |data mengembalikan 1 kalau ada bit data yang bernilai 1, selain itu 0. Berguna untuk mengecek "apakah ini bukan nol?".
  • ^data mengembalikan paritas, yaitu XOR dari semua bit. 1 kalau jumlah angka 1 ganjil, 0 kalau genap.
  • ~&data, ~|data, ~^data adalah 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 << N menggeser a ke kiri sebanyak N posisi bit, mengisi nol di sebelah kanan.
  • a >> N menggeser a ke kanan sebanyak N posisi bit, mengisi nol di sebelah kiri.
  • a <<< N shift kiri aritmetika (sama dengan << untuk unsigned).
  • a >>> N shift kanan aritmetika: mengisi dengan bit tanda saat a bertipe 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).

Ilustrasi bahasa pemrograman di Coddy

Belajar coding dengan Coddy

Mulai