Lab 5: Interface + Coverage
Gün 5: Arayüzler, Assertion ve Coverage | Interface, Virtual Interface, Driver ve Coverage entegrasyonu
Kaynak Kod
// =============================================================================
// GUN 5 - Lab 5: Interface + Virtual Interface + Driver + Coverage
// =============================================================================
// Interface tanimi
interface mem_if(input logic clk);
logic rst_n;
logic cs; // chip select
logic we; // write enable
logic [7:0] addr;
logic [31:0] wdata;
logic [31:0] rdata;
logic ack;
clocking cb @(posedge clk);
default input #1 output #1;
output cs, we, addr, wdata;
input rdata, ack;
endclocking
modport tb (clocking cb, output rst_n, input clk);
modport dut (input clk, rst_n, cs, we, addr, wdata, output rdata, ack);
endinterface
// Basit Bellek DUT
module memory_dut(mem_if.dut mif);
logic [31:0] mem [256];
always @(posedge mif.clk or negedge mif.rst_n) begin
if (!mif.rst_n) begin
mif.rdata <= 0;
mif.ack <= 0;
end else if (mif.cs) begin
if (mif.we) begin
mem[mif.addr] <= mif.wdata;
end else begin
mif.rdata <= mem[mif.addr];
end
mif.ack <= 1;
end else begin
mif.ack <= 0;
end
end
endmodule
// Transaction sinifi
class MemTransaction;
rand bit we;
rand bit [7:0] addr;
rand logic [31:0] wdata;
logic [31:0] rdata;
int id;
static int count = 0;
constraint c_addr {
addr inside {[0:63]};
}
constraint c_data {
we -> wdata != 0;
!we -> wdata == 0;
}
function new();
id = count++;
endfunction
function void display(string prefix = "");
$display(" %sTXN#%0d | %s | Addr=0x%02h | WData=0x%08h | RData=0x%08h",
prefix, id, we ? "WR" : "RD", addr, wdata, rdata);
endfunction
endclass
// Driver sinifi (virtual interface kullanan)
class MemDriver;
virtual mem_if.tb vif;
mailbox #(MemTransaction) mbx;
int driven_count = 0;
function new(virtual mem_if.tb vif, mailbox #(MemTransaction) mbx);
this.vif = vif;
this.mbx = mbx;
endfunction
task run();
MemTransaction txn;
forever begin
mbx.get(txn);
@(vif.cb);
vif.cb.cs <= 1;
vif.cb.we <= txn.we;
vif.cb.addr <= txn.addr;
vif.cb.wdata <= txn.wdata;
@(vif.cb);
wait(vif.cb.ack);
if (!txn.we)
txn.rdata = vif.cb.rdata;
vif.cb.cs <= 0;
driven_count++;
txn.display("[Driver] ");
end
endtask
task reset();
vif.rst_n = 0;
vif.cb.cs <= 0;
vif.cb.we <= 0;
vif.cb.addr <= 0;
vif.cb.wdata <= 0;
repeat(5) @(vif.cb);
vif.rst_n = 1;
@(vif.cb);
$display(" [Driver] Reset tamamlandi");
endtask
endclass
// Coverage sinifi
class MemCoverage;
covergroup mem_cg with function sample(bit we, bit [7:0] addr, logic [31:0] data);
cp_we: coverpoint we {
bins read = {0};
bins write = {1};
}
cp_addr: coverpoint addr {
bins low = {[0:15]};
bins mid = {[16:31]};
bins high = {[32:47]};
bins upper = {[48:63]};
}
cp_data: coverpoint data {
bins zero = {0};
bins nonzero = {[1:$]};
}
cx_we_addr: cross cp_we, cp_addr;
endgroup
mem_cg cg;
function new();
cg = new();
endfunction
function void sample(MemTransaction txn);
cg.sample(txn.we, txn.addr, txn.wdata);
endfunction
function void report();
$display("\n --- Kapsam Raporu ---");
$display(" Toplam : %.1f%%", cg.get_coverage());
$display(" cp_we : %.1f%%", cg.cp_we.get_coverage());
$display(" cp_addr : %.1f%%", cg.cp_addr.get_coverage());
$display(" cp_data : %.1f%%", cg.cp_data.get_coverage());
$display(" cx_we_addr : %.1f%%", cg.cx_we_addr.get_coverage());
endfunction
endclass
// Top-level testbench
module lab5_interface_coverage;
logic clk = 0;
always #5 clk = ~clk;
mem_if mif(clk);
memory_dut dut(mif);
mailbox #(MemTransaction) mbx;
MemDriver drv;
MemCoverage cov;
initial begin
$display("============================================================");
$display(" LAB 5: Interface + Driver + Coverage");
$display("============================================================\n");
mbx = new();
drv = new(mif, mbx);
cov = new();
// Reset
drv.reset();
// Driver'i arka planda calistir
fork
drv.run();
join_none
// Islemler uret ve kuyruga ekle
repeat (50) begin
MemTransaction txn = new();
assert(txn.randomize()) else $fatal(1, "Randomize hata!");
cov.sample(txn);
mbx.put(txn);
end
// Tum islemlerin bitmesini bekle
wait(mbx.num() == 0);
#100;
// Rapor
$display("\n --- Istatistikler ---");
$display(" Toplam surulen: %0d", drv.driven_count);
cov.report();
$display("\n============================================================");
$display(" LAB 5 TAMAMLANDI");
$display("============================================================");
$finish;
end
endmodule