`timescale 1ns/1ps
`include "uvm_macros.svh"
import uvm_pkg::*;
class predictor_bus extends uvm_sequence_item;
`uvm_object_utils(predictor_bus)
uvm_reg_addr_t address;
uvm_reg_data_t data;
uvm_status_e status;
function new(string name="bus"); super.new(name); endfunction
endclass
class predictor_adapter extends uvm_reg_adapter;
function new(); super.new("adapter"); endfunction
virtual function uvm_sequence_item reg2bus(const ref uvm_reg_bus_op rw);
return null;
endfunction
virtual function void bus2reg(uvm_sequence_item item, ref uvm_reg_bus_op rw);
predictor_bus bus;
if (!$cast(bus,item)) `uvm_fatal("CAST", "Expected predictor_bus")
rw.kind = UVM_WRITE;
rw.addr = bus.address;
rw.data = bus.data;
rw.status = bus.status;
rw.byte_en = -1;
endfunction
endclass
class predictor_register extends uvm_reg;
uvm_reg_field field_value;
function new(); super.new("value",64,UVM_NO_COVERAGE); endfunction
function void build();
field_value = new("field_value");
field_value.configure(this,64,0,"RW",0,0,1,0,0);
endfunction
endclass
class predictor_block extends uvm_reg_block;
predictor_register value;
function new(); super.new("model", UVM_NO_COVERAGE); endfunction
function void build();
default_map = create_map("map",0,4,UVM_LITTLE_ENDIAN);
value = new();
value.configure(this);
value.build();
default_map.add_reg(value,0,"RW");
lock_model();
endfunction
endclass
class observed_predictor extends uvm_reg_predictor#(predictor_bus);
uvm_status_e observed_status;
function new(); super.new("predictor",null); endfunction
virtual function void pre_predict(uvm_reg_item rw);
observed_status = rw.status;
endfunction
endclass
module predictor_probe;
initial begin
predictor_block model = new();
predictor_adapter adapter = new();
observed_predictor predictor_value = new();
predictor_bus bus = new();
bit all_ok;
uvm_reg_data_t assembled;
model.build();
predictor_value.adapter = adapter;
predictor_value.map = model.default_map;
for (int failure=0; failure<3; failure++) begin
void'(model.value.predict('h5a));
all_ok = 1;
assembled = 0;
for (int beat=0; beat<2; beat++) begin
bus.address = beat*4;
bus.data = beat == 0 ? 'h89abcdef : 'h01234567;
bus.status = beat == failure ? UVM_NOT_OK : UVM_IS_OK;
all_ok &= bus.status == UVM_IS_OK;
assembled |= bus.data << (32*beat);
if (!$test$plusargs("MIGRATED")) predictor_value.write(bus);
end
// Bounded alternative: complete a monitor transaction before predicting it.
if ($test$plusargs("MIGRATED") && all_ok)
void'(model.value.predict(assembled,-1,UVM_PREDICT_WRITE));
$display("REVIEW|failure_%0d_mirror|%016h", failure, model.value.get_mirrored_value());
if (!$test$plusargs("MIGRATED"))
$display("REVIEW|failure_%0d_status|%0d", failure, predictor_value.observed_status);
end
$display("REVIEW|done|1");
$finish;
end
endmodule