Lab 4: IPC Veri Akışı

Gün 4: Süreçler Arası İletişim (IPC) | Generator-Driver-Monitor arası Mailbox ile veri akışı

Kaynak Kod

// =============================================================================
// GUN 4 - Lab 4: Generator-Driver-Monitor Veri Akisi (Mailbox ile)
// =============================================================================

class Transaction;
  rand logic [7:0]  addr;
  rand logic [31:0] data;
  rand bit          rw;     // 0=read, 1=write
  int               id;
  static int        count = 0;

  constraint c_valid {
    addr inside {[8'h00:8'hFF]};
  }

  function new();
    id = count++;
  endfunction

  function void display(string prefix = "");
    $display("  %sTXN#%0d | %s | Addr=0x%02h | Data=0x%08h",
             prefix, id, rw ? "WR" : "RD", addr, data);
  endfunction

  function Transaction copy();
    Transaction t = new();
    t.addr = this.addr;
    t.data = this.data;
    t.rw   = this.rw;
    t.id   = this.id;
    return t;
  endfunction
endclass

class Generator;
  mailbox #(Transaction) gen2drv;
  int num_txn;
  event done;

  function new(mailbox #(Transaction) mbx, int num = 10);
    this.gen2drv = mbx;
    this.num_txn = num;
  endfunction

  task run();
    Transaction txn;
    $display("\n  [Generator] Baslatildi (%0d islem uretilecek)", num_txn);
    for (int i = 0; i < num_txn; i++) begin
      txn = new();
      assert(txn.randomize()) else $fatal(1, "Randomize hata!");
      $display("  [%0t][Generator] Uretildi:", $time);
      txn.display("    ");
      gen2drv.put(txn);
      #5;
    end
    $display("  [%0t][Generator] Tum islemler uretildi", $time);
    -> done;
  endtask
endclass

class Driver;
  mailbox #(Transaction) gen2drv;
  mailbox #(Transaction) drv2mon;

  function new(mailbox #(Transaction) in_mbx, mailbox #(Transaction) out_mbx);
    this.gen2drv = in_mbx;
    this.drv2mon = out_mbx;
  endfunction

  task run();
    Transaction txn;
    $display("  [Driver] Baslatildi");
    forever begin
      gen2drv.get(txn);
      drive(txn);
      drv2mon.put(txn);  // Monitor'e gonder
    end
  endtask

  task drive(Transaction txn);
    $display("  [%0t][Driver] Suruluyor:", $time);
    txn.display("    ");
    #10;  // Surme suresi
    $display("  [%0t][Driver] Tamamlandi: TXN#%0d", $time, txn.id);
  endtask
endclass

class Monitor;
  mailbox #(Transaction) drv2mon;
  int monitored_count = 0;

  function new(mailbox #(Transaction) mbx);
    this.drv2mon = mbx;
  endfunction

  task run();
    Transaction txn;
    $display("  [Monitor] Baslatildi");
    forever begin
      drv2mon.get(txn);
      monitored_count++;
      $display("  [%0t][Monitor] Izlendi (#%0d):", $time, monitored_count);
      txn.display("    ");
    end
  endtask
endclass

module lab4_ipc_veri_akisi;
  initial begin
    mailbox #(Transaction) gen2drv_mbx = new();
    mailbox #(Transaction) drv2mon_mbx = new();

    Generator gen = new(gen2drv_mbx, 8);
    Driver    drv = new(gen2drv_mbx, drv2mon_mbx);
    Monitor   mon = new(drv2mon_mbx);

    $display("============================================================");
    $display("  LAB 4: Generator -> Driver -> Monitor Veri Akisi");
    $display("============================================================");

    fork
      gen.run();
      drv.run();
      mon.run();
    join_any

    // Generator bitene kadar bekle
    wait(gen.done.triggered);
    #100;  // Pipeline'in bosalmasini bekle

    $display("\n  --- Istatistikler ---");
    $display("  Uretilen  : %0d", gen.num_txn);
    $display("  Izlenen   : %0d", mon.monitored_count);

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