pre/post_randomize()

Gün 3: Rastgele Üretim ve Kısıtlamalar | Randomize öncesi ve sonrası otomatik çağrılan fonksiyonlar

Kaynak Kod

// =============================================================================
// GUN 3 - Konu 5: pre_randomize() ve post_randomize() Fonksiyonlari
// =============================================================================

class EthernetFrame;
  rand bit [47:0] dst_mac;
  rand bit [47:0] src_mac;
  rand bit [15:0] ethertype;
  rand bit [7:0]  payload [];
  rand int        payload_len;
  
  // Hesaplanan alanlar (rastgele degil)
  bit [31:0] crc;
  int        frame_size;
  int        frame_id;
  static int frame_count = 0;

  constraint c_payload {
    payload_len inside {[46:1500]};  // Ethernet min/max
    payload.size() == payload_len;
  }

  constraint c_ethertype {
    ethertype inside {16'h0800,      // IPv4
                      16'h0806,      // ARP
                      16'h86DD};     // IPv6
  }

  // randomize() oncesinde otomatik cagrilir
  function void pre_randomize();
    frame_id = frame_count++;
    $display("  [PRE]  Frame #%0d randomize basliyor...", frame_id);
  endfunction

  // randomize() sonrasinda otomatik cagrilir
  function void post_randomize();
    // CRC hesapla (basitlestirilmis)
    crc = 0;
    crc ^= dst_mac[31:0] ^ dst_mac[47:32];
    crc ^= src_mac[31:0] ^ src_mac[47:32];
    crc ^= {16'h0, ethertype};
    foreach (payload[i])
      crc ^= {24'h0, payload[i]};

    frame_size = 6 + 6 + 2 + payload_len + 4;  // dst+src+type+payload+CRC

    // MAC adreslerini duzelt: unicast (LSB=0) ve locally administered
    dst_mac[0] = 0;  // Unicast
    src_mac[0] = 0;  // Unicast
    src_mac[1] = 1;  // Locally administered

    $display("  [POST] Frame #%0d: CRC=0x%08h, Size=%0d bytes",
             frame_id, crc, frame_size);
  endfunction

  function void display();
    $display("  Frame #%0d:", frame_id);
    $display("    DST MAC : %012h", dst_mac);
    $display("    SRC MAC : %012h", src_mac);
    $display("    Type    : 0x%04h (%s)", ethertype, get_type_name());
    $display("    Payload : %0d bytes", payload_len);
    $display("    CRC     : 0x%08h", crc);
    $display("    Toplam  : %0d bytes", frame_size);
  endfunction

  function string get_type_name();
    case (ethertype)
      16'h0800: return "IPv4";
      16'h0806: return "ARP";
      16'h86DD: return "IPv6";
      default:  return "Bilinmeyen";
    endcase
  endfunction
endclass

module pre_post_randomize;
  initial begin
    EthernetFrame frame;

    $display("=== pre_randomize() ve post_randomize() ===\n");

    frame = new();

    repeat (4) begin
      $display("--- Randomize cagrisi ---");
      assert(frame.randomize()) else $fatal(1, "Randomize hata!");
      frame.display();
      $display();
    end

    // Ozel kisitlama ile
    $display("--- Sadece IPv4 paketleri ---");
    repeat (2) begin
      assert(frame.randomize() with {
        ethertype == 16'h0800;
        payload_len < 100;
      }) else $fatal(1, "Randomize hata!");
      frame.display();
      $display();
    end

    $display("=== pre/post_randomize Sonu ===");
    $finish;
  end
endmodule