Fonksiyonel Kapsam

Gün 5: Arayüzler, Assertion ve Coverage | covergroup, coverpoint, bins, cross coverage

Kaynak Kod

// =============================================================================
// GUN 5 - Konu 5: Fonksiyonel Kapsam (Functional Coverage)
// =============================================================================

class ALU_Transaction;
  typedef enum logic [2:0] {ADD, SUB, AND, OR, XOR, SHL, SHR} op_e;

  rand op_e          operation;
  rand logic [7:0]   operand_a;
  rand logic [7:0]   operand_b;
  logic [15:0]       result;

  constraint c_operands {
    operand_a inside {[0:255]};
    operand_b inside {[0:255]};
  }

  function void compute();
    case (operation)
      ADD: result = operand_a + operand_b;
      SUB: result = operand_a - operand_b;
      AND: result = operand_a & operand_b;
      OR:  result = operand_a | operand_b;
      XOR: result = operand_a ^ operand_b;
      SHL: result = operand_a << operand_b[2:0];
      SHR: result = operand_a >> operand_b[2:0];
    endcase
  endfunction
endclass

module functional_coverage;

  ALU_Transaction txn;

  // =========================================================================
  // COVERGROUP: Kapsam grubu tanimi
  // =========================================================================
  covergroup alu_cg with function sample(
    ALU_Transaction::op_e op,
    logic [7:0] a, logic [7:0] b, logic [15:0] res
  );

    // --- COVERPOINT: Islem kapsanmasi ---
    cp_operation: coverpoint op {
      bins add_bin = {ALU_Transaction::ADD};
      bins sub_bin = {ALU_Transaction::SUB};
      bins and_bin = {ALU_Transaction::AND};
      bins or_bin  = {ALU_Transaction::OR};
      bins xor_bin = {ALU_Transaction::XOR};
      bins shl_bin = {ALU_Transaction::SHL};
      bins shr_bin = {ALU_Transaction::SHR};
    }

    // --- COVERPOINT: Operand A araliklari ---
    cp_op_a: coverpoint a {
      bins zero    = {0};
      bins low     = {[1:63]};
      bins mid     = {[64:191]};
      bins high    = {[192:254]};
      bins max_val = {255};
    }

    // --- COVERPOINT: Operand B araliklari ---
    cp_op_b: coverpoint b {
      bins zero    = {0};
      bins low     = {[1:63]};
      bins mid     = {[64:191]};
      bins high    = {[192:254]};
      bins max_val = {255};
    }

    // --- COVERPOINT: Sonuc araliklari ---
    cp_result: coverpoint res {
      bins zero     = {0};
      bins small    = {[1:255]};
      bins medium   = {[256:65534]};
      bins overflow = {65535};
    }

    // --- COVERPOINT: Kose durumlari ---
    cp_corner: coverpoint a {
      bins boundaries[] = {0, 1, 127, 128, 254, 255};
      illegal_bins never = default;
    }

    // --- CROSS: Islem x Operand A araligi ---
    cx_op_a: cross cp_operation, cp_op_a;

    // --- CROSS: Islem x Operand B araligi ---
    cx_op_b: cross cp_operation, cp_op_b;

  endgroup

  // =========================================================================
  alu_cg cg;

  initial begin
    $display("=== Fonksiyonel Kapsam (Functional Coverage) ===\n");

    txn = new();
    cg  = new();

    // Rastgele test dongusu
    $display("--- 200 Rastgele Islem ---");
    repeat (200) begin
      assert(txn.randomize()) else $fatal(1, "Randomize hata!");
      txn.compute();
      cg.sample(txn.operation, txn.operand_a, txn.operand_b, txn.result);
    end

    // Yonlendirilmis testler (kose durumlari)
    $display("--- Yonlendirilmis Kose Testleri ---");
    begin
      logic [7:0] corners [] = '{0, 1, 127, 128, 254, 255};
      foreach (corners[i]) begin
        foreach (corners[j]) begin
          assert(txn.randomize() with {
            operand_a == corners[i];
            operand_b == corners[j];
          }) else continue;
          txn.compute();
          cg.sample(txn.operation, txn.operand_a, txn.operand_b, txn.result);
        end
      end
    end

    // Kapsam raporu
    $display("\n--- Kapsam Raporu ---");
    $display("  Toplam Kapsam     : %.1f%%", cg.get_coverage());
    $display("  cp_operation      : %.1f%%", cg.cp_operation.get_coverage());
    $display("  cp_op_a           : %.1f%%", cg.cp_op_a.get_coverage());
    $display("  cp_op_b           : %.1f%%", cg.cp_op_b.get_coverage());
    $display("  cp_result         : %.1f%%", cg.cp_result.get_coverage());

    $display("\n=== Fonksiyonel Kapsam Sonu ===");
    $finish;
  end
endmodule