Tutorial Array Verilog: Dari Dasar hingga Teknik Lanjutan SystemVerilog

目次

1. Pendahuluan

Verilog banyak digunakan sebagai bahasa deskripsi perangkat keras (HDL) dan tak tergantikan dalam perancangan sirkuit untuk pengembangan FPGA dan ASIC. Untuk merancang secara efisien dengan Verilog, pemahaman yang kuat tentang array sangat penting. Dengan memanfaatkan array, Anda dapat mengelola kumpulan data secara ringkas dan intuitif, yang meningkatkan keterbacaan serta pemeliharaan deskripsi sirkuit Anda. Array terutama efektif ketika mengelompokkan banyak sinyal atau merepresentasikan struktur memori seperti RAM. Artikel ini berfokus pada kata kunci “Verilog arrays” dan memberikan penjelasan komprehensif mulai dari dasar‑dasar definisi array hingga teknik aplikasi praktis. Kami akan membahas tipe‑tipe array, peningkatan SystemVerilog, kesalahan umum, dan FAQ untuk membantu memperdalam pemahaman Anda. Pemula sekalipun akan menemukan panduan ini mudah diikuti, karena kami menyertakan contoh kode praktis di seluruh artikel. Baca sampai akhir untuk mendapatkan gambaran lengkap.

2. Tipe Data Dasar dalam Verilog

Sebelum bekerja dengan array di Verilog, penting untuk memahami tipe data fundamental. Verilog menyediakan beberapa tipe data utama untuk menangani sinyal logika yang digunakan dalam perancangan sirkuit.

Perbedaan Antara reg dan wire

Tipe data yang paling sering dipakai dalam Verilog adalah “reg” (register) dan “wire”. Kedua tipe ini harus digunakan secara tepat sesuai dengan perilaku sinyal logika.
  • tipe wire Wire digunakan sebagai garis koneksi antara modul atau sirkuit. Wire harus selalu digerakkan oleh sinyal lain, dan penugasan dilakukan dengan pernyataan assign. Cocok untuk output sirkuit kombinatorial. Contoh:
  wire a;
  assign a = b & c;
  • tipe reg Reg digunakan sebagai variabel untuk menyimpan nilai sementara. Reg ditetapkan di dalam blok proses seperti always, dan biasanya dipakai untuk memodelkan elemen penyimpanan (latch atau flip‑flop). Contoh:
  reg q;
  always @(posedge clk) begin
      q <= d;
  end

Tipe Data yang Dapat Digunakan dalam Array

Di Verilog, array biasanya didefinisikan dengan tipe reg, meskipun array tipe wire juga dapat dipakai dalam beberapa kasus. Namun, versi Verilog sebelumnya tidak mendukung array multidimensi. Batasan ini sangat diperbaiki di SystemVerilog. Berikut contoh sederhana sintaks array:
reg [7:0] data_array [0:15];  // An array storing 16 elements, each 8 bits wide
Dengan memahami dasar‑dasar tipe data, Anda dapat menghindari kebingungan saat mendeklarasikan dan menggunakan array. Salah penggunaan reg dan wire dapat menyebabkan kesalahan simulasi atau sintesis, jadi berhati‑hatilah.

3. Konsep Dasar Array

Di Verilog, array dipakai ketika Anda ingin mengelola banyak sinyal dengan tipe yang sama secara kolektif. Array memudahkan pengorganisasian sinyal, meningkatkan keterbacaan kode serta kemudahan penggunaan kembali.

Mendeklarasikan Array

Verilog pada dasarnya mendukung array satu dimensi. Sintaksnya sebagai berikut:
reg [bit-width] array_name [index-range];
Contoh:
reg [7:0] data_array [0:15];  // An array of 16 elements, each storing 8-bit data
Pada contoh ini, data_array memiliki 16 elemen yang diindeks dari 0 sampai 15, dengan setiap elemen menyimpan nilai 8‑bit (1 byte).

Mengakses Elemen Array

Anda dapat mengakses setiap elemen array dengan menentukan nomor indeksnya. Mirip dengan bahasa C, indeks array dimulai dari 0.
data_array[0] = 8'hFF;   // Assign hexadecimal FF to the first element
data_array[1] = 8'd12;   // Assign decimal 12 to the second element
Anda juga dapat menggunakan loop di dalam blok always untuk menginisialisasi atau memanipulasi array.
integer i;
always @(posedge clk) begin
    for (i = 0; i < 16; i = i + 1) begin
        data_array[i] <= 8'd0;
    end
