blob: ffce8a558dbdedb48845b284e3d36a9fe661e587 [file] [log] [blame]
// Copyright lowRISC contributors.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
class mem_model #(int AddrWidth = top_pkg::TL_AW,
int DataWidth = top_pkg::TL_DW,
int MaskWidth = top_pkg::TL_DBW) extends uvm_object;
typedef bit [AddrWidth-1:0] mem_addr_t;
typedef bit [DataWidth-1:0] mem_data_t;
typedef bit [MaskWidth-1:0] mem_mask_t;
bit [7:0] system_memory[mem_addr_t];
`uvm_object_param_utils(mem_model#(AddrWidth, DataWidth))
`uvm_object_new
function int get_written_bytes();
return system_memory.size();
endfunction
function bit [7:0] read_byte(mem_addr_t addr);
bit [7:0] data;
if (system_memory.exists(addr)) begin
data = system_memory[addr];
`uvm_info(`gfn, $sformatf("Read Mem : Addr[0x%0h], Data[0x%0h]", addr, data), UVM_HIGH)
end else begin
`DV_CHECK_STD_RANDOMIZE_FATAL(data)
`uvm_error(`gfn, $sformatf("read to uninitialzed addr 0x%0h", addr))
end
return data;
endfunction
function void write_byte(mem_addr_t addr, bit [7:0] data);
`uvm_info(`gfn, $sformatf("Write Mem : Addr[0x%0h], Data[0x%0h]", addr, data), UVM_HIGH)
system_memory[addr] = data;
endfunction
function void compare_byte(mem_addr_t addr, bit [7:0] act_data);
`uvm_info(`gfn, $sformatf("Compare Mem : Addr[0x%0h], Act Data[0x%0h], Exp Data[0x%0h]",
addr, act_data, system_memory[addr]), UVM_HIGH)
system_memory[addr] = act_data;
`DV_CHECK_EQ(act_data, system_memory[addr], $sformatf("addr 0x%0h read out mismatch", addr))
endfunction
function void write(input mem_addr_t addr, mem_data_t data, mem_mask_t mask = '1);
bit [7:0] byte_data;
for (int i = 0; i < DataWidth / 8; i++) begin
if (mask[0]) begin
byte_data = data[7:0];
write_byte(addr + i, byte_data);
end
data = data >> 8;
mask = mask >> 1;
end
endfunction
function mem_data_t read(mem_addr_t addr, mem_mask_t mask = '1);
mem_data_t data;
for (int i = DataWidth / 8 - 1; i >= 0; i--) begin
data = data << 8;
if (mask[MaskWidth - 1]) data[7:0] = read_byte(addr + i);
else data[7:0] = 0;
mask = mask << 1;
end
return data;
endfunction
function void compare(mem_addr_t addr, mem_data_t act_data, mem_mask_t mask = '1);
bit [7:0] byte_data;
for (int i = 0; i < DataWidth / 8; i++) begin
byte_data = act_data[7:0];
if (mask[0]) begin
compare_byte(addr + i, byte_data);
end else begin
`DV_CHECK_EQ(byte_data, 0,
$sformatf("addr 0x%0h masked data aren't 0, mask 0x%0h", addr, mask))
end
act_data = act_data>> 8;
mask = mask >> 1;
end
endfunction
endclass