[ spi_device, spi_host, top_earlgrey ] Add SPI passthrough to spi_host

- Create new corefile for spi_device_pkg
- Add passthrough structure I/O to spi_host
- Uncomment intermodule connections in top_earlgrey
- Correct typo in spi_device PASSTHROUGH_DEFAULT_REQ interhost

Signed-off-by: Martin Lueker-Boden <martin.lueker-boden@wdc.com>
diff --git a/hw/ip/spi_device/rtl/spi_device_pkg.sv b/hw/ip/spi_device/rtl/spi_device_pkg.sv
index 6c3e42f..edcc7e6 100644
--- a/hw/ip/spi_device/rtl/spi_device_pkg.sv
+++ b/hw/ip/spi_device/rtl/spi_device_pkg.sv
@@ -35,7 +35,7 @@
     logic [3:0] s;
   } passthrough_rsp_t;
 
-  parameter passthrough_req_t PASSTHROUGH_RSQ_DEFAULT = '{
+  parameter passthrough_req_t PASSTHROUGH_REQ_DEFAULT = '{
     passthrough_en: 1'b 0,
     sck:            1'b 0,
     sck_gate_en:    1'b 0,
diff --git a/hw/ip/spi_device/spi_device.core b/hw/ip/spi_device/spi_device.core
index 8805e4c..b6b4828 100644
--- a/hw/ip/spi_device/spi_device.core
+++ b/hw/ip/spi_device/spi_device.core
@@ -16,10 +16,9 @@
       - lowrisc:prim:ram_2p_adv
       - lowrisc:ip:lc_ctrl_pkg
       - lowrisc:prim:lc_sync
+      - lowrisc:ip:spi_device_pkg
     files:
-      - rtl/spi_device_reg_pkg.sv
       - rtl/spi_device_reg_top.sv
-      - rtl/spi_device_pkg.sv
       - rtl/spi_fwm_rxf_ctrl.sv
       - rtl/spi_fwm_txf_ctrl.sv
       - rtl/spi_fwmode.sv
diff --git a/hw/ip/spi_device/spi_device_pkg.core b/hw/ip/spi_device/spi_device_pkg.core
new file mode 100644
index 0000000..0785d9c
--- /dev/null
+++ b/hw/ip/spi_device/spi_device_pkg.core
@@ -0,0 +1,18 @@
+CAPI=2:
+# Copyright lowRISC contributors.
+# Licensed under the Apache License, Version 2.0, see LICENSE for details.
+# SPDX-License-Identifier: Apache-2.0
+name: "lowrisc:ip:spi_device_pkg:0.1"
+description: "spi_device_pkg"
+
+filesets:
+  files_rtl:
+    files:
+      - rtl/spi_device_reg_pkg.sv
+      - rtl/spi_device_pkg.sv
+    file_type: systemVerilogSource
+
+targets:
+  default:
+    filesets:
+      - files_rtl
diff --git a/hw/ip/spi_host/data/spi_host.hjson b/hw/ip/spi_host/data/spi_host.hjson
index 035cefd..ef60a96 100644
--- a/hw/ip/spi_host/data/spi_host.hjson
+++ b/hw/ip/spi_host/data/spi_host.hjson
@@ -9,6 +9,15 @@
   bus_interfaces: [
     { protocol: "tlul", direction: "device" }
   ],
+  inter_signal_list: [
+    { struct:  "passthrough",
+      package: "spi_device_pkg",
+      type:    "req_rsp",
+      name:    "passthrough",
+      act:     "rsp",
+      width:   "1"
+    }
+  ]
   regwidth: "32",
   scan: "true",
   param_list: [
diff --git a/hw/ip/spi_host/rtl/spi_host.sv b/hw/ip/spi_host/rtl/spi_host.sv
index 3a1ce1c..30a1e34 100644
--- a/hw/ip/spi_host/rtl/spi_host.sv
+++ b/hw/ip/spi_host/rtl/spi_host.sv
@@ -31,6 +31,10 @@
   output logic [3:0]       cio_sd_en_o,
   input        [3:0]       cio_sd_i,
 
+  // Passthrough interface
+  input  spi_device_pkg::passthrough_req_t passthrough_i,
+  output spi_device_pkg::passthrough_rsp_t passthrough_o,
+
   output logic             intr_error_o,
   output logic             intr_spi_event_o
 );