end

Keuntungan Menggunakan Array

  • Pemrosesan batch : Dengan loop for, Anda dapat menerapkan operasi yang sama ke banyak sinyal sekaligus.
  • Sirkuit terstruktur : Array membantu mengatur banyak register atau sinyal, menjaga representasi sirkuit tetap jelas.
  • Pemodelan memori : Anda dapat mengimplementasikan struktur memori sederhana seperti RAM atau ROM (dijelaskan pada bab berikutnya).

Hal yang Perlu Diperhatikan

Dalam Verilog, Anda tidak dapat menetapkan nilai ke seluruh array secara langsung (misalnya, data_array = value). Sebaliknya, operasi harus dilakukan elemen per elemen. Selain itu, hanya array satu dimensi yang secara resmi didukung pada Verilog awal, sehingga untuk array multidimensi Anda memerlukan Verilog 2001 atau SystemVerilog.

4. Menggunakan Array Multidimensi

Array dalam Verilog menyederhanakan desain dan membantu mengatur struktur sirkuit. Dengan menggunakan array multidimensi, Anda dapat menangani struktur data yang lebih kompleks secara efisien. Namun, perlu dicatat bahwa Verilog lama (IEEE 1364-1995) tidak mendukung array multidimensi. Mereka secara resmi diperkenalkan pada Verilog 2001. Untuk fleksibilitas yang lebih, disarankan menggunakan SystemVerilog.

Mendeklarasikan Array Multidimensi

Sejak Verilog 2001, Anda dapat mendefinisikan array multidimensi dengan menentukan beberapa indeks untuk satu variabel. Sintaks dasar adalah:
reg [7:0] matrix [0:3][0:3];  // Defines a 4×4 matrix of 8-bit elements
Deklarasi ini membuat array 2D bernama matrix, berisi 16 elemen, masing-masing lebar 8 bit.

Mengakses dan Menetapkan Elemen

Anda dapat mengakses dan menetapkan elemen tertentu dari array multidimensi menggunakan indeks:
matrix[0][0] = 8'hA5;
matrix[2][3] = 8'd255;

Menggunakan Loop for

Array multidimensi dapat dimanipulasi menggunakan loop for bersarang. Contoh inisialisasi:
integer i, j;
always @(posedge clk) begin
    for (i = 0; i < 4; i = i + 1) begin
        for (j = 0; j < 4; j = j + 1) begin
            matrix[i][j] <= 8'd0;
        end
    end
end

Aplikasi Array Multidimensi

  • Berguna dalam desain yang memerlukan operasi matriks atau pemrosesan filter.
  • Dapat diterapkan dalam pemrosesan gambar atau pemrosesan sinyal digital (DSP), untuk penanganan data tingkat piksel.
  • Digunakan dalam struktur blok ROM/RAM dan untuk mengatur pasangan alamat-data.

Batasan dan Pertimbangan

  • Periksa kompatibilitas alat sintesis, karena beberapa alat mungkin tidak sepenuhnya mendukung array multidimensi.
  • Pembatasan dapat berlaku ketika digabungkan dengan instansiasi atau antarmuka.
  • Pahami perbedaan dengan SystemVerilog untuk menghindari masalah kompatibilitas (dijelaskan nanti).

5. Memodelkan Memori dengan Array

Dalam Verilog, Anda dapat memodelkan struktur memori sederhana menggunakan array. Ini memungkinkan Anda mendeskripsikan dan mensimulasikan rangkaian penyimpanan seperti RAM dan ROM secara ringkas dan fleksibel. Secara khusus, model memori berbasis array satu dimensi sering digunakan dalam desain CPU dan sistem komunikasi.

Sintaks Dasar untuk Model Memori

Contoh berikut menggambarkan RAM sederhana dengan kata 32-bit dan 1024 alamat (0–1023):
reg [31:0] memory [0:1023];  // 32-bit × 1024-word memory
Deklarasi ini membuat array bernama memory, di mana setiap indeks (alamat) menyimpan kata 32-bit.

Menulis ke dan Membaca dari Memori

