Anatomi Literal Berukuran
Sebuah literal Verilog punya sampai tiga bagian:
8'b1010_1100
│ │ │
│ │ └─ digits in the chosen base
│ └─── base specifier: b (binary), h (hex), d (decimal), o (octal)
└────── width in bits (decimal)
Dibaca dari kiri ke kanan: "nilai 8-bit, ditulis dalam biner, dengan digit 10101100". Itu 172 dalam desimal, 0xAC dalam hex, bit-bitnya sama ke mana pun cara menulisnya (sebuah konverter basis bilangan menampilkan ketiganya berdampingan). Lebar memberi tahu compiler berapa banyak bit yang harus dialokasikan; basis memberi tahu cara membaca digitnya.
Underscore adalah pemisah visual. 32'b1010_1100_0011_0101 sama dengan 32'b1010110000110101. Pakailah.
Empat Basis
Hex (h) adalah standar untuk apa pun yang lebih lebar dari 4 bit. Biner (b) adalah standar saat kamu ingin langsung membaca pola bitnya. Desimal (d) untuk jumlah yang bermakna bagi manusia. Oktal (o) memang ada, tapi hampir tidak pernah kamu lihat.
Digit hex tidak peka huruf besar-kecil: 8'hAB dan 8'hab sama persis.
Apa yang Terjadi Kalau Nilainya Tidak Pas?
Kalau digitmu tidak memenuhi lebar yang dideklarasikan, Verilog menambahkan nol di sebelah kiri (zero-extend):
8'b101 // equivalent to 8'b00000101 (= 5)
8'hF // equivalent to 8'h0F (= 15)
Kalau digitmu melebihi lebar yang dideklarasikan, Verilog memotong bit-bit atasnya disertai peringatan:
4'hFF // truncates to 4'hF, simulator warns
4'b10000 // truncates to 4'b0000
Peringatan itu temanmu. Jangan dimatikan.
Berukuran vs Tanpa Ukuran
Literal tanpa lebar:
'd10 // unsized, takes default size (≥32 bits)
10 // also unsized - no base means decimal
Di kebanyakan tool, literal tanpa ukuran default-nya 32 bit. Inilah sumber satu kelompok bug tersendiri:
reg [7:0] count;
if (count == -1) ... // -1 is unsized 32-bit; comparison gets weird
Solusinya, tulis 8'hFF alih-alih -1, atau 8'd255, atau {8{1'b1}}. Selalu beri ukuran pada literal saat dipakai di ekspresi dengan lebar tertentu.
Satu-satunya tempat literal tanpa ukuran aman dipakai adalah counter integer di loop for testbench, karena integer-nya cukup lebar sehingga tidak ada hal mengejutkan yang terjadi.
Literal Signed
Secara default, literal berukuran bersifat unsigned:
8'd255 // unsigned 255
8'b1111_1111 // unsigned 255 - same bit pattern, just written differently
Kalau ingin literal dibaca sebagai signed, tambahkan s setelah apostrof:
8'sd10 // signed 10
8'sb1111_1111 // signed -1 (two's complement)
Flag s berpengaruh untuk:
- Operator
<<<dan>>>(shift aritmetika): keduanya melakukan sign-extend pada operand signed. - Operator perbandingan pada ekspresi campuran yang signed.
- Cast
$signed/$unsigned.
Untuk kebanyakan aritmetika biasa pada sinyal bus, kamu tidak perlu menulis s.
Literal Angka dengan X dan Z
Sebuah digit literal bisa berupa x (tidak diketahui) atau z (impedansi tinggi):
8'bx adalah singkatan untuk "kedelapan bit tidak diketahui": nilainya disebarkan untuk memenuhi lebar yang dideklarasikan. Digit x umum dipakai di case default pada state machine dan saat inisialisasi. Kita membahas maknanya di Nilai X dan Z.
Di Mana Literal Berukuran Muncul dalam Praktik
Begitu kamu mulai menulis module sungguhan, literal berukuran muncul di mana-mana:
// Bus widths
input wire [31:0] addr;
wire [31:0] zero = 32'h0;
wire [31:0] all_ones = 32'hFFFF_FFFF;
// State encodings
localparam IDLE = 3'd0;
localparam BUSY = 3'd1;
localparam DONE = 3'd2;
// Masks
wire is_msb_set = data & 32'h8000_0000;
// Comparisons
if (counter == 8'd255) ...
// Reset values
always @(posedge clk) begin
if (reset) data_out <= 8'd0;
else data_out <= data_in;
end
Polanya konsisten: tulis lebarnya, tulis basisnya, tulis digitnya. Setiap literal yang kamu pakai punya bentuk yang sama.
Uji Coba
Sekarang kamu punya semua yang dibutuhkan untuk menulis konstanta apa pun yang mungkin diperlukan sebuah module Verilog. Bagian terakhir dari cerita tipe data adalah apa yang terjadi saat sinyal tidak bernilai 0 atau 1 yang bersih: nilai x dan z.
Pertanyaan yang sering diajukan
Apa arti 8'b1010 di Verilog?
Itu literal biner berukuran: nilai 8-bit yang representasi binernya 00001010. Angka sebelum apostrof adalah lebarnya dalam bit; huruf setelah apostrof adalah basisnya (b biner, h hex, d desimal, o oktal); digit setelahnya adalah nilainya. Literal itu diberi nol di sebelah kiri kalau digitnya tidak memenuhi lebarnya.
Apa perbedaan angka berukuran dan tanpa ukuran di Verilog?
Literal berukuran seperti 8'd10 lebarnya tepat 8 bit. Literal tanpa ukuran seperti 'd10 atau cukup 10 lebarnya default 32 bit, yang biasanya terlalu banyak. Mencampur literal tanpa ukuran ke dalam ekspresi dengan lebar tertentu menimbulkan bug yang sulit dilihat; utamakan literal berukuran di mana pun, kecuali di kode uji yang sekali pakai.
Bagaimana cara menulis angka hex di Verilog?
Pakai penanda basis 'h: 8'hFF adalah nilai 8-bit sebesar 255. Digit hex tidak peka huruf besar-kecil; 8'hff dan 8'hFF sama persis. Kamu bisa mengelompokkan digit dengan underscore agar mudah dibaca: 32'hDEAD_BEEF. Parser mengabaikan underscore itu.
Bagaimana cara kerja underscore di angka Verilog?
Underscore adalah pemisah visual yang diabaikan parser. 32'b1010_1100_0011_0101 bernilai persis sama dengan 32'b1010110000110101, tapi jauh lebih mudah dibaca. Karakter pertama setelah awalan basis tidak boleh underscore, tapi selebihnya kamu bebas menaruhnya di mana saja dalam deretan digit.
Bagaimana cara menulis angka signed di Verilog?
Tambahkan s setelah apostrof: 8'sd10 adalah desimal 10 signed 8-bit, dan 8'sb1111_1111 adalah -1 signed. Secara default, literal berukuran bersifat unsigned; pengubah s membaliknya. Kebanyakan aritmetika memakai operand unsigned; pakai signed hanya saat kamu benar-benar butuh nilai negatif yang terbawa lewat <, >>>, dan operator sejenis.