EDA Playground'da Dene

Verilog vs SystemVerilog

Gün 1: SystemVerilog'a Giriş ve Veri Tipleri | İki dil arasındaki temel farklar ve SV'nin getirdiği yenilikler

Bu derste klasik Verilog ile modern SystemVerilog'u yan yana koyarak; veri tiplerinde, döngü yapılarında ve tip dönüşümlerinde getirilen kolaylıkları somut örneklerle karşılaştıracağız.

Verilog'un Sınırları ve SystemVerilog'un Yanıtı

Verilog, donanım tanımlamak için tasarlanmış olgun bir dildir; ancak gündelik kullanımda yazımı uzatan ve hata yapmaya açık bazı kısıtları vardır:

  • reg / wire ayrımı: Verilog'da bir sinyalin reg mi yoksa wire mı olacağına bağlama göre karar vermek gerekir. SystemVerilog bunu büyük ölçüde tek bir logic tipiyle çözer.
  • Sınırlı tip seti: Verilog esasen reg, wire, integer ve real etrafında döner. SystemVerilog ise bit, byte, shortint, int, longint gibi genişliği net belirli tipler sunar.
  • Hantal döngü sözdizimi: Verilog'da döngü değişkenini ayrıca tanımlamak ve i = i + 1 gibi yazmak gerekir.

Daha İfadeli Kontrol Yapıları

SystemVerilog, yazılım dillerine yaklaşan kontrol yapıları getirir:

  • for döngüsünde yerel tanımlama: for (int i = 0; i < 4; i++) ile döngü değişkeni döngünün içinde tanımlanır ve ++/-- operatörleri kullanılabilir.
  • do-while döngüsü ile gövde en az bir kez çalışır.
  • foreach ile bir dizinin tüm elemanları indeks yönetmeden gezilir.
  • Tip dönüşümleri (casting): int'(r) veya 8'(i) sözdizimiyle tipler ve bit genişlikleri arasında açık (explicit) dönüşüm yapılır.

Kaynak Kod

// =============================================================================
// GUN 1 - Konu 2: Verilog vs. SystemVerilog Farklari
// =============================================================================

module verilog_vs_sv;

  // -------------------------------------------------------------------------
  // VERILOG TARZI (Eski Yontem)
  // -------------------------------------------------------------------------
  reg  [7:0] verilog_data;      // reg ve wire ayrimi gerekli
  wire [7:0] verilog_wire;
  integer    verilog_int;       // 32-bit, her zaman signed
  reg        verilog_array [0:3]; // Kisitli dizi destegi
  
  // -------------------------------------------------------------------------
  // SYSTEMVERILOG TARZI (Modern Yontem)
  // -------------------------------------------------------------------------
  logic [7:0] sv_data;          // Tek tip: hem reg hem wire yerine
  int         sv_int;           // Kompakt 32-bit signed
  bit  [7:0]  sv_fast;          // 2-state, daha hizli simulasyon
  byte        sv_byte;          // 8-bit signed
  shortint    sv_short;         // 16-bit signed
  longint     sv_long;          // 64-bit signed

  // SystemVerilog: Gelismis donguler
  initial begin
    $display("=== Verilog vs. SystemVerilog Karsilastirmasi ===\n");

    // --- Verilog tarzi dongu ---
    $display("[Verilog] Klasik for dongusu:");
    begin : verilog_loop
      integer i;
      for (i = 0; i < 4; i = i + 1) begin
        $display("  i = %0d", i);
      end
    end

    // --- SystemVerilog tarzi dongu ---
    $display("\n[SystemVerilog] Gelismis for dongusu:");
    for (int i = 0; i < 4; i++) begin  // Dongu icinde tanimlama, ++ operatoru
      $display("  i = %0d", i);
    end

    // --- SystemVerilog: do-while ---
    $display("\n[SystemVerilog] do-while dongusu:");
    begin
      int count = 3;
      do begin
        $display("  count = %0d", count);
        count--;
      end while (count > 0);
    end

    // --- SystemVerilog: foreach ---
    $display("\n[SystemVerilog] foreach dongusu:");
    begin
      int arr [5] = '{10, 20, 30, 40, 50};
      foreach (arr[i])
        $display("  arr[%0d] = %0d", i, arr[i]);
    end

    // --- SystemVerilog: case ---
    $display("\n[SystemVerilog] case:");
    begin
      int sel = 2;
      case (sel)
        0: $display("  Secim: A");
        1: $display("  Secim: B");
        2: $display("  Secim: C");
        3: $display("  Secim: D");
      endcase
    end

    // --- SystemVerilog: Otomatik tip donusumu ---
    $display("\n[SystemVerilog] Tip donusumleri:");
    begin
      real    r = 3.14;
      int     i = int'(r);       // Casting
      bit [7:0] b = 8'(i);      // Bit genisligi casting
      $display("  real=%f -> int=%0d -> bit[7:0]=%0d", r, i, b);
    end

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

endmodule

Kodun Açıklaması

  • Modülün başında iki bölüm vardır. Verilog tarzı kısımda reg [7:0] verilog_data, wire [7:0] verilog_wire, integer verilog_int ve reg verilog_array [0:3] tanımları, eski yöntemin tip ayrımını ve sınırlı dizi desteğini gösterir.
  • SystemVerilog tarzı kısımda logic [7:0] sv_data tek tiple reg/wire ihtiyacını karşılar. int, bit [7:0], byte, shortint ve longint ise genişlikleri net belirli tiplerdir (byte=8, shortint=16, int=32, longint=64 bit, tümü signed).
  • verilog_loop adlı begin : ... end bloğu Verilog'un klasik for (i = 0; i < 4; i = i + 1) yazımını; hemen ardından gelen for (int i = 0; i < 4; i++) ise döngü içinde tanımlama ve ++ operatörünü gösterir.
  • do begin ... end while (count > 0) bloğunda count 3'ten başlar ve count-- ile azalır; do-while olduğu için gövde koşul kontrol edilmeden önce çalışır.
  • int arr [5] = '{10, 20, 30, 40, 50}; dizisi foreach (arr[i]) ile gezilir; burada i indeksi otomatik üretilir.
  • case (sel) bloğu sel = 2 olduğu için "Secim: C" dalını seçer.
  • Son blokta real r = 3.14; değeri int'(r) ile tam sayıya, ardından 8'(i) ile 8-bit genişliğe dönüştürülür. int'(r) ondalık kısmı atarak 3 verir.

Önemli Noktalar

  • Yeni tasarımlarda sürdürülen sinyaller için reg/wire yerine logic kullanmak hem okunabilirliği artırır hem de yanlış tip seçimi hatalarını azaltır.
  • Genişliği önemli olan değişkenlerde integer yerine boyutu net olan int, byte, shortint, longint tiplerini tercih edin.
  • for döngüsünde değişkeni döngü içinde tanımlamak (for (int i...)) kapsamı (scope) daraltır ve yan etkileri azaltır.
  • Tip dönüşümlerinde açık casting (int'(...), 8'(...)) kullanmak, gizli/otomatik dönüşümlerden kaynaklanan sürprizleri önler. realint dönüşümünde ondalık kısım atılır.
  • $display içindeki \n kaçış karakteri çıktıyı biçimlendirmek için kullanılır; SystemVerilog bunu Verilog'a göre daha rahat destekler.