[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),