From 9bcb64a8a93446bc81b0090e08d6595c3a7cae20 Mon Sep 17 00:00:00 2001
From: dwf1m12 <d.w.flynn@soton.ac.uk>
Date: Mon, 4 Dec 2023 22:05:43 +0000
Subject: [PATCH] test/diagnostic pad configuration prototype added

---
 .../nanosoc_chip/chip/verilog/nanosoc_chip.v  |   2 +-
 .../pads/glib/verilog/nanosoc_chip_pads.v     | 643 +++++++++++++-----
 verif/tb/verilog/nanosoc_tb.v                 |  14 +-
 verif/tb/verilog/nanosoc_tb_qs.v              |   4 +-
 4 files changed, 498 insertions(+), 165 deletions(-)

diff --git a/nanosoc/nanosoc_chip/chip/verilog/nanosoc_chip.v b/nanosoc/nanosoc_chip/chip/verilog/nanosoc_chip.v
index 4981b33..3c55d72 100644
--- a/nanosoc/nanosoc_chip/chip/verilog/nanosoc_chip.v
+++ b/nanosoc/nanosoc_chip/chip/verilog/nanosoc_chip.v
@@ -65,7 +65,7 @@ module nanosoc_chip #(
   // Scan Wiring
   wire                     SYS_SCANENABLE;      // Scan Mode Enable
   wire                     SYS_TESTMODE;        // Test Mode Enable (Override Synchronisers)
-  wire                     SYS_SCANINHCLK;      // HCLK scan wire
+  wire                     SYS_SCANINHCLK;      // HCLK scan wire - TIE OFF
   wire                     SYS_SCANOUTHCLK;     // Scan Chain Output - UNUSED
   
   // Serial-Wire Debug
