Lab 2: Hiyerarşik Transaction
Gün 2: Nesne Yönelimli Programlama (OOP) | Transaction modeli, kalıtım ve hata enjeksiyonu
Kaynak Kod
// =============================================================================
// GUN 2 - Lab 2: Hiyerarsik Transaction Modeli ve Hata Enjeksiyonu
// =============================================================================
// Bu lab'da:
// - Temel Transaction sinifi olusturulacak
// - Kalitim ile ReadTxn, WriteTxn alt siniflari turetilecek
// - Hata enjeksiyonu yapan ErrorTxn sinifi eklenecek
// - Polimorfizm ile heterojen kuyruk islenecek
// =============================================================================
// --- Temel Islem Sinifi ---
class Transaction;
static int global_id = 0;
int id;
logic [31:0] address;
logic [31:0] data;
bit valid;
int timestamp;
function new(logic [31:0] addr = 0, logic [31:0] data = 0);
this.id = global_id++;
this.address = addr;
this.data = data;
this.valid = 1;
this.timestamp = $time;
endfunction
virtual function string get_type();
return "BASE";
endfunction
virtual function void display();
$display(" [%5s] ID=%0d | Addr=0x%08h | Data=0x%08h | V=%0b | T=%0t",
get_type(), id, address, data, valid, timestamp);
endfunction
virtual function Transaction copy();
Transaction t = new(this.address, this.data);
t.id = this.id;
t.valid = this.valid;
return t;
endfunction
virtual function bit compare(Transaction other);
return (this.address == other.address && this.data == other.data);
endfunction
endclass
// --- Okuma Islemi ---
class ReadTransaction extends Transaction;
int burst_size;
logic [31:0] read_data [$];
function new(logic [31:0] addr, int burst = 1);
super.new(addr, 0);
this.burst_size = burst;
endfunction
virtual function string get_type();
return "READ";
endfunction
task execute();
$display(" >>> READ baslatildi: Addr=0x%08h, Burst=%0d", address, burst_size);
for (int i = 0; i < burst_size; i++) begin
#5;
read_data.push_back($urandom);
end
$display(" <<< READ tamamlandi: %0d veri okundu", read_data.size());
endtask
virtual function void display();
super.display();
$display(" Burst=%0d, Okunan=%0d adet", burst_size, read_data.size());
endfunction
endclass
// --- Yazma Islemi ---
class WriteTransaction extends Transaction;
logic [3:0] byte_enable;
logic [31:0] write_data [$];
function new(logic [31:0] addr, logic [31:0] data, logic [3:0] be = 4'hF);
super.new(addr, data);
this.byte_enable = be;
write_data.push_back(data);
endfunction
virtual function string get_type();
return "WRITE";
endfunction
function void add_data(logic [31:0] d);
write_data.push_back(d);
endfunction
virtual function void display();
super.display();
$display(" BE=0x%01h, WData=%p", byte_enable, write_data);
endfunction
endclass
// --- Hata Enjeksiyonu Sinifi ---
class ErrorTransaction extends WriteTransaction;
typedef enum {NO_ERROR, ADDR_CORRUPT, DATA_CORRUPT, BOTH_CORRUPT} error_type_e;
error_type_e error_mode;
function new(logic [31:0] addr, logic [31:0] data, error_type_e err = NO_ERROR);
super.new(addr, data);
this.error_mode = err;
endfunction
virtual function string get_type();
return "ERROR";
endfunction
function void inject_error();
case (error_mode)
ADDR_CORRUPT: begin
address ^= 32'hFFFF_0000;
$display(" [!] HATA ENJEKSIYONU: Adres bozuldu -> 0x%08h", address);
end
DATA_CORRUPT: begin
data ^= 32'h0000_FFFF;
$display(" [!] HATA ENJEKSIYONU: Veri bozuldu -> 0x%08h", data);
end
BOTH_CORRUPT: begin
address ^= 32'hFFFF_0000;
data ^= 32'h0000_FFFF;
$display(" [!] HATA ENJEKSIYONU: Her ikisi de bozuldu");
end
default: $display(" [OK] Hata yok");
endcase
valid = (error_mode == NO_ERROR);
endfunction
virtual function void display();
super.display();
$display(" Hata Modu: %s", error_mode.name());
endfunction
endclass
// =============================================================================
module lab2_hiyerarsik_transaction;
initial begin
Transaction txn_queue [$]; // Polimorfik kuyruk
$display("============================================================");
$display(" LAB 2: Hiyerarsik Transaction Modeli");
$display("============================================================\n");
// --- 1. Cesitli islemler olustur ---
$display("--- 1. Islem Olusturma ---");
begin
ReadTransaction r1, r2;
WriteTransaction w1, w2;
ErrorTransaction e1, e2, e3;
r1 = new(32'hA000_0000, 4);
r2 = new(32'hA000_0100, 1);
w1 = new(32'hB000_0000, 32'hDEAD_BEEF);
w2 = new(32'hB000_0004, 32'hCAFE_BABE, 4'h3);
e1 = new(32'hC000_0000, 32'h1234_5678, ErrorTransaction::ADDR_CORRUPT);
e2 = new(32'hC000_0004, 32'hABCD_EF01, ErrorTransaction::DATA_CORRUPT);
e3 = new(32'hC000_0008, 32'h9999_9999, ErrorTransaction::BOTH_CORRUPT);
// Polimorfik kuyruga ekle
txn_queue = {r1, r2, w1, w2, e1, e2, e3};
end
// --- 2. Tum islemleri goster ---
$display("\n--- 2. Tum Islemler (Polimorfik display) ---");
foreach (txn_queue[i]) begin
txn_queue[i].display();
$display();
end
// --- 3. Hata enjeksiyonu ---
$display("--- 3. Hata Enjeksiyonu ---");
foreach (txn_queue[i]) begin
ErrorTransaction et;
if ($cast(et, txn_queue[i])) begin
et.inject_error();
et.display();
$display();
end
end
// --- 4. Istatistikler ---
$display("--- 4. Istatistikler ---");
begin
int read_count = 0, write_count = 0, error_count = 0, valid_count = 0;
foreach (txn_queue[i]) begin
ReadTransaction rt;
WriteTransaction wt;
ErrorTransaction et;
if ($cast(et, txn_queue[i])) error_count++;
else if ($cast(rt, txn_queue[i])) read_count++;
else if ($cast(wt, txn_queue[i])) write_count++;
if (txn_queue[i].valid) valid_count++;
end
$display(" Toplam = %0d", txn_queue.size());
$display(" READ = %0d", read_count);
$display(" WRITE = %0d", write_count);
$display(" ERROR = %0d", error_count);
$display(" Gecerli = %0d", valid_count);
$display(" Gecersiz = %0d", txn_queue.size() - valid_count);
end
$display("\n============================================================");
$display(" LAB 2 TAMAMLANDI");
$display("============================================================");
$finish;
end
endmodule