fpga: Add initial Verilog build

Also applied Verilog auto-formatting with:

  verible-verilog-format --inplace fpga/*.v

Change-Id: I3520775fbca49519d8e20d934a7503110a70ff3f
Reviewed-on: https://pigweed-review.googlesource.com/c/gonk/+/185470
Pigweed-Auto-Submit: Anthony DiGirolamo <tonymd@google.com>
Reviewed-by: Umang Shah <umangshah@google.com>
Commit-Queue: Auto-Submit <auto-submit@pigweed-service-accounts.iam.gserviceaccount.com>
diff --git a/fpga/BUILD.gn b/fpga/BUILD.gn
index 6958491..7210567 100644
--- a/fpga/BUILD.gn
+++ b/fpga/BUILD.gn
@@ -17,4 +17,29 @@
 import("//fpga/fpga_image.gni")
 
 group("fpga") {
+  deps = [ ":toplevel" ]
+}
+
+# Build an FPGA bitstream. Outputs are placed in:
+#
+#   out/gn/obj/fpga/toplevel/
+#     toplevel.asc
+#     toplevel.bin
+#     toplevel.json
+#     toplevel_timing_report.json
+#     toplevel_timing_report.txt
+#
+fpga_image("toplevel") {
+  sources = [
+    "gonk/csa_ctl_top.v",
+    "gonk/pll.v",
+    "gonk/rst_sync.v",
+    "gonk/sig_sync.v",
+    "gonk/spi_m_core.v",
+    "gonk/spi_m_core_ctl.v",
+    "gonk/spi_s_core.v",
+    "gonk/top.v",
+  ]
+
+  pcf = "gonk/top.pcf"
 }
diff --git a/fpga/gonk/csa_ctl_top.v b/fpga/gonk/csa_ctl_top.v
new file mode 100644
index 0000000..81ce617
--- /dev/null
+++ b/fpga/gonk/csa_ctl_top.v
@@ -0,0 +1,746 @@
+// Copyright 2023 The Pigweed Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+`timescale 1ns / 1ps
+//////////////////////////////////////////////////////////////////////////////////
+//
+//////////////////////////////////////////////////////////////////////////////////
+
+
+module csa_ctl_top (
+    input mclk_i,
+    input rst_i,
+    input r_w_en_i,
+    input en_i,
+    input mode_i,
+    input [10:0] adc_sel_i,
+    input [5:0] rwaddr_i,
+    input [15:0] wdata_i,
+    output reg dn_o,
+    output reg [39:0] rdata_o,
+    // spi interfaces
+    input miso_i_1,
+    input alertl_i_1,
+    output sclk_o_1,
+    output mosi_o_1,
+    output cs_o_1,
+    //
+    input miso_i_2,
+    input alertl_i_2,
+    output sclk_o_2,
+    output mosi_o_2,
+    output cs_o_2,
+    // spi interface
+    input miso_i_3,
+    input alertl_i_3,
+    output sclk_o_3,
+    output mosi_o_3,
+    output cs_o_3,
+    //
+    input miso_i_4,
+    input alertl_i_4,
+    output sclk_o_4,
+    output mosi_o_4,
+    output cs_o_4,
+    //
+    input miso_i_5,
+    input alertl_i_5,
+    output sclk_o_5,
+    output mosi_o_5,
+    output cs_o_5,
+    //
+    input miso_i_6,
+    input alertl_i_6,
+    output sclk_o_6,
+    output mosi_o_6,
+    output cs_o_6,
+    //
+    input miso_i_7,
+    input alertl_i_7,
+    output sclk_o_7,
+    output mosi_o_7,
+    output cs_o_7,
+    //
+    input miso_i_8,
+    input alertl_i_8,
+    output sclk_o_8,
+    output mosi_o_8,
+    output cs_o_8,
+    //
+    input miso_i_9,
+    input alertl_i_9,
+    output sclk_o_9,
+    output mosi_o_9,
+    output cs_o_9,
+    //
+    input miso_i_10,
+    input alertl_i_10,
+    output sclk_o_10,
+    output mosi_o_10,
+    output cs_o_10,
+    //
+    input miso_i_11,
+    input alertl_i_11,
+    output sclk_o_11,
+    output mosi_o_11,
+    output cs_o_11,
+    //
+    input dn_clr_i,
+    output reg poll_dn_o,
+    // output [11:0] poll_dn,
+    output [23:0] vbus_1,
+    output [23:0] vshunt_1,
+    output [23:0] vbus_2,
+    output [23:0] vshunt_2,
+    output [23:0] vbus_3,
+    output [23:0] vshunt_3,
+    output [23:0] vbus_4,
+    output [23:0] vshunt_4,
+    output [23:0] vbus_5,
+    output [23:0] vshunt_5,
+    output [23:0] vbus_6,
+    output [23:0] vshunt_6,
+    output [23:0] vbus_7,
+    output [23:0] vshunt_7,
+    output [23:0] vbus_8,
+    output [23:0] vshunt_8,
+    output [23:0] vbus_9,
+    output [23:0] vshunt_9,
+    output [23:0] vbus_10,
+    output [23:0] vshunt_10,
+    output [23:0] vbus_11,
+    output [23:0] vshunt_11
+    //
+);
+  //
+  reg
+      dn_latch_r1,
+      dn_latch_r2,
+      dn_latch_r3,
+      dn_latch_r4,
+      dn_latch_r5,
+      dn_latch_r6,
+      dn_latch_r7,
+      dn_latch_r8,
+      dn_latch_r9,
+      dn_latch_r10,
+      dn_latch_r11,
+      rst_i_r;
+  reg
+      poll_dn_latch_r1,
+      poll_dn_latch_r2,
+      poll_dn_latch_r3,
+      poll_dn_latch_r4,
+      poll_dn_latch_r5,
+      poll_dn_latch_r6,
+      poll_dn_latch_r7,
+      poll_dn_latch_r8,
+      poll_dn_latch_r9,
+      poll_dn_latch_r10,
+      poll_dn_latch_r11;
+  reg en_r1, en_r2, en_r3, en_r4, en_r5, en_r6, en_r7, en_r8, en_r9, en_r10, en_r11;
+  reg dn_r, poll_dn_r;
+  reg
+      r_w_en_r1,
+      r_w_en_r2,
+      r_w_en_r3,
+      r_w_en_r4,
+      r_w_en_r5,
+      r_w_en_r6,
+      r_w_en_r7,
+      r_w_en_r8,
+      r_w_en_r9,
+      r_w_en_r10,
+      r_w_en_r11;
+  reg en_r, r_w_en_r;
+  reg [ 5:0] rwaddr_r;
+  reg [10:0] adc_sel_r;
+  reg [15:0] wdata_r;
+  //
+  wire poll_dn_r1,poll_dn_r2,poll_dn_r3,poll_dn_r4,poll_dn_r5,poll_dn_r6,poll_dn_r7,poll_dn_r8,poll_dn_r9,poll_dn_r10,poll_dn_r11;
+  wire dn_r1, dn_r2, dn_r3, dn_r4, dn_r5, dn_r6, dn_r7, dn_r8, dn_r9, dn_r10, dn_r11;
+  wire [39:0] rdata_w1,rdata_w2,rdata_w3,rdata_w4,rdata_w5,rdata_w6,rdata_w7,rdata_w8,rdata_w9,rdata_w10,rdata_w11;
+  //
+
+  always @(posedge mclk_i) begin
+    rst_i_r <= rst_i;
+  end
+
+  spi_m_core_ctl csa_1 (
+      .mclk_i(mclk_i),
+      .rst_i(rst_i_r),
+      .r_w_en_i(r_w_en_r1),
+      .en_i(en_r1),
+      .mode_i(mode_i),
+      .rwaddr_i(rwaddr_r),
+      .wdata_i(wdata_r),
+      .dn_o(dn_r1),
+      .rdata_o(rdata_w1),
+      .vbus_o(vbus_1),
+      .vshunt_o(vshunt_1),
+      .poll_dn_o(poll_dn_r1),
+      .miso_i(miso_i_1),
+      .alert_n_i(alertl_i_1),
+      .sclk_o(sclk_o_1),
+      .mosi_o(mosi_o_1),
+      .cs_o(cs_o_1)
+  );
+
+  spi_m_core_ctl csa_2 (
+      .mclk_i(mclk_i),
+      .rst_i(rst_i_r),
+      .r_w_en_i(r_w_en_r2),
+      .en_i(en_r2),
+      .mode_i(mode_i),
+      .rwaddr_i(rwaddr_r),
+      .wdata_i(wdata_r),
+      .dn_o(dn_r2),
+      .rdata_o(rdata_w2),
+      .vbus_o(vbus_2),
+      .vshunt_o(vshunt_2),
+      .poll_dn_o(poll_dn_r2),
+      .miso_i(miso_i_2),
+      .alert_n_i(alertl_i_2),
+      .sclk_o(sclk_o_2),
+      .mosi_o(mosi_o_2),
+      .cs_o(cs_o_2)
+  );
+
+  spi_m_core_ctl csa_3 (
+      .mclk_i(mclk_i),
+      .rst_i(rst_i_r),
+      .r_w_en_i(r_w_en_r3),
+      .en_i(en_r3),
+      .mode_i(mode_i),
+      .rwaddr_i(rwaddr_r),
+      .wdata_i(wdata_r),
+      .dn_o(dn_r3),
+      .rdata_o(rdata_w3),
+      .vbus_o(vbus_3),
+      .vshunt_o(vshunt_3),
+      .poll_dn_o(poll_dn_r3),
+      .miso_i(miso_i_3),
+      .alert_n_i(alertl_i_3),
+      .sclk_o(sclk_o_3),
+      .mosi_o(mosi_o_3),
+      .cs_o(cs_o_3)
+  );
+
+  spi_m_core_ctl csa_4 (
+      .mclk_i(mclk_i),
+      .rst_i(rst_i_r),
+      .r_w_en_i(r_w_en_r4),
+      .en_i(en_r4),
+      .mode_i(mode_i),
+      .rwaddr_i(rwaddr_r),
+      .wdata_i(wdata_r),
+      .dn_o(dn_r4),
+      .rdata_o(rdata_w4),
+      .vbus_o(vbus_4),
+      .vshunt_o(vshunt_4),
+      .poll_dn_o(poll_dn_r4),
+      .miso_i(miso_i_4),
+      .alert_n_i(alertl_i_4),
+      .sclk_o(sclk_o_4),
+      .mosi_o(mosi_o_4),
+      .cs_o(cs_o_4)
+  );
+
+  spi_m_core_ctl csa_5 (
+      .mclk_i(mclk_i),
+      .rst_i(rst_i_r),
+      .r_w_en_i(r_w_en_r5),
+      .en_i(en_r5),
+      .mode_i(mode_i),
+      .rwaddr_i(rwaddr_r),
+      .wdata_i(wdata_r),
+      .dn_o(dn_r5),
+      .rdata_o(rdata_w5),
+      .vbus_o(vbus_5),
+      .vshunt_o(vshunt_5),
+      .poll_dn_o(poll_dn_r5),
+      .miso_i(miso_i_5),
+      .alert_n_i(alertl_i_5),
+      .sclk_o(sclk_o_5),
+      .mosi_o(mosi_o_5),
+      .cs_o(cs_o_5)
+  );
+
+
+  spi_m_core_ctl csa_6 (
+      .mclk_i(mclk_i),
+      .rst_i(rst_i_r),
+      .r_w_en_i(r_w_en_r6),
+      .en_i(en_r6),
+      .mode_i(mode_i),
+      .rwaddr_i(rwaddr_r),
+      .wdata_i(wdata_r),
+      .dn_o(dn_r6),
+      .rdata_o(rdata_w6),
+      .vbus_o(vbus_6),
+      .vshunt_o(vshunt_6),
+      .poll_dn_o(poll_dn_r6),
+      .miso_i(miso_i_6),
+      .alert_n_i(alertl_i_6),
+      .sclk_o(sclk_o_6),
+      .mosi_o(mosi_o_6),
+      .cs_o(cs_o_6)
+  );
+
+  spi_m_core_ctl csa_7 (
+      .mclk_i(mclk_i),
+      .rst_i(rst_i_r),
+      .r_w_en_i(r_w_en_r7),
+      .en_i(en_r7),
+      .mode_i(mode_i),
+      .rwaddr_i(rwaddr_r),
+      .wdata_i(wdata_r),
+      .dn_o(dn_r7),
+      .rdata_o(rdata_w7),
+      .vbus_o(vbus_7),
+      .vshunt_o(vshunt_7),
+      .poll_dn_o(poll_dn_r7),
+      .miso_i(miso_i_7),
+      .alert_n_i(alertl_i_7),
+      .sclk_o(sclk_o_7),
+      .mosi_o(mosi_o_7),
+      .cs_o(cs_o_7)
+  );
+
+  spi_m_core_ctl csa_8 (
+      .mclk_i(mclk_i),
+      .rst_i(rst_i_r),
+      .r_w_en_i(r_w_en_r8),
+      .en_i(en_r8),
+      .mode_i(mode_i),
+      .rwaddr_i(rwaddr_r),
+      .wdata_i(wdata_r),
+      .dn_o(dn_r8),
+      .rdata_o(rdata_w8),
+      .vbus_o(vbus_8),
+      .vshunt_o(vshunt_8),
+      .poll_dn_o(poll_dn_r8),
+      .miso_i(miso_i_8),
+      .alert_n_i(alertl_i_8),
+      .sclk_o(sclk_o_8),
+      .mosi_o(mosi_o_8),
+      .cs_o(cs_o_8)
+  );
+
+  spi_m_core_ctl csa_9 (
+      .mclk_i(mclk_i),
+      .rst_i(rst_i_r),
+      .r_w_en_i(r_w_en_r9),
+      .en_i(en_r9),
+      .mode_i(mode_i),
+      .rwaddr_i(rwaddr_r),
+      .wdata_i(wdata_r),
+      .dn_o(dn_r9),
+      .rdata_o(rdata_w9),
+      .vbus_o(vbus_9),
+      .vshunt_o(vshunt_9),
+      .poll_dn_o(poll_dn_r9),
+      .miso_i(miso_i_9),
+      .alert_n_i(alertl_i_9),
+      .sclk_o(sclk_o_9),
+      .mosi_o(mosi_o_9),
+      .cs_o(cs_o_9)
+  );
+
+  spi_m_core_ctl csa_10 (
+      .mclk_i(mclk_i),
+      .rst_i(rst_i_r),
+      .r_w_en_i(r_w_en_r10),
+      .en_i(en_r10),
+      .mode_i(mode_i),
+      .rwaddr_i(rwaddr_r),
+      .wdata_i(wdata_r),
+      .dn_o(dn_r10),
+      .rdata_o(rdata_w10),
+      .vbus_o(vbus_10),
+      .vshunt_o(vshunt_10),
+      .poll_dn_o(poll_dn_r10),
+      .miso_i(miso_i_10),
+      .alert_n_i(alertl_i_10),
+      .sclk_o(sclk_o_10),
+      .mosi_o(mosi_o_10),
+      .cs_o(cs_o_10)
+  );
+
+  spi_m_core_ctl csa_11 (
+      .mclk_i(mclk_i),
+      .rst_i(rst_i_r),
+      .r_w_en_i(r_w_en_r11),
+      .en_i(en_r11),
+      .mode_i(mode_i),
+      .rwaddr_i(rwaddr_r),
+      .wdata_i(wdata_r),
+      .dn_o(dn_r11),
+      .rdata_o(rdata_w11),
+      .vbus_o(vbus_11),
+      .vshunt_o(vshunt_11),
+      .poll_dn_o(poll_dn_r11),
+      .miso_i(miso_i_11),
+      .alert_n_i(alertl_i_11),
+      .sclk_o(sclk_o_11),
+      .mosi_o(mosi_o_11),
+      .cs_o(cs_o_11)
+  );
+
+  always @(posedge mclk_i) begin
+    if (rst_i_r) begin
+      poll_dn_o <= 0;
+      dn_o <= 0;
+      en_r <= 0;
+    end else begin
+      poll_dn_o <= poll_dn_r;
+      dn_o <= dn_r;
+      en_r <= en_i;  //(en_i & !mode_i) ;
+    end
+  end
+
+  always @(posedge mclk_i) begin
+    if (rst_i_r) begin
+      wdata_r  <= 0;
+      rwaddr_r <= 0;
+      r_w_en_r <= 0;
+    end else begin
+      if (en_i) begin
+        wdata_r   <= wdata_i;
+        rwaddr_r  <= rwaddr_i[5:0];
+        r_w_en_r  <= r_w_en_i;
+        adc_sel_r <= adc_sel_i;
+      end
+    end
+  end
+
+  always @(posedge mclk_i) begin
+    if (r_w_en_r) begin
+      r_w_en_r1  <= 1;
+      r_w_en_r2  <= 1;
+      r_w_en_r3  <= 1;
+      r_w_en_r4  <= 1;
+      r_w_en_r5  <= 1;
+      r_w_en_r6  <= 1;
+      r_w_en_r7  <= 1;
+      r_w_en_r8  <= 1;
+      r_w_en_r9  <= 1;
+      r_w_en_r10 <= 1;
+      r_w_en_r11 <= 1;
+    end else begin
+      r_w_en_r1  <= 0;
+      r_w_en_r2  <= 0;
+      r_w_en_r3  <= 0;
+      r_w_en_r4  <= 0;
+      r_w_en_r5  <= 0;
+      r_w_en_r6  <= 0;
+      r_w_en_r7  <= 0;
+      r_w_en_r8  <= 0;
+      r_w_en_r9  <= 0;
+      r_w_en_r10 <= 0;
+      r_w_en_r11 <= 0;
+    end
+  end
+
+  always @(posedge mclk_i) begin
+    if (rst_i_r) begin
+      en_r1  <= 0;
+      en_r2  <= 0;
+      en_r3  <= 0;
+      en_r4  <= 0;
+      en_r5  <= 0;
+      en_r6  <= 0;
+      en_r7  <= 0;
+      en_r8  <= 0;
+      en_r9  <= 0;
+      en_r10 <= 0;
+      en_r11 <= 0;
+    end else begin
+      if (en_r) begin
+        en_r1  <= adc_sel_r[0];
+        en_r2  <= adc_sel_r[1];
+        en_r3  <= adc_sel_r[2];
+        en_r4  <= adc_sel_r[3];
+        en_r5  <= adc_sel_r[4];
+        en_r6  <= adc_sel_r[5];
+        en_r7  <= adc_sel_r[6];
+        en_r8  <= adc_sel_r[7];
+        en_r9  <= adc_sel_r[8];
+        en_r10 <= adc_sel_r[9];
+        en_r11 <= adc_sel_r[10];
+      end else begin
+        en_r1  <= 0;
+        en_r2  <= 0;
+        en_r3  <= 0;
+        en_r4  <= 0;
+        en_r5  <= 0;
+        en_r6  <= 0;
+        en_r7  <= 0;
+        en_r8  <= 0;
+        en_r9  <= 0;
+        en_r10 <= 0;
+        en_r11 <= 0;
+      end
+    end
+  end
+
+  always @(posedge mclk_i) begin
+    // priority.
+    if (adc_sel_r < 64) begin
+      if (adc_sel_r[0]) rdata_o <= rdata_w1;
+      else if (adc_sel_r[1]) rdata_o <= rdata_w2;
+      else if (adc_sel_r[2]) rdata_o <= rdata_w3;
+      else if (adc_sel_r[3]) rdata_o <= rdata_w4;
+      else if (adc_sel_r[4]) rdata_o <= rdata_w5;
+      else if (adc_sel_r[5]) rdata_o <= rdata_w6;
+    end else begin
+      if (adc_sel_r[6]) rdata_o <= rdata_w7;
+      else if (adc_sel_r[7]) rdata_o <= rdata_w8;
+      else if (adc_sel_r[8]) rdata_o <= rdata_w9;
+      else if (adc_sel_r[9]) rdata_o <= rdata_w10;
+      else if (adc_sel_r[10]) rdata_o <= rdata_w11;
+      else rdata_o <= 0;
+    end
+  end
+
+  reg dn_latch_0_r, dn_latch_1_r, dn_latch_2_r, dn_latch_3_r;
+  wire dn_latch_0, dn_latch_1, dn_latch_2, dn_latch_3, dn_w;
+
+  // Change to AND to sync after bring-up
+  assign dn_latch_0 = (dn_latch_r7 | dn_latch_r9 | dn_latch_r10);  // bank0
+  assign dn_latch_1 = (dn_latch_r5 | dn_latch_r8 | dn_latch_r1);
+  assign dn_latch_2 = (dn_latch_r4 | dn_latch_r6 | dn_latch_r3);
+  assign dn_latch_3 = (dn_latch_r2 | dn_latch_r11);
+  assign dn_w       = (dn_latch_0_r | dn_latch_1_r | dn_latch_2_r | dn_latch_3_r);
+
+  always @(posedge mclk_i) begin
+    if (rst_i_r) begin
+      dn_r <= 0;
+      dn_latch_0_r <= 0;
+      dn_latch_1_r <= 0;
+      dn_latch_2_r <= 0;
+      dn_latch_3_r <= 0;
+    end else begin
+      dn_latch_0_r <= dn_latch_0;
+      dn_latch_1_r <= dn_latch_1;
+      dn_latch_2_r <= dn_latch_2;
+      dn_latch_3_r <= dn_latch_3;
+      dn_r <= dn_w;
+    end
+  end
+
+  ///
+
+  reg poll_dn_latch_0_r, poll_dn_latch_1_r, poll_dn_latch_2_r, poll_dn_latch_3_r;
+  wire poll_dn_latch_0, poll_dn_latch_1, poll_dn_latch_2, poll_dn_latch_3, poll_dn_w;
+
+  assign poll_dn_latch_0 = (poll_dn_latch_r7 | poll_dn_latch_r9 | poll_dn_latch_r10);  // bank0
+  assign poll_dn_latch_1 = (poll_dn_latch_r5 | poll_dn_latch_r8 | poll_dn_latch_r1);
+  assign poll_dn_latch_2 = (poll_dn_latch_r4 | poll_dn_latch_r6 | poll_dn_latch_r3);
+  assign poll_dn_latch_3 = (poll_dn_latch_r2 | poll_dn_latch_r11);
+  assign poll_dn_w       = (poll_dn_latch_0_r | poll_dn_latch_1_r | poll_dn_latch_2_r | poll_dn_latch_3_r);
+
+  always @(posedge mclk_i) begin
+    if (rst_i_r) begin
+      poll_dn_r <= 0;
+      poll_dn_latch_0_r <= 0;
+      poll_dn_latch_1_r <= 0;
+      poll_dn_latch_2_r <= 0;
+      poll_dn_latch_3_r <= 0;
+    end else begin
+      poll_dn_latch_0_r <= poll_dn_latch_0;
+      poll_dn_latch_1_r <= poll_dn_latch_1;
+      poll_dn_latch_2_r <= poll_dn_latch_2;
+      poll_dn_latch_3_r <= poll_dn_latch_3;
+      poll_dn_r <= poll_dn_w;
+    end
+  end
+
+  always @(posedge mclk_i) begin
+    if (rst_i_r | dn_clr_i) begin
+      dn_latch_r1 <= 0;
+    end else begin
+      if (dn_r1) dn_latch_r1 <= 1;
+    end
+  end
+
+  always @(posedge mclk_i) begin
+    if (rst_i_r | dn_clr_i) begin
+      dn_latch_r2 <= 0;
+    end else begin
+      if (dn_r2) dn_latch_r2 <= 1;
+    end
+  end
+
+  always @(posedge mclk_i) begin
+    if (rst_i_r | dn_clr_i) begin
+      dn_latch_r3 <= 0;
+    end else begin
+      if (dn_r3) dn_latch_r3 <= 1;
+    end
+  end
+
+  always @(posedge mclk_i) begin
+    if (rst_i_r | dn_clr_i) begin
+      dn_latch_r4 <= 0;
+    end else begin
+      if (dn_r4) dn_latch_r4 <= 1;
+    end
+  end
+
+  always @(posedge mclk_i) begin
+    if (rst_i_r | dn_clr_i) begin
+      dn_latch_r5 <= 0;
+    end else begin
+      if (dn_r5) dn_latch_r5 <= 1;
+    end
+  end
+
+  always @(posedge mclk_i) begin
+    if (rst_i_r | dn_clr_i) begin
+      dn_latch_r6 <= 0;
+    end else begin
+      if (dn_r6) dn_latch_r6 <= 1;
+    end
+  end
+
+  always @(posedge mclk_i) begin
+    if (rst_i_r | dn_clr_i) begin
+      dn_latch_r7 <= 0;
+    end else begin
+      if (dn_r7) dn_latch_r7 <= 1;
+    end
+  end
+
+  always @(posedge mclk_i) begin
+    if (rst_i_r | dn_clr_i) begin
+      dn_latch_r8 <= 0;
+    end else begin
+      if (dn_r8) dn_latch_r8 <= 1;
+    end
+  end
+
+  always @(posedge mclk_i) begin
+    if (rst_i_r | dn_clr_i) begin
+      dn_latch_r9 <= 0;
+    end else begin
+      if (dn_r9) dn_latch_r9 <= 1;
+    end
+  end
+
+  always @(posedge mclk_i) begin
+    if (rst_i_r | dn_clr_i) begin
+      dn_latch_r10 <= 0;
+    end else begin
+      if (dn_r10) dn_latch_r10 <= 1;
+    end
+  end
+
+  always @(posedge mclk_i) begin
+    if (rst_i_r | dn_clr_i) begin
+      dn_latch_r11 <= 0;
+    end else begin
+      if (dn_r11) dn_latch_r11 <= 1;
+    end
+  end
+
+  always @(posedge mclk_i) begin
+    if (rst_i_r | dn_clr_i) begin
+      poll_dn_latch_r1 <= 0;
+    end else begin
+      if (poll_dn_r1) poll_dn_latch_r1 <= 1;
+    end
+  end
+
+  always @(posedge mclk_i) begin
+    if (rst_i_r | dn_clr_i) begin
+      poll_dn_latch_r2 <= 0;
+    end else begin
+      if (poll_dn_r2) poll_dn_latch_r2 <= 1;
+    end
+  end
+
+  always @(posedge mclk_i) begin
+    if (rst_i_r | dn_clr_i) begin
+      poll_dn_latch_r3 <= 0;
+    end else begin
+      if (poll_dn_r3) poll_dn_latch_r3 <= 1;
+    end
+  end
+
+  always @(posedge mclk_i) begin
+    if (rst_i_r | dn_clr_i) begin
+      poll_dn_latch_r4 <= 0;
+    end else begin
+      if (poll_dn_r4) poll_dn_latch_r4 <= 1;
+    end
+  end
+
+  always @(posedge mclk_i) begin
+    if (rst_i_r | dn_clr_i) begin
+      poll_dn_latch_r5 <= 0;
+    end else begin
+      if (poll_dn_r5) poll_dn_latch_r5 <= 1;
+    end
+  end
+
+  always @(posedge mclk_i) begin
+    if (rst_i_r | dn_clr_i) begin
+      poll_dn_latch_r6 <= 0;
+    end else begin
+      if (poll_dn_r6) poll_dn_latch_r6 <= 1;
+    end
+  end
+
+  always @(posedge mclk_i) begin
+    if (rst_i_r | dn_clr_i) begin
+      poll_dn_latch_r7 <= 0;
+    end else begin
+      if (poll_dn_r7) poll_dn_latch_r7 <= 1;
+    end
+  end
+
+  always @(posedge mclk_i) begin
+    if (rst_i_r | dn_clr_i) begin
+      poll_dn_latch_r8 <= 0;
+    end else begin
+      if (poll_dn_r8) poll_dn_latch_r8 <= 1;
+    end
+  end
+
+  always @(posedge mclk_i) begin
+    if (rst_i_r | dn_clr_i) begin
+      poll_dn_latch_r9 <= 0;
+    end else begin
+      if (poll_dn_r9) poll_dn_latch_r9 <= 1;
+    end
+  end
+
+  always @(posedge mclk_i) begin
+    if (rst_i_r | dn_clr_i) begin
+      poll_dn_latch_r10 <= 0;
+    end else begin
+      if (poll_dn_r10) poll_dn_latch_r10 <= 1;
+    end
+  end
+
+  always @(posedge mclk_i) begin
+    if (rst_i_r | dn_clr_i) begin
+      poll_dn_latch_r11 <= 0;
+    end else begin
+      if (poll_dn_r11) poll_dn_latch_r11 <= 1;
+    end
+  end
+
+endmodule
diff --git a/fpga/gonk/pll.v b/fpga/gonk/pll.v
new file mode 100644
index 0000000..0196621
--- /dev/null
+++ b/fpga/gonk/pll.v
@@ -0,0 +1,41 @@
+// Copyright 2023 The Pigweed Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+`timescale 1ns / 1ps
+//////////////////////////////////////////////////////////////////////////////////
+//
+//////////////////////////////////////////////////////////////////////////////////
+
+
+module pll (
+    input  clock_in,
+    output clock_out
+    // output locked
+);
+  // assign clock_out=clock_in;
+  SB_PLL40_CORE #(
+      .FEEDBACK_PATH("SIMPLE"),
+      .PLLOUT_SELECT("GENCLK"),
+      .DIVR(4'b0000),
+      .DIVF(7'b0010111),
+      .DIVQ(3'b011),
+      .FILTER_RANGE(3'b001)
+  ) uut (
+      .RESETB(1'b1),
+      .BYPASS(1'b0),
+      .REFERENCECLK(clock_in),
+      .PLLOUTCORE(clock_out)
+  );
+
+endmodule
diff --git a/fpga/gonk/rst_sync.v b/fpga/gonk/rst_sync.v
new file mode 100644
index 0000000..f2fe98d
--- /dev/null
+++ b/fpga/gonk/rst_sync.v
@@ -0,0 +1,66 @@
+// Copyright 2023 The Pigweed Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+`timescale 1ns / 1ps
+//////////////////////////////////////////////////////////////////////////////////
+//
+//
+//////////////////////////////////////////////////////////////////////////////////
+
+
+module rst_sync (
+    input  clk_i,
+    input  rst_i,
+    output rst_o
+);
+
+  reg rst_i_r0, rst_i_r1, rst_i_r2;
+  assign rst_o = rst_i_r2;
+
+  reg [2:0] rst_state;
+  reg [3:0] count;
+
+  always @(posedge clk_i) begin
+    case (rst_state)
+      0: begin
+        rst_i_r0 <= 1;
+        rst_state <= 1;
+        count <= 0;
+      end
+      1: begin
+        rst_i_r0 <= 1;
+        count <= count + 1;
+        if (count >= 4'd9) rst_state <= 2;
+      end
+      2: begin
+        rst_i_r0 <= 0;
+        count <= 0;
+      end
+      default: rst_state <= 0;
+    endcase
+  end
+
+  always @(posedge clk_i or posedge rst_i) begin
+    if (rst_i) begin
+      // rst_i_r0<=1;
+      rst_i_r1 <= 1;
+      rst_i_r2 <= 1;
+    end else begin
+      // rst_i_r0<=rst_i;
+      rst_i_r1 <= rst_i_r0;
+      rst_i_r2 <= rst_i_r1;
+    end
+  end
+
+endmodule
diff --git a/fpga/gonk/sig_sync.v b/fpga/gonk/sig_sync.v
new file mode 100644
index 0000000..6946427
--- /dev/null
+++ b/fpga/gonk/sig_sync.v
@@ -0,0 +1,45 @@
+// Copyright 2023 The Pigweed Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+`timescale 1ns / 1ps
+//////////////////////////////////////////////////////////////////////////////////
+//
+//
+//////////////////////////////////////////////////////////////////////////////////
+
+
+module sig_sync (
+    input  clk_i,
+    input  rst_i,
+    input  sig_i,
+    output sig_o
+);
+
+  reg sig_i_r0, sig_i_r1, sig_i_r2;
+  assign sig_o = sig_i_r2;
+
+  always @(posedge clk_i) begin
+    if (rst_i) begin
+      sig_i_r0 <= 0;
+      sig_i_r1 <= 0;
+      sig_i_r2 <= 0;
+    end else begin
+      sig_i_r0 <= sig_i;
+      sig_i_r1 <= sig_i_r0;
+      sig_i_r2 <= sig_i_r1;
+
+    end
+  end
+
+endmodule
diff --git a/fpga/gonk/spi_m_core.v b/fpga/gonk/spi_m_core.v
new file mode 100644
index 0000000..c3f37c2
--- /dev/null
+++ b/fpga/gonk/spi_m_core.v
@@ -0,0 +1,296 @@
+// Copyright 2023 The Pigweed Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+`timescale 1ns / 1ps
+//////////////////////////////////////////////////////////////////////////////////
+// SPI for INA229
+// Refer Spec: https://www.ti.com/lit/ds/symlink/ina229.pdf?ts=1692387535714&ref_url=https%253A%252F%252Fwww.ti.com%252Fproduct%252FINA229
+//////////////////////////////////////////////////////////////////////////////////
+
+module spi_m_core #(
+    parameter SCK_DIVISOR = 10,
+    parameter MCLK_CYCLE_TIME = 10
+) (
+    input mclk_i,
+    input rst_i,
+    input r_w_en_i,
+    input en_i,
+    input [5:0] rwaddr_i,
+    input [15:0] wdata_i,
+    output reg dn_o,
+    output reg [39:0] rdata_o,
+    // spi interface
+    input miso_i,
+    output reg sclk_o,
+    output reg mosi_o,
+    output reg cs_o
+);
+
+
+  reg
+      miso_r0,
+      miso_r1,
+      miso_r2,
+      rising_edge_det,
+      falling_edge_det,
+      rising_edge_det_r0,
+      rising_edge_det_r1,
+      rising_edge_det_r2,
+      en_r,
+      sck_div_ctr_clr,
+      sclk_clr;
+  reg
+      wr_done_r,
+      rd_en_r,
+      rd_done_r,
+      dat_out_ctr_en_r,
+      r_w_en_r,
+      falling_edge_det_r2,
+      falling_edge_det_r1,
+      falling_edge_det_r0,
+      wait_ctr_en_r,
+      spi_en_r,
+      dn_r,
+      wait_dn_r;
+  reg [3:0] sck_div_ctr_r, wait_ctr_r;
+  reg [2:0] spi_m_state;
+  reg [5:0] rwaddr_latch_r;
+  reg [6:0] rwaddr_r, max_bit_count_r, dat_out_ctr_r, dat_in_ctr;
+  reg [15:0] wdata_r;
+  reg [23:0] dat_out_r;
+  reg [39:0] dat_in_r;
+
+  localparam IDLE = 0;  // Power On State
+  localparam EN = 1;  // Transfer Enabled. Waiting for Transfer Done.
+  localparam DN = 2;  // Transfer Done State. Drive dn_o high.
+  localparam WAIT = 3; // State to Add the min. wait time required b/w CS assertion/de-assertion and CLK Enable/Disable.
+
+  localparam CLK_DIV = SCK_DIVISOR - 1;  // Clock Divisor wrt 100MHz mclk.
+  localparam CLK_DIV_2 = CLK_DIV >> 1;  // CLK_DIV/2
+  localparam t_SCLK_CS_WAIT = 0;  // # no. of mclk cycle wait for t_SCLK_CS
+
+  // SPI State Machine. Mealy, 3 States. Control Signals = en_r, dn_r.
+
+  always @(posedge mclk_i) begin
+    if (rst_i) spi_m_state <= IDLE;
+    else begin
+      case (spi_m_state)
+        IDLE: begin
+          if (en_r) spi_m_state <= EN;
+          else spi_m_state <= IDLE;
+        end
+        EN: begin
+          if (dn_r) spi_m_state <= DN;
+          else spi_m_state <= EN;
+        end
+        DN: begin
+          // if (dn_r)
+          //	spi_m_state<=DN;
+          // else
+          spi_m_state <= IDLE;
+        end
+        default: begin
+          spi_m_state <= IDLE;
+        end
+      endcase
+    end
+  end
+
+  // State Machine O/Ps.
+
+  always @(posedge mclk_i) begin
+    if (rst_i) begin
+      cs_o <= 1;
+      dat_out_ctr_en_r <= 0;
+      spi_en_r <= 0;
+      wait_ctr_en_r <= 0;
+      dn_o <= 0;
+    end else begin
+      case (spi_m_state)
+        IDLE: begin
+          spi_en_r <= 0;
+          dat_out_ctr_en_r <= 0;
+          wait_ctr_en_r <= 0;
+          dn_o <= 0;
+          if (en_r) cs_o <= 0;
+          else cs_o <= 1;
+        end
+        EN: begin
+          cs_o <= 0;
+          wait_ctr_en_r <= 0;
+          dn_o <= 0;
+          if (dn_r) begin
+            spi_en_r <= 0;
+            dat_out_ctr_en_r <= 0;
+          end else begin
+            dat_out_ctr_en_r <= 1;
+            spi_en_r <= 1;
+          end
+        end
+        DN: begin
+          cs_o <= 0;
+          dat_out_ctr_en_r <= 0;
+          spi_en_r <= 0;
+          wait_ctr_en_r <= 0;
+          dn_o <= 1;
+        end
+      endcase
+    end
+  end
+
+  // SCK Logic begin
+  always @(posedge mclk_i) begin
+    if (spi_en_r) begin
+      if (sck_div_ctr_clr) sck_div_ctr_r <= 0;
+      else sck_div_ctr_r <= sck_div_ctr_r + 1;
+    end else sck_div_ctr_r <= 0;
+  end
+
+  always @(posedge mclk_i) begin
+    if (rst_i) begin
+      sclk_o <= 0;
+    end else begin
+      sclk_o <= (spi_en_r && (sck_div_ctr_r > CLK_DIV_2));  // default state = 0
+    end
+  end
+  // SCK Logic End
+
+
+  // Data Transmit and Receive Logic Begin
+  // Pulses to sync transmit and capture with respective clock edges.
+  always @(posedge mclk_i) begin
+    rising_edge_det  <= (sck_div_ctr_r == CLK_DIV_2);
+    falling_edge_det <= (sck_div_ctr_r == CLK_DIV);
+  end
+
+  always @(posedge mclk_i) begin
+    if (dat_out_ctr_en_r) begin
+      if (falling_edge_det) dat_out_ctr_r <= dat_out_ctr_r + 1;
+    end else dat_out_ctr_r <= 0;
+  end
+
+  always @(posedge mclk_i) begin
+    if (rst_i) en_r <= 0;
+    else begin
+      if (dn_r) en_r <= 0;
+      else if (en_i) en_r <= 1;
+    end
+  end
+
+  always @(posedge mclk_i) begin
+    if (rst_i) begin
+      rwaddr_r <= 0;
+      rwaddr_latch_r <= 0;
+      wdata_r <= 0;
+      r_w_en_r <= 0;
+      dat_out_r <= 0;
+    end else begin
+      if (en_i) begin
+        dat_out_r <= {rwaddr_i, 1'b0, r_w_en_i, wdata_i};
+        rwaddr_r <= {rwaddr_i, 1'b0};
+        rwaddr_latch_r <= rwaddr_i;
+        wdata_r <= wdata_i;
+        r_w_en_r <= r_w_en_i;
+      end
+    end
+  end
+
+  always @(posedge mclk_i) begin
+    if (r_w_en_r) begin
+      if (rwaddr_latch_r== 6'd4 || rwaddr_latch_r== 6'd5 || rwaddr_latch_r== 6'd7 || rwaddr_latch_r== 6'd8)
+        max_bit_count_r <= 24;
+      else if (rwaddr_latch_r == 6'd9 || rwaddr_latch_r == 6'd10) max_bit_count_r <= 40;
+      else max_bit_count_r <= 16;
+    end else begin
+      max_bit_count_r <= 16;
+    end
+  end
+
+  always @(posedge mclk_i) begin
+    wr_done_r<=((!r_w_en_r) & (dat_out_ctr_r==24));// && falling_edge_det_r1); // added sync with falling_edge_det_r2
+    rd_en_r <= ((dat_out_ctr_r > 8) && r_w_en_r);  // changed from (dat_out_ctr_r>=8)
+    rd_done_r <= (dat_in_ctr == (max_bit_count_r - 1));
+    wait_dn_r <= (wait_ctr_r == t_SCLK_CS_WAIT);
+    sck_div_ctr_clr <= (sck_div_ctr_r == (CLK_DIV - 1));
+  end
+
+  always @(posedge mclk_i) begin
+    if (rst_i) begin
+      mosi_o <= 1;
+    end else begin
+      if (spi_en_r) begin
+        if (rising_edge_det) begin
+          if (rd_en_r) mosi_o <= 0;
+          else mosi_o <= dat_out_r[23-dat_out_ctr_r];
+        end
+      end else
+        mosi_o <= 1;  // if (cs_o) mosi_o<=1; // change-might create a crit path b/w cs_o and mosi
+    end
+  end
+
+  always @(posedge mclk_i) begin
+    if (rd_en_r) begin
+      if (falling_edge_det_r0) begin
+        dat_in_ctr <= dat_in_ctr + 1;
+      end
+    end else begin
+      dat_in_ctr <= 0;
+    end
+  end
+
+  always @(posedge mclk_i) begin
+    if (rd_en_r) begin
+      if (falling_edge_det_r1) begin
+        dat_in_r <= {dat_in_r, miso_r1};
+      end
+    end else begin
+      dat_in_r <= 0;
+    end
+  end
+
+  always @(posedge mclk_i) begin
+    if (rst_i)  // Rst not required.
+      rdata_o <= 0;
+    else if (rd_done_r & rising_edge_det) rdata_o <= dat_in_r;
+  end
+
+  always @(posedge mclk_i) begin
+    if (wait_ctr_en_r) wait_ctr_r <= wait_ctr_r + 1;
+    else wait_ctr_r <= 0;
+  end
+
+
+  // Using shift reg. pattern. Unsure of ASYNC_REG placement on icestorm.
+  always @(posedge mclk_i) begin
+    if (rst_i) begin
+      {miso_r0, miso_r1, miso_r2} <= 0;
+      {rising_edge_det_r0, rising_edge_det_r1, rising_edge_det_r2} <= 0;
+      {falling_edge_det_r0, falling_edge_det_r1, falling_edge_det_r2} <= 0;
+    end else begin
+      {miso_r2, miso_r1, miso_r0} <= {miso_r1, miso_r0, miso_i};
+      {rising_edge_det_r2, rising_edge_det_r1, rising_edge_det_r0} <= {
+        rising_edge_det_r1, rising_edge_det_r0, rising_edge_det
+      };
+      {falling_edge_det_r2, falling_edge_det_r1, falling_edge_det_r0} <= {
+        falling_edge_det_r1, falling_edge_det_r0, falling_edge_det
+      };
+    end
+  end
+
+  always @(posedge mclk_i) begin
+    dn_r <= (wr_done_r | (rd_done_r));
+  end
+
+  // Data Transmit and Receive Logic End
+endmodule
diff --git a/fpga/gonk/spi_m_core_ctl.v b/fpga/gonk/spi_m_core_ctl.v
new file mode 100644
index 0000000..e1b0377
--- /dev/null
+++ b/fpga/gonk/spi_m_core_ctl.v
@@ -0,0 +1,228 @@
+// Copyright 2023 The Pigweed Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+`timescale 1ns / 1ps
+//////////////////////////////////////////////////////////////////////////////////
+// SPI m Controller
+//
+//////////////////////////////////////////////////////////////////////////////////
+
+
+
+module spi_m_core_ctl (
+    input mclk_i,
+    input rst_i,
+    input r_w_en_i,
+    input en_i,
+    input mode_i,
+    input [5:0] rwaddr_i,
+    input [15:0] wdata_i,
+    output reg dn_o,
+    output reg poll_dn_o,
+    output reg [39:0] rdata_o,
+    output reg [23:0] vbus_o,
+    output reg [23:0] vshunt_o,
+    // spi interface
+    input miso_i,
+    input alert_n_i,
+    output sclk_o,
+    output mosi_o,
+    output cs_o
+);
+
+  reg
+      r_w_en_r,
+      alert_n_r2,
+      alert_n_r1,
+      alert_n_r0,
+      spi_poll_en_r,
+      spi_core_en_r,
+      spi_m_en_r,
+      rst_i_r,
+      wait_ctr_en_r;
+  reg dn_r;
+  reg [1:0] poll_addr_select;
+  reg [2:0] wait_ctr_r;
+  reg [2:0] poll_state;
+  reg [5:0] poll_rwaddr_r;
+  reg [5:0] rwaddr_r;
+  reg [15:0] wdata_r;
+  reg [39:0] spi_rdata_r;
+  wire [39:0] spi_rdata_w;
+  wire dn_w;
+
+  localparam S0 = 0;
+  localparam S1 = 1;
+  localparam S2 = 2;
+  localparam S3 = 3;
+  localparam S4 = 4;
+  localparam poll_r_w_en = 1;  // Continous read.
+  localparam poll_addr0 = 6'b000100;  // 04h = V-shunt Register
+  localparam poll_addr1 = 6'b000101;  // 05h = V-bus Register
+  localparam poll_addr2 = 6'b001011;  // 0Bh = Diag Alert Reg. to clear Alert.
+
+  spi_m_core spi_m_inst (
+      .mclk_i(mclk_i),
+      .rst_i(rst_i_r),
+      .r_w_en_i(r_w_en_r),
+      .en_i(spi_m_en_r),
+      .rwaddr_i(rwaddr_r),
+      .wdata_i(wdata_r),
+      .dn_o(dn_w),
+      .rdata_o(spi_rdata_w),
+      // spi
+      .miso_i(miso_i),
+      .sclk_o(sclk_o),
+      .mosi_o(mosi_o),
+      .cs_o(cs_o)
+  );
+
+  always @(posedge mclk_i) begin
+    rst_i_r <= rst_i;
+  end
+
+  always @(posedge mclk_i) begin
+    if (rst_i_r) spi_m_en_r <= 0;
+    else spi_m_en_r <= (en_i | spi_poll_en_r);
+  end
+
+  always @(posedge mclk_i) begin
+    if (rst_i_r) begin
+      dn_o <= 0;
+      rdata_o <= 0;
+    end else begin
+      if (!mode_i) begin
+        dn_o <= dn_w;
+        if (dn_w) rdata_o <= spi_rdata_w;
+      end
+    end
+  end
+
+  always @(posedge mclk_i) begin
+    if (rst_i_r) begin
+      {alert_n_r0, alert_n_r1, alert_n_r2} <= 3'b111;
+    end else begin
+      {alert_n_r2, alert_n_r1, alert_n_r0} <= {alert_n_r1, alert_n_r0, alert_n_i};
+    end
+  end
+
+  always @(posedge mclk_i) begin
+    if (mode_i) begin  // if mode=0 R/W Mode. // if mode=1 Continous Mode
+      rwaddr_r <= poll_rwaddr_r;
+      wdata_r  <= 0;
+      r_w_en_r <= poll_r_w_en;
+    end else begin
+      rwaddr_r <= rwaddr_i;
+      wdata_r  <= wdata_i;
+      r_w_en_r <= r_w_en_i;
+    end
+  end
+
+  // Shunt reg.s Polling state machine
+
+  always @(posedge mclk_i) begin
+    if (rst_i_r) poll_state <= S0;
+    else begin
+      if (mode_i) begin
+        case (poll_state)
+          S0: begin
+            if (alert_n_r2) poll_state <= S0;
+            else poll_state <= S1;
+          end
+          S1: begin
+            poll_state <= S2;
+          end
+          S2: begin
+            if (dn_w) poll_state <= S3;
+            else poll_state <= S2;
+          end
+          S3: begin
+            if (poll_addr_select[1]) 		// Change to "poll_addr_select<=2" if alert doesn't clear after reading the vbus and vshunt registers.
+              poll_state <= S4;
+            else begin
+              if (wait_ctr_r[2])  //(wait_ctr_r>=5) // Changed to one bit comparator.
+                poll_state <= S1;
+              else poll_state <= S3;
+            end
+          end
+          S4: begin
+            if (alert_n_r2) poll_state <= S0;
+            else poll_state <= S4;
+          end
+          default: poll_state <= S0;
+        endcase
+      end else poll_state <= S0;
+    end
+  end
+
+  always @(posedge mclk_i) begin
+    if (rst_i_r) begin
+      spi_poll_en_r <= 0;
+      wait_ctr_en_r <= 0;
+      poll_dn_o <= 0;
+    end else begin
+      case (poll_state)
+        S0: begin
+          poll_dn_o <= 0;
+          wait_ctr_en_r <= 0;
+          spi_poll_en_r <= 0;
+        end
+        S1: begin
+          poll_dn_o <= 0;
+          spi_poll_en_r <= 1;
+          wait_ctr_en_r <= 0;
+        end
+        S2: begin
+          spi_poll_en_r <= 0;
+          poll_dn_o <= 0;
+          wait_ctr_en_r <= 0;
+        end
+        S3: begin  // min wait time b/w 2 transaction
+          poll_dn_o <= 0;
+          spi_poll_en_r <= 0;
+          wait_ctr_en_r <= 1;
+        end
+        S4: begin
+          spi_poll_en_r <= 0;
+          poll_dn_o <= 1;
+          wait_ctr_en_r <= 0;
+        end
+      endcase
+    end
+  end
+
+  always @(posedge mclk_i) begin
+    if (rst_i_r | poll_dn_o) poll_addr_select <= 0;
+    if (spi_m_en_r & mode_i) poll_addr_select <= poll_addr_select + 1;
+  end
+
+  always @(posedge mclk_i) begin
+    if (poll_addr_select == 0) poll_rwaddr_r <= poll_addr0;
+    else if (poll_addr_select == 1) poll_rwaddr_r <= poll_addr1;
+    else poll_rwaddr_r <= poll_addr2;
+  end
+
+  always @(posedge mclk_i) begin
+    if (dn_w & mode_i) begin
+      if (poll_addr_select == 2'b01) vshunt_o <= spi_rdata_w;
+      else if (poll_addr_select == 2'b10) vbus_o <= spi_rdata_w;
+    end
+  end
+
+  always @(posedge mclk_i) begin
+    if (wait_ctr_en_r) wait_ctr_r <= wait_ctr_r + 1;
+    else wait_ctr_r <= 0;
+  end
+
+endmodule
diff --git a/fpga/gonk/spi_s_core.v b/fpga/gonk/spi_s_core.v
new file mode 100644
index 0000000..349f5a8
--- /dev/null
+++ b/fpga/gonk/spi_s_core.v
@@ -0,0 +1,351 @@
+// Copyright 2023 The Pigweed Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+`timescale 1ns / 1ps
+//////////////////////////////////////////////////////////////////////////////////
+//
+//////////////////////////////////////////////////////////////////////////////////
+
+module spi_s_core (
+    //
+    input [23:0] vbus_1,
+    input [23:0] vshunt_1,
+    input [23:0] vbus_2,
+    input [23:0] vshunt_2,
+    input [23:0] vbus_3,
+    input [23:0] vshunt_3,
+    input [23:0] vbus_4,
+    input [23:0] vshunt_4,
+    input [23:0] vbus_5,
+    input [23:0] vshunt_5,
+    input [23:0] vbus_6,
+    input [23:0] vshunt_6,
+    input [23:0] vbus_7,
+    input [23:0] vshunt_7,
+    input [23:0] vbus_8,
+    input [23:0] vshunt_8,
+    input [23:0] vbus_9,
+    input [23:0] vshunt_9,
+    input [23:0] vbus_10,
+    input [23:0] vshunt_10,
+    input [23:0] vbus_11,
+    input [23:0] vshunt_11,
+    //
+    input dn_i,
+    input poll_dn_i,
+    input [39:0] rdata_i,
+    output reg dn_clr_o,
+    output reg en_o,
+    output reg r_w_en_o,
+    output reg [5:0] rwaddr_o,
+    output reg [15:0] wdata_o,
+    output reg [10:0] adc_sel_o,
+    // sys
+    input mclk_i,
+    input rst_i,
+    input mode_i,
+    output data_valid_o,
+    // spi
+    input sclk_i,
+    input mosi_i,
+    input cs_i,
+    output reg miso_o
+);
+
+  localparam IDLE = 1;
+  localparam WT = 2;
+  localparam DN = 4;
+
+  reg
+      sclk_i_r0,
+      sclk_i_r1,
+      sclk_i_r2,
+      cs_i_r0,
+      cs_i_r1,
+      cs_i_r2,
+      mosi_i_r0,
+      mosi_i_r1,
+      mosi_i_r2,
+      dat_out_dn_r,
+      rst_i_r,
+      wr_dn_valid_r;
+  reg
+      spi_rdy_r,
+      dat_out_dn_latch,
+      dat_out_en_r,
+      dat_out_ctr_clr,
+      poll_dat_ctr_clr,
+      addr_rdy_r,
+      wdata_rdy_r,
+      dat_out_ctr_clr_r,
+      poll_ctr_en_r,
+      poll_ctr_en_r1;
+  reg [2:0] spi_s_state;
+  reg [5:0] rwaddr_latch_r, poll_dat_ctr_r;
+  reg [6:0] dat_in_ctr_r, data_count_max_r, dat_out_ctr;
+  reg [15:0] rwaddr_r, wdata_r, wdata_latch_r;
+  reg [23:0] poll_dat_r;
+  reg [39:0] dat_in_r, dat_out_r, dat_in_r1;
+
+  wire pos_edge, neg_edge, poll_ctr_en_w;
+
+  assign pos_edge      = (sclk_i_r1 & !sclk_i_r2);
+  assign neg_edge      = (!sclk_i_r1 & sclk_i_r2);
+  assign poll_ctr_en_w = dat_out_ctr_clr_r & dat_out_ctr_clr;
+  assign data_valid_o  = (dat_out_en_r | wr_dn_valid_r);
+
+  wire [10:0] test;
+  assign test = (data_count_max_r - 1) - dat_out_ctr;
+
+  always @(posedge mclk_i) begin
+    rst_i_r <= rst_i;
+  end
+
+  always @(posedge mclk_i) begin
+    if (rst_i_r) begin
+      {sclk_i_r0, sclk_i_r1, sclk_i_r2} <= 0;
+      {cs_i_r0, cs_i_r1, cs_i_r2} <= 3'b111;
+      {mosi_i_r0, mosi_i_r1, mosi_i_r2} <= 0;
+
+    end else begin
+      {sclk_i_r2, sclk_i_r1, sclk_i_r0} <= {sclk_i_r1, sclk_i_r0, sclk_i};
+      {cs_i_r0, cs_i_r1, cs_i_r2} <= {cs_i, cs_i_r0, cs_i_r1};
+      {mosi_i_r0, mosi_i_r1, mosi_i_r2} <= {mosi_i, mosi_i_r0, mosi_i_r1};
+    end
+  end
+
+  always @(posedge mclk_i) begin
+    if (rst_i_r) begin
+      dat_in_r <= 0;
+      dat_in_ctr_r <= 0;
+    end else begin
+      if (!cs_i_r2 & spi_rdy_r) begin
+        if (neg_edge) begin
+          dat_in_r <= {dat_in_r, mosi_i_r2};
+          dat_in_ctr_r <= dat_in_ctr_r + 1;
+        end
+      end else begin
+        dat_in_r <= 0;
+        dat_in_ctr_r <= 0;
+      end
+    end
+  end
+
+  always @(posedge mclk_i) begin
+    if (rst_i_r | mode_i) spi_rdy_r <= 0;
+    else begin
+      spi_rdy_r <= (spi_s_state == IDLE);
+    end
+  end
+
+  always @(posedge mclk_i) begin
+    if (rst_i_r) begin
+      addr_rdy_r <= 0;
+    end else begin
+      if (dat_in_ctr_r == 24)  // changed from 16.
+        addr_rdy_r <= 1;
+      else addr_rdy_r <= 0;
+    end
+  end
+
+  always @(posedge mclk_i) begin
+    if (rst_i_r) begin
+      wdata_rdy_r <= 0;
+    end else begin
+      if (dat_in_ctr_r == 40) wdata_rdy_r <= 1;
+      else wdata_rdy_r <= 0;
+    end
+  end
+
+  always @(posedge mclk_i) begin
+    if (rst_i_r) begin
+      rwaddr_o  <= 0;
+      r_w_en_o  <= 0;
+      adc_sel_o <= 0;
+    end else begin
+      if (addr_rdy_r) begin
+        adc_sel_o <= dat_in_r1[17:7];
+        rwaddr_o  <= dat_in_r1[6:1];
+        r_w_en_o  <= dat_in_r1[0];
+      end
+    end
+  end
+
+  always @(posedge mclk_i) begin
+    if (rst_i_r) begin
+      dat_in_r1 <= 0;
+    end else begin
+      dat_in_r1 <= dat_in_r;
+    end
+  end
+
+  always @(posedge mclk_i) begin
+    if (rst_i_r) wdata_o <= 0;
+    else begin
+      if (wdata_rdy_r) wdata_o <= dat_in_r1;
+    end
+  end
+
+  always @(posedge mclk_i) begin
+    if (rst_i_r) en_o <= 0;
+    else begin
+      en_o <= (|adc_sel_o) & (wdata_rdy_r | (r_w_en_o & addr_rdy_r));
+    end
+  end
+
+  always @(posedge mclk_i) begin
+    if (rst_i_r | mode_i) spi_s_state <= IDLE;
+    else begin
+      case (spi_s_state)
+        IDLE: begin
+          if (en_o) spi_s_state <= WT;
+          else spi_s_state <= IDLE;
+          // spi_s_state<=en_o?r_w_en_o?RD:WR:IDLE;
+        end
+        WT: begin
+          if (r_w_en_o) begin
+            if (dat_out_dn_latch) spi_s_state <= DN;
+            else spi_s_state <= WT;
+          end else begin
+            if (dn_i) spi_s_state <= DN;
+            else spi_s_state <= WT;
+          end
+        end
+        DN: begin
+          spi_s_state <= IDLE;  //(pos_edge)?IDLE:DN;
+        end
+        default: spi_s_state <= IDLE;
+      endcase
+    end
+  end
+
+  always @(posedge mclk_i) begin
+    wr_dn_valid_r  <= dn_i & ((~mode_i) & (~r_w_en_o));
+    poll_ctr_en_r  <= poll_ctr_en_w;
+    poll_ctr_en_r1 <= poll_ctr_en_r;
+  end
+
+  always @(posedge mclk_i) begin
+    if (rst_i_r | dat_out_dn_latch) begin
+      dat_out_en_r <= 0;
+    end else begin
+      if ((mode_i & poll_dn_i) | ((!mode_i) & r_w_en_o & dn_i)) dat_out_en_r <= 1;
+    end
+  end
+
+  always @(posedge mclk_i) begin
+    if (rst_i_r) miso_o <= 1;
+    else begin
+      if (dat_out_en_r) begin
+        if (pos_edge) miso_o <= dat_out_r[((data_count_max_r-1)-dat_out_ctr)];
+      end else miso_o <= 1;
+    end
+  end
+
+  always @(posedge mclk_i) begin
+    if (rst_i_r | dat_out_ctr_clr) dat_out_ctr <= 0;
+    else begin
+      if (dat_out_en_r) begin
+        if (neg_edge) dat_out_ctr <= dat_out_ctr + 1;
+      end else dat_out_ctr <= 0;
+    end
+  end
+
+  always @(posedge mclk_i) begin
+    if (rst_i_r) dat_out_r <= 0;
+    else begin
+      if (mode_i) begin
+        dat_out_r <= poll_dat_r;
+      end else begin
+        if (dn_i) dat_out_r <= rdata_i;
+      end
+    end
+  end
+
+  always @(posedge mclk_i) begin
+    case (poll_dat_ctr_r)
+      0: poll_dat_r <= vshunt_1;
+      1: poll_dat_r <= vbus_1;
+      2: poll_dat_r <= vshunt_2;
+      3: poll_dat_r <= vbus_2;
+      4: poll_dat_r <= vshunt_3;
+      5: poll_dat_r <= vbus_3;
+      6: poll_dat_r <= vshunt_4;
+      7: poll_dat_r <= vbus_4;
+      8: poll_dat_r <= vshunt_5;
+      9: poll_dat_r <= vbus_5;
+      10: poll_dat_r <= vshunt_6;
+      11: poll_dat_r <= vbus_6;
+      12: poll_dat_r <= vshunt_7;
+      13: poll_dat_r <= vbus_7;
+      14: poll_dat_r <= vshunt_8;
+      15: poll_dat_r <= vbus_8;
+      16: poll_dat_r <= vshunt_9;
+      17: poll_dat_r <= vbus_9;
+      18: poll_dat_r <= vshunt_10;
+      19: poll_dat_r <= vbus_10;
+      20: poll_dat_r <= vshunt_11;
+      21: poll_dat_r <= vbus_11;
+      default: poll_dat_r <= 0;
+    endcase
+  end
+
+  always @(posedge mclk_i) begin
+    dat_out_ctr_clr   <= (dat_out_ctr == data_count_max_r);
+    dat_out_ctr_clr_r <= dat_out_ctr_clr;
+    poll_dat_ctr_clr  <= (poll_dat_ctr_r == 22);
+  end
+
+  always @(posedge mclk_i) begin
+    if (rst_i_r) dat_out_dn_r <= 0;
+    else
+      dat_out_dn_r <= (((!mode_i) & dat_out_ctr_clr) | (mode_i & poll_dat_ctr_clr));  // pos_edge &
+  end
+
+  always @(posedge mclk_i) begin
+    if (rst_i_r | neg_edge) dat_out_dn_latch <= 0;
+    else if (dat_out_dn_r) dat_out_dn_latch <= 1;
+  end
+
+  always @(posedge mclk_i) begin
+    if (rst_i_r | poll_dat_ctr_clr) poll_dat_ctr_r <= 0;
+    else begin
+      if (poll_ctr_en_w & mode_i) poll_dat_ctr_r <= poll_dat_ctr_r + 1;
+    end
+  end
+
+  always @(posedge mclk_i) begin
+    if (rst_i_r) dn_clr_o <= 0;
+    else begin
+      dn_clr_o <= ((!mode_i & dn_i) | (mode_i & poll_dn_i));
+    end
+  end
+
+  always @(posedge mclk_i) begin
+    if (rst_i_r) begin
+      data_count_max_r <= 16;
+    end else begin
+      if (mode_i) data_count_max_r <= 24;
+      else begin
+        if (r_w_en_o) begin
+          if (rwaddr_o == 4 || rwaddr_o == 5 || rwaddr_o == 7 || rwaddr_o == 8)
+            data_count_max_r <= 24;
+          else if (rwaddr_o == 9 || rwaddr_o == 10) data_count_max_r <= 40;
+          else data_count_max_r <= 16;
+        end else data_count_max_r <= 16;
+      end
+    end
+  end
+
+endmodule
diff --git a/fpga/gonk/top.pcf b/fpga/gonk/top.pcf
new file mode 100644
index 0000000..40a43c3
--- /dev/null
+++ b/fpga/gonk/top.pcf
@@ -0,0 +1,79 @@
+# Copyright 2023 The Pigweed Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may not
+# use this file except in compliance with the License. You may obtain a copy of
+# the License at
+#
+#     https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations under
+# the License.
+
+###IOSet List 63
+set_io led 56
+set_io rst_i 135
+set_io data_valid_o 136
+set_io op_mode_i 137
+set_io sl_cs_i_0 75
+set_io sl_mosi_i_0 74
+set_io sl_miso_o_0 73
+set_io sl_sclk_i_0 76
+set_io cs_o_3 19
+set_io miso_i_4 2
+set_io alertl_i_6 10
+set_io miso_i_3 16
+set_io mosi_o_6 11
+set_io sclk_o_7 139
+set_io alertl_i_1 104
+set_io cs_o_1 106
+set_io mosi_o_9 114
+set_io sclk_o_8 87
+set_io alertl_i_10 118
+set_io alertl_i_8 90
+set_io cs_o_8 93
+set_io miso_i_1 98
+set_io sclk_o_1 97
+set_io mosi_o_1 105
+set_io alertl_i_3 17
+set_io cs_o_10 120
+set_io cs_o_7 144
+set_io miso_i_10 117
+set_io miso_i_8 88
+set_io sclk_o_11 32
+set_io miso_i_7 141
+set_io mosi_o_2 24
+set_io sclk_o_3 15
+set_io alertl_i_5 83
+set_io cs_o_5 85
+set_io mosi_o_10 119
+set_io mosi_o_5 84
+set_io sclk_o_4 1
+set_io miso_i_5 82
+set_io alertl_i_7 142
+set_io mosi_o_7 143
+set_io sclk_o_6 8
+set_io clk_i 129
+set_io cs_o_2 25
+set_io alertl_i_9 113
+set_io cs_o_9 115
+set_io miso_i_2 22
+set_io miso_i_9 112
+set_io mosi_o_8 91
+set_io sclk_o_9 110
+set_io alertl_i_11 34
+set_io mosi_o_3 18
+set_io sclk_o_2 21
+set_io alertl_i_2 23
+set_io cs_o_11 38
+set_io cs_o_6 12
+set_io miso_i_11 33
+set_io sclk_o_10 116
+set_io miso_i_6 9
+set_io alertl_i_4 7
+set_io cs_o_4 4
+set_io mosi_o_11 37
+set_io mosi_o_4 3
+set_io sclk_o_5 81
diff --git a/fpga/gonk/top.v b/fpga/gonk/top.v
new file mode 100644
index 0000000..e1773ec
--- /dev/null
+++ b/fpga/gonk/top.v
@@ -0,0 +1,296 @@
+// Copyright 2023 The Pigweed Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+`timescale 1ns / 1ps
+//////////////////////////////////////////////////////////////////////////////////
+//
+//////////////////////////////////////////////////////////////////////////////////
+module top (
+    input  clk_i,
+    input  rst_i,
+    input  op_mode_i,
+    output data_valid_o,
+    output led,
+    // spi secondary interface
+    input  sl_sclk_i_0,
+    input  sl_mosi_i_0,
+    input  sl_cs_i_0,
+    output sl_miso_o_0,
+    // spi interfaces
+    //
+    input  miso_i_1,
+    input  alertl_i_1,
+    output sclk_o_1,
+    output mosi_o_1,
+    output cs_o_1,
+    //
+    input  miso_i_2,
+    input  alertl_i_2,
+    output sclk_o_2,
+    output mosi_o_2,
+    output cs_o_2,
+    //
+    input  miso_i_3,
+    input  alertl_i_3,
+    output sclk_o_3,
+    output mosi_o_3,
+    output cs_o_3,
+    //
+    input  miso_i_4,
+    input  alertl_i_4,
+    output sclk_o_4,
+    output mosi_o_4,
+    output cs_o_4,
+    //
+    input  miso_i_5,
+    input  alertl_i_5,
+    output sclk_o_5,
+    output mosi_o_5,
+    output cs_o_5,
+    //
+    input  miso_i_6,
+    input  alertl_i_6,
+    output sclk_o_6,
+    output mosi_o_6,
+    output cs_o_6,
+    //
+    input  miso_i_7,
+    input  alertl_i_7,
+    output sclk_o_7,
+    output mosi_o_7,
+    output cs_o_7,
+    //
+    input  miso_i_8,
+    input  alertl_i_8,
+    output sclk_o_8,
+    output mosi_o_8,
+    output cs_o_8,
+    //
+    input  miso_i_9,
+    input  alertl_i_9,
+    output sclk_o_9,
+    output mosi_o_9,
+    output cs_o_9,
+    //
+    input  miso_i_10,
+    input  alertl_i_10,
+    output sclk_o_10,
+    output mosi_o_10,
+    output cs_o_10,
+    //
+    input  miso_i_11,
+    input  alertl_i_11,
+    output sclk_o_11,
+    output mosi_o_11,
+    output cs_o_11
+);
+
+  wire rst_i_sync, poll_dn_w, mclk, en_w, r_w_en_w, mode_i_sync, trf_dn_w, dn_clr;
+  wire [ 5:0] rwaddr_w;
+  wire [10:0] adc_select_w;
+  wire [11:0] poll_dn_bus_w;
+  wire [15:0] wdata_w;
+  wire [23:0] vbus_1,vshunt_1,vbus_2,vshunt_2 ,vbus_3 ,vshunt_3 ,vbus_4 ,vshunt_4 ,vbus_5 ,vshunt_5 ,vbus_6 ,vshunt_6 ;
+  wire [23:0] vbus_7 ,vshunt_7,vbus_8 ,vshunt_8 ,vbus_9 ,vshunt_9 ,vbus_10 ,vshunt_10 ,vbus_11 ,vshunt_11;
+  wire [39:0] rdata_w;
+
+  pll pll_inst (
+      .clock_in (clk_i),
+      .clock_out(mclk)
+  );
+
+  assign led = count[25];
+  reg [25:0] count;
+  initial count = 0;
+  always @(posedge mclk) begin
+    count <= count + 1;
+  end
+
+  spi_s_core spi_s_core_inst (
+      .sclk_i(sl_sclk_i_0),
+      .mosi_i(sl_mosi_i_0),
+      .cs_i(sl_cs_i_0),
+      .miso_o(sl_miso_o_0),
+      //
+      .mclk_i(mclk),
+      .rst_i(rst_i_sync),
+      .en_o(en_w),
+      .rwaddr_o(rwaddr_w),
+      .adc_sel_o(adc_select_w),
+      .wdata_o(wdata_w),
+      .r_w_en_o(r_w_en_w),
+      .data_valid_o(data_valid_o),
+      .mode_i(mode_i_sync),
+      .rdata_i(rdata_w),
+      .poll_dn_i(poll_dn_w),
+      .dn_i(trf_dn_w),
+      .dn_clr_o(dn_clr),
+      .vbus_1(vbus_1),
+      .vshunt_1(vshunt_1),
+      .vbus_2(vbus_2),
+      .vshunt_2(vshunt_2),
+      .vbus_3(vbus_3),
+      .vshunt_3(vshunt_3),
+      .vbus_4(vbus_4),
+      .vshunt_4(vshunt_4),
+      .vbus_5(vbus_5),
+      .vshunt_5(vshunt_5),
+      .vbus_6(vbus_6),
+      .vshunt_6(vshunt_6),
+      .vbus_7(vbus_7),
+      .vshunt_7(vshunt_7),
+      .vbus_8(vbus_8),
+      .vshunt_8(vshunt_8),
+      .vbus_9(vbus_9),
+      .vshunt_9(vshunt_9),
+      .vbus_10(vbus_10),
+      .vshunt_10(vshunt_10),
+      .vbus_11(vbus_11),
+      .vshunt_11(vshunt_11)
+  );
+  //
+  // .vbus_1(1),// vbus_1),
+  // .vshunt_1(2),
+  // .vbus_2(3),
+  // .vshunt_2(4),
+  // .vbus_3(5),
+  // .vshunt_3(6),
+  // .vbus_4(7),
+  // .vshunt_4(8),
+  // .vbus_5(9),
+  // .vshunt_5(10),
+  // .vbus_6(11),
+  // .vshunt_6(12),
+  // .vbus_7(13),
+  // .vshunt_7(14),
+  // .vbus_8(15),
+  // .vshunt_8(16),
+  // .vbus_9(17),
+  // .vshunt_9(19),
+  // .vbus_10(20),
+  // .vshunt_10(21),
+  // .vbus_11(22),
+  // .vshunt_11(23));
+
+
+  rst_sync rst_sync_inst (
+      .clk_i(mclk),
+      .rst_i(rst_i),
+      .rst_o(rst_i_sync)
+  );
+
+  sig_sync op_mode_sync (
+      .clk_i(mclk),
+      .rst_i(rst_i_sync),
+      .sig_i(op_mode_i),
+      .sig_o(mode_i_sync)
+  );
+
+  csa_ctl_top csa_ctl_top_inst (
+      .mclk_i(mclk),
+      .rst_i(rst_i_sync),
+      .r_w_en_i(r_w_en_w),
+      .en_i(en_w),
+      .mode_i(mode_i_sync),
+      .rwaddr_i(rwaddr_w),
+      .adc_sel_i(adc_select_w),
+      .wdata_i(wdata_w),
+      .dn_o(trf_dn_w),
+      .rdata_o(rdata_w),
+      //
+      .dn_clr_i(dn_clr),  // Use to clear data-valid. Short to trf_dn_o of spi core.
+      .poll_dn_o(poll_dn_w),
+      // .poll_dn(),// NC. Only for bringup
+      // spi
+      .miso_i_1(miso_i_1),
+      .alertl_i_1(alertl_i_1),
+      .sclk_o_1(sclk_o_1),
+      .mosi_o_1(mosi_o_1),
+      .cs_o_1(cs_o_1),
+      .miso_i_2(miso_i_2),
+      .alertl_i_2(alertl_i_2),
+      .sclk_o_2(sclk_o_2),
+      .mosi_o_2(mosi_o_2),
+      .cs_o_2(cs_o_2),
+      .miso_i_3(miso_i_3),
+      .alertl_i_3(alertl_i_3),
+      .sclk_o_3(sclk_o_3),
+      .mosi_o_3(mosi_o_3),
+      .cs_o_3(cs_o_3),
+      .miso_i_4(miso_i_4),
+      .alertl_i_4(alertl_i_4),
+      .sclk_o_4(sclk_o_4),
+      .mosi_o_4(mosi_o_4),
+      .cs_o_4(cs_o_4),
+      .miso_i_5(miso_i_5),
+      .alertl_i_5(alertl_i_5),
+      .sclk_o_5(sclk_o_5),
+      .mosi_o_5(mosi_o_5),
+      .cs_o_5(cs_o_5),
+      .miso_i_6(miso_i_6),
+      .alertl_i_6(alertl_i_6),
+      .sclk_o_6(sclk_o_6),
+      .mosi_o_6(mosi_o_6),
+      .cs_o_6(cs_o_6),
+      .miso_i_7(miso_i_7),
+      .alertl_i_7(alertl_i_7),
+      .sclk_o_7(sclk_o_7),
+      .mosi_o_7(mosi_o_7),
+      .cs_o_7(cs_o_7),
+      .miso_i_8(miso_i_8),
+      .alertl_i_8(alertl_i_8),
+      .sclk_o_8(sclk_o_8),
+      .mosi_o_8(mosi_o_8),
+      .cs_o_8(cs_o_8),
+      .miso_i_9(miso_i_9),
+      .alertl_i_9(alertl_i_9),
+      .sclk_o_9(sclk_o_9),
+      .mosi_o_9(mosi_o_9),
+      .cs_o_9(cs_o_9),
+      .miso_i_10(miso_i_10),
+      .alertl_i_10(alertl_i_10),
+      .sclk_o_10(sclk_o_10),
+      .mosi_o_10(mosi_o_10),
+      .cs_o_10(cs_o_10),
+      .miso_i_11(miso_i_11),
+      .alertl_i_11(alertl_i_11),
+      .sclk_o_11(sclk_o_11),
+      .mosi_o_11(mosi_o_11),
+      .cs_o_11(cs_o_11),
+      //
+      .vbus_1(vbus_1),
+      .vshunt_1(vshunt_1),
+      .vbus_2(vbus_2),
+      .vshunt_2(vshunt_2),
+      .vbus_3(vbus_3),
+      .vshunt_3(vshunt_3),
+      .vbus_4(vbus_4),
+      .vshunt_4(vshunt_4),
+      .vbus_5(vbus_5),
+      .vshunt_5(vshunt_5),
+      .vbus_6(vbus_6),
+      .vshunt_6(vshunt_6),
+      .vbus_7(vbus_7),
+      .vshunt_7(vshunt_7),
+      .vbus_8(vbus_8),
+      .vshunt_8(vshunt_8),
+      .vbus_9(vbus_9),
+      .vshunt_9(vshunt_9),
+      .vbus_10(vbus_10),
+      .vshunt_10(vshunt_10),
+      .vbus_11(vbus_11),
+      .vshunt_11(vshunt_11)
+  );
+
+endmodule