diff --git a/nanosoc/nanosoc_chip/pads/glib/verilog/nanosoc_chip_pads.v b/nanosoc/nanosoc_chip/pads/glib/verilog/nanosoc_chip_pads.v
index 6c11506..39b81d6 100644
--- a/nanosoc/nanosoc_chip/pads/glib/verilog/nanosoc_chip_pads.v
+++ b/nanosoc/nanosoc_chip/pads/glib/verilog/nanosoc_chip_pads.v
@@ -56,23 +56,121 @@ module nanosoc_chip_pads (
 //------------------------------------
 // internal wires
 
-  wire          clk_i;
-  wire          test_i;
-  wire          nrst_i;
-  wire  [15:0]  p0_i; // level-shifted input from pad
-  wire  [15:0]  p0_o; // output port drive
-  wire  [15:0]  p0_e; // active high output drive enable (pad tech dependent)
-  wire  [15:0]  p0_z; // active low output drive enable (pad tech dependent)
-  wire  [15:0]  p1_i; // level-shifted input from pad
-  wire  [15:0]  p1_o; // output port drive
-  wire  [15:0]  p1_e; // active high output drive enable (pad tech dependent)
-  wire  [15:0]  p1_z; // active low output drive enable (pad tech dependent)
-
-  wire          swdio_i;
-  wire          swdio_o;
-  wire          swdio_e;
-  wire          swdio_z;
-  wire          swdclk_i;
+localparam GPIO_TIO = 4;
+
+wire        pad_clk_i;
+wire        pad_nrst_i;
+wire        pad_test_i;
+wire        pad_swdclk_i;
+wire        pad_swdio_i;
+wire        pad_swdio_o;
+wire        pad_swdio_e;
+wire        pad_swdio_z;
+wire [15:0] pad_gpio_port0_i ; 
+wire [15:0] pad_gpio_port0_o ;
+wire [15:0] pad_gpio_port0_e ;
+wire [15:0] pad_gpio_port0_z ;
+wire [15:0] pad_gpio_port1_i ;
+wire [15:0] pad_gpio_port1_o ;
+wire [15:0] pad_gpio_port1_e ;
+wire [15:0] pad_gpio_port1_z ;
+wire        soc_nreset;
+wire        soc_diag_mode;
+wire        soc_diag_ctrl;
+wire        soc_scan_mode;
+wire        soc_scan_enable;
+wire [GPIO_TIO-1:0] soc_scan_in; //soc test status outputs
+wire [GPIO_TIO-1:0] soc_scan_out; //soc test status outputs
+wire        soc_bist_mode;
+wire        soc_bist_enable;
+wire [GPIO_TIO-1:0] soc_bist_in; //soc test status outputs
+wire [GPIO_TIO-1:0] soc_bist_out; //soc test status outputs
+wire        soc_alt_mode; // ALT MODE = UART
+wire        soc_uart_rxd_i; // UART RXD
+wire        soc_uart_txd_o = 1'b1; // UART TXD
+wire        soc_swd_mode; // SWD mode
+wire        soc_swd_clk_i; // SWDCLK
+wire        soc_swd_dio_i; // SWDIO tristate input
+wire        soc_swd_dio_o; // SWDIO trstate output
+wire        soc_swd_dio_e; // SWDIO tristate output enable
+wire        soc_swd_dio_z; // SWDIO tristate output hiz
+wire [15:0] soc_gpio_port0_i; // GPIO SOC tristate input
+wire [15:0] soc_gpio_port0_o; // GPIO SOC trstate output
+wire [15:0] soc_gpio_port0_e; // GPIO SOC tristate output enable
+wire [15:0] soc_gpio_port0_z; // GPIO SOC tristate output hiz
+wire [15:0] soc_gpio_port1_i; // GPIO SOC tristate input
+wire [15:0] soc_gpio_port1_o; // GPIO SOC trstate output
+wire [15:0] soc_gpio_port1_e; // GPIO SOC tristate output enable
+wire [15:0] soc_gpio_port1_z; // GPIO SOC tristate output hiz
+
+// connect up high order GPIOs
+assign soc_gpio_port0_i[15:GPIO_TIO] = pad_gpio_port0_i[15:GPIO_TIO];
+assign pad_gpio_port0_o[15:GPIO_TIO] = soc_gpio_port0_o[15:GPIO_TIO];
+assign pad_gpio_port0_e[15:GPIO_TIO] = soc_gpio_port0_e[15:GPIO_TIO];
+assign pad_gpio_port0_z[15:GPIO_TIO] = soc_gpio_port0_z[15:GPIO_TIO];
+assign soc_gpio_port1_i[15:GPIO_TIO] = pad_gpio_port1_i[15:GPIO_TIO];
+assign pad_gpio_port1_o[15:GPIO_TIO] = soc_gpio_port1_o[15:GPIO_TIO];
+assign pad_gpio_port1_e[15:GPIO_TIO] = soc_gpio_port1_e[15:GPIO_TIO];
+assign pad_gpio_port1_z[15:GPIO_TIO] = soc_gpio_port1_z[15:GPIO_TIO];
+
+wire tiehi = 1'b1;
+wire tielo = 1'b0;
+
+nanosoc_chip_cfg #(
+    .GPIO_TIO (GPIO_TIO)
+  )
+  u_nanosoc_chip_cfg
+  (
+  // Primary Inputs
+   .pad_clk_i        (pad_clk_i         )
+  ,.pad_nrst_i       (pad_nrst_i        )
+  ,.pad_test_i       (pad_test_i        )
+  // Alternate/reconfigurable IP and associated bidirectional I/O
+  ,.pad_altin_i      (pad_swdclk_i      )  // SWCLK/UARTRXD/SCAN-ENABLE
+  ,.pad_altio_i      (pad_swdio_i       )  // SWDIO/UARTTXD tristate input
+  ,.pad_altio_o      (pad_swdio_o       )  // SWDIO/UARTTXD trstate output
+  ,.pad_altio_e      (pad_swdio_e       )  // SWDIO/UARTTXD tristate output enable
+  ,.pad_altio_z      (pad_swdio_z       )  // SWDIO/UARTTXD tristate output hiz
+  // Reconfigurable General Purpose bidirectional I/Os Port-0 (user)
+  ,.pad_gpio_port0_i (pad_gpio_port0_i[GPIO_TIO-1:0]) // GPIO PAD tristate input
+  ,.pad_gpio_port0_o (pad_gpio_port0_o[GPIO_TIO-1:0]) // GPIO PAD trstate output
+  ,.pad_gpio_port0_e (pad_gpio_port0_e[GPIO_TIO-1:0]) // GPIO PAD tristate output enable
+  ,.pad_gpio_port0_z (pad_gpio_port0_z[GPIO_TIO-1:0]) // GPIO PAD tristate output hiz
+  // Reconfigurable General Purpose bidirectional I/Os Port-1 (system)
+  ,.pad_gpio_port1_i (pad_gpio_port1_i[GPIO_TIO-1:0]) // GPIO PAD tristate input
+  ,.pad_gpio_port1_o (pad_gpio_port1_o[GPIO_TIO-1:0]) // GPIO PAD trstate output
+  ,.pad_gpio_port1_e (pad_gpio_port1_e[GPIO_TIO-1:0]) // GPIO PAD tristate output enable
+  ,.pad_gpio_port1_z (pad_gpio_port1_z[GPIO_TIO-1:0]) // GPIO PAD tristate output hiz
+  //SOC
+  ,.soc_nreset       (soc_nreset        )
+  ,.soc_diag_mode    (soc_diag_mode     )
+  ,.soc_diag_ctrl    (soc_diag_ctrl     )
+  ,.soc_scan_mode    (soc_scan_mode     )
+  ,.soc_scan_enable  (soc_scan_enable   )
+  ,.soc_scan_in      (soc_scan_in       ) // soc test scan chain inputs
+  ,.soc_scan_out     (soc_scan_out      ) // soc test scan chain outputs
+  ,.soc_bist_mode    (soc_bist_mode     )
+  ,.soc_bist_enable  (soc_bist_enable   )
+  ,.soc_bist_in      (soc_bist_in       ) // soc bist control inputs
+  ,.soc_bist_out     (soc_bist_out      ) // soc test status outputs
+  ,.soc_alt_mode     (soc_alt_mode      )// ALT MODE = UART
+  ,.soc_uart_rxd_i   (soc_uart_rxd_i    ) // UART RXD
+  ,.soc_uart_txd_o   (soc_uart_txd_o    ) // UART TXD
+  ,.soc_swd_mode     (soc_swd_mode      ) // SWD mode
+  ,.soc_swd_clk_i    (soc_swd_clk_i     ) // SWDCLK
+  ,.soc_swd_dio_i    (soc_swd_dio_i     ) // SWDIO tristate input
+  ,.soc_swd_dio_o    (soc_swd_dio_o     ) // SWDIO trstate output
+  ,.soc_swd_dio_e    (soc_swd_dio_e     ) // SWDIO tristate output enable
+  ,.soc_swd_dio_z    (soc_swd_dio_z     ) // SWDIO tristate output hiz
+  ,.soc_gpio_port0_i (soc_gpio_port0_i[GPIO_TIO-1:0]) // GPIO SOC tristate input
+  ,.soc_gpio_port0_o (soc_gpio_port0_o[GPIO_TIO-1:0]) // GPIO SOC trstate output
+  ,.soc_gpio_port0_e (soc_gpio_port0_e[GPIO_TIO-1:0]) // GPIO SOC tristate output enable
+  ,.soc_gpio_port0_z (soc_gpio_port0_z[GPIO_TIO-1:0]) // GPIO SOC tristate output hiz
+  ,.soc_gpio_port1_i (soc_gpio_port1_i[GPIO_TIO-1:0]) // GPIO SOC tristate input
+  ,.soc_gpio_port1_o (soc_gpio_port1_o[GPIO_TIO-1:0]) // GPIO SOC trstate output
+  ,.soc_gpio_port1_e (soc_gpio_port1_e[GPIO_TIO-1:0]) // GPIO SOC tristate output enable
+  ,.soc_gpio_port1_z (soc_gpio_port1_z[GPIO_TIO-1:0]) // GPIO SOC tristate output hiz
+);
 
  // --------------------------------------------------------------------------------
  // Cortex-M0 nanosoc Microcontroller
