Diziler (Arrays)
Gün 1: SystemVerilog'a Giriş ve Veri Tipleri | Sabit boyutlu, dinamik ve ilişkisel diziler
Bu derste SystemVerilog'un üç temel dizi türünü, hangi senaryoda hangisinin uygun olduğunu ve yerleşik dizi metodlarını (sum, min, max, sort, unique...) öğreneceğiz.
Üç Dizi Türü
SystemVerilog, ihtiyaca göre seçilen üç ana dizi türü sunar:
- Sabit boyutlu (fixed-size) diziler: Boyut derleme zamanında bellidir (
int fixed_arr [5];). Çok boyutlu olabilirler (int matrix [3][4];). Bellek önceden ayrılır, erişim hızlıdır. - Dinamik (dynamic) diziler: Boyut çalışma zamanında
new[]ile belirlenir (int dyn_arr [];). Gerektiğinde yeniden boyutlandırılabilir vedelete()ile temizlenebilir. - İlişkisel (associative) diziler: Anahtar–değer eşlemesi yapar (
int assoc_arr [string];). Çok büyük ama seyrek (sparse) adres uzaylarını modellemek için idealdir; yalnızca yazılan girdiler için bellek harcar.
Dizi Metodları
SystemVerilog dizilerde doğrudan kullanılabilen güçlü metodlar sağlar:
- İndirgeme:
sum(),min(),max() - Sıralama/düzen:
sort(),rsort()(tersten),shuffle()(karıştır) - Filtreleme:
unique()ile tekrarsız elemanlar - Sorgu (associative):
num()eleman sayısı,exists()anahtar var mı
foreach döngüsü, indeksleri elle yönetmeden tüm dizi türlerini gezmenin en pratik yoludur; çok boyutlu dizilerde foreach (matrix[i, j]) gibi birden çok indeks kullanılabilir.
Kaynak Kod
// =============================================================================
// GUN 1 - Konu 5: Diziler (Arrays): Sabit, Dinamik, Iliskisel
// =============================================================================
module diziler;
// -------------------------------------------------------------------------
// SABIT BOYUTLU DIZILER (Fixed-Size Arrays)
// -------------------------------------------------------------------------
int fixed_arr [5]; // 5 elemanli unpacked dizi
logic [7:0] packed_arr [3]; // 3 elemanli, her biri 8-bit
int matrix [3][4]; // 2 boyutlu dizi (3 satir, 4 sutun)
// -------------------------------------------------------------------------
// DINAMIK DIZILER (Dynamic Arrays)
// -------------------------------------------------------------------------
int dyn_arr []; // Boyut calisma zamaninda belirlenir
// -------------------------------------------------------------------------
// ILISKISEL DIZILER (Associative Arrays)
// -------------------------------------------------------------------------
int assoc_arr [string]; // String anahtarli
int sparse_mem [int]; // Int anahtarli
initial begin
$display("=== SystemVerilog Diziler ===\n");
// --- Sabit Boyutlu Dizi ---
$display("--- Sabit Boyutlu Diziler ---");
fixed_arr = '{10, 20, 30, 40, 50};
foreach (fixed_arr[i])
$display(" fixed_arr[%0d] = %0d", i, fixed_arr[i]);
// 2D dizi
$display("\n 2D Matris (3x4):");
foreach (matrix[i, j])
matrix[i][j] = (i * 4) + j;
foreach (matrix[i]) begin
$write(" Satir %0d: ", i);
foreach (matrix[i][j])
$write("%3d ", matrix[i][j]);
$display();
end
// Dizi metodlari
$display("\n Dizi Metodlari:");
$display(" sum = %0d", fixed_arr.sum());
$display(" min = %0d", fixed_arr.min());
$display(" max = %0d", fixed_arr.max());
$display(" unique = %p", fixed_arr.unique());
// Siralama
fixed_arr.rsort();
$display(" rsort = %p", fixed_arr);
fixed_arr.shuffle();
$display(" shuffle = %p", fixed_arr);
// --- Dinamik Dizi ---
$display("\n--- Dinamik Diziler ---");
dyn_arr = new[5];
foreach (dyn_arr[i]) dyn_arr[i] = (i + 1) * 100;
$display(" Baslangic boyut = %0d", dyn_arr.size());
foreach (dyn_arr[i]) $display(" dyn_arr[%0d] = %0d", i, dyn_arr[i]);
// Boyut degistirme (mevcut veriyi koruyarak)
dyn_arr = new[8](dyn_arr);
dyn_arr[5] = 600; dyn_arr[6] = 700; dyn_arr[7] = 800;
$display("\n Yeni boyut = %0d", dyn_arr.size());
foreach (dyn_arr[i]) $display(" dyn_arr[%0d] = %0d", i, dyn_arr[i]);
// Silme
dyn_arr.delete();
$display(" Silme sonrasi boyut = %0d", dyn_arr.size());
// --- Iliskisel Dizi ---
$display("\n--- Iliskisel Diziler ---");
// String anahtarli
assoc_arr["sifirlama"] = 0;
assoc_arr["baslat"] = 1;
assoc_arr["durdur"] = 2;
assoc_arr["hata"] = 99;
$display(" Eleman sayisi = %0d", assoc_arr.num());
if (assoc_arr.exists("hata"))
$display(" 'hata' anahtari mevcut, deger = %0d", assoc_arr["hata"]);
// foreach ile gezinme
foreach (assoc_arr[key])
$display(" assoc_arr[\"%s\"] = %0d", key, assoc_arr[key]);
// Seyrek bellek modeli
$display("\n Seyrek Bellek Modeli:");
sparse_mem[32'h0000] = 'hAA;
sparse_mem[32'h1000] = 'hBB;
sparse_mem[32'hFFFF] = 'hCC;
foreach (sparse_mem[addr])
$display(" MEM[0x%04h] = 0x%02h", addr, sparse_mem[addr]);
$display("\n=== Diziler Sonu ===");
$finish;
end
endmodule
Kodun Açıklaması
fixed_arr = '{10, 20, 30, 40, 50};ile sabit boyutlu dizi toplu atama (array literal) ile doldurulur veforeach (fixed_arr[i])ile yazdırılır.int matrix [3][4];iki boyutlu dizidir.foreach (matrix[i, j]) matrix[i][j] = (i * 4) + j;tek satırda her iki indeksi birden gezer; ardından satır satır basılır.- Dizi metodları
fixed_arrüzerinde gösterilir:sum()toplamı,min()/max()uç değerleri,unique()tekrarsız elemanları döndürür.rsort()diziyi büyükten küçüğe sıralar,shuffle()rastgele karıştırır (yerinde değiştirir). dyn_arr = new[5];dinamik diziyi 5 elemanlı oluşturur;foreachile(i + 1) * 100değerleri atanır.dyn_arr.size()anlık boyutu verir.dyn_arr = new[8](dyn_arr);diziyi 8 elemana büyütürken mevcut veriyi korur (parantez içindekidyn_arreski içeriği taşır); ardındandyn_arr[5],[6],[7]elle doldurulur.dyn_arr.delete();diziyi tamamen boşaltır, boyut0olur.- İlişkisel dizide
assoc_arr["hata"] = 99;gibi string anahtarlı girdiler eklenir;assoc_arr.num()eleman sayısını,assoc_arr.exists("hata")anahtarın varlığını sorgular.foreach (assoc_arr[key])ile anahtar üzerinden gezilir. sparse_mem[32'h0000],[32'h1000],[32'hFFFF]girdileri seyrek bellek modelini gösterir: 64K'lık bir adres uzayında yalnızca 3 girdi için bellek harcanır.
Önemli Noktalar
- Doğru türü seçin: Boyut sabitse fixed-size, çalışma zamanında değişiyorsa dynamic, anahtar–değer veya seyrek adresleme gerekiyorsa associative dizi kullanın.
- Dinamik diziyi büyütürken eski veriyi korumak için
new[N](eski_dizi)biçimini kullanın; aksi hâlde dizi yeni boyutta sıfırlanır. - İlişkisel diziler bellek açısından verimlidir ama erişim sırası tanımlı değildir; sırayı önemsiyorsanız anahtarları ayrıca sıralayın.
unique(),min(),max()gibi metodlar yeni bir kuyruk (queue) döndürür; orijinal diziyi değiştirmezler. Buna karşılıksort(),rsort(),shuffle()diziyi yerinde değiştirir.- Çok boyutlu dizilerde
foreach (matrix[i, j])sözdizimi, iç içe döngülere göre daha kısa ve okunaklıdır. - İlişkisel bir anahtara erişmeden önce
exists()ile kontrol etmek, tanımsız girdi okumaktan kaynaklı sürprizleri önler.