Operasi baca/tulis memori menggunakan array dapat dijelaskan sebagai berikut:
// Write operation
always @(posedge clk) begin
    if (we) begin
        memory[addr] <= data_in;
    end
end

// Read operation
assign data_out = memory[addr];
Poin penting:
  • Operasi penulisan bersifat sinkron dengan posedge clk dan bersyarat (dikendalikan oleh we, enable menulis).
  • Operasi pembacaan biasanya diimplementasikan menggunakan assign untuk pembacaan kombinatorial (asinkron).

Inisialisasi Memori

Untuk testbench atau penyiapan keadaan awal, Anda dapat menginisialisasi array di dalam blok initial:
integer i;
initial begin
    for (i = 0; i < 1024; i = i + 1) begin
        memory[i] = 32'd0;
    end
end
Anda juga dapat memuat nilai awal dari file eksternal menggunakan $readmemh atau $readmemb:
initial begin
    $readmemh("rom_init.hex", memory);  // Initialize from a hex file
end

Kasus Penggunaan Praktis

  • File register dalam CPU atau mikrokontroler
  • Simulasi perilaku Block RAM (BRAM) di dalam FPGA
  • Verifikasi perilaku memori cache
  • Simulasi pembacaan data ROM

Hal-hal yang Perlu Diperhatikan

  • Seiring ukuran array meningkat, waktu simulasi dan sumber daya sintesis juga bertambah.
  • Pilih timing pembacaan (sinkron vs. asinkron) dengan hati-hati berdasarkan spesifikasi desain dan alat.
  • Saat menargetkan sintesis, ikuti aturan inferensi memori spesifik yang direkomendasikan oleh vendor alat.

6. Peningkatan Array di SystemVerilog

Sampai Verilog 2001, fungsionalitas array terbatas, sering membuat desain menjadi rumit. Untuk mengatasinya, SystemVerilog memperkenalkan peningkatan signifikan, memungkinkan penanganan array yang lebih fleksibel dan kuat. Bagian ini menjelaskan tiga tipe utama array yang tersedia di SystemVerilog: dynamic arrays, associative arrays, dan queues. Kami akan membahas fitur‑fitur dan kasus penggunaannya.

Array Dinamis

Fitur

  • Ukuran array dapat diubah saat runtime.
  • Berguna ketika ukuran tidak diketahui sebelumnya atau berubah selama eksekusi.

Deklarasi dan Contoh

int dyn_array[];             // Declare a dynamic array
dyn_array = new[10];         // Initialize with 10 elements
dyn_array[0] = 100;

Kasus Penggunaan

  • Penyimpanan data sementara di testbench
  • Mengelola buffer berukuran variabel

Array Asosiatif

Fitur

  • Indeks dapat berupa nilai sewenang-wenang (integer, string, dll.).
  • Berfungsi seperti tabel hash.

Deklarasi dan Contoh

int assoc_array[string];     // Associative array using strings as keys
assoc_array["id_001"] = 42;

Kasus Penggunaan

  • Menyimpan nilai konfigurasi untuk parameter
  • Mencari nilai berdasarkan ID atau nama

Antrian

Fitur

  • Berperilaku seperti struktur FIFO (First-In, First-Out).
  • Mendukung penyisipan dan penghapusan yang mudah, ideal untuk aliran data dinamis.

Deklarasi dan Contoh

int queue_array[$];          // Declare a queue array

queue_array.push_back(10);   // Add element at the end
queue_array.push_front(5);   // Add element at the front
int val = queue_array.pop_front();  // Remove element from the front

Kasus Penggunaan

  • Penyimpanan data sementara (buffer FIFO)
  • Penanganan peristiwa dan manajemen transaksi

Perbandingan dan Penggunaan

Tipe ArrayResizableJenis IndeksTerbaik Untuk
Array DinamisYaIntegerKetika ukuran tidak diketahui atau variabel
Array AsosiatifYaApa saja (int, string, dll.)Pencarian mirip tabel hash
QueueYaOtomatis (depan/ belakang)Penyisipan/Penghapusan yang sering

Hal-hal yang Perlu Diperhatikan

  • Array yang ditingkatkan ini adalah fitur khusus SystemVerilog dan tidak tersedia di Verilog.
  • Dukungan sintesis tergantung pada alat, dan biasanya digunakan untuk testbench.
  • Jika menargetkan FPGA atau ASIC, selalu periksa apakah fitur ini didukung sebelum implementasi.

