[spi_device/dv] randomize sram setting and add test for extreme size
1. randomly allocate memory
2. add extreme test with min/max sram fifo size
diff --git a/hw/ip/spi_device/dv/Makefile b/hw/ip/spi_device/dv/Makefile
index 78f11b9..808862a 100644
--- a/hw/ip/spi_device/dv/Makefile
+++ b/hw/ip/spi_device/dv/Makefile
@@ -77,6 +77,10 @@
UVM_TEST_SEQ = spi_device_fifo_underflow_overflow_vseq
endif
+ifeq (${TEST_NAME},spi_device_extreme_fifo_size)
+ UVM_TEST_SEQ = spi_device_extreme_fifo_size_vseq
+endif
+
####################################################################################################
## Include the tool Makefile below ##
## Dont add anything else below it! ##
diff --git a/hw/ip/spi_device/dv/env/seq_lib/spi_device_base_vseq.sv b/hw/ip/spi_device/dv/env/seq_lib/spi_device_base_vseq.sv
index 30ac945..2ca6cc5 100644
--- a/hw/ip/spi_device/dv/env/seq_lib/spi_device_base_vseq.sv
+++ b/hw/ip/spi_device/dv/env/seq_lib/spi_device_base_vseq.sv
@@ -10,7 +10,8 @@
);
`uvm_object_utils(spi_device_base_vseq)
- bit do_spi_device_init = 1'b0;
+ bit do_spi_device_init = 1'b0;
+ bit do_spi_device_mem_cfg = 1'b1;
bit [1:0] spi_mode = 0; // TODO fixed value in spec now
@@ -19,13 +20,13 @@
rand bit host_bit_dir;
rand bit device_bit_dir;
- rand bit [31:0] sram_host_base_addr;
- rand bit [31:0] sram_host_limit_addr;
- rand bit [31:0] sram_device_base_addr;
- rand bit [31:0] sram_device_limit_addr;
+ rand uint sram_host_base_addr;
+ rand uint sram_host_limit_addr;
+ rand uint sram_device_base_addr;
+ rand uint sram_device_limit_addr;
- // TODO: remove this eventually
- constraint sanity_constraints_c {
+ // override it in random seq
+ constraint sram_constraints_c {
// host and device addr space within sram should not overlap
sram_host_base_addr == 32'h0;
sram_host_limit_addr == 32'h1ff; // 512 bytes
@@ -45,10 +46,6 @@
if (do_spi_device_init) spi_device_init();
endtask
- virtual task dut_shutdown();
- super.dut_shutdown();
- endtask
-
// check if any remaining data
virtual task check_for_tx_rx_idle();
uint tx_avail_bytes, rx_avail_bytes;
@@ -79,9 +76,12 @@
ral.cfg.rx_order.set(host_bit_dir);
//ral.cfg.timer_v.set(rx_timer); TODO do it later
csr_update(.csr(ral.cfg));
-
- set_sram_host_addr_range(sram_host_base_addr, sram_host_limit_addr);
- set_sram_device_addr_range(sram_device_base_addr, sram_device_limit_addr);
+ if (do_spi_device_mem_cfg) begin
+ set_sram_host_addr_range(sram_host_base_addr, sram_host_limit_addr);
+ set_sram_device_addr_range(sram_device_base_addr, sram_device_limit_addr);
+ // only configure sram once
+ do_spi_device_mem_cfg = 0;
+ end
endtask
virtual task reset_fifo(bit txfifo, bit rxfifo);
@@ -151,8 +151,9 @@
tx_wptr = ral.txf_ptr.wptr.get_mirrored_value();
foreach (device_data[i]) begin
bit [TL_DW-1:0] tx_wptr_addr;
- tx_wptr_addr = cfg.sram_start_addr + ral.txf_addr.base.get_mirrored_value()
- + tx_wptr[SRAM_MSB:0];
+ bit [TL_DW-1:0] tx_base_addr = ral.txf_addr.base.get_mirrored_value();
+ tx_base_addr[1:0] = 0; // ignore lower 2 bits
+ tx_wptr_addr = cfg.sram_start_addr + tx_base_addr + tx_wptr[SRAM_MSB:0];
`uvm_info(`gfn, $sformatf({"tx_wptr[SRAM_MSB:0] = 0x%0h, tx_wptr_phase_bit = 0x%0h, ",
"tx_sram_size_bytes = 0x%0h, tx_wptr_addr = 0x%0h"},
tx_wptr[SRAM_MSB:0], tx_wptr[SRAM_PTR_PHASE_BIT],
@@ -181,8 +182,9 @@
repeat (num_words) begin
bit [TL_DW-1:0] rx_rptr_addr;
logic [TL_DW-1:0] word_data;
- rx_rptr_addr = cfg.sram_start_addr + ral.rxf_addr.base.get_mirrored_value()
- + rx_rptr[SRAM_MSB:0];
+ bit [TL_DW-1:0] rx_base_addr = ral.rxf_addr.base.get_mirrored_value();
+ rx_base_addr[1:0] = 0; // ignore lower 2 bits
+ rx_rptr_addr = cfg.sram_start_addr + rx_base_addr + rx_rptr[SRAM_MSB:0];
`uvm_info(`gfn, $sformatf({"rx_rptr[SRAM_MSB:0] = 0x%0h, rx_rptr_phase_bit = 0x%0h, ",
"rx_sram_size_bytes = 0x%0h, rx_rptr_addr = 0x%0h"},
rx_rptr[SRAM_MSB:0], rx_rptr[SRAM_PTR_PHASE_BIT],
diff --git a/hw/ip/spi_device/dv/env/seq_lib/spi_device_extreme_fifo_size_vseq.sv b/hw/ip/spi_device/dv/env/seq_lib/spi_device_extreme_fifo_size_vseq.sv
new file mode 100644
index 0000000..9c2ec58
--- /dev/null
+++ b/hw/ip/spi_device/dv/env/seq_lib/spi_device_extreme_fifo_size_vseq.sv
@@ -0,0 +1,35 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+
+// test tx/rx sram fifo with extreme setting, size 1 word and SRAM_SIZE-1 word
+class spi_device_extreme_fifo_size_vseq extends spi_device_txrx_vseq;
+ `uvm_object_utils(spi_device_extreme_fifo_size_vseq)
+ `uvm_object_new
+
+ constraint sram_size_constraints_c {
+ host_sram_word_size dist {
+ 1 :/ 1, // 1 word
+ SRAM_SIZE[31:2]/2 :/ 1, // half of the total mem
+ SRAM_SIZE[31:2]-1 :/ 1, // max size
+ [2:SRAM_SIZE[31:2]-2] :/ 1
+ };
+ device_sram_word_size dist {
+ 1 :/ 1, // 1 word
+ SRAM_SIZE[31:2]/2 :/ 1, // half of the total mem
+ SRAM_SIZE[31:2]-1 :/ 1, // max size
+ [2:SRAM_SIZE[31:2]-2] :/ 1
+ };
+ }
+
+ // reduce total data to reduce sim time as fifo size is too small and it takes much longer time
+ // to finish
+ constraint tx_total_bytes_c {
+ tx_total_bytes inside {[SRAM_SIZE/2 : SRAM_SIZE*2]};
+ tx_total_bytes[1:0] == 0; // word aligned
+ }
+
+ constraint num_trans_c {
+ num_trans == 2;
+ }
+endclass : spi_device_extreme_fifo_size_vseq
diff --git a/hw/ip/spi_device/dv/env/seq_lib/spi_device_sanity_vseq.sv b/hw/ip/spi_device/dv/env/seq_lib/spi_device_sanity_vseq.sv
index 8adc8cd..a353353 100644
--- a/hw/ip/spi_device/dv/env/seq_lib/spi_device_sanity_vseq.sv
+++ b/hw/ip/spi_device/dv/env/seq_lib/spi_device_sanity_vseq.sv
@@ -8,7 +8,6 @@
`uvm_object_utils(spi_device_sanity_vseq)
`uvm_object_new
-
constraint num_trans_c {
num_trans inside {[1:6]};
}
diff --git a/hw/ip/spi_device/dv/env/seq_lib/spi_device_txrx_vseq.sv b/hw/ip/spi_device/dv/env/seq_lib/spi_device_txrx_vseq.sv
index 81d806b..c4e04de 100644
--- a/hw/ip/spi_device/dv/env/seq_lib/spi_device_txrx_vseq.sv
+++ b/hw/ip/spi_device/dv/env/seq_lib/spi_device_txrx_vseq.sv
@@ -20,6 +20,10 @@
rand uint rx_delay;
rand uint spi_delay;
+ // helper variables for sram randomization
+ rand uint host_sram_word_size;
+ rand uint device_sram_word_size;
+
constraint tx_total_bytes_c {
tx_total_bytes inside {[SRAM_SIZE : 10 * SRAM_SIZE]};
tx_total_bytes[1:0] == 0; // word aligned
@@ -54,7 +58,38 @@
}
constraint num_trans_c {
- num_trans inside {[5:8]};
+ num_trans == 5;
+ }
+
+ // lower 2 bits are ignored, use word granularity to contrain the sram setting
+ constraint sram_constraints_c {
+ // if limit is 0, it means 1 word
+ sram_host_limit_addr[31:2] < (SRAM_SIZE/SRAM_WORD_SIZE);
+ sram_device_limit_addr[31:2] < (SRAM_SIZE/SRAM_WORD_SIZE);
+
+ sram_host_base_addr <= sram_host_limit_addr;
+ sram_device_base_addr <= sram_device_limit_addr;
+ // host and device addr space within sram should not overlap
+ if (sram_host_limit_addr < sram_device_base_addr) {
+ sram_host_limit_addr[31:2] < sram_device_base_addr[31:2];
+ sram_device_limit_addr < SRAM_SIZE;
+ } else {
+ sram_device_limit_addr[31:2] < sram_host_base_addr[31:2];
+ sram_host_limit_addr < SRAM_SIZE;
+ }
+ host_sram_word_size == sram_host_limit_addr[31:2] - sram_host_base_addr[31:2] + 1;
+ device_sram_word_size == sram_device_limit_addr[31:2] - sram_device_base_addr[31:2] + 1;
+ }
+
+ // size from 25 to SRAM_SIZE/SRAM_WORD_SIZE-25
+ // override it if test extreme cases
+ constraint sram_size_constraints_c {
+ host_sram_word_size inside {[25:SRAM_SIZE/SRAM_WORD_SIZE]};
+ device_sram_word_size inside {[25:SRAM_SIZE/SRAM_WORD_SIZE]};
+ host_sram_word_size == device_sram_word_size dist {
+ 1 :/ 2,
+ 0 :/ 1
+ };
}
virtual task body();
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 26bdba1..643e7bf 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
@@ -8,3 +8,4 @@
`include "spi_device_txrx_vseq.sv"
`include "spi_device_fifo_full_vseq.sv"
`include "spi_device_fifo_underflow_overflow_vseq.sv"
+`include "spi_device_extreme_fifo_size_vseq.sv"
diff --git a/hw/ip/spi_device/dv/env/spi_device_scoreboard.sv b/hw/ip/spi_device/dv/env/spi_device_scoreboard.sv
index 115f92b..666b5c0 100644
--- a/hw/ip/spi_device/dv/env/spi_device_scoreboard.sv
+++ b/hw/ip/spi_device/dv/env/spi_device_scoreboard.sv
@@ -82,6 +82,8 @@
uint tx_limit = ral.txf_addr.limit.get_mirrored_value();
uint rx_limit = ral.rxf_addr.limit.get_mirrored_value();
uint mem_addr = item.a_addr - cfg.sram_start_addr;
+ tx_base[1:0] = 0;
+ rx_base[1:0] = 0;
if (mem_addr inside {[tx_base : tx_base + tx_limit]}) begin // TX address
if (write && channel == AddrChannel) begin
tx_mem.write(mem_addr - tx_base, item.a_data);
diff --git a/hw/ip/spi_device/dv/tests/spi_device_base_test.sv b/hw/ip/spi_device/dv/tests/spi_device_base_test.sv
index ebbe910..51d99a7 100644
--- a/hw/ip/spi_device/dv/tests/spi_device_base_test.sv
+++ b/hw/ip/spi_device/dv/tests/spi_device_base_test.sv
@@ -9,7 +9,7 @@
virtual function void build_phase(uvm_phase phase);
max_quit_count = 50;
- test_timeout_ns = 400_000_000; // 400ms
+ test_timeout_ns = 600_000_000; // 600ms
super.build_phase(phase);
// configure the spi agent to be in Host mode
cfg.m_spi_agent_cfg.mode = Host;