`timescale 1ns/1ps
`include "uvm_macros.svh"
import uvm_pkg::*;
class width_item extends uvm_sequence_item;
bit write;
bit [31:0] data;
function new(string name="width_item"); super.new(name); endfunction
endclass
class width_adapter extends uvm_reg_adapter;
function new(string name="width_adapter"); super.new(name); endfunction
function uvm_sequence_item reg2bus(const ref uvm_reg_bus_op rw);
width_item item = new();
uvm_reg_data_t data = rw.data;
`ifdef REVIEW_UVM20
if ($test$plusargs("MIGRATED") && rw.kind == UVM_WRITE) data = {<< byte {data}};
`endif
item.write = rw.kind == UVM_WRITE;
item.data = data;
return item;
endfunction
function void bus2reg(uvm_sequence_item bus, ref uvm_reg_bus_op rw);
width_item item;
if (!$cast(item, bus)) `uvm_fatal("WIDTH", "Unexpected bus item")
rw.kind = item.write ? UVM_WRITE : UVM_READ;
rw.data = item.data;
`ifdef REVIEW_UVM20
if ($test$plusargs("MIGRATED") && !item.write) rw.data = {<< byte {rw.data}};
`endif
rw.status = UVM_IS_OK;
endfunction
endclass
class width_driver extends uvm_driver#(width_item);
bit [31:0] hardware;
int transfers;
function new(string name, uvm_component parent); super.new(name, parent); endfunction
task run_phase(uvm_phase phase);
width_item item;
forever begin
seq_item_port.get_next_item(item);
#1;
if (item.write) hardware = item.data;
else item.data = hardware;
transfers++;
seq_item_port.item_done();
end
endtask
endclass
class width_register extends uvm_reg;
uvm_reg_field value;
function new(string name="reg32"); super.new(name, 32, UVM_NO_COVERAGE); endfunction
function void build();
value = new("value");
value.configure(this, 32, 0, "RW", 0, 0, 1, 0, 1);
endfunction
endclass
class width_block extends uvm_reg_block;
width_register reg32;
function new(string name="model"); super.new(name, UVM_NO_COVERAGE); endfunction
function void build();
reg32 = new(); reg32.configure(this); reg32.build();
default_map = create_map("map", 0, 4, UVM_BIG_ENDIAN, 1);
default_map.add_reg(reg32, 0, "RW");
lock_model();
endfunction
endclass
class width_test extends uvm_test;
`uvm_component_utils(width_test)
uvm_sequencer#(width_item) sequencer;
width_driver driver;
width_adapter adapter;
width_block model;
function new(string name, uvm_component parent); super.new(name, parent); endfunction
function void build_phase(uvm_phase phase);
super.build_phase(phase);
sequencer = new("sequencer", this); driver = new("driver", this);
adapter = new(); model = new(); model.build();
endfunction
function void connect_phase(uvm_phase phase);
driver.seq_item_port.connect(sequencer.seq_item_export);
model.default_map.set_sequencer(sequencer, adapter);
model.default_map.set_auto_predict(1);
endfunction
task run_phase(uvm_phase phase);
uvm_status_e status;
uvm_reg_data_t value;
phase.raise_objection(this);
model.reg32.write(status, 'h12345678);
$display("REVIEW|write_ok|%0d", status == UVM_IS_OK);
$display("REVIEW|hardware|%08h", driver.hardware);
driver.hardware = 'h12345678;
model.reg32.read(status, value);
$display("REVIEW|read_ok|%0d", status == UVM_IS_OK);
$display("REVIEW|read_value|%08h", value[31:0]);
$display("REVIEW|transfers|%0d", driver.transfers);
$display("REVIEW|done|1");
phase.drop_objection(this);
endtask
endclass
module reg_width_probe;
initial run_test("width_test");
endmodule