diff --git a/doc/verification.rst b/doc/verification.rst index b5fac5c2..073b7d02 100644 --- a/doc/verification.rst +++ b/doc/verification.rst @@ -46,8 +46,8 @@ execution. Memory Model """""""""""" -The code can be found in the -`dv/uvm/core_ibex/common/mem_model `_ +The code is vendored from OpenTitan and can be found in the +`vendor/lowrisc_ip/mem_model `_ directory. The testbench instantiates a single instance of this memory model that it loads the compiled assembly test program into at the beginning of each test. diff --git a/dv/uvm/core_ibex/common/mem_model/mem_model.sv b/dv/uvm/core_ibex/common/mem_model/mem_model.sv deleted file mode 100644 index b6f71114..00000000 --- a/dv/uvm/core_ibex/common/mem_model/mem_model.sv +++ /dev/null @@ -1,57 +0,0 @@ -// Copyright lowRISC contributors. -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 - -class mem_model#(parameter int ADDR_WIDTH = 32, - parameter int DATA_WIDTH = 32) extends uvm_object; - - typedef bit [ADDR_WIDTH-1:0] mem_addr_t; - typedef bit [DATA_WIDTH-1:0] mem_data_t; - - bit [7:0] system_memory[mem_addr_t]; - - `uvm_object_param_utils(mem_model#(ADDR_WIDTH, DATA_WIDTH)) - - function new(string name=""); - super.new(name); - 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(get_full_name(), - $sformatf("Read Mem : Addr[0x%0h], Data[0x%0h]", addr, data), UVM_HIGH) - end - else begin - `DV_CHECK_STD_RANDOMIZE_FATAL(data) - `uvm_error(get_full_name(), $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(get_full_name(), - $sformatf("Write Mem : Addr[0x%0h], Data[0x%0h]", addr, data), UVM_HIGH) - system_memory[addr] = data; - endfunction - - function void write(input mem_addr_t addr, mem_data_t data); - bit [7:0] byte_data; - for(int i=0; i> 8; - end - endfunction - - function mem_data_t read(mem_addr_t addr); - mem_data_t data; - for(int i=DATA_WIDTH/8-1; i>=0; i--) begin - data = data << 8; - data[7:0] = read_byte(addr+i); - end - return data; - endfunction - -endclass diff --git a/dv/uvm/core_ibex/ibex_dv.f b/dv/uvm/core_ibex/ibex_dv.f index 52bf6f8a..5da9f549 100644 --- a/dv/uvm/core_ibex/ibex_dv.f +++ b/dv/uvm/core_ibex/ibex_dv.f @@ -61,13 +61,13 @@ ${PRJ_DIR}/ibex/vendor/google_riscv-dv/src/riscv_signature_pkg.sv +incdir+${PRJ_DIR}/ibex/dv/uvm/core_ibex/tests +incdir+${PRJ_DIR}/ibex/dv/uvm/core_ibex/common/ibex_mem_intf_agent +incdir+${PRJ_DIR}/ibex/dv/uvm/core_ibex/common/irq_agent -+incdir+${PRJ_DIR}/ibex/dv/uvm/core_ibex/common/mem_model ++incdir+${PRJ_DIR}/ibex/vendor/lowrisc_ip/mem_model +incdir+${PRJ_DIR}/ibex/vendor/lowrisc_ip/dv_utils ${PRJ_DIR}/ibex/dv/uvm/top_pkg/top_pkg.sv ${PRJ_DIR}/ibex/vendor/lowrisc_ip/common_ifs/clk_rst_if.sv ${PRJ_DIR}/ibex/vendor/lowrisc_ip/common_ifs/pins_if.sv ${PRJ_DIR}/ibex/vendor/lowrisc_ip/dv_utils/dv_utils_pkg.sv -${PRJ_DIR}/ibex/dv/uvm/core_ibex/common/mem_model/mem_model_pkg.sv +${PRJ_DIR}/ibex/vendor/lowrisc_ip/mem_model/mem_model_pkg.sv ${PRJ_DIR}/ibex/dv/uvm/core_ibex/common/ibex_mem_intf_agent/ibex_mem_intf.sv ${PRJ_DIR}/ibex/dv/uvm/core_ibex/common/ibex_mem_intf_agent/ibex_mem_intf_agent_pkg.sv ${PRJ_DIR}/ibex/dv/uvm/core_ibex/common/irq_agent/irq_if.sv diff --git a/vendor/lowrisc_ip.vendor.hjson b/vendor/lowrisc_ip.vendor.hjson index 1f0a35ca..b93e8c51 100644 --- a/vendor/lowrisc_ip.vendor.hjson +++ b/vendor/lowrisc_ip.vendor.hjson @@ -15,6 +15,7 @@ {from: "hw/dv/sv/csr_utils", to: "csr_utils"}, {from: "hw/dv/sv/dv_lib", to: "dv_lib"}, {from: "hw/dv/sv/dv_base_reg", to: "dv_base_reg"}, + {from: "hw/dv/sv/mem_model", to: "mem_model"}, {from: "hw/dv/verilator", to: "dv_verilator"}, // We apply a patch to the top_pkg core file name when vendoring in diff --git a/vendor/lowrisc_ip/mem_model/README.md b/vendor/lowrisc_ip/mem_model/README.md new file mode 100644 index 00000000..dc8c8181 --- /dev/null +++ b/vendor/lowrisc_ip/mem_model/README.md @@ -0,0 +1,26 @@ +## Memory Model +The memory model UVC models a memory device which any host interface can read +from or write to. It is implemented as a `uvm_object`, and instantiates an +associative array of bytes `system_memory`. This class is paramterized by both +the address width and the data width, and creates two `typedefs` to represent +both, `mem_addr_t` and `mem_data_t`. +The `mem_model` class has four main functions, which are detailed below. + +### `read_byte(mem_addr_t addr)` +This function looks up the byte of data corresponding to the memory address +passed in, and returns it. If the address does not exist in `system_memory`, it +will randomize the returned data and throw a `UVM_ERROR`. + +### `write_byte(mem_addr_t addr, bit [7:0] data)` +This function simply assigns the given data to the specified memory address +location in `system_memory`. + +### `write(input mem_addr_t addr, mem_data_t data)` +This function writes a full memory word of width `mem_data_t` to the specified +address, breaking it down into a series of back-to-back calls to `write_byte()` +to correctly byte-address the memory. + +### `read(mem_addr_t addr)` +This function reads a full memory word of width `mem_data_t` from the specified +address, breaking it down into a series of back-to-back calls to `read_byte()` +to correctly byte-address the memory. diff --git a/dv/uvm/core_ibex/common/mem_model/mem_model.core b/vendor/lowrisc_ip/mem_model/mem_model.core similarity index 92% rename from dv/uvm/core_ibex/common/mem_model/mem_model.core rename to vendor/lowrisc_ip/mem_model/mem_model.core index 890bab60..f6da0921 100644 --- a/dv/uvm/core_ibex/common/mem_model/mem_model.core +++ b/vendor/lowrisc_ip/mem_model/mem_model.core @@ -8,7 +8,7 @@ description: "DV Memory Model" filesets: files_dv: depend: - - lowrisc:dv:dv_utils + - lowrisc:constants:top_pkg files: - mem_model_pkg.sv - mem_model.sv: {is_include_file: true} diff --git a/vendor/lowrisc_ip/mem_model/mem_model.sv b/vendor/lowrisc_ip/mem_model/mem_model.sv new file mode 100644 index 00000000..ffce8a55 --- /dev/null +++ b/vendor/lowrisc_ip/mem_model/mem_model.sv @@ -0,0 +1,85 @@ +// 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 diff --git a/dv/uvm/core_ibex/common/mem_model/mem_model_pkg.sv b/vendor/lowrisc_ip/mem_model/mem_model_pkg.sv similarity index 100% rename from dv/uvm/core_ibex/common/mem_model/mem_model_pkg.sv rename to vendor/lowrisc_ip/mem_model/mem_model_pkg.sv