[spi_device] Update Status TB to test WREN/ WRDI
This commit revises the spid_status pre_dv to test WREN/ WRDI/ SW update
of STATUS CSR.
Signed-off-by: Eunchan Kim <eunchan@opentitan.org>
diff --git a/hw/ip/spi_device/pre_dv/tb/spid_common.sv b/hw/ip/spi_device/pre_dv/tb/spid_common.sv
index 35dd100..5b9b61b 100644
--- a/hw/ip/spi_device/pre_dv/tb/spid_common.sv
+++ b/hw/ip/spi_device/pre_dv/tb/spid_common.sv
@@ -56,6 +56,38 @@
import spi_device_pkg::NumTotalCmdInfo;
parameter cmd_info_t [NumTotalCmdInfo-1:0] CmdInfo = {
+ // 27: WRDI
+ '{
+ valid: 1'b 1,
+ opcode: 8'h 04,
+ addr_mode: AddrDisabled,
+ addr_swap_en: 1'b 0,
+ mbyte_en: 1'b 0,
+ dummy_en: 1'b 0,
+ dummy_size: '0,
+ payload_en: 4'b 0001, // MISO
+ payload_dir: PayloadIn,
+ payload_swap_en: 1'b 0,
+ upload: 1'b 0,
+ busy: 1'b 0
+
+ },
+ // 26: WREN
+ '{
+ valid: 1'b 1,
+ opcode: 8'h 06,
+ addr_mode: AddrDisabled,
+ addr_swap_en: 1'b 0,
+ mbyte_en: 1'b 0,
+ dummy_en: 1'b 0,
+ dummy_size: '0,
+ payload_en: 4'b 0001, // MISO
+ payload_dir: PayloadIn,
+ payload_swap_en: 1'b 0,
+ upload: 1'b 0,
+ busy: 1'b 0
+
+ },
// 25: EX4B
'{
valid: 1'b 0,
@@ -702,6 +734,34 @@
endtask : spiflash_readstatus
+ task automatic spiflash_wel(
+ virtual spi_if.tb sif,
+ input spi_byte_t opcode
+ );
+ automatic spi_fifo_t send_data [$];
+ automatic spi_data_t rcv_data [$];
+
+ send_data.push_back('{data: opcode, dir: DirIn, mode: IoSingle});
+ spi_transaction(sif, send_data, rcv_data);
+
+ $display("WREN sent!");
+
+ endtask : spiflash_wel
+
+ task automatic spiflash_wren(
+ virtual spi_if.tb sif,
+ input spi_byte_t opcode
+ );
+ spiflash_wel(sif, opcode);
+ endtask : spiflash_wren
+
+ task automatic spiflash_wrdi(
+ virtual spi_if.tb sif,
+ input spi_byte_t opcode
+ );
+ spiflash_wel(sif, opcode);
+ endtask : spiflash_wrdi
+
task automatic spiflash_readjedec(
virtual spi_if.tb sif,
input spi_data_t opcode,
diff --git a/hw/ip/spi_device/pre_dv/tb/spid_status_tb.sv b/hw/ip/spi_device/pre_dv/tb/spid_status_tb.sv
index 3cf522f..6197334 100644
--- a/hw/ip/spi_device/pre_dv/tb/spid_status_tb.sv
+++ b/hw/ip/spi_device/pre_dv/tb/spid_status_tb.sv
@@ -50,7 +50,7 @@
sel_datapath_e dut_sel_dp;
// Command info for Read Status
// CmdReadStauts1, CmdReadStatus2, CmdReadStatus3
- cmd_info_index_e cmd_info_idx;
+ logic [CmdInfoIdxW-1:0] cmd_info_idx;
cmd_info_t cmd_info;
logic sys_status_we;
@@ -60,8 +60,12 @@
spi_mode_e spi_mode;
- logic s2p_valid;
- logic [7:0] s2p_data;
+ logic s2p_valid;
+ spi_byte_t s2p_data;
+
+ // wel_test_complete: Host triggers when wren/wrdi sent
+ // wel_update_done: SW triggers when update Status after wel_test
+ event wel_test_complete, wel_update_done;
initial begin
sck_clk.set_period_ps(SckPeriod);
@@ -107,6 +111,52 @@
spiflash_readstatus(tb_sif, 8'h 15, data);
$display("SPI Flash Read Status Tested!!");
+
+ $display("WREN/ WRDI tests");
+ spiflash_wren(tb_sif, 8'h 06); // WREN
+
+ repeat(20) @(sck_clk.cbn);
+
+ // Read back and check
+ spiflash_readstatus(tb_sif, 8'h 05, data);
+
+ assert(data[1] == 1'b 1);
+
+ repeat(20) @(sck_clk.cbn);
+
+ spiflash_wrdi(tb_sif, 8'h 04); // WRDI
+
+ repeat(20) @(sck_clk.cbn);
+
+ // Read back and check
+ spiflash_readstatus(tb_sif, 8'h 05, data);
+
+ assert(data[1] == 1'b 0);
+
+ repeat(20) @(sck_clk.cbn);
+ ->wel_test_complete;
+
+ @(wel_update_done);
+
+ // Expect SW to set WEL again.
+ // The SW request is comitted after a SPI transaction is received.
+ // Sending read status command but expect WEL still 0.
+ // Then next Read Status will return the correct value (WEL == 1)
+
+ @(sck_clk.cbn);
+ // This should return 0 for WEL
+ spiflash_readstatus(tb_sif, 8'h 05, data);
+ assert(data[1] == 1'b 0);
+ repeat(20) @(sck_clk.cbn);
+
+ // This should return 1 for WEL
+ spiflash_readstatus(tb_sif, 8'h 05, data);
+
+ assert(data[1] == 1'b 1);
+ repeat(20) @(sck_clk.cbn);
+
+
+ $display("TEST PASSED CHECKS");
endtask : host
task sw();
@@ -123,6 +173,24 @@
@(posedge clk);
sys_status_we = 1'b 0;
+ @(wel_test_complete);
+
+ // Host has issued WREN then WRDI then read back the STATUS and checked if
+ // HW updates the value correctly.
+ // Now, SW reverts WEL bit (to 1), then informs host system to read back
+ // the STATUS
+
+ @(posedge clk);
+
+ sys_status_we = 1'b 1;
+ sys_status_in = 24'h 0A_BC_D2; // Set WEL
+ @(posedge clk);
+ sys_status_we = 1'b 0;
+
+ repeat (10) @(posedge clk);
+
+ ->wel_update_done;
+
forever @(posedge clk); // Wait host transaction done
endtask : sw
@@ -132,16 +200,20 @@
io_mode_e dut_iomode, s2p_iomode;
+ logic sck_we_set, sck_we_clr;
+
spid_status dut (
.clk_i (gated_sck),
.rst_ni (rst_spi_n),
.clk_out_i (gated_sck_inverted),
+ .clk_csb_i (sif.csb),
+
.sys_clk_i (clk),
.sys_rst_ni (rst_n),
- .csb_i (sif.csb),
+ .sys_csb_deasserted_pulse_i (sys_csb_deasserted_pulse), // TODO
.sys_status_we_i (sys_status_we ),
.sys_status_i (sys_status_in ),
@@ -159,7 +231,10 @@
.inclk_busy_set_i (busy_set), // SCK domain
- .inclk_busy_broadcast_o () // SCK domain
+ .inclk_we_set_i (sck_we_set),
+ .inclk_we_clr_i (sck_we_clr),
+
+ .csb_busy_broadcast_o () // SCK domain
);
spi_cmdparse cmdparse (
@@ -179,10 +254,23 @@
.cmd_info_o (cmd_info),
.cmd_info_idx_o (cmd_info_idx),
+ // CFG: Intercept
+ .cfg_intercept_en_status_i (1'b 1),
+ .cfg_intercept_en_jedec_i (1'b 1),
+ .cfg_intercept_en_sfdp_i (1'b 1),
+
+ // Intercept assumed
+ .intercept_status_o (),
+ .intercept_jedec_o (),
+ .intercept_sfdp_o (),
+
.cmd_config_req_o (),
.cmd_config_idx_o ()
);
+ assign sck_we_set = (dut_sel_dp == DpWrEn);
+ assign sck_we_clr = (dut_sel_dp == DpWrDi);
+
spi_s2p s2p (
.clk_i (gated_sck),
.rst_ni (rst_spi_n),