7. Praktik Terbaik untuk Operasi Array

Saat bekerja dengan array di Verilog atau SystemVerilog, fokus pada kode yang efisien dan mudah dibaca secara langsung menghasilkan desain perangkat keras yang lebih berkualitas. Bab ini menyoroti praktik terbaik untuk menangani array dengan aman dan efektif.

Perjelas Tujuan dengan Komentar dan Penamaan

Meskipun array dapat diskalakan dan nyaman, tidak selalu jelas apa yang diwakili setiap elemen. Untuk menghindari kebingungan, ikuti pedoman berikut:
  • Gunakan nama yang bermakna untuk array: reg [7:0] sensor_data [0:7];
  • Tambahkan komentar untuk menjelaskan tujuan atau satuan:
// Stores 8-bit data from 8 sensors
reg [7:0] sensor_data [0:7];

Hati-hati dengan Batas Loop

Saat menggunakan loop for untuk memanipulasi array, sangat penting untuk mendefinisikan batas indeks dengan benar:
  • Batas atas yang salah → akses di luar jangkauan (kesalahan logika atau peringatan simulator)
  • Putuskan dengan hati-hati apakah akan menggunakan < atau <= untuk penghentian loop
Contoh:
integer i;
always @(posedge clk) begin
    for (i = 0; i < 8; i = i + 1) begin
        sensor_data[i] <= 8'd0;
    end
end

Selalu Inisialisasi Secara Eksplisit

Meninggalkan array tidak terinisialisasi dapat mempengaruhi hasil simulasi. Hal ini terutama penting untuk array yang memodelkan RAM atau bank register. Selalu inisialisasi secara eksplisit:
initial begin
    for (i = 0; i < 256; i = i + 1)
        mem[i] = 32'd0;
end
Di SystemVerilog, konstruktor atau foreach loops memungkinkan inisialisasi yang lebih sederhana.

Rancang Modul yang Dapat Digunakan Kembali

Desain berbasis array dapat beradaptasi secara fleksibel terhadap perubahan jumlah instance atau lebar bit. Untuk memaksimalkan kegunaan kembali, pertimbangkan:
  • Menggunakan parameter untuk membuat ukuran array dapat dikonfigurasi:
parameter DEPTH = 16;
reg [7:0] buffer [0:DEPTH-1];
  • Memungkinkan pengiriman parameter eksternal meningkatkan kegunaan kembali modul.

Pertimbangkan Synthesizability

Saat menggunakan array, selalu perhatikan kompatibilitas alat sintesis:
  • Array reg satu dimensi Verilog: umumnya dapat disintesis
  • Array dinamis/associative/queue SystemVerilog: tidak dapat disintesis (hanya untuk simulasi)
Oleh karena itu, untuk sirkuit yang dapat disintesis, gunakan array reg tradisional.

Gunakan Array vs. Modul dengan Tepat

Meskipun array dapat mengurangi ukuran kode, desain yang terlalu kompleks mungkin lebih diuntungkan dengan memecah fungsionalitas menjadi modul terpisah untuk kemudahan pemeliharaan.
  • Operasi kecil dan identik → array dengan for loops
  • Fungsionalitas berbeda atau desain skala besar → desain modular dan hierarkis

8. Pertanyaan yang Sering Diajukan (FAQ)

Saat menggunakan array dalam Verilog atau SystemVerilog, pengguna pemula hingga menengah sering menemui hambatan yang sama. Di sini kami menjawab tiga pertanyaan umum tentang “array Verilog,” memberikan jawaban praktis dan wawasan dari pengalaman desain dunia nyata.

Q1. Saya mendapatkan error saat menggunakan array multidimensi di Verilog. Mengapa?

A1.

Hal ini terjadi karena Verilog 1995 dan versi awal Verilog 2001 tidak mendukung array multidimensi sama sekali atau hanya mendukungnya secara terbatas. Sebagai contoh, kode berikut akan menyebabkan error kompilasi di Verilog 1995:
reg [7:0] matrix [0:3][0:3];  // Supported only in Verilog 2001 or later
Solusi:
  • Pastikan lingkungan pengembangan Anda mematuhi Verilog 2001 atau lebih baru.
  • Jika keterbatasan masih ada, tulis ulang menggunakan array satu dimensi dengan indeks yang dihitung.
