[spi_device/dv] Add direct test to verify read buffer CSRs directly verify read buffer related CSRs - readbuf_watermark, readbuf_flip and last_read_addr Signed-off-by: Weicai Yang <weicai@google.com>
diff --git a/hw/ip/spi_device/data/spi_device_testplan.hjson b/hw/ip/spi_device/data/spi_device_testplan.hjson index 1d63cf5..677bf26 100644 --- a/hw/ip/spi_device/data/spi_device_testplan.hjson +++ b/hw/ip/spi_device/data/spi_device_testplan.hjson
@@ -355,7 +355,7 @@ index 0. - Check correctness of `last_read_addr`, `readbuf_watermark` and `readbuf_flip`.''' milestone: V2 - tests: ["spi_device_flash_mode"] + tests: ["spi_device_flash_mode", "spi_device_read_buffer_direct"] } { name: cmd_dummy_cycle
diff --git a/hw/ip/spi_device/dv/env/seq_lib/spi_device_pass_base_vseq.sv b/hw/ip/spi_device/dv/env/seq_lib/spi_device_pass_base_vseq.sv index 9c7ce35..32b578f 100644 --- a/hw/ip/spi_device/dv/env/seq_lib/spi_device_pass_base_vseq.sv +++ b/hw/ip/spi_device/dv/env/seq_lib/spi_device_pass_base_vseq.sv
@@ -98,6 +98,14 @@ read_addr_size_type inside {ReadAddrWithinMailbox, ReadAddrOutsideMailbox}; } + rand bit [9:0] read_threshold_val; + constraint read_threshold_val_c { + read_threshold_val dist { + 0 :/ 1, + [1:4] :/ 1, + [5:'h3fe] :/ 3, + 'h3ff :/ 1}; + } `uvm_object_utils(spi_device_pass_base_vseq) `uvm_object_new @@ -343,6 +351,10 @@ `DV_CHECK_RANDOMIZE_FATAL(ral.jedec_id) csr_update(.csr(ral.jedec_id)); + // disable watermark event + ral.read_threshold.set(read_threshold_val); + csr_update(ral.read_threshold); + config_all_cmd_infos(); spi_device_flash_auto_rsp_nonblocking();
diff --git a/hw/ip/spi_device/dv/env/seq_lib/spi_device_read_buffer_direct_vseq.sv b/hw/ip/spi_device/dv/env/seq_lib/spi_device_read_buffer_direct_vseq.sv new file mode 100644 index 0000000..33cde88 --- /dev/null +++ b/hw/ip/spi_device/dv/env/seq_lib/spi_device_read_buffer_direct_vseq.sv
@@ -0,0 +1,92 @@ +// Copyright lowRISC contributors. +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// direct test to verify read buffer related CSRs +// - readbuf_watermark, readbuf_flip and last_read_addr +class spi_device_read_buffer_direct_vseq extends spi_device_flash_mode_vseq; + `uvm_object_utils(spi_device_read_buffer_direct_vseq) + `uvm_object_new + + task body(); + int start_addr = 0; + int payload_size; + spi_device_flash_pass_init(); + + // disable watermark event + ral.read_threshold.set(0); + csr_update(ral.read_threshold); + + `uvm_info(`gfn, "reading from 0 to half size", UVM_MEDIUM) + payload_size = READ_BUFFER_SIZE / 2; + send_read_cmd(start_addr, payload_size); + check_interrupts(.interrupts((1 << ReadbufFlip)), .check_set(1)); + start_addr += payload_size; + + `uvm_info(`gfn, "reading from half size to max size", UVM_MEDIUM) + // start_addr need to be kept increasing which is how we track the flip bit event + send_read_cmd(start_addr, payload_size); + check_interrupts(.interrupts((1 << ReadbufFlip)), .check_set(1)); + start_addr += payload_size; + + start_addr += READ_BUFFER_SIZE / 2 - 1; + `uvm_info(`gfn, $sformatf("reading only the last byte of the 1st half at 0x%0x", start_addr), + UVM_MEDIUM) + send_read_cmd(.start_addr(start_addr), .payload_size(1)); + check_interrupts(.interrupts((1 << ReadbufFlip)), .check_set(1)); + start_addr += 1; + + start_addr += READ_BUFFER_SIZE / 2 - 1; + `uvm_info(`gfn, $sformatf("reading only the last byte of the 2nd half at 0x%0x", start_addr), + UVM_MEDIUM) + send_read_cmd(.start_addr(start_addr), .payload_size(1)); + check_interrupts(.interrupts((1 << ReadbufFlip)), .check_set(1)); + start_addr += 1; + + // no watermark event as threshold is 0 + check_interrupts(.interrupts((1 << ReadbufWatermark)), .check_set(0)); + + // testing ReadbufWatermark + `DV_CHECK_MEMBER_RANDOMIZE_WITH_FATAL(read_threshold_val, read_threshold_val > 0;) + ral.read_threshold.set(read_threshold_val); + csr_update(ral.read_threshold); + + if (read_threshold_val > 1) begin + `uvm_info(`gfn, "reading from 0 to read_threshold_val - 2", UVM_MEDIUM) + payload_size = read_threshold_val - 1; + send_read_cmd(.start_addr(start_addr), .payload_size(payload_size)); + check_interrupts(.interrupts((1 << ReadbufWatermark)), .check_set(0)); + start_addr += payload_size; + end + + `uvm_info(`gfn, "reading 1 more byte at read_threshold_val - 1", UVM_MEDIUM) + send_read_cmd(.start_addr(start_addr), .payload_size(1)); + check_interrupts(.interrupts((1 << ReadbufWatermark)), .check_set(1)); + start_addr += 1; + + payload_size = READ_BUFFER_SIZE / 2 - 1; + `uvm_info(`gfn, "reading from read_threshold_val for 1k", UVM_MEDIUM) + send_read_cmd(.start_addr(start_addr), .payload_size(payload_size)); + // no watermark as watermark event isn't sticky + check_interrupts(.interrupts((1 << ReadbufWatermark)), .check_set(0)); + check_interrupts(.interrupts((1 << ReadbufFlip)), .check_set(1)); + start_addr += payload_size; + + start_addr += 1; + `uvm_info(`gfn, "reading 1 more byte at read_threshold_val - 1 in 2nd half", UVM_MEDIUM) + send_read_cmd(.start_addr(start_addr), .payload_size(1)); + check_interrupts(.interrupts((1 << ReadbufWatermark)), .check_set(1)); + endtask + + task send_read_cmd(bit[31:0] start_addr, int payload_size); + bit [7:0] opcode; + + `DV_CHECK_STD_RANDOMIZE_WITH_FATAL(opcode, + opcode inside {READ_CMD_LIST} && opcode inside {valid_opcode_q};) + + spi_host_xfer_flash_item(opcode, payload_size, start_addr); + cfg.clk_rst_vif.wait_clks(10); + + csr_rd_check(.ptr(ral.last_read_addr), .compare_value(start_addr + payload_size)); + endtask +endclass : spi_device_read_buffer_direct_vseq
diff --git a/hw/ip/spi_device/dv/env/seq_lib/spi_device_vseq_list.sv b/hw/ip/spi_device/dv/env/seq_lib/spi_device_vseq_list.sv index c8400ce..319f23f 100644 --- a/hw/ip/spi_device/dv/env/seq_lib/spi_device_vseq_list.sv +++ b/hw/ip/spi_device/dv/env/seq_lib/spi_device_vseq_list.sv
@@ -30,4 +30,5 @@ `include "spi_device_upload_vseq.sv" `include "spi_device_cfg_cmd_vseq.sv" `include "spi_device_flash_mode_vseq.sv" +`include "spi_device_read_buffer_direct_vseq.sv" `include "spi_device_flash_all_vseq.sv"
diff --git a/hw/ip/spi_device/dv/env/spi_device_env.core b/hw/ip/spi_device/dv/env/spi_device_env.core index cbe77aa..98c3f16 100644 --- a/hw/ip/spi_device/dv/env/spi_device_env.core +++ b/hw/ip/spi_device/dv/env/spi_device_env.core
@@ -46,6 +46,7 @@ - seq_lib/spi_device_upload_vseq.sv: {is_include_file: true} - seq_lib/spi_device_cfg_cmd_vseq.sv: {is_include_file: true} - seq_lib/spi_device_flash_mode_vseq.sv: {is_include_file: true} + - seq_lib/spi_device_read_buffer_direct_vseq.sv: {is_include_file: true} - seq_lib/spi_device_flash_all_vseq.sv: {is_include_file: true} file_type: systemVerilogSource
diff --git a/hw/ip/spi_device/dv/spi_device_sim_cfg.hjson b/hw/ip/spi_device/dv/spi_device_sim_cfg.hjson index 841a13f..ccb1da0 100644 --- a/hw/ip/spi_device/dv/spi_device_sim_cfg.hjson +++ b/hw/ip/spi_device/dv/spi_device_sim_cfg.hjson
@@ -176,6 +176,11 @@ } { + name: spi_device_read_buffer_direct + uvm_test_seq: spi_device_read_buffer_direct_vseq + } + + { name: spi_device_flash_all uvm_test_seq: spi_device_flash_all_vseq }