Scoreboard
Gün 7: Bitirme Projesi - Bölüm 2 | Referans model ile DUT çıkışını karşılaştırma
Kaynak Kod
// =============================================================================
// GUN 7 - Konu 2: Scoreboard - Referans Model ile DUT Karsilastirmasi
// =============================================================================
class ALU_Scoreboard;
mailbox #(ALU_Transaction) drv2scb; // Driver'dan beklenen
mailbox #(ALU_Transaction) mon2scb; // Monitor'den gercek
int pass_count = 0;
int fail_count = 0;
int total_count = 0;
function new(mailbox #(ALU_Transaction) drv_mbx, mailbox #(ALU_Transaction) mon_mbx);
this.drv2scb = drv_mbx;
this.mon2scb = mon_mbx;
endfunction
task run();
ALU_Transaction expected, actual;
logic [15:0] ref_result;
logic [3:0] ref_flags;
$display("[Scoreboard] Baslatildi");
forever begin
drv2scb.get(expected);
mon2scb.get(actual);
total_count++;
// Referans model hesaplama
compute_reference(expected.opcode, expected.operand_a, expected.operand_b,
ref_result, ref_flags);
// Karsilastirma
if (actual.result === ref_result) begin
pass_count++;
end else begin
fail_count++;
$display("[Scoreboard] HATA #%0d!", total_count);
$display(" Islem : %s", expected.opcode.name());
$display(" A=0x%02h, B=0x%02h", expected.operand_a, expected.operand_b);
$display(" Beklenen : result=0x%04h, flags=%04b", ref_result, ref_flags);
$display(" Gercek : result=0x%04h, flags=%04b", actual.result, actual.flags);
end
end
endtask
// Referans model: ALU davranisini yazilimda modelle
function void compute_reference(
ALU_Transaction::opcode_e opcode,
logic [7:0] a, logic [7:0] b,
output logic [15:0] result,
output logic [3:0] flags
);
logic [16:0] temp;
flags = 0;
case (opcode)
ALU_Transaction::OP_ADD: begin
temp = {1'b0, a} + {1'b0, b};
result = temp[15:0];
flags[2] = temp[8]; // carry
flags[3] = (a[7] == b[7]) && (temp[7] != a[7]); // overflow
end
ALU_Transaction::OP_SUB: begin
temp = {1'b0, a} - {1'b0, b};
result = temp[15:0];
flags[2] = temp[8]; // borrow
flags[3] = (a[7] != b[7]) && (temp[7] != a[7]); // overflow
end
ALU_Transaction::OP_AND: result = {8'h00, a & b};
ALU_Transaction::OP_OR: result = {8'h00, a | b};
ALU_Transaction::OP_XOR: result = {8'h00, a ^ b};
ALU_Transaction::OP_NOT: result = {8'h00, ~a};
ALU_Transaction::OP_SHL: result = a << b[2:0];
ALU_Transaction::OP_SHR: result = a >> b[2:0];
endcase
// Zero & Negative
if (opcode inside {ALU_Transaction::OP_ADD, ALU_Transaction::OP_SUB})
flags[0] = (temp[7:0] == 0);
else
flags[0] = (result == 0);
flags[1] = result[15] | result[7];
endfunction
function void report();
$display("\n ========== SCOREBOARD RAPORU ==========");
$display(" Toplam : %0d", total_count);
$display(" Basarili: %0d", pass_count);
$display(" Basarisiz: %0d", fail_count);
if (fail_count == 0)
$display(" *** TUM TESTLER BASARILI! ***");
else
$display(" !!! %0d HATA TESPIT EDILDI !!!", fail_count);
$display(" ========================================");
endfunction
endclass