init
This commit is contained in:
116
code/vezba10/verif/calc_scoreboard.sv
Normal file
116
code/vezba10/verif/calc_scoreboard.sv
Normal file
@@ -0,0 +1,116 @@
|
||||
`ifndef CALC_SCOREBOARD_SV
|
||||
`define CALC_SCOREBOARD_SV
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Calc1 scoreboard (self-checking, reference-model based - Vezba 10).
|
||||
//
|
||||
// For every transaction collected by the monitor, the embedded reference model
|
||||
// (predictor) computes the expected response/result from the stimulus and
|
||||
// compares it against what the DUT actually produced. Mismatches are reported
|
||||
// as UVM_ERROR.
|
||||
//-----------------------------------------------------------------------------
|
||||
class calc_scoreboard extends uvm_scoreboard;
|
||||
|
||||
// control fields
|
||||
bit checks_enable = 1;
|
||||
bit coverage_enable = 1;
|
||||
|
||||
// TLM port connecting the scoreboard to the monitor
|
||||
uvm_analysis_imp#(calc_seq_item, calc_scoreboard) item_collected_imp;
|
||||
|
||||
// bookkeeping
|
||||
int unsigned num_of_tr;
|
||||
int unsigned num_passed;
|
||||
int unsigned num_failed;
|
||||
|
||||
`uvm_component_utils_begin(calc_scoreboard)
|
||||
`uvm_field_int(checks_enable, UVM_DEFAULT)
|
||||
`uvm_field_int(coverage_enable, UVM_DEFAULT)
|
||||
`uvm_component_utils_end
|
||||
|
||||
function new(string name = "calc_scoreboard", uvm_component parent = null);
|
||||
super.new(name,parent);
|
||||
item_collected_imp = new("item_collected_imp", this);
|
||||
endfunction : new
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Reference model / predictor.
|
||||
// Computes the expected response and result for a Calc1 command, following
|
||||
// the functional specification (Vezba 5, Tabela 6/7/8).
|
||||
// All arithmetic is unsigned.
|
||||
//--------------------------------------------------------------------------
|
||||
function void predict(input bit [CMD_WIDTH-1:0] cmd,
|
||||
input bit [DATA_WIDTH-1:0] op1,
|
||||
input bit [DATA_WIDTH-1:0] op2,
|
||||
output bit [RESP_WIDTH-1:0] exp_resp,
|
||||
output bit [DATA_WIDTH-1:0] exp_data);
|
||||
bit [DATA_WIDTH:0] tmp; // one extra bit to catch carry/borrow
|
||||
exp_data = '0;
|
||||
case (cmd)
|
||||
CMD_ADD : begin
|
||||
tmp = {1'b0, op1} + {1'b0, op2};
|
||||
if (tmp[DATA_WIDTH]) exp_resp = RESP_ERROR; // overflow
|
||||
else begin exp_resp = RESP_SUCCESS; exp_data = tmp[DATA_WIDTH-1:0]; end
|
||||
end
|
||||
CMD_SUB : begin
|
||||
if (op1 < op2) exp_resp = RESP_ERROR; // underflow
|
||||
else begin exp_resp = RESP_SUCCESS; exp_data = op1 - op2; end
|
||||
end
|
||||
CMD_SHL : begin
|
||||
exp_resp = RESP_SUCCESS;
|
||||
exp_data = op1 << op2[4:0];
|
||||
end
|
||||
CMD_SHR : begin
|
||||
exp_resp = RESP_SUCCESS;
|
||||
exp_data = op1 >> op2[4:0];
|
||||
end
|
||||
default : begin
|
||||
exp_resp = RESP_ERROR; // invalid command
|
||||
end
|
||||
endcase
|
||||
endfunction : predict
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Analysis-port callback: invoked by the monitor for each collected item.
|
||||
//--------------------------------------------------------------------------
|
||||
function void write(calc_seq_item tr);
|
||||
bit [RESP_WIDTH-1:0] exp_resp;
|
||||
bit [DATA_WIDTH-1:0] exp_data;
|
||||
bit ok;
|
||||
|
||||
num_of_tr++;
|
||||
if (!checks_enable) return;
|
||||
|
||||
predict(tr.cmd, tr.op1, tr.op2, exp_resp, exp_data);
|
||||
|
||||
// The result data is only meaningful for a successful operation.
|
||||
ok = (tr.resp === exp_resp) &&
|
||||
((exp_resp !== RESP_SUCCESS) || (tr.result === exp_data));
|
||||
|
||||
if (ok) begin
|
||||
num_passed++;
|
||||
`uvm_info(get_type_name(),
|
||||
$sformatf("PASS: %s | expected resp=%0d data=0x%08h",
|
||||
tr.convert2string(), exp_resp, exp_data), UVM_HIGH)
|
||||
end
|
||||
else begin
|
||||
num_failed++;
|
||||
`uvm_error(get_type_name(),
|
||||
$sformatf("MISMATCH on port %0d, cmd=%s op1=0x%08h op2=0x%08h : expected resp=%0d data=0x%08h, got resp=%0d data=0x%08h",
|
||||
tr.port+1, tr.cmd2string(), tr.op1, tr.op2,
|
||||
exp_resp, exp_data, tr.resp, tr.result))
|
||||
end
|
||||
endfunction : write
|
||||
|
||||
function void report_phase(uvm_phase phase);
|
||||
`uvm_info(get_type_name(),
|
||||
$sformatf("Scoreboard examined %0d transactions: %0d passed, %0d failed",
|
||||
num_of_tr, num_passed, num_failed), UVM_LOW)
|
||||
if (num_failed != 0)
|
||||
`uvm_warning(get_type_name(),
|
||||
$sformatf("%0d transaction(s) did NOT match the reference model", num_failed))
|
||||
endfunction : report_phase
|
||||
|
||||
endclass : calc_scoreboard
|
||||
|
||||
`endif
|
||||
Reference in New Issue
Block a user