Assertions (SVA)

Gün 5: Arayüzler, Assertion ve Coverage | Immediate ve Concurrent assertion'lar, property, sequence

Kaynak Kod

// =============================================================================
// GUN 5 - Konu 4: SystemVerilog Assertions (SVA) - Immediate ve Concurrent
// =============================================================================

module assertions;
  logic clk = 0;
  always #5 clk = ~clk;

  logic       rst_n;
  logic       req;
  logic       gnt;
  logic       valid;
  logic       ready;
  logic [7:0] data;
  logic       error;

  // Basit DUT davranisi
  always @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
      gnt   <= 0;
      ready <= 0;
      error <= 0;
    end else begin
      gnt   <= req;           // 1 cycle gecikme ile grant
      ready <= valid;         // 1 cycle gecikme ile ready
      error <= (data == 8'hFF); // 0xFF hata
    end
  end

  // =========================================================================
  // IMMEDIATE ASSERTIONS: Prosedurel blok icinde, aninda kontrol
  // =========================================================================
  
  // assert: Kosul saglanmali
  always @(posedge clk) begin
    if (rst_n) begin
      // Basit immediate assertion
      assert_valid_data: assert (data !== 8'hxx)
        else $warning("[%0t] Data belirsiz (x)!", $time);

      // Error ve valid ayni anda olmamali
      assert_no_error_valid: assert (!(error && valid))
        else $error("[%0t] Error ve valid ayni anda aktif!", $time);
    end
  end

  // =========================================================================
  // CONCURRENT ASSERTIONS: Zamansal iliskileri kontrol eder
  // =========================================================================

  // Property: req -> sonraki cycle gnt gelmeli
  property p_req_gnt;
    @(posedge clk) disable iff (!rst_n)
    req |=> gnt;  // |=> bir sonraki cycle'da
  endproperty

  // Property: valid kalktiginda 1-3 cycle icinde ready gelmeli
  property p_valid_ready;
    @(posedge clk) disable iff (!rst_n)
    valid |-> ##[1:3] ready;  // 1-3 cycle icinde
  endproperty

  // Property: Reset'te tum cikislar sifir
  property p_reset_check;
    @(posedge clk)
    !rst_n |-> !gnt && !ready && !error;
  endproperty

  // Property: Req dustugunde gnt de dusmeli
  property p_req_deassert;
    @(posedge clk) disable iff (!rst_n)
    $fell(req) |=> $fell(gnt);
  endproperty

  // Assertion'lari etkinlestir
  assert property (p_req_gnt)
    else $error("[%0t] REQ->GNT ihlali!", $time);

  assert property (p_valid_ready)
    else $error("[%0t] VALID->READY ihlali!", $time);

  assert property (p_reset_check)
    else $error("[%0t] Reset kontrol ihlali!", $time);

  // Cover: Bu durumun gerceklestigini dogrula
  cover property (p_req_gnt)
    $display("[%0t] COVER: req->gnt gozlemlendi", $time);

  // =========================================================================
  // Sequence tanimlari
  // =========================================================================
  sequence s_handshake;
    valid ##[1:3] ready;
  endsequence

  sequence s_burst;
    valid [*4];  // 4 ardisik cycle valid
  endsequence

  // =========================================================================
  // Test Uyaricilari
  // =========================================================================
  initial begin
    $display("=== SystemVerilog Assertions (SVA) ===\n");

    rst_n = 0; req = 0; valid = 0; data = 0;
    #20;
    rst_n = 1;
    #10;

    // Normal req/gnt
    $display("--- Normal REQ/GNT ---");
    @(posedge clk); req = 1;
    @(posedge clk); @(posedge clk);
    req = 0;
    #20;

    // Valid/Ready handshake
    $display("--- VALID/READY Handshake ---");
    @(posedge clk); valid = 1; data = 8'hAB;
    @(posedge clk); @(posedge clk);
    valid = 0;
    #30;

    // Hata durumu
    $display("--- Hata Testi (data=0xFF) ---");
    @(posedge clk); valid = 1; data = 8'hFF;
    @(posedge clk); valid = 0; data = 0;
    #30;

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