Lab 3: Generator Sınıfı

Gün 3: Rastgele Üretim ve Kısıtlamalar | Senaryoya uygun rastgele veri üreten Generator tasarımı

Kaynak Kod

// =============================================================================
// GUN 3 - Lab 3: Generator Sinifi - Senaryoya Uygun Rastgele Veri Uretimi
// =============================================================================

class BusTransaction;
  typedef enum logic [1:0] {READ=0, WRITE=1, BURST_READ=2, BURST_WRITE=3} cmd_e;
  typedef enum {VALID, ADDR_ERROR, DATA_ERROR, PROTOCOL_ERROR} status_e;

  rand cmd_e         command;
  rand logic [31:0]  address;
  rand logic [31:0]  data;
  rand int unsigned  burst_length;
  rand bit [3:0]     byte_strobe;
  rand bit [2:0]     id;
  rand status_e      status;
  
  bit [31:0] crc;
  int txn_id;
  static int count = 0;

  // --- Temel kisitlamalar ---
  constraint c_base {
    burst_length inside {[1:16]};
    (command inside {READ, WRITE}) -> burst_length == 1;
    (command inside {BURST_READ, BURST_WRITE}) -> burst_length inside {[2:16]};
  }

  // --- Gecerli paket ---
  constraint c_valid {
    status == VALID;
    address[1:0] == 2'b00;  // 4-byte hizali
    byte_strobe != 0;
  }

  // --- Adres araliklari ---
  constraint c_addr_region_A {
    address inside {[32'h0000_0000:32'h0000_FFFF]};
  }
  constraint c_addr_region_B {
    address inside {[32'h1000_0000:32'h1000_FFFF]};
  }
  constraint c_addr_region_C {
    address inside {[32'hFFFF_0000:32'hFFFF_FFFF]};
  }

  // --- Komut dagilimi ---
  constraint c_cmd_dist {
    command dist { READ := 30, WRITE := 30, BURST_READ := 20, BURST_WRITE := 20 };
  }

  // --- Hata enjeksiyonu ---
  constraint c_inject_error {
    status dist { VALID := 80, ADDR_ERROR := 10, DATA_ERROR := 5, PROTOCOL_ERROR := 5 };
  }

  function new();
    txn_id = count++;
    c_addr_region_B.constraint_mode(0);
    c_addr_region_C.constraint_mode(0);
    c_inject_error.constraint_mode(0);
  endfunction

  function void post_randomize();
    crc = address ^ data ^ {29'h0, command};
    if (status == ADDR_ERROR)
      address[1:0] = 2'b11;  // Hizalamayi boz
    else if (status == DATA_ERROR)
      data = ~data;
  endfunction

  function void display();
    $display("  TXN#%03d | %-11s | Addr=0x%08h | Data=0x%08h | Burst=%2d | BE=%04b | ID=%0d | %s",
             txn_id, command.name(), address, data, burst_length, 
             byte_strobe, id, status.name());
  endfunction
endclass

class Generator;
  BusTransaction txn;
  int num_transactions;
  string scenario_name;

  function new(int num = 10);
    this.num_transactions = num;
    this.txn = new();
  endfunction

  // Senaryo 1: Normal trafik
  task run_normal_traffic();
    scenario_name = "Normal Trafik";
    $display("\n=== Senaryo: %s (%0d txn) ===", scenario_name, num_transactions);
    repeat (num_transactions) begin
      assert(txn.randomize()) else $fatal(1, "Randomize hata!");
      txn.display();
    end
  endtask

  // Senaryo 2: Sadece okuma
  task run_read_only();
    scenario_name = "Sadece Okuma";
    $display("\n=== Senaryo: %s ===", scenario_name);
    repeat (num_transactions) begin
      assert(txn.randomize() with { command inside {BusTransaction::READ, BusTransaction::BURST_READ}; })
        else $fatal(1, "Randomize hata!");
      txn.display();
    end
  endtask

  // Senaryo 3: Yuksek adres bolgesi
  task run_high_address();
    scenario_name = "Yuksek Adres Bolgesi";
    $display("\n=== Senaryo: %s ===", scenario_name);
    txn.c_addr_region_A.constraint_mode(0);
    txn.c_addr_region_C.constraint_mode(1);
    repeat (num_transactions) begin
      assert(txn.randomize()) else $fatal(1, "Randomize hata!");
      txn.display();
    end
    txn.c_addr_region_A.constraint_mode(1);
    txn.c_addr_region_C.constraint_mode(0);
  endtask

  // Senaryo 4: Hata enjeksiyonu
  task run_error_injection();
    scenario_name = "Hata Enjeksiyonu";
    $display("\n=== Senaryo: %s ===", scenario_name);
    txn.c_valid.constraint_mode(0);
    txn.c_inject_error.constraint_mode(1);
    repeat (num_transactions) begin
      assert(txn.randomize()) else $fatal(1, "Randomize hata!");
      txn.display();
    end
    txn.c_valid.constraint_mode(1);
    txn.c_inject_error.constraint_mode(0);
  endtask
endclass

module lab3_generator;
  initial begin
    Generator gen;

    $display("============================================================");
    $display("  LAB 3: Generator Sinifi - Senaryolu Rastgele Uretim");
    $display("============================================================");

    gen = new(8);

    gen.run_normal_traffic();
    gen.run_read_only();
    gen.run_high_address();
    gen.run_error_injection();

    $display("\n============================================================");
    $display("  LAB 3 TAMAMLANDI");
    $display("============================================================");
    $finish;
  end
endmodule