@@ -57,53 +61,80 @@
     .devmode_i  (1'b1)
   );
 
-  logic  passthru;
-  assign passthru = reg2hw.control.passthru.q;
-
-  assign cio_sck_en_o = 1'b1;
-  assign cio_csb_en_o = {NumCS{1'b1}};
 
   logic             sck;
   logic [NumCS-1:0] csb;
-  logic [3:0]       sd_o;
+  logic [3:0]       sd_out;
   logic [3:0]       sd_en;
   logic [3:0]       sd_i;
 
-  logic             pt_sck;
-  logic [NumCS-1:0] pt_csb;
-  logic [3:0]       pt_sd_o;
-  logic [3:0]       pt_sd_en;
-  logic [3:0]       pt_sd_i;
+  if (NumCS == 1) begin : gen_passthrough_implementation
+    logic passthrough_en;
+    assign passthrough_en  = passthrough_i.passthrough_en;
 
-  // TODO: Route passthru outputs to ports once structure is defined
-  assign pt_sck   = 1'b0;
-  assign pt_csb   = {NumCS{1'b1}};
-  assign pt_sd_en = 4'h0;
-  assign pt_sd_o  = 4'h0;
+    logic        pt_sck;
+    logic        pt_sck_en;
+    logic [0:0]  pt_csb;
+    logic [0:0]  pt_csb_en;
+    logic [3:0]  pt_sd_out;
+    logic [3:0]  pt_sd_en;
 
-  assign cio_sck_o    = passthru ? pt_sck : sck;
-  assign cio_csb_o    = passthru ? pt_csb : csb;
-  assign cio_sd_o     = passthru ? pt_sd_o : sd_o;
-  assign cio_sd_en_o  = passthru ? pt_sd_en : sd_en;
-  assign pt_sd_i      = cio_sd_i;
-  assign sd_i         = cio_sd_i;
+    assign pt_sck       = passthrough_i.sck;
+    assign pt_sck_en    = passthrough_i.sck_en;
+    assign pt_csb[0]    = passthrough_i.csb;
+    assign pt_csb_en[0] = passthrough_i.csb_en;
+    assign pt_sd_out    = passthrough_i.s;
+    assign pt_sd_en     = passthrough_i.s_en;
+
+    assign cio_sck_o    = passthrough_en ? pt_sck    : sck;
+    assign cio_sck_en_o = passthrough_en ? pt_sck_en : 1'b1;
+    assign cio_csb_o    = passthrough_en ? pt_csb    : csb;
+    assign cio_csb_en_o = passthrough_en ? pt_csb_en : 1'b1;
+    assign cio_sd_o     = passthrough_en ? pt_sd_out : sd_out;
+    assign cio_sd_en_o  = passthrough_en ? pt_sd_en  : sd_en;
+
+  end                   : gen_passthrough_implementation
+  else begin            : gen_passthrough_ignore
+     // Passthrough only supported for instances with one CSb line
+    `ASSERT(PassthroughNumCSCompat_A, !passthrough_en, clk_i, rst_ni)
+
+    assign cio_sck_o    = sck;
+    assign cio_sck_en_o = 1'b1;
+    assign cio_csb_o    = csb;
+    assign cio_csb_en_o = {NumCS{1'b1}};
+    assign cio_sd_o     = sd_out;
+    assign cio_sd_en_o  = sd_en;
+
+    logic       unused_pt_en;
+    logic       unused_pt_sck;
+    logic       unused_pt_sck_en;
+    logic       unused_pt_csb;
+    logic       unused_pt_csb_en;
+    logic [3:0] unused_pt_sd_out;
+    logic [3:0] unused_pt_sd_en;
+
+    assign unused_pt_en     = passthrough_i.passthrough_en;
+    assign unused_pt_sck    = passthrough_i.sck;
+    assign unused_pt_sck_en = passthrough_i.sck_en;
+    assign unused_pt_csb    = passthrough_i.csb;
+    assign unused_pt_csb_en = passthrough_i.csb_en;
+    assign unused_pt_sd_out = passthrough_i.s;
+    assign unused_pt_sd_en  = passthrough_i.s_en;
+
+  end                   : gen_passthrough_ignore
+
+  logic unused_pt_sck_gate_en;
+  assign unused_pt_sck_gate_en = passthrough_i.sck_gate_en;
+
+  assign passthrough_o.s = cio_sd_i;
+  assign sd_i            = cio_sd_i;
 
   // TODO: REMOVE THIS CODE
   // Temp tie-offs to silence lint warnings
   logic unused_scan;
-  logic unused_flop;
 
   assign unused_scan = ^scanmode_i;
 
-  always_ff @(posedge clk_core_i or negedge rst_core_ni) begin
-    if (!rst_core_ni) begin
-      unused_flop <= 1'b0;
-    end else begin
-      unused_flop <= ^pt_sd_i;
-    end
-  end
-
-
   assign hw2reg.status.byteorder.d  = ByteOrder;
   assign hw2reg.status.byteorder.de = 1'b1;
 
@@ -392,7 +423,7 @@
     .rx_ready_i      (core_rx_ready),
     .sck_o           (sck),
     .csb_o           (csb),
-    .sd_o,
+    .sd_o            (sd_out),
     .sd_en_o         (sd_en),
     .sd_i,
     .rx_stall_o      (core_rx_stall),
diff --git a/hw/ip/spi_host/spi_host.core b/hw/ip/spi_host/spi_host.core
index d965b2c..dd97bff 100644
--- a/hw/ip/spi_host/spi_host.core
+++ b/hw/ip/spi_host/spi_host.core
@@ -12,6 +12,7 @@
       - lowrisc:prim:all
       - lowrisc:ip:lc_ctrl
       - lowrisc:ip:tlul
+      - lowrisc:ip:spi_device_pkg
     files:
       - rtl/spi_host_reg_pkg.sv
       - rtl/spi_host_cmd_pkg.sv
diff --git a/hw/top_earlgrey/data/autogen/top_earlgrey.gen.hjson b/hw/top_earlgrey/data/autogen/top_earlgrey.gen.hjson
index 8292d37..8be4673 100644
--- a/hw/top_earlgrey/data/autogen/top_earlgrey.gen.hjson
+++ b/hw/top_earlgrey/data/autogen/top_earlgrey.gen.hjson
@@ -743,6 +743,9 @@
           act: req
           width: 1
           inst_name: spi_device
+          default: ""
+          end_idx: -1
+          top_signame: spi_device_passthrough
           index: -1
         }
         {
@@ -788,6 +791,18 @@
       inter_signal_list:
       [
         {
+          name: passthrough
+          struct: passthrough
+          package: spi_device_pkg
+          type: req_rsp
+          act: rsp
+          width: 1
+          inst_name: spi_host0
+          default: ""
+          top_signame: spi_device_passthrough
+          index: -1
+        }
+        {
           name: tl
           struct: tl
           package: tlul_pkg
@@ -830,6 +845,16 @@
       inter_signal_list:
       [
         {
+          name: passthrough
+          struct: passthrough
+          package: spi_device_pkg
+          type: req_rsp
+          act: rsp
+          width: 1
+          inst_name: spi_host1
+          index: -1
+        }
+        {
           name: tl
           struct: tl
           package: tlul_pkg
@@ -5973,6 +5998,10 @@
         otp_ctrl.lc_seed_hw_rd_en
         flash_ctrl.lc_seed_hw_rd_en
       ]
+      spi_device.passthrough:
+      [
+        spi_host0.passthrough
+      ]
       pwrmgr_aon.wakeups:
       [
         sysrst_ctrl_aon.gsc_wk
@@ -11603,6 +11632,9 @@
         act: req
         width: 1
         inst_name: spi_device
+        default: ""
+        end_idx: -1
+        top_signame: spi_device_passthrough
         index: -1
       }
       {
@@ -11619,6 +11651,18 @@
         index: -1
       }
       {
+        name: passthrough
+        struct: passthrough
+        package: spi_device_pkg
+        type: req_rsp
+        act: rsp
+        width: 1
+        inst_name: spi_host0
+        default: ""
+        top_signame: spi_device_passthrough
+        index: -1
+      }
+      {
         name: tl
         struct: tl
         package: tlul_pkg
@@ -11632,6 +11676,16 @@
         index: -1
       }
       {
+        name: passthrough
+        struct: passthrough
+        package: spi_device_pkg
+        type: req_rsp
+        act: rsp
+        width: 1
+        inst_name: spi_host1
+        index: -1
+      }
+      {
         name: tl
         struct: tl
         package: tlul_pkg
@@ -16896,6 +16950,28 @@
         default: lc_ctrl_pkg::Off
       }
       {
+        package: spi_device_pkg
+        struct: passthrough_req
+        signame: spi_device_passthrough_req
+        width: 1
+        type: req_rsp
+        end_idx: -1
+        act: req
+        suffix: req
+        default: ""
+      }
+      {
+        package: spi_device_pkg
+        struct: passthrough_rsp
+        signame: spi_device_passthrough_rsp
+        width: 1
+        type: req_rsp
+        end_idx: -1
+        act: req
+        suffix: rsp
+        default: spi_device_pkg::PASSTHROUGH_RSP_DEFAULT
+      }
+      {
         package: ""
         struct: logic
         signame: pwrmgr_aon_wakeups
diff --git a/hw/top_earlgrey/data/top_earlgrey.hjson b/hw/top_earlgrey/data/top_earlgrey.hjson
index 1cffa00..e827180 100644
--- a/hw/top_earlgrey/data/top_earlgrey.hjson
+++ b/hw/top_earlgrey/data/top_earlgrey.hjson
@@ -951,7 +951,7 @@
       'lc_ctrl.lc_seed_hw_rd_en'           : ['otp_ctrl.lc_seed_hw_rd_en',
                                               'flash_ctrl.lc_seed_hw_rd_en'],
 
-      //'spi_device.passthrough': ['spi_host0.passthrough']
+      'spi_device.passthrough'     : ['spi_host0.passthrough']
     }
 
     // top is to connect to top net/struct.
diff --git a/hw/top_earlgrey/rtl/autogen/top_earlgrey.sv b/hw/top_earlgrey/rtl/autogen/top_earlgrey.sv
index dba7cf5..7d64c51 100644
--- a/hw/top_earlgrey/rtl/autogen/top_earlgrey.sv
+++ b/hw/top_earlgrey/rtl/autogen/top_earlgrey.sv
@@ -532,6 +532,8 @@
   lc_ctrl_pkg::lc_tx_t       lc_ctrl_lc_iso_part_sw_rd_en;
   lc_ctrl_pkg::lc_tx_t       lc_ctrl_lc_iso_part_sw_wr_en;
   lc_ctrl_pkg::lc_tx_t       lc_ctrl_lc_seed_hw_rd_en;
+  spi_device_pkg::passthrough_req_t       spi_device_passthrough_req;
+  spi_device_pkg::passthrough_rsp_t       spi_device_passthrough_rsp;
   logic [4:0] pwrmgr_aon_wakeups;
   logic [1:0] pwrmgr_aon_rstreqs;
   tlul_pkg::tl_h2d_t       rom_ctrl_rom_tl_req;
@@ -1174,8 +1176,8 @@
 
       // Inter-module signals
       .ram_cfg_i(ast_ram_2p_cfg),
-      .passthrough_o(),
-      .passthrough_i(spi_device_pkg::PASSTHROUGH_RSP_DEFAULT),
+      .passthrough_o(spi_device_passthrough_req),
+      .passthrough_i(spi_device_passthrough_rsp),
       .tl_i(spi_device_tl_req),
       .tl_o(spi_device_tl_rsp),
       .scanmode_i,
@@ -1205,6 +1207,8 @@
       .intr_spi_event_o (intr_spi_host0_spi_event),
 
       // Inter-module signals
+      .passthrough_i(spi_device_passthrough_req),
+      .passthrough_o(spi_device_passthrough_rsp),
       .tl_i(spi_host0_tl_req),
       .tl_o(spi_host0_tl_rsp),
       .scanmode_i,
@@ -1234,6 +1238,8 @@
       .intr_spi_event_o (intr_spi_host1_spi_event),
 
       // Inter-module signals
+      .passthrough_i(spi_device_pkg::PASSTHROUGH_REQ_DEFAULT),
+      .passthrough_o(),
       .tl_i(spi_host1_tl_req),
       .tl_o(spi_host1_tl_rsp),
       .scanmode_i,