[spi_device] Add SRAM tasks

This commit adds sram read/write word functions (tasks) to the
spid_common package. It can be called to update the DPSRAM inside
SPI_DEVICE IP from SW side.

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 ffaf715..4a430f0 100644
--- a/hw/ip/spi_device/pre_dv/tb/spid_common.sv
+++ b/hw/ip/spi_device/pre_dv/tb/spid_common.sv
@@ -613,9 +613,9 @@
 
     sif.sd_in[3:0] = 4'h z;
 
-    loop = (mode == IoSingle) ? 7 :
-           (mode == IoDual)   ? 3 :
-           (mode == IoQuad)   ? 1 : 7;
+    loop = (mode == IoSingle) ? 8 :
+           (mode == IoDual)   ? 4 :
+           (mode == IoQuad)   ? 2 : 8;
     repeat(loop) @(negedge sif.clk);
   endtask : spi_highz
 
@@ -816,4 +816,95 @@
 
   endtask : spiflash_program
 
+  task automatic spiflash_readsfdp(
+    virtual spi_if.tb  sif,
+    input spi_data_t   opcode,
+    input logic [23:0] addr,
+    input int          size, // #bytes
+    input spi_data_t   payload [$]
+  );
+    automatic spi_fifo_t send_data [$];
+    automatic spi_data_t rcv_data [$];
+
+    // opcode
+    send_data.push_back('{data: opcode, dir: DirIn, mode: IoSingle});
+    // address
+    for (int i = 2 ; i >= 0 ; i--) begin
+      send_data.push_back('{data: addr[8*i+:8], dir: DirNone, mode: IoNone});
+    end
+
+    // dummy
+    send_data.push_back('{data: 'z, dir: DirZ, mode: IoNone});
+
+    // Receive data
+    repeat(size) begin
+      send_data.push_back('{data: '0, dir: DirOut, mode: IoSingle});
+    end
+
+    spi_transaction(sif, send_data, rcv_data);
+
+    assert(rcv_data.size() == size);
+
+    repeat (size) begin
+      payload.push_back(rcv_data.pop_front());
+    end
+
+    $display("Read SFDP [%x + %d]", addr, size);
+
+    for (int i = 0 ; i < size ; i++) begin
+      $display("[%x]: %x", addr+24'(i), payload[i]);
+    end
+
+  endtask : spiflash_readsfdp
+
+
+  // SRAM interface
+  task automatic sram_readword(
+    const ref logic clk,
+
+    ref sram_l2m_t       l2m,
+    const ref logic      gnt,
+    const ref sram_m2l_t m2l,
+
+    input  logic [SramAw-1:0] addr,
+    output logic [SramDw-1:0] rdata
+  );
+    l2m.req   = 1'b 1;
+    l2m.addr  = addr;
+    l2m.we    = 1'b 0;
+    l2m.wdata = '0;
+    l2m.wstrb = '0;
+
+    @(posedge clk iff gnt == 1'b 1);
+    l2m.req   = 1'b 0;
+    // Check if rvalid?
+    while (m2l.rvalid == 1'b 0) begin
+      @(posedge clk);
+    end
+    rdata = m2l.rdata;
+    assert(m2l.rerror == '0);
+
+  endtask : sram_readword
+
+  task automatic sram_writeword(
+    const ref logic clk,
+
+    ref sram_l2m_t       l2m,
+    const ref logic      gnt,
+    const ref sram_m2l_t m2l,
+
+    input logic [SramAw-1:0] addr,
+    input logic [SramDw-1:0] wdata
+  );
+    l2m.req   = 1'b 1;
+    l2m.addr  = addr;
+    l2m.we    = 1'b 1;
+    l2m.wdata = wdata;
+    l2m.wstrb = '1;
+
+    @(posedge clk iff gnt == 1'b 1);
+    l2m.req   = 1'b 0;
+
+  endtask : sram_writeword
+
 endpackage : spid_common