@@ -80,50 +178,45 @@ module nanosoc_chip_pads (
 
   nanosoc_chip u_nanosoc_chip (
 `ifdef POWER_PINS
-  .VDD        (VDD),
-  .VSS        (VSS),
-  .VDDACC     (VDDACC),
+  .VDD         (VDD),
+  .VSS         (VSS),
+  .VDDACC      (VDDACC),
 `endif
 `ifdef ASIC_TEST_PORTS
-  .diag_mode   (1'b0),
-  .diag_ctrl   (1'b0),
-  .scan_mode   (1'b0),
-  .scan_enable (1'b0),
-  .scan_in     (4'b0000), // soc test scan chain inputs
-  .scan_out    ( ),       // soc test scan chain outputs
-  .bist_mode   (1'b0),
-  .bist_enable (1'b0),
-  .bist_in     (4'b0000), // soc bist control inputs
-  .bist_out    ( ),       // soc test status outputs
-  .alt_mode    (1'b0),    // ALT MODE = UART
-  .uart_rxd_i  (1'b1),    // UART RXD
-  .uart_txd_o  ( ),       // UART TXD
-  .swd_mode    (1'b1),    // SWD mode
+  .diag_mode   (soc_diag_mode     ),
+  .diag_ctrl   (soc_diag_ctrl     ),
+  .scan_mode   (soc_scan_mode     ),
+  .scan_enable (soc_scan_enable   ),
+  .scan_in     (soc_scan_in       ), // soc test scan chain inputs
+  .scan_out    (soc_scan_out      ),       // soc test scan chain outputs
+  .bist_mode   (soc_bist_mode     ),
+  .bist_enable (soc_bist_enable   ),
+  .bist_in     (soc_bist_in       ), // soc bist control inputs
+  .bist_out    (soc_bist_out      ),       // soc test status outputs
+  .alt_mode    (soc_alt_mode      )// ALT MODE = UART
+  .uart_rxd_i  (soc_uart_rxd_i    ) // UART RXD
+  .uart_txd_o  (soc_uart_txd_o    ) // UART TXD
+  .swd_mode    (soc_swd_mode      ),    // SWD mode
 `endif
-  .clk_i(clk_i),
-  .test_i(test_i),
-  .nrst_i(nrst_i),
-  .p0_i(p0_i), // level-shifted input from pad
-  .p0_o(p0_o), // output port drive
-  .p0_e(p0_e), // active high output drive enable (pad tech dependent)
-  .p0_z(p0_z), // active low output drive enable (pad tech dependent)
-  .p1_i(p1_i), // level-shifted input from pad
-  .p1_o(p1_o), // output port drive
-  .p1_e(p1_e), // active high output drive enable (pad tech dependent)
-  .p1_z(p1_z), // active low output drive enable (pad tech dependent)
-  .swdio_i(swdio_i),
-  .swdio_o(swdio_o),
-  .swdio_e(swdio_e),
-  .swdio_z(swdio_z),
-  .swdclk_i(swdclk_i)
+  .clk_i       (pad_clk_i),
+  .test_i      (soc_scan_mode), //(test_i),
+  .nrst_i      (soc_nreset), //(nrst_i),
+  .p0_i        (soc_gpio_port0_i), // level-shifted input from pad
+  .p0_o        (soc_gpio_port0_o), // output port drive
+  .p0_e        (soc_gpio_port0_e), // active high output drive enable (pad tech dependent)
+  .p0_z        (soc_gpio_port0_z), // active low output drive enable (pad tech dependent)
+  .p1_i        (soc_gpio_port1_i), // level-shifted input from pad
+  .p1_o        (soc_gpio_port1_o), // output port drive
+  .p1_e        (soc_gpio_port1_e), // active high output drive enable (pad tech dependent)
+  .p1_z        (soc_gpio_port1_z), // active low output drive enable (pad tech dependent)
+  .swdio_i     (soc_swd_dio_i),
+  .swdio_o     (soc_swd_dio_o),
+  .swdio_e     (soc_swd_dio_e),
+  .swdio_z     (soc_swd_dio_z),
+  .swdclk_i    (soc_swd_clk_i)
   );
 
 
-//TIE_HI uTIEHI (.tiehi(tiehi));
- wire tiehi = 1'b1;
-//TIE_LO uTIELO (.tielo(tielo));
- wire tielo = 1'b0;
-
  // --------------------------------------------------------------------------------
  // IO pad (GLIB Generic Library napping)
  // --------------------------------------------------------------------------------
@@ -160,35 +253,35 @@ PAD_VDDSOC uPAD_VDDACC_1(
 PAD_INOUT8MA_NOE uPAD_CLK_I (
    .PAD (CLK), 
    .O   (tielo),
-   .I   (clk_i), 
+   .I   (pad_clk_i), 
    .NOE (tiehi)
    );
 
 PAD_INOUT8MA_NOE uPAD_XTAL_I (
    .PAD (TEST), 
    .O   (tielo),
-   .I   (test_i), 
+   .I   (pad_test_i), 
    .NOE (tiehi)
    );
 
 PAD_INOUT8MA_NOE uPAD_NRST_I (
    .PAD (NRST), 
    .O   (tielo),
-   .I   (nrst_i), 
+   .I   (pad_nrst_i), 
    .NOE (tiehi)
    );
 
 PAD_INOUT8MA_NOE uPAD_SWDIO_IO (
    .PAD (SWDIO), 
-   .O   (swdio_o), 
-   .I   (swdio_i),
-   .NOE (swdio_z)
+   .O   (pad_swdio_o), 
+   .I   (pad_swdio_i),
+   .NOE (pad_swdio_z)
    );
 
 PAD_INOUT8MA_NOE uPAD_SWDCK_I (
    .PAD (SWDCK), 
    .O   (tielo), 
-   .I   (swdclk_i),
+   .I   (pad_swdclk_i),
    .NOE (tiehi)
    );
 
@@ -196,231 +289,465 @@ PAD_INOUT8MA_NOE uPAD_SWDCK_I (
 
 PAD_INOUT8MA_NOE uPAD_P0_00 (
    .PAD (P0[00]), 
-   .O   (p0_o[00]), 
-   .I   (p0_i[00]),
-   .NOE (p0_z[00])
+   .O   (pad_gpio_port0_o[00]), 
+   .I   (pad_gpio_port0_i[00]),
+   .NOE (pad_gpio_port0_z[00])
    );
 
 PAD_INOUT8MA_NOE uPAD_P0_01 (
    .PAD (P0[01]), 
-   .O   (p0_o[01]), 
-   .I   (p0_i[01]),
-   .NOE (p0_z[01])
+   .O   (pad_gpio_port0_o[01]), 
+   .I   (pad_gpio_port0_i[01]),
+   .NOE (pad_gpio_port0_z[01])
    );
   
 PAD_INOUT8MA_NOE uPAD_P0_02 (
    .PAD (P0[02]), 
-   .O   (p0_o[02]), 
-   .I   (p0_i[02]),
-   .NOE (p0_z[02])
+   .O   (pad_gpio_port0_o[02]), 
+   .I   (pad_gpio_port0_i[02]),
+   .NOE (pad_gpio_port0_z[02])
    );
 
 PAD_INOUT8MA_NOE uPAD_P0_03 (
    .PAD (P0[03]), 
-   .O   (p0_o[03]), 
-   .I   (p0_i[03]),
-   .NOE (p0_z[03])
+   .O   (pad_gpio_port0_o[03]), 
+   .I   (pad_gpio_port0_i[03]),
+   .NOE (pad_gpio_port0_z[03])
    );
 
 PAD_INOUT8MA_NOE uPAD_P0_04 (
    .PAD (P0[04]), 
-   .O   (p0_o[04]), 
-   .I   (p0_i[04]),
-   .NOE (p0_z[04])
+   .O   (pad_gpio_port0_o[04]), 
+   .I   (pad_gpio_port0_i[04]),
+   .NOE (pad_gpio_port0_z[04])
    );
 
 PAD_INOUT8MA_NOE uPAD_P0_05 (
    .PAD (P0[05]), 
-   .O   (p0_o[05]), 
-   .I   (p0_i[05]),
-   .NOE (p0_z[05])
+   .O   (pad_gpio_port0_o[05]), 
+   .I   (pad_gpio_port0_i[05]),
+   .NOE (pad_gpio_port0_z[05])
    );
   
 PAD_INOUT8MA_NOE uPAD_P0_06 (
    .PAD (P0[06]), 
-   .O   (p0_o[06]), 
-   .I   (p0_i[06]),
-   .NOE (p0_z[06])
+   .O   (pad_gpio_port0_o[06]), 
+   .I   (pad_gpio_port0_i[06]),
+   .NOE (pad_gpio_port0_z[06])
    );
 
 PAD_INOUT8MA_NOE uPAD_P0_07 (
    .PAD (P0[07]), 
-   .O   (p0_o[07]), 
-   .I   (p0_i[07]),
-   .NOE (p0_z[07])
+   .O   (pad_gpio_port0_o[07]), 
+   .I   (pad_gpio_port0_i[07]),
+   .NOE (pad_gpio_port0_z[07])
    );
   
 PAD_INOUT8MA_NOE uPAD_P0_08 (
    .PAD (P0[08]), 
-   .O   (p0_o[08]), 
-   .I   (p0_i[08]),
-   .NOE (p0_z[08])
+   .O   (pad_gpio_port0_o[08]), 
+   .I   (pad_gpio_port0_i[08]),
+   .NOE (pad_gpio_port0_z[08])
    );
 
 PAD_INOUT8MA_NOE uPAD_P0_09 (
    .PAD (P0[09]), 
-   .O   (p0_o[09]), 
-   .I   (p0_i[09]),
-   .NOE (p0_z[09])
+   .O   (pad_gpio_port0_o[09]), 
+   .I   (pad_gpio_port0_i[09]),
+   .NOE (pad_gpio_port0_z[09])
    );
   
 PAD_INOUT8MA_NOE uPAD_P0_10 (
    .PAD (P0[10]), 
-   .O   (p0_o[10]), 
-   .I   (p0_i[10]),
-   .NOE (p0_z[10])
+   .O   (pad_gpio_port0_o[10]), 
+   .I   (pad_gpio_port0_i[10]),
+   .NOE (pad_gpio_port0_z[10])
    );
 
 PAD_INOUT8MA_NOE uPAD_P0_11 (
    .PAD (P0[11]), 
-   .O   (p0_o[11]), 
-   .I   (p0_i[11]),
-   .NOE (p0_z[11])
+   .O   (pad_gpio_port0_o[11]), 
+   .I   (pad_gpio_port0_i[11]),
+   .NOE (pad_gpio_port0_z[11])
    );
   
 PAD_INOUT8MA_NOE uPAD_P0_12 (
    .PAD (P0[12]), 
-   .O   (p0_o[12]), 
-   .I   (p0_i[12]),
-   .NOE (p0_z[12])
+   .O   (pad_gpio_port0_o[12]), 
+   .I   (pad_gpio_port0_i[12]),
+   .NOE (pad_gpio_port0_z[12])
    );
 
 PAD_INOUT8MA_NOE uPAD_P0_13 (
    .PAD (P0[13]), 
-   .O   (p0_o[13]), 
-   .I   (p0_i[13]),
-   .NOE (p0_z[13])
+   .O   (pad_gpio_port0_o[13]), 
+   .I   (pad_gpio_port0_i[13]),
+   .NOE (pad_gpio_port0_z[13])
    );
   
 PAD_INOUT8MA_NOE uPAD_P0_14 (
    .PAD (P0[14]), 
-   .O   (p0_o[14]), 
-   .I   (p0_i[14]),
-   .NOE (p0_z[14])
+   .O   (pad_gpio_port0_o[14]), 
+   .I   (pad_gpio_port0_i[14]),
+   .NOE (pad_gpio_port0_z[14])
    );
 
 PAD_INOUT8MA_NOE uPAD_P0_15 (
    .PAD (P0[15]), 
-   .O   (p0_o[15]), 
-   .I   (p0_i[15]),
-   .NOE (p0_z[15])
+   .O   (pad_gpio_port0_o[15]), 
+   .I   (pad_gpio_port0_i[15]),
+   .NOE (pad_gpio_port0_z[15])
    );
   
 // GPI.I Port 1 x 16
 
 PAD_INOUT8MA_NOE uPAD_P1_00 (
    .PAD (P1[00]), 
-   .O   (p1_o[00]), 
-   .I   (p1_i[00]),
-   .NOE (p1_z[00])
+   .O   (pad_gpio_port1_o[00]), 
+   .I   (pad_gpio_port1_i[00]),
+   .NOE (pad_gpio_port1_z[00])
    );
 
 PAD_INOUT8MA_NOE uPAD_P1_01 (
    .PAD (P1[01]), 
-   .O   (p1_o[01]), 
-   .I   (p1_i[01]),
-   .NOE (p1_z[01])
+   .O   (pad_gpio_port1_o[01]), 
+   .I   (pad_gpio_port1_i[01]),
+   .NOE (pad_gpio_port1_z[01])
    );
   
 PAD_INOUT8MA_NOE uPAD_P1_02 (
    .PAD (P1[02]), 
-   .O   (p1_o[02]), 
-   .I   (p1_i[02]),
-   .NOE (p1_z[02])
+   .O   (pad_gpio_port1_o[02]), 
+   .I   (pad_gpio_port1_i[02]),
+   .NOE (pad_gpio_port1_z[02])
    );
 
 PAD_INOUT8MA_NOE uPAD_P1_03 (
    .PAD (P1[03]), 
-   .O   (p1_o[03]), 
-   .I   (p1_i[03]),
-   .NOE (p1_z[03])
+   .O   (pad_gpio_port1_o[03]), 
+   .I   (pad_gpio_port1_i[03]),
+   .NOE (pad_gpio_port1_z[03])
    );
 
 PAD_INOUT8MA_NOE uPAD_P1_04 (
    .PAD (P1[04]), 
-   .O   (p1_o[04]), 
-   .I   (p1_i[04]),
-   .NOE (p1_z[04])
+   .O   (pad_gpio_port1_o[04]), 
+   .I   (pad_gpio_port1_i[04]),
+   .NOE (pad_gpio_port1_z[04])
    );
 
 PAD_INOUT8MA_NOE uPAD_P1_05 (
    .PAD (P1[05]), 
-   .O   (p1_o[05]), 
-   .I   (p1_i[05]),
-   .NOE (p1_z[05])
+   .O   (pad_gpio_port1_o[05]), 
+   .I   (pad_gpio_port1_i[05]),
+   .NOE (pad_gpio_port1_z[05])
    );
   
 PAD_INOUT8MA_NOE uPAD_P1_06 (
    .PAD (P1[06]), 
-   .O   (p1_o[06]), 
-   .I   (p1_i[06]),
-   .NOE (p1_z[06])
+   .O   (pad_gpio_port1_o[06]), 
+   .I   (pad_gpio_port1_i[06]),
+   .NOE (pad_gpio_port1_z[06])
    );
 
 PAD_INOUT8MA_NOE uPAD_P1_07 (
    .PAD (P1[07]), 
-   .O   (p1_o[07]), 
-   .I   (p1_i[07]),
-   .NOE (p1_z[07])
+   .O   (pad_gpio_port1_o[07]), 
+   .I   (pad_gpio_port1_i[07]),
+   .NOE (pad_gpio_port1_z[07])
    );
   
 PAD_INOUT8MA_NOE uPAD_P1_08 (
    .PAD (P1[08]), 
-   .O   (p1_o[08]), 
-   .I   (p1_i[08]),
-   .NOE (p1_z[08])
+   .O   (pad_gpio_port1_o[08]), 
+   .I   (pad_gpio_port1_i[08]),
+   .NOE (pad_gpio_port1_z[08])
    );
 
 PAD_INOUT8MA_NOE uPAD_P1_09 (
    .PAD (P1[09]), 
-   .O   (p1_o[09]), 
-   .I   (p1_i[09]),
-   .NOE (p1_z[09])
+   .O   (pad_gpio_port1_o[09]), 
+   .I   (pad_gpio_port1_i[09]),
+   .NOE (pad_gpio_port1_z[09])
    );
   
 PAD_INOUT8MA_NOE uPAD_P1_10 (
    .PAD (P1[10]), 
-   .O   (p1_o[10]), 
-   .I   (p1_i[10]),
-   .NOE (p1_z[10])
+   .O   (pad_gpio_port1_o[10]), 
+   .I   (pad_gpio_port1_i[10]),
+   .NOE (pad_gpio_port1_z[10])
    );
 
 PAD_INOUT8MA_NOE uPAD_P1_11 (
    .PAD (P1[11]), 
-   .O   (p1_o[11]), 
-   .I   (p1_i[11]),
-   .NOE (p1_z[11])
+   .O   (pad_gpio_port1_o[11]), 
+   .I   (pad_gpio_port1_i[11]),
+   .NOE (pad_gpio_port1_z[11])
    );
   
 PAD_INOUT8MA_NOE uPAD_P1_12 (
    .PAD (P1[12]), 
-   .O   (p1_o[12]), 
-   .I   (p1_i[12]),
-   .NOE (p1_z[12])
+   .O   (pad_gpio_port1_o[12]), 
+   .I   (pad_gpio_port1_i[12]),
+   .NOE (pad_gpio_port1_z[12])
    );
 
 PAD_INOUT8MA_NOE uPAD_P1_13 (
    .PAD (P1[13]), 
-   .O   (p1_o[13]), 
-   .I   (p1_i[13]),
-   .NOE (p1_z[13])
+   .O   (pad_gpio_port1_o[13]), 
+   .I   (pad_gpio_port1_i[13]),
+   .NOE (pad_gpio_port1_z[13])
    );
   
 PAD_INOUT8MA_NOE uPAD_P1_14 (
    .PAD (P1[14]), 
-   .O   (p1_o[14]), 
-   .I   (p1_i[14]),
-   .NOE (p1_z[14])
+   .O   (pad_gpio_port1_o[14]), 
+   .I   (pad_gpio_port1_i[14]),
+   .NOE (pad_gpio_port1_z[14])
    );
 
 PAD_INOUT8MA_NOE uPAD_P1_15 (
    .PAD (P1[15]), 
-   .O   (p1_o[15]), 
-   .I   (p1_i[15]),
-   .NOE (p1_z[15])
+   .O   (pad_gpio_port1_o[15]), 
+   .I   (pad_gpio_port1_i[15]),
+   .NOE (pad_gpio_port1_z[15])
    );
 
 endmodule
 
+// A joint work commissioned on behalf of SoC Labs, under Arm Academic Access license.
+//
+// Contributors
+//
+// David Flynn (d.w.flynn@soton.ac.uk)
+//
+// Copyright (c) 2023, SoC Labs (www.soclabs.org)
+//-----------------------------------------------------------------------------
 
+module nanosoc_chip_cfg  #(
+// --------------------------------------------------------------------------
+// Parameter Declarations
+// --------------------------------------------------------------------------
+  parameter GPIO_TIO = 4  // number of GPIO TEST IO pins to reconfigure
+ )
+(
+  // Primary Inputs
+   input  wire                pad_clk_i    // CLK  pad input
+  ,input  wire                pad_nrst_i   // NRST pad input
+  ,input  wire                pad_test_i   // TEST pad input
+  // Alternate/reconfigurable input and associated bidirectional inout
+  ,input  wire                pad_altin_i  // SWCLK/UARTRXD/SCAN-ENABLE
+  ,input  wire                pad_altio_i  // SWDIO/UARTTXD tristate input
+  ,output wire                pad_altio_o  // SWDIO/UARTTXD trstate output
+  ,output wire                pad_altio_e  // SWDIO/UARTTXD tristate output enable
+  ,output wire                pad_altio_z  // SWDIO/UARTTXD tristate output hiz
+  // Reconfigurable General Purpose bidirectional I/Os Port-0 (user)
+  ,input  wire [GPIO_TIO-1:0] pad_gpio_port0_i  // GPIO PAD tristate input
+  ,output wire [GPIO_TIO-1:0] pad_gpio_port0_o  // GPIO PAD trstate output
+  ,output wire [GPIO_TIO-1:0] pad_gpio_port0_e  // GPIO PAD tristate output enable
+  ,output wire [GPIO_TIO-1:0] pad_gpio_port0_z  // GPIO PAD tristate output hiz
+  // Reconfigurable General Purpose bidirectional I/Os Port-1 (system)
+  ,input  wire [GPIO_TIO-1:0] pad_gpio_port1_i  // GPIO PAD tristate input
+  ,output wire [GPIO_TIO-1:0] pad_gpio_port1_o  // GPIO PAD trstate output
+  ,output wire [GPIO_TIO-1:0] pad_gpio_port1_e  // GPIO PAD tristate output enable
+  ,output wire [GPIO_TIO-1:0] pad_gpio_port1_z  // GPIO PAD tristate output hiz
+  //SOC
+  ,output wire                soc_nreset
+  ,output wire                soc_diag_mode
+  ,output wire                soc_diag_ctrl
+  ,output wire                soc_scan_mode
+  ,output wire                soc_scan_enable
+  ,output wire [GPIO_TIO-1:0] soc_scan_in  // soc test scan chain inputs
+  ,input  wire [GPIO_TIO-1:0] soc_scan_out // soc test scan chain outputs
+
+  ,output wire                soc_bist_mode
+  ,output wire                soc_bist_enable
+  ,output wire [GPIO_TIO-1:0] soc_bist_in  // soc bist control inputs
+  ,input  wire [GPIO_TIO-1:0] soc_bist_out // soc test status outputs
+
+  ,output wire                soc_alt_mode    // ALT MODE = UART
+  ,output wire                soc_uart_rxd_i  // UART RXD
+  ,input  wire                soc_uart_txd_o  // UART TXD
+  ,output wire                soc_swd_mode    // SWD mode
+  ,output wire                soc_swd_clk_i   // SWDCLK
+  ,output wire                soc_swd_dio_i   // SWDIO tristate input
+  ,input  wire                soc_swd_dio_o   // SWDIO trstate output
+  ,input  wire                soc_swd_dio_e   // SWDIO tristate output enable
+  ,input  wire                soc_swd_dio_z   // SWDIO tristate output hiz
+
+  ,output wire [GPIO_TIO-1:0] soc_gpio_port0_i  // GPIO SOC tristate input
+  ,input  wire [GPIO_TIO-1:0] soc_gpio_port0_o  // GPIO SOC trstate output
+  ,input  wire [GPIO_TIO-1:0] soc_gpio_port0_e  // GPIO SOC tristate output enable
+  ,input  wire [GPIO_TIO-1:0] soc_gpio_port0_z  // GPIO SOC tristate output hiz
+
+  ,output wire [GPIO_TIO-1:0] soc_gpio_port1_i  // GPIO SOC tristate input
+  ,input  wire [GPIO_TIO-1:0] soc_gpio_port1_o  // GPIO SOC trstate output
+  ,input  wire [GPIO_TIO-1:0] soc_gpio_port1_e  // GPIO SOC tristate output enable
+  ,input  wire [GPIO_TIO-1:0] soc_gpio_port1_z  // GPIO SOC tristate output hiz
+
+);
+
+// --------------------------------------------------------------------------
+// Primary POR/Reset synchronizer
+//  (Active-Low assertion for 9+ valid clocks)
+// generate rising-edge synchornized resets:
+//   nrst_early - early reset initialization of configuration mode state
+//   soc_nrst   - soc reset (8/9-clock cycles after NRST deasserted)
+// --------------------------------------------------------------------------
+
+reg [7:0] sync_nrst_sr; // 8-sbit shift-right shift-reg
+
+  always @(posedge pad_clk_i or negedge pad_nrst_i)
+    if(!pad_nrst_i)
+        sync_nrst_sr <= 8'b00000000;
+    else if (!sync_nrst_sr[0]) // gate clock off after reset complete
+        sync_nrst_sr <= {1'b1, sync_nrst_sr[7:1]};
+
+wire nrst_early = sync_nrst_sr[6]; // 2nd register stage
+
+wire cfg_window = !sync_nrst_sr[0]; // until final register stage
+
+wire cfg_sample  = sync_nrst_sr[6] & !sync_nrst_sr[2]; // safe to sample config modes
+wire cfg_capture = sync_nrst_sr[2] & !sync_nrst_sr[1]; // safe to capture config
+
+// --------------------------------------------------------------------------
+// test control synchronizer
+//    independently synchronized to NRST so -1/0/+1 cyce relationship 
+//  (requires 9+ valid clocks before fully initialised)
+// generate rising-edge synchornized state decodes:
+//   held-low during reset
+//   rising-edge near reset deassertion (ALT-mode entry)
+//   falling-edge near reset deassertion (BIST-mode entry)
+//   held-high during reset (SCAN-mode entry
+// --------------------------------------------------------------------------
+
+reg [7:0] sync_tst_sr; // 8-bit shift-right shift-reg
+// requires 8 clock cycles of reset to flush through as not resettable
+
+  always @(posedge pad_clk_i)
+    if (cfg_window) // gate clock after configuration window
+        sync_tst_sr <= {pad_test_i, sync_tst_sr[7:1]};
+
+wire test_heldlow = !(|sync_tst_sr[6:0]);
+wire test_posedge =  ( sync_tst_sr[4] & !sync_tst_sr[3]);
+wire test_negedge =  (!sync_tst_sr[4] &  sync_tst_sr[3]);
+wire test_heldhi  =   &sync_tst_sr[6:0];
+
+localparam SYSCONFIG  = 2'b00;
+localparam ALTCONFIG  = 2'b01;
+localparam BISTCONFIG = 2'b10;
+localparam SCANCONFIG = 2'b11;
+
+reg [1:0] cfg_mode;
+
+  always @(posedge pad_clk_i or negedge nrst_early)
+    if(!nrst_early) begin
+        cfg_mode <= SYSCONFIG; // //pulldown
+    end else if (cfg_sample) begin
+      if      (test_posedge) cfg_mode <= ALTCONFIG;  // test timed with nrst
+      else if (test_negedge) cfg_mode <= BISTCONFIG; // test timed with !nrst
+      else if (test_heldhi ) cfg_mode <= SCANCONFIG; // pullup
+    end
+
+// --------------------------------------------------------------------------
+
+reg [7:0] sync_alt_sr; // 8-bit shift-right shift-reg
+// requires 8 clock cycles of reset to flush through as not resettable
+
+  always @(posedge pad_clk_i)
+    if (cfg_window) // gate clock after configuration window
+        sync_alt_sr <= {pad_altin_i, sync_alt_sr[7:1]};
+
+wire alt_heldlow  = !(|sync_alt_sr[6:0]);
+wire alt_posedge  =  ( sync_alt_sr[4] & !sync_alt_sr[3]);
+wire alt_negedge  =  (!sync_alt_sr[4] &  sync_alt_sr[3]);
+wire alt_heldhi   =   &sync_alt_sr[6:0];
+
+reg [1:0] cfg_diag;
+
+  always @(posedge pad_clk_i or negedge nrst_early)
+    if(!nrst_early) begin
+        cfg_diag <= 2'b00; // unused - pulldown?
+    end else if (cfg_sample) begin
+      if      (alt_posedge ) cfg_diag <= 2'b01; // alt timed with nrst
+      else if (alt_negedge ) cfg_diag <= 2'b10; // alt timed with !nrst
+//      else if (alt_heldhi  ) cfg_diag <= 2'b11; // unused - pullup?
+    end
+
+// --------------------------------------------------------------------------
+
+reg cfg_sys;
+reg cfg_alt;
+reg cfg_bist;
+reg cfg_scan;
+reg diag_mode;
+reg diag_ctrl;
+
+// (tristated IO depending on pullup/pulldowns when until cnfigured)
+
+  always @(posedge pad_clk_i or negedge nrst_early)
+    if(!nrst_early) begin
+      cfg_sys    <= 1'b0;
+      cfg_alt    <= 1'b0;
+      cfg_bist   <= 1'b0;
+      cfg_scan   <= 1'b0;
+      diag_mode  <= 1'b0;
+      diag_ctrl  <= 1'b0;
+    end else if (cfg_capture) begin
+      case (cfg_mode)
+      SYSCONFIG  : cfg_sys   <= 1'b1;
+      ALTCONFIG  : cfg_alt   <= 1'b1;
+      BISTCONFIG : cfg_bist  <= 1'b1;
+      SCANCONFIG : cfg_scan  <= 1'b1;
+      endcase
+      diag_mode   <= cfg_diag[0]; // !cfg_diag[1] &  cfg_diag[0];
+      diag_ctrl   <= cfg_diag[1]; // cfg_diag[1] & !cfg_diag[0];
+    end
+
+// --------------------------------------------------------------------------
+// SoC IO reconfiguration
+// --------------------------------------------------------------------------
+
+// ungated clock, no PLL/locked gating
+assign soc_nreset = sync_nrst_sr[0];
+
+assign soc_scan_mode    =  cfg_scan;
+assign soc_scan_enable  =  cfg_scan & pad_altin_i;
+assign soc_scan_in      = (cfg_scan) ? pad_gpio_port0_i : {GPIO_TIO{1'b0}};
+
+assign soc_bist_mode    =  cfg_bist;
+assign soc_bist_enable  =  cfg_bist & pad_altin_i;
+assign soc_bist_in      = (cfg_bist) ? pad_gpio_port0_i : {GPIO_TIO{1'b0}};
+
+wire   cfg_scan_or_bist = cfg_scan | cfg_bist;
+
+wire [GPIO_TIO-1:0] scan_or_bist_out = ({GPIO_TIO{cfg_scan}} & soc_scan_out)
+                                     | ({GPIO_TIO{cfg_bist}} & soc_bist_out);
+
+assign pad_gpio_port0_o = (cfg_scan_or_bist) ? {GPIO_TIO{1'b0}} : soc_gpio_port0_o;
+assign pad_gpio_port0_e = (cfg_scan_or_bist) ? {GPIO_TIO{1'b0}} : soc_gpio_port0_e;
+assign pad_gpio_port0_z = ~pad_gpio_port0_e;
+assign soc_gpio_port0_i =  pad_gpio_port0_i;
+
+assign pad_gpio_port1_o = (cfg_scan_or_bist) ? scan_or_bist_out : soc_gpio_port1_o;
+assign pad_gpio_port1_e = (cfg_scan_or_bist) ? {GPIO_TIO{1'b1}} : soc_gpio_port1_e;
+assign pad_gpio_port1_z = ~pad_gpio_port1_e;
+assign soc_gpio_port1_i =  pad_gpio_port1_i;
+
+assign soc_swd_mode = cfg_sys;
+
+assign soc_alt_mode = cfg_alt;
+
+assign soc_swd_clk_i =  cfg_sys & pad_altin_i; // low unless configured
+assign soc_swd_dio_i =  cfg_sys & pad_altio_i;
+
+assign soc_uart_rxd_i =  !cfg_alt | pad_altin_i; // high unless configured
+
+assign pad_altio_o = (cfg_sys & soc_swd_dio_o) | (cfg_alt & soc_uart_txd_o);
+assign pad_altio_e = (cfg_sys & soc_swd_dio_e) | (cfg_alt);
+assign pad_altio_z = !pad_altio_e;
+
+assign soc_diag_mode = diag_mode;
+assign soc_diag_ctrl = diag_ctrl;
 
+endmodule
diff --git a/verif/tb/verilog/nanosoc_tb.v b/verif/tb/verilog/nanosoc_tb.v
index 7dad76f..56decb4 100644
--- a/verif/tb/verilog/nanosoc_tb.v
+++ b/verif/tb/verilog/nanosoc_tb.v
@@ -41,8 +41,11 @@
 module nanosoc_tb;
 
   wire        CLK;   // crystal pin 1
-  wire        TEST;   // crystal pin 2
+  wire        TEST;  // 0 for system usaged
   wire        NRST;    // active low reset
+  wire        NRST_early;  // active low reset
+  wire        NRST_late;   // active low reset
+  wire        NRST_ext;    // active low reset
 
   wire [15:0] P0;      // Port 0
   wire [15:0] P1;      // Port 1
@@ -130,13 +133,13 @@ SROM_Ax32
   nanosoc_clkreset u_nanosoc_clkreset(
   .CLK       (CLK),
   .NRST      (NRST),
-  .NRST_early( ),
-  .NRST_late ( ),
-  .NRST_ext  ( )
+  .NRST_early(NRST_early),
+  .NRST_late (NRST_late),
+  .NRST_ext  (NRST_ext )
   );
   `endif
 
-  assign TEST=1'b0;
+  assign TEST = 1'b0;
   
   // Pullup to suppress X-inputs
   pullup(P0[ 0]);
@@ -173,6 +176,7 @@ SROM_Ax32
   pullup(P1[14]);
   pullup(P1[15]);
 
+
  // --------------------------------------------------------------------------------
  // UART output capture
  // --------------------------------------------------------------------------------
diff --git a/verif/tb/verilog/nanosoc_tb_qs.v b/verif/tb/verilog/nanosoc_tb_qs.v
index 56fe9a8..2b814c8 100644
--- a/verif/tb/verilog/nanosoc_tb_qs.v
+++ b/verif/tb/verilog/nanosoc_tb_qs.v
@@ -40,7 +40,7 @@
 module nanosoc_tb_qs;
 
   wire        CLK;   // crystal pin 1
-  wire        TEST = 1'b0;   // crystal pin 2
+  wire        TEST;  // 0 for system usage
   wire        NRST;    // active low reset
 
   wire [15:0] P0;      // Port 0
@@ -135,6 +135,8 @@ SROM_Ax32
   );
   `endif
 
+  assign TEST = 1'b0;
+
   // Pullup to suppress X-inputs
   pullup(P0[ 0]);
   pullup(P0[ 1]);
-- 
GitLab