EDA Playground'da Dene

String İşlemleri

Gün 1: SystemVerilog'a Giriş ve Veri Tipleri | String manipülasyonları ve dönüşüm metodları

⭐⭐Repo Önerisi: ClueLogic'in geliştirmiş olduğu generic bir SystemVerilog kütüphanesi var. Bu kütüphanede string işlemleriyle ilgili çok güzel fonksiyonlar mevcut.

İncelemek isterseniz: ClueLib

Bu derste SystemVerilog'un yerleşik string tipini ve onun zengin metodlarını öğreneceğiz: birleştirme, uzunluk, karşılaştırma, karakter erişimi, alt string, harf dönüşümü ve sayı çevrimleri.

SystemVerilog string Tipi

Verilog'da metinler ham bit vektörlerinde saklanırken, SystemVerilog ayrı bir string tipi sunar. Bu tip dinamik uzunluktadır (boyut yönetimi otomatiktir) ve yazılım dillerine benzer pratik metodlar içerir. Doğrulama dünyasında log mesajları, paket isimleri ve rapor üretimi için sürekli kullanılır.

Temel İşlemler ve Metodlar

  • Birleştirme (concatenation): {str1, " ", str2} sözdizimiyle stringler birleştirilir.
  • Uzunluk: .len() karakter sayısını verir.
  • Karşılaştırma: == doğrudan eşitlik; .icompare() büyük/küçük harf duyarsız karşılaştırma yapar (0 ise eşit).
  • Karakter erişimi: .getc(i) i'inci karakterin ASCII kodunu okur, .putc(i, c) o konumdaki karakteri değiştirir.
  • Alt string: .substr(a, b) a ile b indeksleri arasındaki (her ikisi dahil) parçayı verir.
  • Harf dönüşümü: .toupper() ve .tolower().

Sayı Dönüşümleri ve Formatlama

String ↔ sayı çevrimi doğrulamada sık gerekir:

  • String'den sayıya: .atoi() (decimal), .atohex() (hex), .atobin() (binary), .atooct() (octal)
  • Sayıdan string'e: .itoa(val), .hextoa(val)
  • Formatlı string: $sformatf(...), tıpkı $display gibi biçim belirteçleri kullanır ama sonucu ekrana basmak yerine bir string olarak döndürür.

Kaynak Kod

// =============================================================================
// GUN 1 - Konu 7: String Manipulasyonlari
// =============================================================================

module string_manipulasyonlari;

  string str1, str2, str3;
  string str_arr [$];

  initial begin
    $display("=== SystemVerilog String Islemleri ===\n");

    // --- Temel Atama ve Birlestirme ---
    $display("--- Temel Islemler ---");
    str1 = "Merhaba";
    str2 = "SystemVerilog";
    str3 = {str1, " ", str2, "!"};  // Birlestirme (concatenation)
    $display("  str1 = %s", str1);
    $display("  str2 = %s", str2);
    $display("  Birlesik = %s", str3);

    // --- Uzunluk ---
    $display("\n--- String Uzunlugu ---");
    $display("  \"%s\" uzunluk = %0d", str3, str3.len());

    // --- Karsilastirma ---
    $display("\n--- Karsilastirma ---");
    str1 = "ABC";
    str2 = "abc";
    $display("  \"%s\" == \"%s\" -> %0b", str1, str2, (str1 == str2));
    $display("  icompare (buyuk/kucuk harf duyarsiz) -> %0d", str1.icompare(str2));
    // icompare: 0 ise esit, negatifse str1 < str2

    // --- Alt String ve Karakter Erisimi ---
    $display("\n--- Karakter Erisimi ---");
    str1 = "SystemVerilog";
    $display("  String = %s", str1);
    $display("  str[0] = %c (ASCII: %0d)", str1.getc(0), str1.getc(0));
    $display("  str[6] = %c", str1.getc(6));
    
    // Karakter degistirme
    str1.putc(0, "s");  // S -> s
    $display("  putc(0,'s') -> %s", str1);

    // --- Substring ---
    $display("\n--- Alt String (substr) ---");
    str1 = "Dogrulama_Muhendisi";
    str2 = str1.substr(0, 8);   // 0'dan 8'e kadar (dahil)
    $display("  \"%s\".substr(0,8) = \"%s\"", str1, str2);

    // --- Buyuk/Kucuk Harf ---
    $display("\n--- Harf Donusumu ---");
    str1 = "Hello World";
    $display("  toupper = %s", str1.toupper());
    $display("  tolower = %s", str1.tolower());

    // --- Sayi Donusumleri ---
    $display("\n--- String <-> Sayi Donusumu ---");
    str1 = "255";
    $display("  \"%s\".atoi()  = %0d (decimal)", str1, str1.atoi());
    
    str1 = "FF";
    $display("  \"%s\".atohex() = %0d (hex -> decimal)", str1, str1.atohex());

    str1 = "11111111";
    $display("  \"%s\".atobin() = %0d (bin -> decimal)", str1, str1.atobin());

    str1 = "377";
    $display("  \"%s\".atooct() = %0d (oct -> decimal)", str1, str1.atooct());

    // Sayidan stringe
    begin
      int val = 42;
      str1.itoa(val);
      $display("  itoa(%0d)  = \"%s\"", val, str1);
      str2.hextoa(val);
      $display("  hextoa(%0d) = \"%s\"", val, str2);
    end

    // --- Formatli String ---
    $display("\n--- $sformatf (Formatli String) ---");
    begin
      int addr = 'hABCD;
      int data = 'hDEAD;
      string msg;
      msg = $sformatf("Adres: 0x%04h, Veri: 0x%04h, Zaman: %0t", addr, data, $time);
      $display("  %s", msg);
    end

    // --- String Kuyruk ---
    $display("\n--- String Kuyruk ---");
    str_arr = '{"Generator", "Driver", "Monitor", "Scoreboard"};
    $display("  Testbench Bilesenleri:");
    foreach (str_arr[i])
      $display("    [%0d] %s", i, str_arr[i]);

    $display("\n=== String Islemleri Sonu ===");
    $finish;
  end

