Virtual Interface

Gün 5: Arayüzler, Assertion ve Coverage | Sınıflar içinden fiziksel arayüze erişim

Kaynak Kod

// =============================================================================
// GUN 5 - Konu 3: Virtual Interfaces (Siniflar Icinden Arayuze Erisim)
// =============================================================================

interface simple_if(input logic clk);
  logic       valid;
  logic       ready;
  logic [7:0] data;

  clocking cb @(posedge clk);
    default input #1 output #1;
    output valid, data;
    input  ready;
  endclocking

  modport tb  (clocking cb, input clk);
  modport dut (input clk, valid, data, output ready);
endinterface

// --- Sinif: Virtual Interface kullanan Driver ---
class Driver;
  virtual simple_if.tb vif;  // Virtual interface handle
  int txn_count = 0;

  function new(virtual simple_if.tb vif);
    this.vif = vif;
  endfunction

  task drive(input logic [7:0] data);
    @(vif.cb);
    vif.cb.valid <= 1;
    vif.cb.data  <= data;
    @(vif.cb);
    wait(vif.cb.ready);
    vif.cb.valid <= 0;
    txn_count++;
    $display("  [%0t][Driver] Gonderildi: data=0x%02h (#%0d)", $time, data, txn_count);
  endtask

  task reset();
    vif.cb.valid <= 0;
    vif.cb.data  <= 0;
    @(vif.cb);
    $display("  [%0t][Driver] Reset yapildi", $time);
  endtask
endclass

// --- Sinif: Virtual Interface kullanan Monitor ---
class Monitor;
  virtual simple_if.tb vif;
  int observed_count = 0;
  logic [7:0] observed_data [$];

  function new(virtual simple_if.tb vif);
    this.vif = vif;
  endfunction

  task run();
    $display("  [Monitor] Dinleme basladi");
    forever begin
      @(vif.cb);
      if (vif.cb.valid && vif.cb.ready) begin
        observed_count++;
        observed_data.push_back(vif.cb.data);
        $display("  [%0t][Monitor] Gozlemlendi: data=0x%02h (#%0d)",
                 $time, vif.cb.data, observed_count);
      end
    end
  endtask
endclass

// Basit DUT
module simple_dut(simple_if.dut sif);
  always @(posedge sif.clk) begin
    sif.ready <= sif.valid;  // 1 cycle gecikme ile ready
  end
endmodule

// Top-level
module virtual_interface;
  logic clk = 0;
  always #5 clk = ~clk;

  simple_if sif(clk);
  simple_dut dut(sif);

  Driver  drv;
  Monitor mon;

  initial begin
    $display("=== Virtual Interface ===\n");

    // Virtual interface ile siniflari olustur
    drv = new(sif);
    mon = new(sif);

    // Monitor'u arka planda calistir
    fork
      mon.run();
    join_none

    // Reset
    drv.reset();
    #20;

    // Veri gonder
    for (int i = 0; i < 8; i++) begin
      drv.drive(i * 16 + 'hA0);
    end

    #50;
    $display("\n  --- Sonuc ---");
    $display("  Driver gonderdi : %0d", drv.txn_count);
    $display("  Monitor gozledi : %0d", mon.observed_count);
    $display("  Gozlenen veriler: %p", mon.observed_data);

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