reg [7:0] matrix_1d [0:15];  // Flattened 4x4 array, accessed with (i*4 + j)

Q2. Jika saya mendeskripsikan RAM menggunakan array di Verilog, apakah itu akan berfungsi pada perangkat keras?

A2.

Ya. RAM yang dideskripsikan menggunakan array di Verilog didukung oleh sebagian besar alat sintesis. Contoh umum:
reg [31:0] mem [0:255];  // 32-bit × 256-word RAM
Hal-hal yang perlu diperhatikan:
  • Alat sintesis harus mengenali deskripsi ini sebagai inferensi block RAM.
  • Timing baca/tulis (sinkron vs. asinkron) dan gaya akses harus mengikuti template spesifik atau alat mungkin tidak dapat menginferensi memori dengan benar.
Solusi:
  • Ikuti panduan sintesis yang disediakan oleh vendor FPGA/ASIC Anda.
  • Jika perilaku berbeda antara simulasi dan perangkat keras, periksa log dan debug langkah demi langkah.

Q3. Bisakah saya menggunakan array dinamis, array asosiatif, atau queue SystemVerilog pada perangkat keras sebenarnya?

A3.

Secara umum, array dinamis, array asosiatif, dan queue tidak dapat disintesis (hanya simulasi). Meskipun mereka memberikan kode yang fleksibel, mereka tidak dapat dipetakan langsung ke logika perangkat keras. Oleh karena itu, array ini terutama digunakan untuk:
  • Penyimpanan data sementara di testbench
  • Implementasi randomisasi atau scoreboard dalam lingkungan verifikasi
  • Deskripsi transaksi yang kompleks
Catatan Implementasi:
  • Setiap kode desain yang menggunakan tipe array ini akan diabaikan atau menyebabkan error pada alat sintesis.
  • Jika implementasi perangkat keras diperlukan, konversi menjadi reg atau array satu dimensi berukuran tetap.

9. Kesimpulan

Dalam artikel ini, kami memfokuskan pada kata kunci “Verilog arrays” dan menjelaskan penggunaannya dari dasar hingga aplikasi lanjutan. Menguasai array dalam desain sirkuit secara langsung berkontribusi pada efisiensi, keterbacaan, dan pemeliharaan.

Poin Penting

  • Dengan memahami tipe data dasar Verilog (reg dan wire), Anda dapat menghindari kesalahan saat bekerja dengan array.
  • Array satu dimensi adalah struktur penting untuk mengelompokkan data dan memodelkan memori.
  • Array multidimensi didukung sejak Verilog 2001 dan versi selanjutnya, memungkinkan desain bergaya matriks.
  • SystemVerilog memperkenalkan struktur fleksibel seperti array dinamis, array asosiatif, dan antrian (terutama untuk simulasi dan verifikasi).
  • Dengan mengikuti praktik terbaik penanganan array (inisialisasi, penamaan, kegunaan kembali, pertimbangan sintesis), Anda dapat menulis kode yang lebih berkualitas.

Tips Praktis

Array sangat kuat, tetapi tidak boleh digunakan secara sembarangan untuk segala hal. Saat menulis kode yang dapat disintesis atau berkolaborasi dalam tim, selalu ikuti batasan dan panduan gaya. Fitur array lanjutan SystemVerilog sebaiknya digunakan dengan mempertimbangkan simulasi, untuk memaksimalkan manfaatnya. Desainer yang baik tahu cara memilih struktur yang tepat untuk tujuan yang tepat.

Topik Selanjutnya yang Direkomendasikan

Jika Anda kini memahami dasar-dasar array, kami menyarankan untuk mengeksplorasi topik terkait berikut:
  • Menggunakan pernyataan generate untuk pembuatan sirkuit dinamis dengan array
  • Menggabungkan interface dengan array untuk desain bus
  • Mengimplementasikan FIFO, buffer cincin, dan optimasi ROM menggunakan array
Menguasai array adalah langkah pertama yang penting bagi seorang desainer Verilog. Dengan memperdalam pemahaman Anda, Anda akan dapat menangani desain sirkuit yang semakin kompleks dengan percaya diri.