endmodule

Kodun Açıklaması

  • str3 = {str1, " ", str2, "!"}; birleştirme işlemini gösterir; "Merhaba", boşluk, "SystemVerilog" ve "!" tek bir string'e birleştirilir.
  • str3.len() birleşik string'in karakter sayısını döndürür.
  • Karşılaştırma bölümünde str1 = "ABC", str2 = "abc" için (str1 == str2) farklı oldukları için 0 verir; str1.icompare(str2) ise büyük/küçük harf duyarsız olduğundan 0 (eşit) döndürür.
  • str1.getc(0) ilk karakterin ASCII kodunu verir; %c ile karakter, %0d ile sayısal kodu basılır. str1.putc(0, "s"); ilk karakteri (S) küçük s ile değiştirir.
  • str1.substr(0, 8) "Dogrulama_Muhendisi" içinden 0–8 indeksleri arasını ("Dogrulama") çıkarır; her iki uç da dahildir.
  • str1.toupper() ve str1.tolower() orijinal string'i değiştirmeden büyük/küçük harfe çevrilmiş bir kopya döndürür.
  • Sayı dönüşümleri: "255".atoi() → 255, "FF".atohex() → 255, "11111111".atobin() → 255, "377".atooct() → 255. Dört farklı tabandaki gösterimin aynı değere karşılık gelmesi öğreticidir.
  • str1.itoa(val) 42 sayısını "42" string'ine; str2.hextoa(val) ise onaltılık gösterimine çevirir. Bu metodlar sonucu çağrıldıkları string değişkenine yazar.
  • $sformatf("Adres: 0x%04h, ...", addr, data, $time) biçimli bir metni msg değişkenine üretir; $display gibi formatlar ama ekrana basmaz.
  • Sonda str_arr string kuyruğu '{"Generator", "Driver", "Monitor", "Scoreboard"} ile doldurulup foreach ile listelenir.

Önemli Noktalar

  • string tipi dinamik uzunluktadır; Verilog'daki gibi sabit bit vektörü genişliği ayırmanıza gerek yoktur.
  • == büyük/küçük harf duyarlıdır; harf durumunu yok saymak istiyorsanız .icompare() kullanın (0 eşitliği gösterir).
  • getc/putc indeksleri 0 tabanlıdır; sınır dışı erişimden kaçının. substr(a, b) aralığında hem a hem b dahildir.
  • .toupper()/.tolower() yeni bir string döndürür, orijinali değiştirmez; oysa .putc(), .itoa(), .hextoa() çağrıldıkları değişkeni yerinde günceller.
  • atoi/atohex/atobin/atooct taban seçimini siz yaparsınız; girdinin tabanına uygun metodu seçmek doğru sonucu garanti eder.
  • Log ve rapor üretiminde $display yerine $sformatf ile string oluşturup saklamak, mesajları yeniden kullanmayı ve scoreboard'a iletmeyi kolaylaştırır.