From 74c6c043fa2c01e6c4bd622b2ba7e57714cc7aaa Mon Sep 17 00:00:00 2001
From: dwf1m12 <d.w.flynn@soton.ac.uk>
Date: Sun, 26 Mar 2023 21:43:10 +0100
Subject: [PATCH] dev version of example AES128 accelerator , simulates, but
 FPGA build problem?

---
 .../ip_repo/ADPcontrol_1.0/component.xml      |   31 +-
 .../soclabs.org_user_ADPcontrol_1.0.zip       |  Bin 17477 -> 17528 bytes
 .../ip_repo/ADPcontrol_1.0/src/ADPmanager.v   | 1597 +++++----
 .../ip_repo/axi_stream_io_1.0/component.xml   |   54 +-
 .../soclabs.org_user_axi_stream_io_1.0.zip    |  Bin 16165 -> 16438 bytes
 .../fpga_imp/scripts/build_mcu_fpga_ip.tcl    |    1 +
 .../target_fpga_zcu104/design_1_wrapper.v     |   92 +-
 .../target_fpga_zcu104/fpga_pinmap.xdc        |   74 +-
 Cortex-M0/nanosoc/systems/mcu/rtl_sim/adp.cmd |   42 +-
 .../nanosoc/systems/mcu/rtl_sim/makefile      |    2 +-
 .../systems/mcu/verilog/nanosoc_chip.v        |   70 +-
 .../mcu/verilog/soclabs_ahb_aes128_ctrl.v     | 3015 +++++++++++++++++
 IPLIB/ADPcontrol_v1_0/ADPmanager.v            |    4 +-
 13 files changed, 4059 insertions(+), 923 deletions(-)
 create mode 100644 Cortex-M0/nanosoc/systems/mcu/verilog/soclabs_ahb_aes128_ctrl.v

diff --git a/Cortex-M0/nanosoc/systems/mcu/fpga_imp/ip_repo/ADPcontrol_1.0/component.xml b/Cortex-M0/nanosoc/systems/mcu/fpga_imp/ip_repo/ADPcontrol_1.0/component.xml
index 8b10546..d347000 100755
--- a/Cortex-M0/nanosoc/systems/mcu/fpga_imp/ip_repo/ADPcontrol_1.0/component.xml
+++ b/Cortex-M0/nanosoc/systems/mcu/fpga_imp/ip_repo/ADPcontrol_1.0/component.xml
@@ -346,7 +346,7 @@
         <spirit:parameters>
           <spirit:parameter>
             <spirit:name>viewChecksum</spirit:name>
-            <spirit:value>e4d9de63</spirit:value>
+            <spirit:value>d49cf1f2</spirit:value>
           </spirit:parameter>
         </spirit:parameters>
       </spirit:view>
@@ -362,7 +362,7 @@
         <spirit:parameters>
           <spirit:parameter>
             <spirit:name>viewChecksum</spirit:name>
-            <spirit:value>e4d9de63</spirit:value>
+            <spirit:value>d49cf1f2</spirit:value>
           </spirit:parameter>
         </spirit:parameters>
       </spirit:view>
@@ -882,8 +882,8 @@
       </xilinx:taxonomies>
       <xilinx:displayName>ADPcontrol_v1.0</xilinx:displayName>
       <xilinx:autoFamilySupportLevel>level_1</xilinx:autoFamilySupportLevel>
-      <xilinx:coreRevision>28</xilinx:coreRevision>
-      <xilinx:coreCreationDateTime>2023-03-17T11:11:19Z</xilinx:coreCreationDateTime>
+      <xilinx:coreRevision>30</xilinx:coreRevision>
+      <xilinx:coreCreationDateTime>2023-03-26T20:12:13Z</xilinx:coreCreationDateTime>
       <xilinx:tags>
         <xilinx:tag xilinx:name="ui.data.coregen.dd@1d457846_ARCHIVE_LOCATION">c:/Users/dflynn/pynq/ip_repo/ADPcontrol_1.0</xilinx:tag>
         <xilinx:tag xilinx:name="ui.data.coregen.dd@37c19d7d_ARCHIVE_LOCATION">c:/Users/dflynn/pynq/ip_repo/ADPcontrol_1.0</xilinx:tag>
@@ -1405,13 +1405,34 @@
         <xilinx:tag xilinx:name="ui.data.coregen.df@5f536198_ARCHIVE_LOCATION">/home/dwf1m12/soclabs_git_new/nanosoc/Cortex-M0/nanosoc/systems/mcu/fpga_imp/ip_repo/ADPcontrol_1.0</xilinx:tag>
         <xilinx:tag xilinx:name="ui.data.coregen.df@59f8726d_ARCHIVE_LOCATION">/home/dwf1m12/soclabs_git_new/nanosoc/Cortex-M0/nanosoc/systems/mcu/fpga_imp/ip_repo/ADPcontrol_1.0</xilinx:tag>
         <xilinx:tag xilinx:name="ui.data.coregen.df@3a228f4c_ARCHIVE_LOCATION">/home/dwf1m12/soclabs_git_new/nanosoc/Cortex-M0/nanosoc/systems/mcu/fpga_imp/ip_repo/ADPcontrol_1.0</xilinx:tag>
+        <xilinx:tag xilinx:name="ui.data.coregen.df@4b62686b_ARCHIVE_LOCATION">/home/dwf1m12/soclabs_git_new/nanosoc/Cortex-M0/nanosoc/systems/mcu/fpga_imp/ip_repo/ADPcontrol_1.0</xilinx:tag>
+        <xilinx:tag xilinx:name="ui.data.coregen.df@22cf5990_ARCHIVE_LOCATION">/home/dwf1m12/soclabs_git_new/nanosoc/Cortex-M0/nanosoc/systems/mcu/fpga_imp/ip_repo/ADPcontrol_1.0</xilinx:tag>
+        <xilinx:tag xilinx:name="ui.data.coregen.df@2dc36876_ARCHIVE_LOCATION">/home/dwf1m12/soclabs_git_new/nanosoc/Cortex-M0/nanosoc/systems/mcu/fpga_imp/ip_repo/ADPcontrol_1.0</xilinx:tag>
+        <xilinx:tag xilinx:name="ui.data.coregen.df@755c78e0_ARCHIVE_LOCATION">/home/dwf1m12/soclabs_git_new/nanosoc/Cortex-M0/nanosoc/systems/mcu/fpga_imp/ip_repo/ADPcontrol_1.0</xilinx:tag>
+        <xilinx:tag xilinx:name="ui.data.coregen.df@7e696db_ARCHIVE_LOCATION">/home/dwf1m12/soclabs_git_new/nanosoc/Cortex-M0/nanosoc/systems/mcu/fpga_imp/ip_repo/ADPcontrol_1.0</xilinx:tag>
+        <xilinx:tag xilinx:name="ui.data.coregen.df@2487a8ea_ARCHIVE_LOCATION">/home/dwf1m12/soclabs_git_new/nanosoc/Cortex-M0/nanosoc/systems/mcu/fpga_imp/ip_repo/ADPcontrol_1.0</xilinx:tag>
+        <xilinx:tag xilinx:name="ui.data.coregen.df@239bc11f_ARCHIVE_LOCATION">/home/dwf1m12/soclabs_git_new/nanosoc/Cortex-M0/nanosoc/systems/mcu/fpga_imp/ip_repo/ADPcontrol_1.0</xilinx:tag>
+        <xilinx:tag xilinx:name="ui.data.coregen.df@19bc8965_ARCHIVE_LOCATION">/home/dwf1m12/soclabs_git_new/nanosoc/Cortex-M0/nanosoc/systems/mcu/fpga_imp/ip_repo/ADPcontrol_1.0</xilinx:tag>
+        <xilinx:tag xilinx:name="ui.data.coregen.df@4dd7a85f_ARCHIVE_LOCATION">/home/dwf1m12/soclabs_git_new/nanosoc/Cortex-M0/nanosoc/systems/mcu/fpga_imp/ip_repo/ADPcontrol_1.0</xilinx:tag>
+        <xilinx:tag xilinx:name="ui.data.coregen.df@3188363f_ARCHIVE_LOCATION">/home/dwf1m12/soclabs_git_new/nanosoc/Cortex-M0/nanosoc/systems/mcu/fpga_imp/ip_repo/ADPcontrol_1.0</xilinx:tag>
+        <xilinx:tag xilinx:name="ui.data.coregen.df@1bdf84f9_ARCHIVE_LOCATION">/home/dwf1m12/soclabs_git_new/nanosoc/Cortex-M0/nanosoc/systems/mcu/fpga_imp/ip_repo/ADPcontrol_1.0</xilinx:tag>
+        <xilinx:tag xilinx:name="ui.data.coregen.df@42836bd1_ARCHIVE_LOCATION">/home/dwf1m12/soclabs_git_new/nanosoc/Cortex-M0/nanosoc/systems/mcu/fpga_imp/ip_repo/ADPcontrol_1.0</xilinx:tag>
+        <xilinx:tag xilinx:name="ui.data.coregen.df@7ab99bfa_ARCHIVE_LOCATION">/home/dwf1m12/soclabs_git_new/nanosoc/Cortex-M0/nanosoc/systems/mcu/fpga_imp/ip_repo/ADPcontrol_1.0</xilinx:tag>
+        <xilinx:tag xilinx:name="ui.data.coregen.df@7c0521da_ARCHIVE_LOCATION">/home/dwf1m12/soclabs_git_new/nanosoc/Cortex-M0/nanosoc/systems/mcu/fpga_imp/ip_repo/ADPcontrol_1.0</xilinx:tag>
+        <xilinx:tag xilinx:name="ui.data.coregen.df@207e0ff9_ARCHIVE_LOCATION">/home/dwf1m12/soclabs_git_new/nanosoc/Cortex-M0/nanosoc/systems/mcu/fpga_imp/ip_repo/ADPcontrol_1.0</xilinx:tag>
+        <xilinx:tag xilinx:name="ui.data.coregen.df@10fe6d44_ARCHIVE_LOCATION">/home/dwf1m12/soclabs_git_new/nanosoc/Cortex-M0/nanosoc/systems/mcu/fpga_imp/ip_repo/ADPcontrol_1.0</xilinx:tag>
+        <xilinx:tag xilinx:name="ui.data.coregen.df@3030bfdb_ARCHIVE_LOCATION">/home/dwf1m12/soclabs_git_new/nanosoc/Cortex-M0/nanosoc/systems/mcu/fpga_imp/ip_repo/ADPcontrol_1.0</xilinx:tag>
+        <xilinx:tag xilinx:name="ui.data.coregen.df@636c2387_ARCHIVE_LOCATION">/home/dwf1m12/soclabs_git_new/nanosoc/Cortex-M0/nanosoc/systems/mcu/fpga_imp/ip_repo/ADPcontrol_1.0</xilinx:tag>
+        <xilinx:tag xilinx:name="ui.data.coregen.df@50f99d3_ARCHIVE_LOCATION">/home/dwf1m12/soclabs_git_new/nanosoc/Cortex-M0/nanosoc/systems/mcu/fpga_imp/ip_repo/ADPcontrol_1.0</xilinx:tag>
+        <xilinx:tag xilinx:name="ui.data.coregen.df@2383ab98_ARCHIVE_LOCATION">/home/dwf1m12/soclabs_git_new/nanosoc/Cortex-M0/nanosoc/systems/mcu/fpga_imp/ip_repo/ADPcontrol_1.0</xilinx:tag>
+        <xilinx:tag xilinx:name="ui.data.coregen.df@7ff47a8_ARCHIVE_LOCATION">/home/dwf1m12/soclabs_git_new/nanosoc/Cortex-M0/nanosoc/systems/mcu/fpga_imp/ip_repo/ADPcontrol_1.0</xilinx:tag>
       </xilinx:tags>
     </xilinx:coreExtensions>
     <xilinx:packagingInfo>
       <xilinx:xilinxVersion>2021.1</xilinx:xilinxVersion>
       <xilinx:checksum xilinx:scope="busInterfaces" xilinx:value="cf8749a1"/>
       <xilinx:checksum xilinx:scope="addressSpaces" xilinx:value="2ed9224a"/>
-      <xilinx:checksum xilinx:scope="fileGroups" xilinx:value="6203a1ee"/>
+      <xilinx:checksum xilinx:scope="fileGroups" xilinx:value="b17660f5"/>
       <xilinx:checksum xilinx:scope="ports" xilinx:value="2212c402"/>
       <xilinx:checksum xilinx:scope="hdlParameters" xilinx:value="cd165264"/>
       <xilinx:checksum xilinx:scope="parameters" xilinx:value="35656c35"/>
diff --git a/Cortex-M0/nanosoc/systems/mcu/fpga_imp/ip_repo/ADPcontrol_1.0/soclabs.org_user_ADPcontrol_1.0.zip b/Cortex-M0/nanosoc/systems/mcu/fpga_imp/ip_repo/ADPcontrol_1.0/soclabs.org_user_ADPcontrol_1.0.zip
index 3abb2fcb7d874d62c253813441c291e06284c7ab..04eb1f8079b4c7eaab525013d43dac28bac7d6ee 100644
GIT binary patch
delta 15062
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

delta 14970
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

diff --git a/Cortex-M0/nanosoc/systems/mcu/fpga_imp/ip_repo/ADPcontrol_1.0/src/ADPmanager.v b/Cortex-M0/nanosoc/systems/mcu/fpga_imp/ip_repo/ADPcontrol_1.0/src/ADPmanager.v
index 5c6ec0b..f056b75 100755
--- a/Cortex-M0/nanosoc/systems/mcu/fpga_imp/ip_repo/ADPcontrol_1.0/src/ADPmanager.v
+++ b/Cortex-M0/nanosoc/systems/mcu/fpga_imp/ip_repo/ADPcontrol_1.0/src/ADPmanager.v
@@ -1,800 +1,797 @@
-//-----------------------------------------------------------------------------
-// soclabs ASCII Debug Protocol controller
-// A joint work commissioned on behalf of SoC Labs, under Arm Academic Access license.
-//
-// Contributors
-//
-// David Flynn (d.w.flynn@soton.ac.uk)
-//
-// Copyright © 2021-3, SoC Labs (www.soclabs.org)
-//-----------------------------------------------------------------------------
-
-//`define ADPBASIC 1
-
-module ADPmanager // AHB initiator interface
-   #(parameter PROMPT_CHAR          = "]"
-    )
-            ( input  wire                  HCLK,
-              input  wire                  HRESETn,
-              output wire        [31:0]    HADDR32_o,
-              output wire        [ 2:0]    HBURST3_o,
-              output wire                  HMASTLOCK_o,
-              output wire        [ 3:0]    HPROT4_o,
-              output wire        [ 2:0]    HSIZE3_o,
-              output wire        [ 1:0]    HTRANS2_o,
-              output wire        [31:0]    HWDATA32_o,
-              output wire                  HWRITE_o,
-              input  wire         [31:0]   HRDATA32_i,
-              input  wire                  HREADY_i,
-              input  wire                  HRESP_i,
-// COMIO interface
-    output wire [ 7:0] GPO8_o,
-    input  wire [ 7:0] GPI8_i,
-//    input  wire     COM_RXE_i,
-    input  wire [ 7:0] COMRX_TDATA_i,
-    input  wire        COMRX_TVALID_i,
-    output wire        COMRX_TREADY_o,
-//    input  wire     COM_TXF_i,
-    output wire [ 7:0] COMTX_TDATA_o,
-    output wire        COMTX_TVALID_o,
-    input  wire        COMTX_TREADY_i,
-// STDIO interface
-//    input  wire     STDOUT_RXE_i,
-    input  wire [ 7:0] STDRX_TDATA_i,
-    input  wire        STDRX_TVALID_i,
-    output wire        STDRX_TREADY_o,
-//    input  wire     STDIN_TXF_i
-    output wire [ 7:0] STDTX_TDATA_o,
-    output wire        STDTX_TVALID_o,
-    input  wire        STDTX_TREADY_i
-);
-
-wire COM_RXE_i = !COMRX_TVALID_i;
-wire COM_TXF_i = !COMTX_TREADY_i;
-
-//wire adp_rx_req = COMRX_TVALID_i & COMRX_TREADY_o;
-//wire std_rx_req = STDRX_TVALID_i & STDRX_TREADY_o;
-
-
-wire STD_TXF_i = !STDTX_TREADY_i;
-wire STD_RXE_i = !STDRX_TVALID_i;
-
-`ifdef ADPBASIC
-  localparam BANNERHEX = 32'h50c1ab01;
-`else
-  localparam BANNERHEX = 32'h50c1ab03;
-`endif
- 
-localparam CMD_bad = 4'b0000;
-localparam CMD_A   = 4'b0001;  // set Address
-localparam CMD_C   = 4'b0010;  // Control
-localparam CMD_R   = 4'b0011;  // Read word, addr++
-localparam CMD_S   = 4'b0100;  // Status/STDIN
-localparam CMD_W   = 4'b0100;  // Write word, addr++
-localparam CMD_X   = 4'b0101;  // eXit
-`ifndef ADPBASIC
-localparam CMD_F   = 4'b1000;  // Fill (wordocunt) from addr++
-localparam CMD_M   = 4'b1001;  // set read Mask
-localparam CMD_P   = 4'b1010;  // Poll hardware  (count)
-localparam CMD_U   = 4'b1011;  // (Binary) Upload (wordocunt) from addr++
-localparam CMD_V   = 4'b1100;  // match Value
-`endif
-
-
-function FNvalid_adp_entry; // Escape char
-input [7:0] char8;
-  FNvalid_adp_entry = (char8[7:0] ==  8'h1b);
-endfunction
-
-function [3:0] FNvalid_cmd;
-input [7:0] char8;
-case (char8[7:0])
-"A": FNvalid_cmd = CMD_A;
-"a": FNvalid_cmd = CMD_A;
-"C": FNvalid_cmd = CMD_C;
-"c": FNvalid_cmd = CMD_C;
-"R": FNvalid_cmd = CMD_R;
-"r": FNvalid_cmd = CMD_R;
-"S": FNvalid_cmd = CMD_S;
-"s": FNvalid_cmd = CMD_S;
-"W": FNvalid_cmd = CMD_W;
-"w": FNvalid_cmd = CMD_W;
-"X": FNvalid_cmd = CMD_X;
-"x": FNvalid_cmd = CMD_X;
-`ifndef ADPBASIC
-"F": FNvalid_cmd = CMD_F;
-"f": FNvalid_cmd = CMD_F;
-"M": FNvalid_cmd = CMD_M;
-"m": FNvalid_cmd = CMD_M;
-"P": FNvalid_cmd = CMD_P;
-"p": FNvalid_cmd = CMD_P;
-"U": FNvalid_cmd = CMD_U;
-"u": FNvalid_cmd = CMD_U;
-"V": FNvalid_cmd = CMD_V;
-"v": FNvalid_cmd = CMD_V;
-`endif
-default:
-      FNvalid_cmd = 0;
-endcase
-endfunction
-
-function FNvalid_space; // space or tab char
-input [7:0] char8;
-  FNvalid_space = ((char8[7:0] == 8'h20) || (char8[7:0] == 8'h09));
-endfunction
-
-function FNnull; // space or tab char
-input [7:0] char8;
-  FNnull = (char8[7:0] == 8'h00);
-endfunction
-
-function FNexit; // EOF
-input [7:0] char8;
-  FNexit = ((char8[7:0] == 8'h04) || (char8[7:0] == 8'h00));
-endfunction
-
-function FNvalid_EOL; // CR or LF
-input [7:0] char8;
-  FNvalid_EOL = ((char8[7:0] == 8'h0a) || (char8[7:0] == 8'h0d));
-endfunction
-
-function FNuppercase;
-input [7:0] char8;
-  FNuppercase = (char8[6]) ? (char8 & 8'h5f) : (char8);
-endfunction
- 
-function [63:0] FNBuild_param64_hexdigit;
-input [63:0] param64;
-input [7:0] char8;
-case (char8[7:0])
-"\t":FNBuild_param64_hexdigit = 64'b0; // tab starts new (zeroed) param64
-" ": FNBuild_param64_hexdigit = 64'b0; // space starts new (zeroed) param64
-"x": FNBuild_param64_hexdigit = 64'b0; // hex prefix starts new (zeroed) param64
-"X": FNBuild_param64_hexdigit = 64'b0; // hex prefix starts new (zeroed) param64
-"0": FNBuild_param64_hexdigit = {param64[59:0],4'b0000};
-"1": FNBuild_param64_hexdigit = {param64[59:0],4'b0001};
-"2": FNBuild_param64_hexdigit = {param64[59:0],4'b0010};
-"3": FNBuild_param64_hexdigit = {param64[59:0],4'b0011};
-"4": FNBuild_param64_hexdigit = {param64[59:0],4'b0100};
-"5": FNBuild_param64_hexdigit = {param64[59:0],4'b0101};
-"6": FNBuild_param64_hexdigit = {param64[59:0],4'b0110};
-"7": FNBuild_param64_hexdigit = {param64[59:0],4'b0111};
-"8": FNBuild_param64_hexdigit = {param64[59:0],4'b1000};
-"9": FNBuild_param64_hexdigit = {param64[59:0],4'b1001};
-"A": FNBuild_param64_hexdigit = {param64[59:0],4'b1010};
-"B": FNBuild_param64_hexdigit = {param64[59:0],4'b1011};
-"C": FNBuild_param64_hexdigit = {param64[59:0],4'b1100};
-"D": FNBuild_param64_hexdigit = {param64[59:0],4'b1101};
-"E": FNBuild_param64_hexdigit = {param64[59:0],4'b1110};
-"F": FNBuild_param64_hexdigit = {param64[59:0],4'b1111};
-"a": FNBuild_param64_hexdigit = {param64[59:0],4'b1010};
-"b": FNBuild_param64_hexdigit = {param64[59:0],4'b1011};
-"c": FNBuild_param64_hexdigit = {param64[59:0],4'b1100};
-"d": FNBuild_param64_hexdigit = {param64[59:0],4'b1101};
-"e": FNBuild_param64_hexdigit = {param64[59:0],4'b1110};
-"f": FNBuild_param64_hexdigit = {param64[59:0],4'b1111};
-default: FNBuild_param64_hexdigit = param64; // EOL etc returns param64 unchanged
-endcase
-endfunction
-
-function [63:0] FNBuild_param64_byte;
-input [63:0] param64;
-input [7:0] byte;
-  FNBuild_param64_byte = {byte[7:0], param64[63:08]};
-endfunction
-
-function [31:0] FNBuild_param32_hexdigit;
-input [31:0] param32;
-input [7:0] char8;
-case (char8[7:0])
-"\t":FNBuild_param32_hexdigit = 32'b0; // tab starts new (zeroed) param32
-" ": FNBuild_param32_hexdigit = 32'b0; // space starts new (zeroed) param32
-"x": FNBuild_param32_hexdigit = 32'b0; // hex prefix starts new (zeroed) param32
-"X": FNBuild_param32_hexdigit = 32'b0; // hex prefix starts new (zeroed) param32
-"0": FNBuild_param32_hexdigit = {param32[27:0],4'b0000};
-"1": FNBuild_param32_hexdigit = {param32[27:0],4'b0001};
-"2": FNBuild_param32_hexdigit = {param32[27:0],4'b0010};
-"3": FNBuild_param32_hexdigit = {param32[27:0],4'b0011};
-"4": FNBuild_param32_hexdigit = {param32[27:0],4'b0100};
-"5": FNBuild_param32_hexdigit = {param32[27:0],4'b0101};
-"6": FNBuild_param32_hexdigit = {param32[27:0],4'b0110};
-"7": FNBuild_param32_hexdigit = {param32[27:0],4'b0111};
-"8": FNBuild_param32_hexdigit = {param32[27:0],4'b1000};
-"9": FNBuild_param32_hexdigit = {param32[27:0],4'b1001};
-"A": FNBuild_param32_hexdigit = {param32[27:0],4'b1010};
-"B": FNBuild_param32_hexdigit = {param32[27:0],4'b1011};
-"C": FNBuild_param32_hexdigit = {param32[27:0],4'b1100};
-"D": FNBuild_param32_hexdigit = {param32[27:0],4'b1101};
-"E": FNBuild_param32_hexdigit = {param32[27:0],4'b1110};
-"F": FNBuild_param32_hexdigit = {param32[27:0],4'b1111};
-"a": FNBuild_param32_hexdigit = {param32[27:0],4'b1010};
-"b": FNBuild_param32_hexdigit = {param32[27:0],4'b1011};
-"c": FNBuild_param32_hexdigit = {param32[27:0],4'b1100};
-"d": FNBuild_param32_hexdigit = {param32[27:0],4'b1101};
-"e": FNBuild_param32_hexdigit = {param32[27:0],4'b1110};
-"f": FNBuild_param32_hexdigit = {param32[27:0],4'b1111};
-default: FNBuild_param32_hexdigit = param32; // EOL etc returns param32 unchanged
-endcase
-endfunction
-
-function [31:0] FNBuild_param32_byte;
-input [31:0] param32;
-input [7:0] byte;
-  FNBuild_param32_byte = {byte[7:0], param32[31:08]};
-endfunction
-
-
-
-function [7:0] FNmap_hex_digit;
-input [3:0] nibble;
-case (nibble[3:0])
-4'b0000: FNmap_hex_digit = "0";
-4'b0001: FNmap_hex_digit = "1";
-4'b0010: FNmap_hex_digit = "2";
-4'b0011: FNmap_hex_digit = "3";
-4'b0100: FNmap_hex_digit = "4";
-4'b0101: FNmap_hex_digit = "5";
-4'b0110: FNmap_hex_digit = "6";
-4'b0111: FNmap_hex_digit = "7";
-4'b1000: FNmap_hex_digit = "8";
-4'b1001: FNmap_hex_digit = "9";
-4'b1010: FNmap_hex_digit = "a";
-4'b1011: FNmap_hex_digit = "b";
-4'b1100: FNmap_hex_digit = "c";
-4'b1101: FNmap_hex_digit = "d";
-4'b1110: FNmap_hex_digit = "e";
-4'b1111: FNmap_hex_digit = "f";
-default: FNmap_hex_digit = "0";
-endcase
-endfunction
-
-
-// as per Vivado synthesis mapping
-`ifdef ADPFSMDESIGN
-localparam   ADP_WRITEHEX = 6'b000000 ; 
-localparam  ADP_WRITEHEXS = 6'b000001 ; 
-localparam  ADP_WRITEHEX9 = 6'b000010 ; 
-localparam  ADP_WRITEHEX8 = 6'b000011 ; 
-localparam  ADP_WRITEHEX7 = 6'b000100 ; 
-localparam  ADP_WRITEHEX6 = 6'b000101 ; 
-localparam  ADP_WRITEHEX5 = 6'b000110 ; 
-localparam  ADP_WRITEHEX4 = 6'b000111 ; 
-localparam  ADP_WRITEHEX3 = 6'b001000 ; 
-localparam  ADP_WRITEHEX2 = 6'b001001 ; 
-localparam  ADP_WRITEHEX1 = 6'b001010 ; 
-localparam  ADP_WRITEHEX0 = 6'b001011 ; 
-localparam    ADP_LINEACK = 6'b001100 ; 
-localparam   ADP_LINEACK2 = 6'b001101 ; 
-localparam     ADP_PROMPT = 6'b001110 ; 
-localparam      ADP_IOCHK = 6'b001111 ; 
-localparam     ADP_STDOUT = 6'b010000 ; 
-localparam    ADP_STDOUT1 = 6'b010001 ; 
-localparam    ADP_STDOUT2 = 6'b010010 ; 
-localparam    ADP_STDOUT3 = 6'b010011 ; 
-localparam      ADP_RXCMD = 6'b010100 ; 
-localparam    ADP_RXPARAM = 6'b010101 ; 
-localparam     ADP_ACTION = 6'b010110 ; 
-localparam     ADP_SYSCTL = 6'b010111 ; 
-localparam       ADP_READ = 6'b011000 ; 
-localparam     ADP_SYSCHK = 6'b011001 ; 
-localparam      ADP_STDIN = 6'b011010 ; 
-localparam      ADP_WRITE = 6'b011011 ; 
-localparam       ADP_EXIT = 6'b011100 ; 
-localparam      STD_IOCHK = 6'b011101 ; 
-localparam       STD_RXD1 = 6'b011110 ; 
-localparam       STD_RXD2 = 6'b011111 ; 
-localparam       STD_TXD1 = 6'b100000 ; 
-localparam       STD_TXD2 = 6'b100001 ; 
-localparam      ADP_UCTRL = 6'b100010 ; 
-localparam    ADP_UREADB0 = 6'b100011 ; 
-localparam    ADP_UREADB1 = 6'b100100 ; 
-localparam    ADP_UREADB2 = 6'b100101 ; 
-localparam    ADP_UREADB3 = 6'b100110 ; 
-localparam     ADP_UWRITE = 6'b100111 ;
-localparam       ADP_POLL = 6'b101000 ; 
-localparam      ADP_POLL1 = 6'b101001 ; 
-localparam      ADP_POLL2 = 6'b101010 ;
-localparam      ADP_FCTRL = 6'b101011 ; 
-localparam     ADP_FWRITE = 6'b101100 ;
-localparam    ADP_ECHOCMD = 6'b101101 ;
-localparam    ADP_ECHOBUS = 6'b101110 ;
-localparam    ADP_UNKNOWN = 6'b101111 ;
-reg  [5:0] adp_state   ;
-`else
-// one-hot encoded explicitly
-localparam   ADP_WRITEHEX = 48'b000000000000000000000000000000000000000000000001 ; // = 6'b000000
-localparam  ADP_WRITEHEXS = 48'b000000000000000000000000000000000000000000000010 ; // = 6'b000001
-localparam  ADP_WRITEHEX9 = 48'b000000000000000000000000000000000000000000000100 ; // = 6'b000010
-localparam  ADP_WRITEHEX8 = 48'b000000000000000000000000000000000000000000001000 ; // = 6'b000011
-localparam  ADP_WRITEHEX7 = 48'b000000000000000000000000000000000000000000010000 ; // = 6'b000100
-localparam  ADP_WRITEHEX6 = 48'b000000000000000000000000000000000000000000100000 ; // = 6'b000101
-localparam  ADP_WRITEHEX5 = 48'b000000000000000000000000000000000000000001000000 ; // = 6'b000110
-localparam  ADP_WRITEHEX4 = 48'b000000000000000000000000000000000000000010000000 ; // = 6'b000111
-localparam  ADP_WRITEHEX3 = 48'b000000000000000000000000000000000000000100000000 ; // = 6'b001000
-localparam  ADP_WRITEHEX2 = 48'b000000000000000000000000000000000000001000000000 ; // = 6'b001001
-localparam  ADP_WRITEHEX1 = 48'b000000000000000000000000000000000000010000000000 ; // = 6'b001010
-localparam  ADP_WRITEHEX0 = 48'b000000000000000000000000000000000000100000000000 ; // = 6'b001011
-localparam    ADP_LINEACK = 48'b000000000000000000000000000000000001000000000000 ; // = 6'b001100
-localparam   ADP_LINEACK2 = 48'b000000000000000000000000000000000010000000000000 ; // = 6'b001101
-localparam     ADP_PROMPT = 48'b000000000000000000000000000000000100000000000000 ; // = 6'b001110
-localparam      ADP_IOCHK = 48'b000000000000000000000000000000001000000000000000 ; // = 6'b001111
-localparam     ADP_STDOUT = 48'b000000000000000000000000000000010000000000000000 ; // = 6'b010000
-localparam    ADP_STDOUT1 = 48'b000000000000000000000000000000100000000000000000 ; // = 6'b010001
-localparam    ADP_STDOUT2 = 48'b000000000000000000000000000001000000000000000000 ; // = 6'b010010
-localparam    ADP_STDOUT3 = 48'b000000000000000000000000000010000000000000000000 ; // = 6'b010011
-localparam      ADP_RXCMD = 48'b000000000000000000000000000100000000000000000000 ; // = 6'b010100
-localparam    ADP_RXPARAM = 48'b000000000000000000000000001000000000000000000000 ; // = 6'b010101
-localparam     ADP_ACTION = 48'b000000000000000000000000010000000000000000000000 ; // = 6'b010110
-localparam     ADP_SYSCTL = 48'b000000000000000000000000100000000000000000000000 ; // = 6'b010111
-localparam       ADP_READ = 48'b000000000000000000000001000000000000000000000000 ; // = 6'b011000
-localparam     ADP_SYSCHK = 48'b000000000000000000000010000000000000000000000000 ; // = 6'b011001
-localparam      ADP_STDIN = 48'b000000000000000000000100000000000000000000000000 ; // = 6'b011010
-localparam      ADP_WRITE = 48'b000000000000000000001000000000000000000000000000 ; // = 6'b011011
-localparam       ADP_EXIT = 48'b000000000000000000010000000000000000000000000000 ; // = 6'b011100
-localparam      STD_IOCHK = 48'b000000000000000000100000000000000000000000000000 ; // = 6'b011101
-localparam       STD_RXD1 = 48'b000000000000000001000000000000000000000000000000 ; // = 6'b011110
-localparam       STD_RXD2 = 48'b000000000000000010000000000000000000000000000000 ; // = 6'b011111
-localparam       STD_TXD1 = 48'b000000000000000100000000000000000000000000000000 ; // = 6'b100000
-localparam       STD_TXD2 = 48'b000000000000001000000000000000000000000000000000 ; // = 6'b100001
-localparam      ADP_UCTRL = 48'b000000000000010000000000000000000000000000000000 ; // = 6'b100010
-localparam    ADP_UREADB0 = 48'b000000000000100000000000000000000000000000000000 ; // = 6'b100011
-localparam    ADP_UREADB1 = 48'b000000000001000000000000000000000000000000000000 ; // = 6'b100100
-localparam    ADP_UREADB2 = 48'b000000000010000000000000000000000000000000000000 ; // = 6'b100101
-localparam    ADP_UREADB3 = 48'b000000000100000000000000000000000000000000000000 ; // = 6'b100110
-localparam     ADP_UWRITE = 48'b000000001000000000000000000000000000000000000000 ; // = 6'b100111
-localparam       ADP_POLL = 48'b000000010000000000000000000000000000000000000000 ; // = 6'b101000
-localparam      ADP_POLL1 = 48'b000000100000000000000000000000000000000000000000 ; // = 6'b101001
-localparam      ADP_POLL2 = 48'b000001000000000000000000000000000000000000000000 ; // = 6'b101010
-localparam      ADP_FCTRL = 48'b000010000000000000000000000000000000000000000000 ; // = 6'b101011
-localparam     ADP_FWRITE = 48'b000100000000000000000000000000000000000000000000 ; // = 6'b101100
-localparam    ADP_ECHOCMD = 48'b001000000000000000000000000000000000000000000000 ; // = 6'b101101
-localparam    ADP_ECHOBUS = 48'b010000000000000000000000000000000000000000000000 ; // = 6'b101110
-localparam    ADP_UNKNOWN = 48'b100000000000000000000000000000000000000000000000 ; // = 6'b101111
-reg [47:0] adp_state   ;
-`endif
-
-reg [31:0] adp_bus_data;
-reg        banner      ;
-reg        com_tx_req  ;
-reg  [7:0] com_tx_byte ;
-reg        com_rx_ack  ;
-reg        std_tx_req  ;
-reg [ 7:0] std_tx_byte;
-reg        std_rx_ack  ;
-reg        adp_bus_req ;
-reg        adp_bus_write ;
-reg        adp_bus_err ;
-reg  [7:0] adp_cmd     ;
-reg [32:0] adp_param   ;
-reg [31:0] adp_addr    ;
-reg        adp_addr_inc;
-reg [31:0] adp_sys     ;
-
-assign GPO8_o = adp_sys[7:0];
-
-// ADP RX stream
-wire        com_rx_req = COMRX_TVALID_i;
-wire [ 7:0] com_rx_byte = COMRX_TDATA_i;
-assign      COMRX_TREADY_o = com_rx_ack;
-// ADP TX stream
-wire        com_tx_ack = COMTX_TREADY_i;
-assign      COMTX_TDATA_o = com_tx_byte;
-assign      COMTX_TVALID_o = com_tx_req;
-// STD RX stream (from STDOUT)
-wire        std_rx_req  = STDRX_TVALID_i;
-wire [ 7:0] std_rx_byte = STDRX_TDATA_i;
-assign      STDRX_TREADY_o = std_rx_ack;
-// STD TX stream (to STDIN)
-wire         std_tx_ack = STDTX_TREADY_i;
-assign       STDTX_TDATA_o = std_tx_byte;
-assign       STDTX_TVALID_o = std_tx_req;
-
-//AMBA AHB master as "stream" interface
-reg        ahb_dphase;
-wire       ahb_aphase = adp_bus_req & !ahb_dphase;
-wire       adp_bus_ack = ahb_dphase & HREADY_i;
-// control pipe
-always @(posedge HCLK or negedge HRESETn)
-  if(!HRESETn)
-    ahb_dphase    <= 0;
-  else if (HREADY_i)
-    ahb_dphase    <= (ahb_aphase);
-
-assign HADDR32_o     =  adp_addr;
-assign HBURST3_o     =  3'b001; // "INCR" burst signalled whenever transfer;
-assign HMASTLOCK_o   =  1'b0;
-assign HPROT4_o[3:0] = {1'b0, 1'b0, 1'b1, 1'b1};
-assign HSIZE3_o[2:0] = {1'b0, 2'b10};
-assign HTRANS2_o     = {ahb_aphase,1'b0}; // non-seq
-assign HWDATA32_o    =  adp_bus_data;
-assign HWRITE_o      =  adp_bus_write;
-
-
-`ifndef ADPBASIC
-reg  [31:0] adp_val;
-reg  [31:0] adp_mask;
-reg  [31:0] adp_poll;
-reg  [31:0] adp_count;
-reg         adp_count_dec ;
-wire        adp_delay_done;
-wire        poll2_loop_next;
-`endif
-
-// ADP_control flags in the 'C' control field
-wire        adp_disable;
-wire        adp_stdin_wait;
-
-// commnon interface handshake terms
-wire com_rx_done   = COMRX_TVALID_i & COMRX_TREADY_o;
-wire com_tx_done   = COMTX_TVALID_o & COMTX_TREADY_i;
-wire std_rx_done   = STDRX_TVALID_i & STDRX_TREADY_o;
-wire std_tx_done   = STDTX_TVALID_o & STDTX_TREADY_i;
-wire adp_bus_done  = (adp_bus_req & adp_bus_ack);
-
-// common task to set up for next state
-task ADP_LINEACK_next; // prepare newline TX (and cancel any startup banner)
-//  begin com_tx_req <= 1; com_tx_byte <= 8'h0A; banner <= 0; adp_state <= ADP_LINEACK; end
-  begin com_tx_req <= 1; com_tx_byte <= 8'h0A; adp_state <= ADP_LINEACK; end
-endtask
-task ADP_PROMPT_next; // prepare prompt TX
-  begin com_tx_req <= 1; com_tx_byte <= PROMPT_CHAR; adp_state <= ADP_PROMPT; end
-endtask
-task ADP_BUSWRITEINC_next; // prepare bus write and addr++ on completion
-  begin adp_bus_req <=1; adp_bus_write <=1; adp_addr_inc <=1; end
-endtask
-task ADP_BUSREADINC_next; // prepare bus read and addr++ on completion
-  begin adp_bus_req <=1; adp_bus_write <=0; adp_addr_inc <=1; end
-endtask
-
-task ADP_hexdigit_next; // output nibble
-input [3:0] nibble;
-  begin com_tx_req <= 1; com_tx_byte <= FNmap_hex_digit(nibble[3:0]); end
-endtask
-task ADP_txchar_next; // output char
-input [7:0] byte;
-  begin com_tx_req<= 1; com_tx_byte <= byte; end
-endtask
-
-task com_rx_nxt; com_rx_ack <=1; endtask
-
-function FNcount_down_zero_next; // param about to be zero
-input [31:0] counter;
-  FNcount_down_zero_next = !(|counter[31:1]);
-endfunction
-
-always @(posedge HCLK or negedge HRESETn)
-  if(!HRESETn) begin
-      adp_state    <= ADP_WRITEHEX ;
-      adp_bus_data <= BANNERHEX;
-      banner       <= 1; // start-up HEX message
-      com_tx_req   <= 0; // default no TX req
-      com_rx_ack   <= 0; // default no RX ack
-      std_tx_req   <= 0; // default no TX req
-      std_rx_ack   <= 0; // default no RX ack
-      adp_bus_req  <= 0; // default no bus transaction
-      adp_bus_err  <= 0; // default no bus error
-      adp_cmd      <= 0;
-      adp_param    <= 0;
-      adp_addr     <= 0;
-      adp_addr_inc <= 0;
-      adp_bus_write<= 0;
-`ifndef ADPBASIC
-      adp_count    <= 0;
-      adp_count_dec<= 0;
-      adp_val      <= 0;
-      adp_mask     <= 0;
-      adp_sys      <= 0;
-`endif
-  end else begin // default states
-      adp_state    <= adp_state; // default to hold current state
-      com_tx_req   <= 0; // default no TX req
-      com_rx_ack   <= 0; // default no RX ack
-      std_tx_req   <= 0; // default no TX req
-      std_rx_ack   <= 0; // default no RX ack
-      adp_bus_req  <= 0; // default no bus transaction
-      adp_addr     <= (adp_addr_inc & adp_bus_done) ? adp_addr + 4 : adp_addr; // address++
-      adp_addr_inc <= 0;
-`ifndef ADPBASIC
-      adp_count    <= (adp_count_dec & adp_bus_done & |adp_count) ? adp_count - 1 : adp_count; // param--
-      adp_count_dec<= 0;
-`endif     
-    case (adp_state)
-// >>>>>>>>>>>>>>>> STDIO BYPASS >>>>>>>>>>>>>>>>>>>>>>
-       STD_IOCHK:  // check for commsrx or STDOUT and not busy service, else loop back
-         if (com_rx_req) begin com_rx_ack <= 1; adp_state <= STD_RXD1; end // input char pending for STDIN
-//         else if (com_tx_ack & std_rx_req) begin std_rx_ack <= 1; adp_state <= STD_TXD1; end // STDOUT char pending and not busy
-         else if (std_rx_req) begin std_rx_ack <= 1; adp_state <= STD_TXD1; end // STDOUT char pending
-       STD_TXD1:  // get STD out char
-         if (std_rx_done)
-           begin com_tx_byte <= std_rx_byte; com_tx_req <= 1; adp_state <= STD_TXD2; end
-         else std_rx_ack <= 1; // extend
-       STD_TXD2:  // output char to ADP channel
-         if (com_tx_done) begin adp_state <= STD_IOCHK; end
-         else com_tx_req <= 1;  // extend
-       STD_RXD1:  // read rx char and check for ADP entry else STDIN **
-         if (com_rx_done) begin
-           if (FNvalid_adp_entry(com_rx_byte))
-             begin ADP_txchar_next(8'h0A); adp_state <= ADP_LINEACK; end // ADP prompt
-           else if (std_tx_ack)
-             begin std_tx_byte <= com_rx_byte; std_tx_req <= 1; adp_state <= STD_RXD2; end
-           else adp_state <= STD_IOCHK; // otherwise discard STDIN char and process OP data if blocked
-         end else com_rx_ack <= 1;  // extend
-       STD_RXD2:  // get STD in char
-         if (std_tx_done) begin adp_state <= STD_IOCHK; end
-         else std_tx_req <= 1; // extend
-              
-// >>>>>>>>>>>>>>>> ADP Monitor >>>>>>>>>>>>>>>>>>>>>>
-       ADP_PROMPT:  // transition after reset deassertion
-         if (com_tx_done) begin adp_state <= ADP_IOCHK; end
-         else com_tx_req <= 1;  // extend
-
-       ADP_IOCHK:  // check for commsrx or STDOUT and not busy service, else loop back
-         if (std_rx_req) begin com_tx_byte <= "<"; com_tx_req <= 1; adp_state <= ADP_STDOUT; end
-         else if (com_rx_req) begin com_rx_ack <= 1; adp_state <= ADP_RXCMD; end
-
-//         if (com_rx_req) begin com_rx_ack <= 1; adp_state <= ADP_RXCMD; end
-//         else if (com_tx_ack & std_rx_req) begin com_tx_byte <= "<"; com_tx_req <= 1; adp_state <= ADP_STDOUT; end
-////         else if (std_rx_req) begin com_tx_byte <= "<"; com_tx_req <= 1; adp_state <= ADP_STDOUT; end
-
-// >>>>>>>>>>>>>>>> ADP <STDOUT> >>>>>>>>>>>>>>>>>>>>>>
-       ADP_STDOUT:  // output "<"
-         if (com_tx_done) begin std_rx_ack <= 1; adp_state <= ADP_STDOUT1; end
-         else com_tx_req <= 1; // extend stream request if not ready
-       ADP_STDOUT1:  // get STD out char
-         if (std_rx_done) begin com_tx_byte <= std_rx_byte; com_tx_req <= 1; adp_state <= ADP_STDOUT2; end
-         else std_rx_ack <= 1; // else extend
-       ADP_STDOUT2:  // output char
-         if (com_tx_done) begin com_tx_byte <= ">"; com_tx_req <= 1; adp_state <= ADP_STDOUT3; end
-         else com_tx_req <= 1;  // else extend
-       ADP_STDOUT3:  // output ">"
-         if (com_tx_done) begin if (com_rx_req) begin com_rx_ack <= 1; adp_state <= ADP_RXCMD; end else adp_state <= ADP_IOCHK; end
-         else com_tx_req <= 1; // else extend
-
-// >>>>>>>>>>>>>>>> ADP COMMAND PARSING >>>>>>>>>>>>>>>>>>>>>>
-       ADP_RXCMD:  // read and save ADP command
-         if (com_rx_done) begin
-           if (FNexit(com_rx_byte)) adp_state <= STD_IOCHK; // immediate exit
-           else if (FNvalid_space(com_rx_byte)) com_rx_ack <= 1; // retry for a command
-           else if (FNvalid_EOL(com_rx_byte)) begin adp_cmd <= "?"; adp_state <= ADP_ACTION; end // no command, skip param
-           else begin adp_cmd <= com_rx_byte; adp_param <= 33'h1_00000000; com_rx_ack <= 1; adp_state <= ADP_RXPARAM; end // get optional parameter
-         end
-         else com_rx_ack <= 1; // extend stream request if not ready
-       ADP_RXPARAM:  // read and build hex parameter
-         if (com_rx_done) begin  // RX byte
-           if (FNexit(com_rx_byte)) adp_state <= STD_IOCHK; // exit
-           else if (FNvalid_EOL(com_rx_byte))
-`ifndef ADPBASIC
-            begin adp_count <= adp_param[31:0]; adp_state <= ADP_ACTION; end // parameter complete on EOL
-`else
-            begin adp_state <= ADP_ACTION; end // parameter complete on EOL
-`endif
-           else
-             begin adp_param <= {1'b0,FNBuild_param32_hexdigit(adp_param[31:0], com_rx_byte)}; com_rx_ack <= 1; end // build parameter
-           end
-         else com_rx_ack <= 1;
-
-       ADP_ACTION:  // parse command and action with parameter
-         if (FNexit(com_rx_byte))
-           adp_state <= STD_IOCHK;
-         else if (FNvalid_cmd(adp_cmd) == CMD_A)
-           begin if (adp_param[32] == 1'b1) adp_param <= {1'b0, adp_addr}; else adp_addr <= adp_param[31:0];
-             adp_state <= ADP_ECHOCMD; end
-         else if (FNvalid_cmd(adp_cmd) == CMD_C) begin
-           if (adp_param[32]) // report GPO
-             begin adp_state <= ADP_SYSCTL; end
-           else if (adp_param[31:8] == 1) // clear selected bits in GPO
-             begin adp_sys[7:0] <= adp_sys[7:0] & ~adp_param[7:0]; adp_state <= ADP_SYSCTL; end
-           else if (adp_param[31:8] == 2) // set selected bits in GPO
-             begin adp_sys[7:0] <= adp_sys[7:0] | adp_param[7:0]; adp_state <= ADP_SYSCTL; end
-           else if (adp_param[31:8] == 3) // overwrite bits in GPO
-             begin adp_sys[7:0] <= adp_param[7:0]; adp_state <= ADP_SYSCTL; end
-           else // 4 etc, report GPO
-             begin adp_state <= ADP_SYSCTL; end
-           end
-         else if (FNvalid_cmd(adp_cmd) == CMD_R)
-           begin ADP_BUSREADINC_next(); adp_state <= ADP_READ;
-`ifndef ADPBASIC
-             adp_count_dec <= 1'b1; // optional loop param
-`endif
-           end // no param required
-         else if (FNvalid_cmd(adp_cmd) == CMD_S)
-           begin adp_state <= ADP_SYSCHK; end
-         else if (FNvalid_cmd(adp_cmd) == CMD_W)
-           begin adp_bus_data <= adp_param[31:0]; ADP_BUSWRITEINC_next(); adp_state <= ADP_WRITE; end
-         else if (FNvalid_cmd(adp_cmd) == CMD_X)
-           begin com_tx_byte <= 8'h0a; com_tx_req <= 1; adp_state <= ADP_EXIT; end
-`ifndef ADPBASIC
-         else if (FNvalid_cmd(adp_cmd) == CMD_U)
-           if (FNcount_down_zero_next(adp_param[31:0])) adp_state <= ADP_ECHOCMD; else adp_state <= ADP_UCTRL; // non-zero count
-         else if (FNvalid_cmd(adp_cmd) == CMD_M)
-           begin if (adp_param[32] == 1'b1) adp_param <= {1'b0,adp_mask}; else adp_mask <= adp_param[31:0];
-             adp_state <= ADP_ECHOCMD; end
-         else if (FNvalid_cmd(adp_cmd) == CMD_P)
-           if (FNcount_down_zero_next(adp_param[31:0])) adp_state <= ADP_ECHOCMD; else adp_state <= ADP_POLL; // non-zero count
-         else if (FNvalid_cmd(adp_cmd) == CMD_V)
-           begin if (adp_param[32] == 1'b1) adp_param <= {1'b0,adp_val}; else adp_val <= adp_param[31:0];
-             adp_state <= ADP_ECHOCMD; end
-         else if (FNvalid_cmd(adp_cmd) == CMD_F)
-           if (FNcount_down_zero_next(adp_param[31:0])) adp_state <= ADP_ECHOCMD; else adp_state <= ADP_FCTRL; // non-zero count
-`endif
-         else
-           begin ADP_txchar_next("?"); adp_state <= ADP_UNKNOWN; end // unrecognised/invald
-
-// >>>>>>>>>>>>>>>> ADP BUS WRITE and READ >>>>>>>>>>>>>>>>>>>>>>
-
-       ADP_WRITE:  // perform bus write at current address pointer (and auto increment)
-         if (adp_bus_done) begin adp_state <= ADP_ECHOCMD; adp_bus_err <= HRESP_i; end
-         else begin ADP_BUSWRITEINC_next(); end // extend request
-              
-       ADP_READ:  // perform bus read at current adp address (and auto increment)  - and report in hex
-         if (adp_bus_done) begin adp_bus_data <= HRDATA32_i; adp_bus_err <= HRESP_i; ADP_txchar_next("R"); adp_state <= ADP_ECHOBUS; end
-         else begin
-           ADP_BUSREADINC_next();
-`ifndef ADPBASIC
-           adp_count_dec<= 1'b1;
-`endif
-         end // extend request
-
-`ifndef ADPBASIC
-
-// >>>>>>>>>>>>>>>> ADP BINARY UPLOAD >>>>>>>>>>>>>>>>>>>>>>
-       ADP_UCTRL:  // set control value
-         begin com_rx_ack <= 1; adp_state <= ADP_UREADB0; end  // read next 4 bytes
-       ADP_UREADB0: // read raw binary byte
-         if (com_rx_done) begin com_rx_ack <= 1; adp_bus_data[31:24] <= com_rx_byte; adp_state <= ADP_UREADB1; end
-         else com_rx_ack <= 1;  // extend stream request if not ready
-       ADP_UREADB1: // read raw binary byte
-         if (com_rx_done) begin com_rx_ack <= 1; adp_bus_data[23:16] <= com_rx_byte; adp_state <= ADP_UREADB2; end
-         else com_rx_ack <= 1;  // extend stream request if not ready
-       ADP_UREADB2: // read raw binary byte 0
-         if (com_rx_done) begin com_rx_ack <= 1; adp_bus_data[15: 8] <= com_rx_byte; adp_state <= ADP_UREADB3; end
-         else com_rx_ack <= 1;  // extend stream request if not ready
-       ADP_UREADB3: // read raw binary byte 0
-         if (com_rx_done)
-           begin adp_bus_data[ 7: 0] <= com_rx_byte; ADP_BUSWRITEINC_next(); adp_count_dec <= 1; adp_state <= ADP_UWRITE; end
-         else com_rx_ack <= 1;  // extend stream request if not ready
-       ADP_UWRITE:  // Write word to Addr++
-         if (adp_bus_done) begin // auto address++, count--
-           if (FNcount_down_zero_next(adp_count)) adp_state <= ADP_ECHOCMD; else begin adp_state <= ADP_UREADB0; adp_bus_err <= adp_bus_err | HRESP_i; end
-         end else begin  ADP_BUSWRITEINC_next(); adp_count_dec <= 1; end // extend request
-
-// >>>>>>>>>>>>>>>> ADP BUS READ LOOP >>>>>>>>>>>>>>>>>>>>>>
-       ADP_POLL:  // set poll value
-         begin adp_bus_req <= 1; adp_bus_write <= 0; adp_state <= ADP_POLL1; end
-       ADP_POLL1:  // wait for read data, no addr++
-         if (adp_bus_done) begin adp_bus_data <= HRDATA32_i; adp_count_dec <=1; adp_state <= ADP_POLL2; adp_bus_err <= adp_bus_err | HRESP_i; end
-         else begin adp_bus_req <= 1; adp_count_dec <=1; end
-       ADP_POLL2:
-         if (FNcount_down_zero_next(adp_count)) begin adp_state <= ADP_ECHOCMD; adp_bus_err <= 1'b1; end // timeout
-         else if (((adp_bus_data  & adp_mask) ^ adp_val) == 0) begin adp_state <= ADP_ECHOCMD; adp_param <= {1'b0, (adp_param[31:0] - adp_count)}; end // exact match
-         else adp_state <= ADP_POLL;
-
-// >>>>>>>>>>>>>>>> ADP (ZERO) FILL MEMORY >>>>>>>>>>>>>>>>>>>>>>
-       ADP_FCTRL:  // set control value
-           begin adp_bus_data <= adp_val; ADP_BUSWRITEINC_next(); adp_count_dec <= 1; adp_state <= ADP_FWRITE; end
-       ADP_FWRITE:  // Write word to Addr++
-         if (adp_bus_done) begin // auto address++, count--
-           if (FNcount_down_zero_next(adp_count)) adp_state <= ADP_ECHOCMD; else begin adp_state <= ADP_FCTRL;  adp_bus_err <= adp_bus_err | HRESP_i; end
-         end else begin  ADP_BUSWRITEINC_next(); adp_count_dec <= 1; end // extend request
-`endif
-        
-        // >>>>>>>>>>>>>>>> ADP MISC >>>>>>>>>>>>>>>>>>>>>>
-
-       ADP_UNKNOWN:  // output "?"
-         if (com_tx_done) begin ADP_LINEACK_next(); end
-         else com_tx_req <= 1;  // extend stream request if not ready
-
-       ADP_EXIT:  // exit ADP mode
-         if (com_tx_done) adp_state <= STD_IOCHK;
-         else com_tx_req <= 1;  // extend stream request if not ready
-
-       ADP_SYSCHK:  // check STDIN fifo
-         begin // no upper flags so STDIN char
-           if (std_tx_ack) begin std_tx_req <=1; std_tx_byte <= adp_param[7:0]; adp_state <= ADP_STDIN; end
-           else begin adp_bus_err <= 1'b1; adp_state <= ADP_ECHOCMD; end // signal error then echo comand
-         end 
-       ADP_STDIN:  // push char into STDIN
-         if (std_tx_done) begin adp_bus_data <= {24'b0,adp_param[7:0]}; ADP_txchar_next("S"); adp_state <= ADP_ECHOBUS;  end
-         else std_tx_req <= 1; // extend
-
-       ADP_SYSCTL:  // read current status - and report in hex
-         begin adp_bus_data <= {GPI8_i[7:0],adp_sys[7:0],adp_param[15:0]}; ADP_txchar_next("C"); adp_state <= ADP_ECHOBUS;  end
-     
-       ADP_ECHOCMD:  // output command and (param) data
-         begin ADP_txchar_next(adp_cmd & 8'h5f); adp_bus_data <= adp_param[31:0]; adp_state <= ADP_ECHOBUS; end // output command char
-       ADP_ECHOBUS:  // output command space and (bus) data
-         if (com_tx_done) begin adp_state <= ADP_WRITEHEXS; ADP_txchar_next(adp_bus_err ? "!" : " "); end // output space char, or "!" on bus error      
-         else com_tx_req <= 1;  // extend 
-           
-       ADP_WRITEHEX:  // output hex word with prefix
-         begin adp_state <= ADP_WRITEHEXS; ADP_txchar_next(adp_bus_err ? "!" : " "); end // output space char, or "!" on bus error
-
-       ADP_WRITEHEXS:
-         if (com_tx_done) begin adp_state <= ADP_WRITEHEX9; ADP_txchar_next("0"); end // output "0" hex prefix
-         else com_tx_req <= 1;  // extend
-       ADP_WRITEHEX9:
-         if (com_tx_done) begin adp_state <= ADP_WRITEHEX8; ADP_txchar_next("x"); end // output "x" hex prefix
-         else com_tx_req <= 1;  // extend
-       ADP_WRITEHEX8:
-         if (com_tx_done) begin adp_state <= ADP_WRITEHEX7; ADP_hexdigit_next(adp_bus_data[31:28]); end // hex nibble 7
-         else com_tx_req <= 1;  // extend
-       ADP_WRITEHEX7:  // output hex nibble 7
-         if (com_tx_done) begin adp_state <= ADP_WRITEHEX6; ADP_hexdigit_next(adp_bus_data[27:24]); end // hex nibble 6
-         else com_tx_req <= 1;  // extend
-       ADP_WRITEHEX6:  // output hex nibble 6
-         if (com_tx_done) begin adp_state <= ADP_WRITEHEX5; ADP_hexdigit_next(adp_bus_data[23:20]); end // hex nibble 5
-         else com_tx_req <= 1;  // extend
-       ADP_WRITEHEX5:  // output hex nibble 5
-         if (com_tx_done) begin adp_state <= ADP_WRITEHEX4; ADP_hexdigit_next(adp_bus_data[19:16]); end // hex nibble 4
-         else com_tx_req <= 1;  // extend
-       ADP_WRITEHEX4:  // output hex nibble 4
-         if (com_tx_done) begin adp_state <= ADP_WRITEHEX3; ADP_hexdigit_next(adp_bus_data[15:12]); end // hex nibble 3
-         else com_tx_req <= 1;  // extend
-       ADP_WRITEHEX3:  // output hex nibble 3
-         if (com_tx_done) begin adp_state <= ADP_WRITEHEX2; ADP_hexdigit_next(adp_bus_data[11: 8]); end // hex nibble 2
-         else com_tx_req <= 1;  // extend
-       ADP_WRITEHEX2:  // output hex nibble 2
-         if (com_tx_done) begin adp_state <= ADP_WRITEHEX1; ADP_hexdigit_next(adp_bus_data[ 7: 4]); end // hex nibble 1
-         else com_tx_req <= 1;  // extend
-       ADP_WRITEHEX1:  // output hex nibble 1
-         if (com_tx_done) begin adp_state <= ADP_WRITEHEX0; ADP_hexdigit_next(adp_bus_data[ 3: 0]); end // hex nibble 0
-         else com_tx_req <= 1;  // extend
-       ADP_WRITEHEX0:  // output hex nibble 0 (if not startup banner then scan to end of line before lineack
-         if (com_tx_done) begin
-           adp_bus_err <= 1'b0; // clear sticky bus error flag
-           if (banner) begin ADP_LINEACK_next(); end
-           else begin ADP_txchar_next(8'h0A); com_tx_req <= 1; adp_state <= ADP_LINEACK; end // newline and prompt
-         end else com_tx_req <= 1;  // extend
-
-       ADP_LINEACK:  // write EOLN 
-         if (com_tx_done) begin
-           begin ADP_txchar_next(8'h0D); adp_state <= ADP_LINEACK2; end
-         end else com_tx_req <= 1;  // extend
-       ADP_LINEACK2: // CR
-         if (com_tx_done) begin
-           if (banner) begin banner <= 0; adp_state <= STD_IOCHK; end
-`ifndef ADPBASIC
-           else if ((FNvalid_cmd(adp_cmd) == CMD_R) & |adp_count) //// non-zero count
-             begin ADP_BUSREADINC_next(); adp_count_dec <= 1'b1; adp_state <= ADP_READ; end // 
-`endif
-           else begin ADP_txchar_next(PROMPT_CHAR); adp_state <= ADP_PROMPT; end
-         end else com_tx_req <= 1;  // extend
-      default: 
-        begin ADP_txchar_next("#"); adp_state <= ADP_UNKNOWN; end // default error
-    endcase
-  end
-
-endmodule
-
-////AHBLITE_ADPMASTER instancing
-//ADPmaster
-//   #(.PROMPT_CHAR     ("]"))
-// ADPmaster(
-//  .HCLK        (ahb_hclk      ),
-//  .HRESETn     (ahb_hrestn    ),
-//  .HADDR32_o   (ahb_haddr     ),
-//  .HBURST3_o   (ahb_hburst    ),
-//  .HMASTLOCK_o (ahb_hmastlock ),
-//  .HPROT4_o    (ahb_hprot     ),
-//  .HSIZE3_o    (ahb_hsize     ),
-//  .HTRANS2_o   (ahb_htrans    ),
-//  .HWDATA32_o  (ahb_hwdata    ),
-//  .HWRITE_o    (ahb_hwrite    ),
-//  .HRDATA32_i  (ahb_hrdata    ),
-//  .HREADY_i    (ahb_hready    ),
-//  .HRESP_i     (ahb_hresp     ),
-  
-//  .COMRX_TREADY_o(com_rx_tready),
-//  .COMRX_TDATA_i(com_rx_tdata),
-//  .COMRX_TVALID_i(com_rx_tvalid),
-//  .STDRX_TREADY_o(std_rx_tready),
-//  .STDRX_TDATA_i(std_rx_tdata),
-//  .STDRX_TVALID_i(std_rx_tvalid),
-//  .COMTX_TVALID_o(com_tx_tvalid),
-//  .COMTX_TDATA_o(com_tx_tdata),
-//  .COMTX_TREADY_i(com_tx_tready),
-//  .STDTX_TVALID_o(std_tx_tvalid),
-//  .STDTX_TDATA_o(std_tx_tdata),
-//  .STDTX_TREADY_i(std_tx_tready)
-
-//  );
+//-----------------------------------------------------------------------------
+// soclabs ASCII Debug Protocol controller
+// 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) 2021-3, SoC Labs (www.soclabs.org)
+//-----------------------------------------------------------------------------
+
+
+//`define ADPBASIC 1
+
+module ADPmanager // AHB initiator interface
+   #(parameter PROMPT_CHAR          = "]"
+    )
+            ( input  wire                  HCLK,
+              input  wire                  HRESETn,
+              output wire        [31:0]    HADDR32_o,
+              output wire        [ 2:0]    HBURST3_o,
+              output wire                  HMASTLOCK_o,
+              output wire        [ 3:0]    HPROT4_o,
+              output wire        [ 2:0]    HSIZE3_o,
+              output wire        [ 1:0]    HTRANS2_o,
+              output wire        [31:0]    HWDATA32_o,
+              output wire                  HWRITE_o,
+              input  wire         [31:0]   HRDATA32_i,
+              input  wire                  HREADY_i,
+              input  wire                  HRESP_i,
+// COMIO interface
+    output wire [ 7:0] GPO8_o,
+    input  wire [ 7:0] GPI8_i,
+//    input  wire     COM_RXE_i,
+    input  wire [ 7:0] COMRX_TDATA_i,
+    input  wire        COMRX_TVALID_i,
+    output wire        COMRX_TREADY_o,
+//    input  wire     COM_TXF_i,
+    output wire [ 7:0] COMTX_TDATA_o,
+    output wire        COMTX_TVALID_o,
+    input  wire        COMTX_TREADY_i,
+// STDIO interface
+//    input  wire     STDOUT_RXE_i,
+    input  wire [ 7:0] STDRX_TDATA_i,
+    input  wire        STDRX_TVALID_i,
+    output wire        STDRX_TREADY_o,
+//    input  wire     STDIN_TXF_i
+    output wire [ 7:0] STDTX_TDATA_o,
+    output wire        STDTX_TVALID_o,
+    input  wire        STDTX_TREADY_i
+);
+
+wire COM_RXE_i = !COMRX_TVALID_i;
+wire COM_TXF_i = !COMTX_TREADY_i;
+
+//wire adp_rx_req = COMRX_TVALID_i & COMRX_TREADY_o;
+//wire std_rx_req = STDRX_TVALID_i & STDRX_TREADY_o;
+
+
+wire STD_TXF_i = !STDTX_TREADY_i;
+wire STD_RXE_i = !STDRX_TVALID_i;
+
+`ifdef ADPBASIC
+  localparam BANNERHEX = 32'h50c1ab01;
+`else
+  localparam BANNERHEX = 32'h50c1ab03;
+`endif
+
+localparam CMD_bad = 4'b0000;
+localparam CMD_A   = 4'b0001;  // set Address
+localparam CMD_C   = 4'b0010;  // Control
+localparam CMD_R   = 4'b0011;  // Read word, addr++
+localparam CMD_S   = 4'b0100;  // Status/STDIN
+localparam CMD_W   = 4'b0101;  // Write word, addr++
+localparam CMD_X   = 4'b0110;  // eXit
+`ifndef ADPBASIC
+localparam CMD_F   = 4'b1000;  // Fill (wordocunt) from addr++
+localparam CMD_M   = 4'b1001;  // set read Mask
+localparam CMD_P   = 4'b1010;  // Poll hardware  (count)
+localparam CMD_U   = 4'b1011;  // (Binary) Upload (wordocunt) from addr++
+localparam CMD_V   = 4'b1100;  // match Value
+`endif
+
+
+function FNvalid_adp_entry; // Escape char
+input [7:0] char8;
+  FNvalid_adp_entry = (char8[7:0] ==  8'h1b);
+endfunction
+
+function [3:0] FNvalid_cmd;
+input [7:0] char8;
+case (char8[7:0])
+"A": FNvalid_cmd = CMD_A;
+"a": FNvalid_cmd = CMD_A;
+"C": FNvalid_cmd = CMD_C;
+"c": FNvalid_cmd = CMD_C;
+"R": FNvalid_cmd = CMD_R;
+"r": FNvalid_cmd = CMD_R;
+"S": FNvalid_cmd = CMD_S;
+"s": FNvalid_cmd = CMD_S;
+"W": FNvalid_cmd = CMD_W;
+"w": FNvalid_cmd = CMD_W;
+"X": FNvalid_cmd = CMD_X;
+"x": FNvalid_cmd = CMD_X;
+`ifndef ADPBASIC
+"F": FNvalid_cmd = CMD_F;
+"f": FNvalid_cmd = CMD_F;
+"M": FNvalid_cmd = CMD_M;
+"m": FNvalid_cmd = CMD_M;
+"P": FNvalid_cmd = CMD_P;
+"p": FNvalid_cmd = CMD_P;
+"U": FNvalid_cmd = CMD_U;
+"u": FNvalid_cmd = CMD_U;
+"V": FNvalid_cmd = CMD_V;
+"v": FNvalid_cmd = CMD_V;
+`endif
+default:
+      FNvalid_cmd = 0;
+endcase
+endfunction
+
+function FNvalid_space; // space or tab char
+input [7:0] char8;
+  FNvalid_space = ((char8[7:0] == 8'h20) || (char8[7:0] == 8'h09));
+endfunction
+
+function FNnull; // space or tab char
+input [7:0] char8;
+  FNnull = (char8[7:0] == 8'h00);
+endfunction
+
+function FNexit; // EOF
+input [7:0] char8;
+  FNexit = ((char8[7:0] == 8'h04) || (char8[7:0] == 8'h00));
+endfunction
+
+function FNvalid_EOL; // CR or LF
+input [7:0] char8;
+  FNvalid_EOL = ((char8[7:0] == 8'h0a) || (char8[7:0] == 8'h0d));
+endfunction
+
+function FNuppercase;
+input [7:0] char8;
+  FNuppercase = (char8[6]) ? (char8 & 8'h5f) : (char8);
+endfunction
+
+function [63:0] FNBuild_param64_hexdigit;
+input [63:0] param64;
+input [7:0] char8;
+case (char8[7:0])
+"\t":FNBuild_param64_hexdigit = 64'b0; // tab starts new (zeroed) param64
+" ": FNBuild_param64_hexdigit = 64'b0; // space starts new (zeroed) param64
+"x": FNBuild_param64_hexdigit = 64'b0; // hex prefix starts new (zeroed) param64
+"X": FNBuild_param64_hexdigit = 64'b0; // hex prefix starts new (zeroed) param64
+"0": FNBuild_param64_hexdigit = {param64[59:0],4'b0000};
+"1": FNBuild_param64_hexdigit = {param64[59:0],4'b0001};
+"2": FNBuild_param64_hexdigit = {param64[59:0],4'b0010};
+"3": FNBuild_param64_hexdigit = {param64[59:0],4'b0011};
+"4": FNBuild_param64_hexdigit = {param64[59:0],4'b0100};
+"5": FNBuild_param64_hexdigit = {param64[59:0],4'b0101};
+"6": FNBuild_param64_hexdigit = {param64[59:0],4'b0110};
+"7": FNBuild_param64_hexdigit = {param64[59:0],4'b0111};
+"8": FNBuild_param64_hexdigit = {param64[59:0],4'b1000};
+"9": FNBuild_param64_hexdigit = {param64[59:0],4'b1001};
+"A": FNBuild_param64_hexdigit = {param64[59:0],4'b1010};
+"B": FNBuild_param64_hexdigit = {param64[59:0],4'b1011};
+"C": FNBuild_param64_hexdigit = {param64[59:0],4'b1100};
+"D": FNBuild_param64_hexdigit = {param64[59:0],4'b1101};
+"E": FNBuild_param64_hexdigit = {param64[59:0],4'b1110};
+"F": FNBuild_param64_hexdigit = {param64[59:0],4'b1111};
+"a": FNBuild_param64_hexdigit = {param64[59:0],4'b1010};
+"b": FNBuild_param64_hexdigit = {param64[59:0],4'b1011};
+"c": FNBuild_param64_hexdigit = {param64[59:0],4'b1100};
+"d": FNBuild_param64_hexdigit = {param64[59:0],4'b1101};
+"e": FNBuild_param64_hexdigit = {param64[59:0],4'b1110};
+"f": FNBuild_param64_hexdigit = {param64[59:0],4'b1111};
+default: FNBuild_param64_hexdigit = param64; // EOL etc returns param64 unchanged
+endcase
+endfunction
+
+function [63:0] FNBuild_param64_byte;
+input [63:0] param64;
+input [7:0] byte;
+  FNBuild_param64_byte = {byte[7:0], param64[63:08]};
+endfunction
+
+function [31:0] FNBuild_param32_hexdigit;
+input [31:0] param32;
+input [7:0] char8;
+case (char8[7:0])
+"\t":FNBuild_param32_hexdigit = 32'b0; // tab starts new (zeroed) param32
+" ": FNBuild_param32_hexdigit = 32'b0; // space starts new (zeroed) param32
+"x": FNBuild_param32_hexdigit = 32'b0; // hex prefix starts new (zeroed) param32
+"X": FNBuild_param32_hexdigit = 32'b0; // hex prefix starts new (zeroed) param32
+"0": FNBuild_param32_hexdigit = {param32[27:0],4'b0000};
+"1": FNBuild_param32_hexdigit = {param32[27:0],4'b0001};
+"2": FNBuild_param32_hexdigit = {param32[27:0],4'b0010};
+"3": FNBuild_param32_hexdigit = {param32[27:0],4'b0011};
+"4": FNBuild_param32_hexdigit = {param32[27:0],4'b0100};
+"5": FNBuild_param32_hexdigit = {param32[27:0],4'b0101};
+"6": FNBuild_param32_hexdigit = {param32[27:0],4'b0110};
+"7": FNBuild_param32_hexdigit = {param32[27:0],4'b0111};
+"8": FNBuild_param32_hexdigit = {param32[27:0],4'b1000};
+"9": FNBuild_param32_hexdigit = {param32[27:0],4'b1001};
+"A": FNBuild_param32_hexdigit = {param32[27:0],4'b1010};
+"B": FNBuild_param32_hexdigit = {param32[27:0],4'b1011};
+"C": FNBuild_param32_hexdigit = {param32[27:0],4'b1100};
+"D": FNBuild_param32_hexdigit = {param32[27:0],4'b1101};
+"E": FNBuild_param32_hexdigit = {param32[27:0],4'b1110};
+"F": FNBuild_param32_hexdigit = {param32[27:0],4'b1111};
+"a": FNBuild_param32_hexdigit = {param32[27:0],4'b1010};
+"b": FNBuild_param32_hexdigit = {param32[27:0],4'b1011};
+"c": FNBuild_param32_hexdigit = {param32[27:0],4'b1100};
+"d": FNBuild_param32_hexdigit = {param32[27:0],4'b1101};
+"e": FNBuild_param32_hexdigit = {param32[27:0],4'b1110};
+"f": FNBuild_param32_hexdigit = {param32[27:0],4'b1111};
+default: FNBuild_param32_hexdigit = param32; // EOL etc returns param32 unchanged
+endcase
+endfunction
+
+function [31:0] FNBuild_param32_byte;
+input [31:0] param32;
+input [7:0] byte;
+  FNBuild_param32_byte = {byte[7:0], param32[31:08]};
+endfunction
+
+
+
+function [7:0] FNmap_hex_digit;
+input [3:0] nibble;
+case (nibble[3:0])
+4'b0000: FNmap_hex_digit = "0";
+4'b0001: FNmap_hex_digit = "1";
+4'b0010: FNmap_hex_digit = "2";
+4'b0011: FNmap_hex_digit = "3";
+4'b0100: FNmap_hex_digit = "4";
+4'b0101: FNmap_hex_digit = "5";
+4'b0110: FNmap_hex_digit = "6";
+4'b0111: FNmap_hex_digit = "7";
+4'b1000: FNmap_hex_digit = "8";
+4'b1001: FNmap_hex_digit = "9";
+4'b1010: FNmap_hex_digit = "a";
+4'b1011: FNmap_hex_digit = "b";
+4'b1100: FNmap_hex_digit = "c";
+4'b1101: FNmap_hex_digit = "d";
+4'b1110: FNmap_hex_digit = "e";
+4'b1111: FNmap_hex_digit = "f";
+default: FNmap_hex_digit = "0";
+endcase
+endfunction
+
+
+// as per Vivado synthesis mapping
+`ifdef ADPFSMDESIGN
+localparam   ADP_WRITEHEX = 6'b000000 ;
+localparam  ADP_WRITEHEXS = 6'b000001 ;
+localparam  ADP_WRITEHEX9 = 6'b000010 ;
+localparam  ADP_WRITEHEX8 = 6'b000011 ;
+localparam  ADP_WRITEHEX7 = 6'b000100 ;
+localparam  ADP_WRITEHEX6 = 6'b000101 ;
+localparam  ADP_WRITEHEX5 = 6'b000110 ;
+localparam  ADP_WRITEHEX4 = 6'b000111 ;
+localparam  ADP_WRITEHEX3 = 6'b001000 ;
+localparam  ADP_WRITEHEX2 = 6'b001001 ;
+localparam  ADP_WRITEHEX1 = 6'b001010 ;
+localparam  ADP_WRITEHEX0 = 6'b001011 ;
+localparam    ADP_LINEACK = 6'b001100 ;
+localparam   ADP_LINEACK2 = 6'b001101 ;
+localparam     ADP_PROMPT = 6'b001110 ;
+localparam      ADP_IOCHK = 6'b001111 ;
+localparam     ADP_STDOUT = 6'b010000 ;
+localparam    ADP_STDOUT1 = 6'b010001 ;
+localparam    ADP_STDOUT2 = 6'b010010 ;
+localparam    ADP_STDOUT3 = 6'b010011 ;
+localparam      ADP_RXCMD = 6'b010100 ;
+localparam    ADP_RXPARAM = 6'b010101 ;
+localparam     ADP_ACTION = 6'b010110 ;
+localparam     ADP_SYSCTL = 6'b010111 ;
+localparam       ADP_READ = 6'b011000 ;
+localparam     ADP_SYSCHK = 6'b011001 ;
+localparam      ADP_STDIN = 6'b011010 ;
+localparam      ADP_WRITE = 6'b011011 ;
+localparam       ADP_EXIT = 6'b011100 ;
+localparam      STD_IOCHK = 6'b011101 ;
+localparam       STD_RXD1 = 6'b011110 ;
+localparam       STD_RXD2 = 6'b011111 ;
+localparam       STD_TXD1 = 6'b100000 ;
+localparam       STD_TXD2 = 6'b100001 ;
+localparam      ADP_UCTRL = 6'b100010 ;
+localparam    ADP_UREADB0 = 6'b100011 ;
+localparam    ADP_UREADB1 = 6'b100100 ;
+localparam    ADP_UREADB2 = 6'b100101 ;
+localparam    ADP_UREADB3 = 6'b100110 ;
+localparam     ADP_UWRITE = 6'b100111 ;
+localparam       ADP_POLL = 6'b101000 ;
+localparam      ADP_POLL1 = 6'b101001 ;
+localparam      ADP_POLL2 = 6'b101010 ;
+localparam      ADP_FCTRL = 6'b101011 ;
+localparam     ADP_FWRITE = 6'b101100 ;
+localparam    ADP_ECHOCMD = 6'b101101 ;
+localparam    ADP_ECHOBUS = 6'b101110 ;
+localparam    ADP_UNKNOWN = 6'b101111 ;
+reg  [5:0] adp_state   ;
+`else
+// one-hot encoded explicitly
+localparam   ADP_WRITEHEX = 48'b000000000000000000000000000000000000000000000001 ; // = 6'b000000
+localparam  ADP_WRITEHEXS = 48'b000000000000000000000000000000000000000000000010 ; // = 6'b000001
+localparam  ADP_WRITEHEX9 = 48'b000000000000000000000000000000000000000000000100 ; // = 6'b000010
+localparam  ADP_WRITEHEX8 = 48'b000000000000000000000000000000000000000000001000 ; // = 6'b000011
+localparam  ADP_WRITEHEX7 = 48'b000000000000000000000000000000000000000000010000 ; // = 6'b000100
+localparam  ADP_WRITEHEX6 = 48'b000000000000000000000000000000000000000000100000 ; // = 6'b000101
+localparam  ADP_WRITEHEX5 = 48'b000000000000000000000000000000000000000001000000 ; // = 6'b000110
+localparam  ADP_WRITEHEX4 = 48'b000000000000000000000000000000000000000010000000 ; // = 6'b000111
+localparam  ADP_WRITEHEX3 = 48'b000000000000000000000000000000000000000100000000 ; // = 6'b001000
+localparam  ADP_WRITEHEX2 = 48'b000000000000000000000000000000000000001000000000 ; // = 6'b001001
+localparam  ADP_WRITEHEX1 = 48'b000000000000000000000000000000000000010000000000 ; // = 6'b001010
+localparam  ADP_WRITEHEX0 = 48'b000000000000000000000000000000000000100000000000 ; // = 6'b001011
+localparam    ADP_LINEACK = 48'b000000000000000000000000000000000001000000000000 ; // = 6'b001100
+localparam   ADP_LINEACK2 = 48'b000000000000000000000000000000000010000000000000 ; // = 6'b001101
+localparam     ADP_PROMPT = 48'b000000000000000000000000000000000100000000000000 ; // = 6'b001110
+localparam      ADP_IOCHK = 48'b000000000000000000000000000000001000000000000000 ; // = 6'b001111
+localparam     ADP_STDOUT = 48'b000000000000000000000000000000010000000000000000 ; // = 6'b010000
+localparam    ADP_STDOUT1 = 48'b000000000000000000000000000000100000000000000000 ; // = 6'b010001
+localparam    ADP_STDOUT2 = 48'b000000000000000000000000000001000000000000000000 ; // = 6'b010010
+localparam    ADP_STDOUT3 = 48'b000000000000000000000000000010000000000000000000 ; // = 6'b010011
+localparam      ADP_RXCMD = 48'b000000000000000000000000000100000000000000000000 ; // = 6'b010100
+localparam    ADP_RXPARAM = 48'b000000000000000000000000001000000000000000000000 ; // = 6'b010101
+localparam     ADP_ACTION = 48'b000000000000000000000000010000000000000000000000 ; // = 6'b010110
+localparam     ADP_SYSCTL = 48'b000000000000000000000000100000000000000000000000 ; // = 6'b010111
+localparam       ADP_READ = 48'b000000000000000000000001000000000000000000000000 ; // = 6'b011000
+localparam     ADP_SYSCHK = 48'b000000000000000000000010000000000000000000000000 ; // = 6'b011001
+localparam      ADP_STDIN = 48'b000000000000000000000100000000000000000000000000 ; // = 6'b011010
+localparam      ADP_WRITE = 48'b000000000000000000001000000000000000000000000000 ; // = 6'b011011
+localparam       ADP_EXIT = 48'b000000000000000000010000000000000000000000000000 ; // = 6'b011100
+localparam      STD_IOCHK = 48'b000000000000000000100000000000000000000000000000 ; // = 6'b011101
+localparam       STD_RXD1 = 48'b000000000000000001000000000000000000000000000000 ; // = 6'b011110
+localparam       STD_RXD2 = 48'b000000000000000010000000000000000000000000000000 ; // = 6'b011111
+localparam       STD_TXD1 = 48'b000000000000000100000000000000000000000000000000 ; // = 6'b100000
+localparam       STD_TXD2 = 48'b000000000000001000000000000000000000000000000000 ; // = 6'b100001
+localparam      ADP_UCTRL = 48'b000000000000010000000000000000000000000000000000 ; // = 6'b100010
+localparam    ADP_UREADB0 = 48'b000000000000100000000000000000000000000000000000 ; // = 6'b100011
+localparam    ADP_UREADB1 = 48'b000000000001000000000000000000000000000000000000 ; // = 6'b100100
+localparam    ADP_UREADB2 = 48'b000000000010000000000000000000000000000000000000 ; // = 6'b100101
+localparam    ADP_UREADB3 = 48'b000000000100000000000000000000000000000000000000 ; // = 6'b100110
+localparam     ADP_UWRITE = 48'b000000001000000000000000000000000000000000000000 ; // = 6'b100111
+localparam       ADP_POLL = 48'b000000010000000000000000000000000000000000000000 ; // = 6'b101000
+localparam      ADP_POLL1 = 48'b000000100000000000000000000000000000000000000000 ; // = 6'b101001
+localparam      ADP_POLL2 = 48'b000001000000000000000000000000000000000000000000 ; // = 6'b101010
+localparam      ADP_FCTRL = 48'b000010000000000000000000000000000000000000000000 ; // = 6'b101011
+localparam     ADP_FWRITE = 48'b000100000000000000000000000000000000000000000000 ; // = 6'b101100
+localparam    ADP_ECHOCMD = 48'b001000000000000000000000000000000000000000000000 ; // = 6'b101101
+localparam    ADP_ECHOBUS = 48'b010000000000000000000000000000000000000000000000 ; // = 6'b101110
+localparam    ADP_UNKNOWN = 48'b100000000000000000000000000000000000000000000000 ; // = 6'b101111
+reg [47:0] adp_state   ;
+`endif
+
+reg [31:0] adp_bus_data;
+reg        banner      ;
+reg        com_tx_req  ;
+reg  [7:0] com_tx_byte ;
+reg        com_rx_ack  ;
+reg        std_tx_req  ;
+reg [ 7:0] std_tx_byte;
+reg        std_rx_ack  ;
+reg        adp_bus_req ;
+reg        adp_bus_write ;
+reg        adp_bus_err ;
+reg  [7:0] adp_cmd     ;
+reg [32:0] adp_param   ;
+reg [31:0] adp_addr    ;
+reg        adp_addr_inc;
+reg [31:0] adp_sys     ;
+
+assign GPO8_o = adp_sys[7:0];
+
+// ADP RX stream
+wire        com_rx_req = COMRX_TVALID_i;
+wire [ 7:0] com_rx_byte = COMRX_TDATA_i;
+assign      COMRX_TREADY_o = com_rx_ack;
+// ADP TX stream
+wire        com_tx_ack = COMTX_TREADY_i;
+assign      COMTX_TDATA_o = com_tx_byte;
+assign      COMTX_TVALID_o = com_tx_req;
+// STD RX stream (from STDOUT)
+wire        std_rx_req  = STDRX_TVALID_i;
+wire [ 7:0] std_rx_byte = STDRX_TDATA_i;
+assign      STDRX_TREADY_o = std_rx_ack;
+// STD TX stream (to STDIN)
+wire         std_tx_ack = STDTX_TREADY_i;
+assign       STDTX_TDATA_o = std_tx_byte;
+assign       STDTX_TVALID_o = std_tx_req;
+
+//AMBA AHB master as "stream" interface
+reg        ahb_dphase;
+wire       ahb_aphase = adp_bus_req & !ahb_dphase;
+wire       adp_bus_ack = ahb_dphase & HREADY_i;
+// control pipe
+always @(posedge HCLK or negedge HRESETn)
+  if(!HRESETn)
+    ahb_dphase    <= 0;
+  else if (HREADY_i)
+    ahb_dphase    <= (ahb_aphase);
+
+assign HADDR32_o     =  adp_addr;
+assign HBURST3_o     =  3'b001; // "INCR" burst signalled whenever transfer;
+assign HMASTLOCK_o   =  1'b0;
+assign HPROT4_o[3:0] = {1'b0, 1'b0, 1'b1, 1'b1};
+assign HSIZE3_o[2:0] = {1'b0, 2'b10};
+assign HTRANS2_o     = {ahb_aphase,1'b0}; // non-seq
+assign HWDATA32_o    =  adp_bus_data;
+assign HWRITE_o      =  adp_bus_write;
+
+
+`ifndef ADPBASIC
+reg  [31:0] adp_val;
+reg  [31:0] adp_mask;
+reg  [31:0] adp_poll;
+reg  [31:0] adp_count;
+reg         adp_count_dec ;
+wire        adp_delay_done;
+wire        poll2_loop_next;
+`endif
+
+// ADP_control flags in the 'C' control field
+wire        adp_disable;
+wire        adp_stdin_wait;
+
+// commnon interface handshake terms
+wire com_rx_done   = COMRX_TVALID_i & COMRX_TREADY_o;
+wire com_tx_done   = COMTX_TVALID_o & COMTX_TREADY_i;
+wire std_rx_done   = STDRX_TVALID_i & STDRX_TREADY_o;
+wire std_tx_done   = STDTX_TVALID_o & STDTX_TREADY_i;
+wire adp_bus_done  = (adp_bus_req & adp_bus_ack);
+
+// common task to set up for next state
+task ADP_LINEACK_next; // prepare newline TX (and cancel any startup banner)
+//  begin com_tx_req <= 1; com_tx_byte <= 8'h0A; banner <= 0; adp_state <= ADP_LINEACK; end
+  begin com_tx_req <= 1; com_tx_byte <= 8'h0A; adp_state <= ADP_LINEACK; end
+endtask
+task ADP_PROMPT_next; // prepare prompt TX
+  begin com_tx_req <= 1; com_tx_byte <= PROMPT_CHAR; adp_state <= ADP_PROMPT; end
+endtask
+task ADP_BUSWRITEINC_next; // prepare bus write and addr++ on completion
+  begin adp_bus_req <=1; adp_bus_write <=1; adp_addr_inc <=1; end
+endtask
+task ADP_BUSREADINC_next; // prepare bus read and addr++ on completion
+  begin adp_bus_req <=1; adp_bus_write <=0; adp_addr_inc <=1; end
+endtask
+
+task ADP_hexdigit_next; // output nibble
+input [3:0] nibble;
+  begin com_tx_req <= 1; com_tx_byte <= FNmap_hex_digit(nibble[3:0]); end
+endtask
+task ADP_txchar_next; // output char
+input [7:0] byte;
+  begin com_tx_req<= 1; com_tx_byte <= byte; end
+endtask
+
+task com_rx_nxt; com_rx_ack <=1; endtask
+
+function FNcount_down_zero_next; // param about to be zero
+input [31:0] counter;
+  FNcount_down_zero_next = !(|counter[31:1]);
+endfunction
+
+always @(posedge HCLK or negedge HRESETn)
+  if(!HRESETn) begin
+      adp_state    <= ADP_WRITEHEX ;
+      adp_bus_data <= BANNERHEX;
+      banner       <= 1; // start-up HEX message
+      com_tx_req   <= 0; // default no TX req
+      com_rx_ack   <= 0; // default no RX ack
+      std_tx_req   <= 0; // default no TX req
+      std_rx_ack   <= 0; // default no RX ack
+      adp_bus_req  <= 0; // default no bus transaction
+      adp_bus_err  <= 0; // default no bus error
+      adp_cmd      <= 0;
+      adp_param    <= 0;
+      adp_addr     <= 0;
+      adp_addr_inc <= 0;
+      adp_bus_write<= 0;
+`ifndef ADPBASIC
+      adp_count    <= 0;
+      adp_count_dec<= 0;
+      adp_val      <= 0;
+      adp_mask     <= 0;
+      adp_sys      <= 0;
+`endif
+  end else begin // default states
+      adp_state    <= adp_state; // default to hold current state
+      com_tx_req   <= 0; // default no TX req
+      com_rx_ack   <= 0; // default no RX ack
+      std_tx_req   <= 0; // default no TX req
+      std_rx_ack   <= 0; // default no RX ack
+      adp_bus_req  <= 0; // default no bus transaction
+      adp_addr     <= (adp_addr_inc & adp_bus_done) ? adp_addr + 4 : adp_addr; // address++
+      adp_addr_inc <= 0;
+`ifndef ADPBASIC
+      adp_count    <= (adp_count_dec & adp_bus_done & |adp_count) ? adp_count - 1 : adp_count; // param--
+      adp_count_dec<= 0;
+`endif
+    case (adp_state)
+// >>>>>>>>>>>>>>>> STDIO BYPASS >>>>>>>>>>>>>>>>>>>>>>
+       STD_IOCHK:  // check for commsrx or STDOUT and not busy service, else loop back
+         if (com_rx_req) begin com_rx_ack <= 1; adp_state <= STD_RXD1; end // input char pending for STDIN
+//         else if (com_tx_ack & std_rx_req) begin std_rx_ack <= 1; adp_state <= STD_TXD1; end // STDOUT char pending and not busy
+         else if (std_rx_req) begin std_rx_ack <= 1; adp_state <= STD_TXD1; end // STDOUT char pending
+       STD_TXD1:  // get STD out char
+         if (std_rx_done)
+           begin com_tx_byte <= std_rx_byte; com_tx_req <= 1; adp_state <= STD_TXD2; end
+         else std_rx_ack <= 1; // extend
+       STD_TXD2:  // output char to ADP channel
+         if (com_tx_done) begin adp_state <= STD_IOCHK; end
+         else com_tx_req <= 1;  // extend
+       STD_RXD1:  // read rx char and check for ADP entry else STDIN **
+         if (com_rx_done) begin
+           if (FNvalid_adp_entry(com_rx_byte))
+             begin ADP_txchar_next(8'h0A); adp_state <= ADP_LINEACK; end // ADP prompt
+           else if (std_tx_ack)
+             begin std_tx_byte <= com_rx_byte; std_tx_req <= 1; adp_state <= STD_RXD2; end
+           else adp_state <= STD_IOCHK; // otherwise discard STDIN char and process OP data if blocked
+         end else com_rx_ack <= 1;  // extend
+       STD_RXD2:  // get STD in char
+         if (std_tx_done) begin adp_state <= STD_IOCHK; end
+         else std_tx_req <= 1; // extend
+
+// >>>>>>>>>>>>>>>> ADP Monitor >>>>>>>>>>>>>>>>>>>>>>
+       ADP_PROMPT:  // transition after reset deassertion
+         if (com_tx_done) begin adp_state <= ADP_IOCHK; end
+         else com_tx_req <= 1;  // extend
+
+       ADP_IOCHK:  // check for commsrx or STDOUT and not busy service, else loop back
+         if (std_rx_req) begin com_tx_byte <= "<"; com_tx_req <= 1; adp_state <= ADP_STDOUT; end
+         else if (com_rx_req) begin com_rx_ack <= 1; adp_state <= ADP_RXCMD; end
+
+// >>>>>>>>>>>>>>>> ADP <STDOUT> >>>>>>>>>>>>>>>>>>>>>>
+       ADP_STDOUT:  // output "<"
+         if (com_tx_done) begin std_rx_ack <= 1; adp_state <= ADP_STDOUT1; end
+         else com_tx_req <= 1; // extend stream request if not ready
+       ADP_STDOUT1:  // get STD out char
+         if (std_rx_done) begin com_tx_byte <= std_rx_byte; com_tx_req <= 1; adp_state <= ADP_STDOUT2; end
+         else std_rx_ack <= 1; // else extend
+       ADP_STDOUT2:  // output char
+         if (com_tx_done) begin com_tx_byte <= ">"; com_tx_req <= 1; adp_state <= ADP_STDOUT3; end
+         else com_tx_req <= 1;  // else extend
+       ADP_STDOUT3:  // output ">"
+         if (com_tx_done) begin if (com_rx_req) begin com_rx_ack <= 1; adp_state <= ADP_RXCMD; end else adp_state <= ADP_IOCHK; end
+         else com_tx_req <= 1; // else extend
+
+// >>>>>>>>>>>>>>>> ADP COMMAND PARSING >>>>>>>>>>>>>>>>>>>>>>
+       ADP_RXCMD:  // read and save ADP command
+         if (com_rx_done) begin
+           if (FNexit(com_rx_byte)) adp_state <= STD_IOCHK; // immediate exit
+           else if (FNvalid_space(com_rx_byte)) com_rx_ack <= 1; // retry for a command
+           else if (FNvalid_EOL(com_rx_byte)) begin adp_cmd <= "?"; adp_state <= ADP_ACTION; end // no command, skip param
+           else begin adp_cmd <= com_rx_byte; adp_param <= 33'h1_00000000; com_rx_ack <= 1; adp_state <= ADP_RXPARAM; end // get optional parameter
+         end
+         else com_rx_ack <= 1; // extend stream request if not ready
+       ADP_RXPARAM:  // read and build hex parameter
+         if (com_rx_done) begin  // RX byte
+           if (FNexit(com_rx_byte)) adp_state <= STD_IOCHK; // exit
+           else if (FNvalid_EOL(com_rx_byte))
+`ifndef ADPBASIC
+            begin adp_count <= adp_param[31:0]; adp_state <= ADP_ACTION; end // parameter complete on EOL
+`else
+            begin adp_state <= ADP_ACTION; end // parameter complete on EOL
+`endif
+           else
+             begin adp_param <= {1'b0,FNBuild_param32_hexdigit(adp_param[31:0], com_rx_byte)}; com_rx_ack <= 1; end // build parameter
+           end
+         else com_rx_ack <= 1;
+
+       ADP_ACTION:  // parse command and action with parameter
+         if (FNexit(com_rx_byte))
+           adp_state <= STD_IOCHK;
+         else if (FNvalid_cmd(adp_cmd) == CMD_A)
+           begin if (adp_param[32] == 1'b1) adp_param <= {1'b0, adp_addr}; else adp_addr <= adp_param[31:0];
+             adp_state <= ADP_ECHOCMD; end
+         else if (FNvalid_cmd(adp_cmd) == CMD_C) begin
+           if (adp_param[32]) // report GPO
+             begin adp_state <= ADP_SYSCTL; end
+           else if (adp_param[31:8] == 1) // clear selected bits in GPO
+             begin adp_sys[7:0] <= adp_sys[7:0] & ~adp_param[7:0]; adp_state <= ADP_SYSCTL; end
+           else if (adp_param[31:8] == 2) // set selected bits in GPO
+             begin adp_sys[7:0] <= adp_sys[7:0] | adp_param[7:0]; adp_state <= ADP_SYSCTL; end
+           else if (adp_param[31:8] == 3) // overwrite bits in GPO
+             begin adp_sys[7:0] <= adp_param[7:0]; adp_state <= ADP_SYSCTL; end
+           else // 4 etc, report GPO
+             begin adp_state <= ADP_SYSCTL; end
+           end
+         else if (FNvalid_cmd(adp_cmd) == CMD_R)
+           begin ADP_BUSREADINC_next(); adp_state <= ADP_READ;
+`ifndef ADPBASIC
+             adp_count_dec <= 1'b1; // optional loop param
+`endif
+           end // no param required
+         else if (FNvalid_cmd(adp_cmd) == CMD_S)
+           begin adp_state <= ADP_SYSCHK; end
+         else if (FNvalid_cmd(adp_cmd) == CMD_W)
+           begin adp_bus_data <= adp_param[31:0]; ADP_BUSWRITEINC_next(); adp_state <= ADP_WRITE; end
+         else if (FNvalid_cmd(adp_cmd) == CMD_X)
+           begin com_tx_byte <= 8'h0a; com_tx_req <= 1; adp_state <= ADP_EXIT; end
+`ifndef ADPBASIC
+         else if (FNvalid_cmd(adp_cmd) == CMD_U)
+           if (FNcount_down_zero_next(adp_param[31:0])) adp_state <= ADP_ECHOCMD; else adp_state <= ADP_UCTRL; // non-zero count
+         else if (FNvalid_cmd(adp_cmd) == CMD_M)
+           begin if (adp_param[32] == 1'b1) adp_param <= {1'b0,adp_mask}; else adp_mask <= adp_param[31:0];
+             adp_state <= ADP_ECHOCMD; end
+         else if (FNvalid_cmd(adp_cmd) == CMD_P)
+           if (FNcount_down_zero_next(adp_param[31:0])) adp_state <= ADP_ECHOCMD; else adp_state <= ADP_POLL; // non-zero count
+         else if (FNvalid_cmd(adp_cmd) == CMD_V)
+           begin if (adp_param[32] == 1'b1) adp_param <= {1'b0,adp_val}; else adp_val <= adp_param[31:0];
+             adp_state <= ADP_ECHOCMD; end
+         else if (FNvalid_cmd(adp_cmd) == CMD_F)
+           if (FNcount_down_zero_next(adp_param[31:0])) adp_state <= ADP_ECHOCMD; else adp_state <= ADP_FCTRL; // non-zero count
+`endif
+         else
+           begin ADP_txchar_next("?"); adp_state <= ADP_UNKNOWN; end // unrecognised/invald
+
+// >>>>>>>>>>>>>>>> ADP BUS WRITE and READ >>>>>>>>>>>>>>>>>>>>>>
+
+       ADP_WRITE:  // perform bus write at current address pointer (and auto increment)
+         if (adp_bus_done) begin adp_state <= ADP_ECHOCMD; adp_bus_err <= HRESP_i; end
+         else begin ADP_BUSWRITEINC_next(); end // extend request
+
+       ADP_READ:  // perform bus read at current adp address (and auto increment)  - and report in hex
+         if (adp_bus_done) begin adp_bus_data <= HRDATA32_i; adp_bus_err <= HRESP_i; ADP_txchar_next("R"); adp_state <= ADP_ECHOBUS; end
+         else begin
+           ADP_BUSREADINC_next();
+`ifndef ADPBASIC
+           adp_count_dec<= 1'b1;
+`endif
+         end // extend request
+
+`ifndef ADPBASIC
+
+// >>>>>>>>>>>>>>>> ADP BINARY UPLOAD >>>>>>>>>>>>>>>>>>>>>>
+       ADP_UCTRL:  // set control value
+         begin com_rx_ack <= 1; adp_state <= ADP_UREADB0; end  // read next 4 bytes
+       ADP_UREADB0: // read raw binary byte
+         if (com_rx_done) begin com_rx_ack <= 1; adp_bus_data[31:24] <= com_rx_byte; adp_state <= ADP_UREADB1; end
+         else com_rx_ack <= 1;  // extend stream request if not ready
+       ADP_UREADB1: // read raw binary byte
+         if (com_rx_done) begin com_rx_ack <= 1; adp_bus_data[23:16] <= com_rx_byte; adp_state <= ADP_UREADB2; end
+         else com_rx_ack <= 1;  // extend stream request if not ready
+       ADP_UREADB2: // read raw binary byte 0
+         if (com_rx_done) begin com_rx_ack <= 1; adp_bus_data[15: 8] <= com_rx_byte; adp_state <= ADP_UREADB3; end
+         else com_rx_ack <= 1;  // extend stream request if not ready
+       ADP_UREADB3: // read raw binary byte 0
+         if (com_rx_done)
+           begin adp_bus_data[ 7: 0] <= com_rx_byte; ADP_BUSWRITEINC_next(); adp_count_dec <= 1; adp_state <= ADP_UWRITE; end
+         else com_rx_ack <= 1;  // extend stream request if not ready
+       ADP_UWRITE:  // Write word to Addr++
+         if (adp_bus_done) begin // auto address++, count--
+           if (FNcount_down_zero_next(adp_count)) adp_state <= ADP_ECHOCMD; else begin adp_state <= ADP_UREADB0; adp_bus_err <= adp_bus_err | HRESP_i; end
+         end else begin  ADP_BUSWRITEINC_next(); adp_count_dec <= 1; end // extend request
+
+// >>>>>>>>>>>>>>>> ADP BUS READ LOOP >>>>>>>>>>>>>>>>>>>>>>
+       ADP_POLL:  // set poll value
+         begin adp_bus_req <= 1; adp_bus_write <= 0; adp_state <= ADP_POLL1; end
+       ADP_POLL1:  // wait for read data, no addr++
+         if (adp_bus_done) begin adp_bus_data <= HRDATA32_i; adp_count_dec <=1; adp_state <= ADP_POLL2; adp_bus_err <= adp_bus_err | HRESP_i; end
+         else begin adp_bus_req <= 1; adp_count_dec <=1; end
+       ADP_POLL2:
+         if (FNcount_down_zero_next(adp_count)) begin adp_state <= ADP_ECHOCMD; adp_bus_err <= 1'b1; end // timeout
+         else if (((adp_bus_data  & adp_mask) ^ adp_val) == 0) begin adp_state <= ADP_ECHOCMD; adp_param <= {1'b0, (adp_param[31:0] - adp_count)}; end // exact match
+         else adp_state <= ADP_POLL;
+
+// >>>>>>>>>>>>>>>> ADP (ZERO) FILL MEMORY >>>>>>>>>>>>>>>>>>>>>>
+       ADP_FCTRL:  // set control value
+           begin adp_bus_data <= adp_val; ADP_BUSWRITEINC_next(); adp_count_dec <= 1; adp_state <= ADP_FWRITE; end
+       ADP_FWRITE:  // Write word to Addr++
+         if (adp_bus_done) begin // auto address++, count--
+           if (FNcount_down_zero_next(adp_count)) adp_state <= ADP_ECHOCMD; else begin adp_state <= ADP_FCTRL;  adp_bus_err <= adp_bus_err | HRESP_i; end
+         end else begin  ADP_BUSWRITEINC_next(); adp_count_dec <= 1; end // extend request
+`endif
+
+        // >>>>>>>>>>>>>>>> ADP MISC >>>>>>>>>>>>>>>>>>>>>>
+
+       ADP_UNKNOWN:  // output "?"
+         if (com_tx_done) begin ADP_LINEACK_next(); end
+         else com_tx_req <= 1;  // extend stream request if not ready
+
+       ADP_EXIT:  // exit ADP mode
+         if (com_tx_done) adp_state <= STD_IOCHK;
+         else com_tx_req <= 1;  // extend stream request if not ready
+
+       ADP_SYSCHK:  // check STDIN fifo
+         begin // no upper flags so STDIN char
+           if (std_tx_ack) begin std_tx_req <=1; std_tx_byte <= adp_param[7:0]; adp_state <= ADP_STDIN; end
+           else begin adp_bus_err <= 1'b1; adp_state <= ADP_ECHOCMD; end // signal error then echo comand
+         end
+       ADP_STDIN:  // push char into STDIN
+         if (std_tx_done) begin adp_bus_data <= {24'b0,adp_param[7:0]}; ADP_txchar_next("S"); adp_state <= ADP_ECHOBUS;  end
+         else std_tx_req <= 1; // extend
+
+       ADP_SYSCTL:  // read current status - and report in hex
+         begin adp_bus_data <= {GPI8_i[7:0],adp_sys[7:0],adp_param[15:0]}; ADP_txchar_next("C"); adp_state <= ADP_ECHOBUS;  end
+
+       ADP_ECHOCMD:  // output command and (param) data
+         begin ADP_txchar_next(adp_cmd & 8'h5f); adp_bus_data <= adp_param[31:0]; adp_state <= ADP_ECHOBUS; end // output command char
+       ADP_ECHOBUS:  // output command space and (bus) data
+         if (com_tx_done) begin adp_state <= ADP_WRITEHEXS; ADP_txchar_next(adp_bus_err ? "!" : " "); end // output space char, or "!" on bus error
+         else com_tx_req <= 1;  // extend
+
+       ADP_WRITEHEX:  // output hex word with prefix
+         begin adp_state <= ADP_WRITEHEXS; ADP_txchar_next(adp_bus_err ? "!" : " "); end // output space char, or "!" on bus error
+
+       ADP_WRITEHEXS:
+         if (com_tx_done) begin adp_state <= ADP_WRITEHEX9; ADP_txchar_next("0"); end // output "0" hex prefix
+         else com_tx_req <= 1;  // extend
+       ADP_WRITEHEX9:
+         if (com_tx_done) begin adp_state <= ADP_WRITEHEX8; ADP_txchar_next("x"); end // output "x" hex prefix
+         else com_tx_req <= 1;  // extend
+       ADP_WRITEHEX8:
+         if (com_tx_done) begin adp_state <= ADP_WRITEHEX7; ADP_hexdigit_next(adp_bus_data[31:28]); end // hex nibble 7
+         else com_tx_req <= 1;  // extend
+       ADP_WRITEHEX7:  // output hex nibble 7
+         if (com_tx_done) begin adp_state <= ADP_WRITEHEX6; ADP_hexdigit_next(adp_bus_data[27:24]); end // hex nibble 6
+         else com_tx_req <= 1;  // extend
+       ADP_WRITEHEX6:  // output hex nibble 6
+         if (com_tx_done) begin adp_state <= ADP_WRITEHEX5; ADP_hexdigit_next(adp_bus_data[23:20]); end // hex nibble 5
+         else com_tx_req <= 1;  // extend
+       ADP_WRITEHEX5:  // output hex nibble 5
+         if (com_tx_done) begin adp_state <= ADP_WRITEHEX4; ADP_hexdigit_next(adp_bus_data[19:16]); end // hex nibble 4
+         else com_tx_req <= 1;  // extend
+       ADP_WRITEHEX4:  // output hex nibble 4
+         if (com_tx_done) begin adp_state <= ADP_WRITEHEX3; ADP_hexdigit_next(adp_bus_data[15:12]); end // hex nibble 3
+         else com_tx_req <= 1;  // extend
+       ADP_WRITEHEX3:  // output hex nibble 3
+         if (com_tx_done) begin adp_state <= ADP_WRITEHEX2; ADP_hexdigit_next(adp_bus_data[11: 8]); end // hex nibble 2
+         else com_tx_req <= 1;  // extend
+       ADP_WRITEHEX2:  // output hex nibble 2
+         if (com_tx_done) begin adp_state <= ADP_WRITEHEX1; ADP_hexdigit_next(adp_bus_data[ 7: 4]); end // hex nibble 1
+         else com_tx_req <= 1;  // extend
+       ADP_WRITEHEX1:  // output hex nibble 1
+         if (com_tx_done) begin adp_state <= ADP_WRITEHEX0; ADP_hexdigit_next(adp_bus_data[ 3: 0]); end // hex nibble 0
+         else com_tx_req <= 1;  // extend
+       ADP_WRITEHEX0:  // output hex nibble 0 (if not startup banner then scan to end of line before lineack
+         if (com_tx_done) begin
+           adp_bus_err <= 1'b0; // clear sticky bus error flag
+           if (banner) begin ADP_LINEACK_next(); end
+           else begin ADP_txchar_next(8'h0A); com_tx_req <= 1; adp_state <= ADP_LINEACK; end // newline and prompt
+         end else com_tx_req <= 1;  // extend
+
+       ADP_LINEACK:  // write EOLN
+         if (com_tx_done) begin
+           begin ADP_txchar_next(8'h0D); adp_state <= ADP_LINEACK2; end
+         end else com_tx_req <= 1;  // extend
+       ADP_LINEACK2: // CR
+         if (com_tx_done) begin
+           if (banner) begin banner <= 0; adp_state <= STD_IOCHK; end
+`ifndef ADPBASIC
+           else if ((FNvalid_cmd(adp_cmd) == CMD_R) & |adp_count) //// non-zero count
+             begin ADP_BUSREADINC_next(); adp_count_dec <= 1'b1; adp_state <= ADP_READ; end //
+`endif
+           else begin ADP_txchar_next(PROMPT_CHAR); adp_state <= ADP_PROMPT; end
+         end else com_tx_req <= 1;  // extend
+      default:
+        begin ADP_txchar_next("#"); adp_state <= ADP_UNKNOWN; end // default error
+    endcase
+  end
+
+endmodule
+
+////AHBLITE_ADPMASTER instancing
+//ADPmaster
+//   #(.PROMPT_CHAR     ("]"))
+// ADPmaster(
+//  .HCLK        (ahb_hclk      ),
+//  .HRESETn     (ahb_hrestn    ),
+//  .HADDR32_o   (ahb_haddr     ),
+//  .HBURST3_o   (ahb_hburst    ),
+//  .HMASTLOCK_o (ahb_hmastlock ),
+//  .HPROT4_o    (ahb_hprot     ),
+//  .HSIZE3_o    (ahb_hsize     ),
+//  .HTRANS2_o   (ahb_htrans    ),
+//  .HWDATA32_o  (ahb_hwdata    ),
+//  .HWRITE_o    (ahb_hwrite    ),
+//  .HRDATA32_i  (ahb_hrdata    ),
+//  .HREADY_i    (ahb_hready    ),
+//  .HRESP_i     (ahb_hresp     ),
+
+//  .COMRX_TREADY_o(com_rx_tready),
+//  .COMRX_TDATA_i(com_rx_tdata),
+//  .COMRX_TVALID_i(com_rx_tvalid),
+//  .STDRX_TREADY_o(std_rx_tready),
+//  .STDRX_TDATA_i(std_rx_tdata),
+//  .STDRX_TVALID_i(std_rx_tvalid),
+//  .COMTX_TVALID_o(com_tx_tvalid),
+//  .COMTX_TDATA_o(com_tx_tdata),
+//  .COMTX_TREADY_i(com_tx_tready),
+//  .STDTX_TVALID_o(std_tx_tvalid),
+//  .STDTX_TDATA_o(std_tx_tdata),
+//  .STDTX_TREADY_i(std_tx_tready)
+
+//  );
diff --git a/Cortex-M0/nanosoc/systems/mcu/fpga_imp/ip_repo/axi_stream_io_1.0/component.xml b/Cortex-M0/nanosoc/systems/mcu/fpga_imp/ip_repo/axi_stream_io_1.0/component.xml
index 5696e41..072555f 100755
--- a/Cortex-M0/nanosoc/systems/mcu/fpga_imp/ip_repo/axi_stream_io_1.0/component.xml
+++ b/Cortex-M0/nanosoc/systems/mcu/fpga_imp/ip_repo/axi_stream_io_1.0/component.xml
@@ -341,28 +341,45 @@
           <spirit:displayName>RX FIFO</spirit:displayName>
           <spirit:description>Data RX FIFO</spirit:description>
           <spirit:addressOffset>0x00</spirit:addressOffset>
-          <spirit:size spirit:format="long">1</spirit:size>
+          <spirit:size spirit:format="long" spirit:bitStringLength="8">32</spirit:size>
+          <spirit:volatile>true</spirit:volatile>
+          <spirit:access>read-only</spirit:access>
+          <spirit:reset>
+            <spirit:value spirit:format="long">0</spirit:value>
+          </spirit:reset>
         </spirit:register>
         <spirit:register>
           <spirit:name>TX_FIFO</spirit:name>
           <spirit:displayName>TX_FIFO</spirit:displayName>
           <spirit:description>Data TX FIFO</spirit:description>
           <spirit:addressOffset>0x04</spirit:addressOffset>
-          <spirit:size spirit:format="long">1</spirit:size>
+          <spirit:size spirit:format="long" spirit:bitStringLength="8">32</spirit:size>
+          <spirit:volatile>true</spirit:volatile>
+          <spirit:access>read-write</spirit:access>
         </spirit:register>
         <spirit:register>
           <spirit:name>STAT_REG</spirit:name>
           <spirit:displayName>STAT_REG</spirit:displayName>
           <spirit:description>Status register</spirit:description>
           <spirit:addressOffset>0x08</spirit:addressOffset>
-          <spirit:size spirit:format="long">1</spirit:size>
+          <spirit:size spirit:format="long" spirit:bitStringLength="8">32</spirit:size>
+          <spirit:volatile>true</spirit:volatile>
+          <spirit:access>read-only</spirit:access>
+          <spirit:reset>
+            <spirit:value spirit:format="long">0</spirit:value>
+          </spirit:reset>
         </spirit:register>
         <spirit:register>
           <spirit:name>CTRL_REG</spirit:name>
           <spirit:displayName>CTRL_REG</spirit:displayName>
           <spirit:description>Control register</spirit:description>
           <spirit:addressOffset>0x0c</spirit:addressOffset>
-          <spirit:size spirit:format="long">1</spirit:size>
+          <spirit:size spirit:format="long" spirit:bitStringLength="8">32</spirit:size>
+          <spirit:volatile>true</spirit:volatile>
+          <spirit:access>read-write</spirit:access>
+          <spirit:reset>
+            <spirit:value spirit:format="long">0</spirit:value>
+          </spirit:reset>
         </spirit:register>
       </spirit:addressBlock>
     </spirit:memoryMap>
@@ -1023,11 +1040,11 @@
       <xilinx:displayName>axi_stream_io_v1.0</xilinx:displayName>
       <xilinx:vendorDisplayName>SoC Labs</xilinx:vendorDisplayName>
       <xilinx:vendorURL>http://www.soclabs.org</xilinx:vendorURL>
-      <xilinx:coreRevision>18</xilinx:coreRevision>
+      <xilinx:coreRevision>19</xilinx:coreRevision>
       <xilinx:upgrades>
         <xilinx:canUpgradeFrom>xilinx.com:user:axi_stream_io:1.0</xilinx:canUpgradeFrom>
       </xilinx:upgrades>
-      <xilinx:coreCreationDateTime>2023-02-19T21:07:14Z</xilinx:coreCreationDateTime>
+      <xilinx:coreCreationDateTime>2023-03-20T20:25:28Z</xilinx:coreCreationDateTime>
       <xilinx:tags>
         <xilinx:tag xilinx:name="ui.data.coregen.dd@16fed581_ARCHIVE_LOCATION">c:/Users/dflynn/pynq/ip_repo/axi_stream_io_1.0</xilinx:tag>
         <xilinx:tag xilinx:name="ui.data.coregen.dd@2ec9608d_ARCHIVE_LOCATION">c:/Users/dflynn/pynq/ip_repo/axi_stream_io_1.0</xilinx:tag>
@@ -1467,12 +1484,35 @@
         <xilinx:tag xilinx:name="ui.data.coregen.df@6d178b5c_ARCHIVE_LOCATION">/home/dwf1m12/soclabs_git_new/nanosoc/Cortex-M0/nanosoc/systems/mcu/fpga_imp/ip_repo/axi_stream_io_1.0</xilinx:tag>
         <xilinx:tag xilinx:name="ui.data.coregen.df@33a003ad_ARCHIVE_LOCATION">/home/dwf1m12/soclabs_git_new/nanosoc/Cortex-M0/nanosoc/systems/mcu/fpga_imp/ip_repo/axi_stream_io_1.0</xilinx:tag>
         <xilinx:tag xilinx:name="ui.data.coregen.df@6e2ec915_ARCHIVE_LOCATION">/home/dwf1m12/soclabs_git_new/nanosoc/Cortex-M0/nanosoc/systems/mcu/fpga_imp/ip_repo/axi_stream_io_1.0</xilinx:tag>
+        <xilinx:tag xilinx:name="ui.data.coregen.df@6f7af038_ARCHIVE_LOCATION">/home/dwf1m12/soclabs_git_new/nanosoc/Cortex-M0/nanosoc/systems/mcu/fpga_imp/ip_repo/axi_stream_io_1.0</xilinx:tag>
+        <xilinx:tag xilinx:name="ui.data.coregen.df@10651fc4_ARCHIVE_LOCATION">/home/dwf1m12/soclabs_git_new/nanosoc/Cortex-M0/nanosoc/systems/mcu/fpga_imp/ip_repo/axi_stream_io_1.0</xilinx:tag>
+        <xilinx:tag xilinx:name="ui.data.coregen.df@21018812_ARCHIVE_LOCATION">/home/dwf1m12/soclabs_git_new/nanosoc/Cortex-M0/nanosoc/systems/mcu/fpga_imp/ip_repo/axi_stream_io_1.0</xilinx:tag>
+        <xilinx:tag xilinx:name="ui.data.coregen.df@3608e300_ARCHIVE_LOCATION">/home/dwf1m12/soclabs_git_new/nanosoc/Cortex-M0/nanosoc/systems/mcu/fpga_imp/ip_repo/axi_stream_io_1.0</xilinx:tag>
+        <xilinx:tag xilinx:name="ui.data.coregen.df@122973b0_ARCHIVE_LOCATION">/home/dwf1m12/soclabs_git_new/nanosoc/Cortex-M0/nanosoc/systems/mcu/fpga_imp/ip_repo/axi_stream_io_1.0</xilinx:tag>
+        <xilinx:tag xilinx:name="ui.data.coregen.df@69f031ac_ARCHIVE_LOCATION">/home/dwf1m12/soclabs_git_new/nanosoc/Cortex-M0/nanosoc/systems/mcu/fpga_imp/ip_repo/axi_stream_io_1.0</xilinx:tag>
+        <xilinx:tag xilinx:name="ui.data.coregen.df@6cac1894_ARCHIVE_LOCATION">/home/dwf1m12/soclabs_git_new/nanosoc/Cortex-M0/nanosoc/systems/mcu/fpga_imp/ip_repo/axi_stream_io_1.0</xilinx:tag>
+        <xilinx:tag xilinx:name="ui.data.coregen.df@47aa9444_ARCHIVE_LOCATION">/home/dwf1m12/soclabs_git_new/nanosoc/Cortex-M0/nanosoc/systems/mcu/fpga_imp/ip_repo/axi_stream_io_1.0</xilinx:tag>
+        <xilinx:tag xilinx:name="ui.data.coregen.df@e948638_ARCHIVE_LOCATION">/home/dwf1m12/soclabs_git_new/nanosoc/Cortex-M0/nanosoc/systems/mcu/fpga_imp/ip_repo/axi_stream_io_1.0</xilinx:tag>
+        <xilinx:tag xilinx:name="ui.data.coregen.df@240a46bd_ARCHIVE_LOCATION">/home/dwf1m12/soclabs_git_new/nanosoc/Cortex-M0/nanosoc/systems/mcu/fpga_imp/ip_repo/axi_stream_io_1.0</xilinx:tag>
+        <xilinx:tag xilinx:name="ui.data.coregen.df@1ec145a1_ARCHIVE_LOCATION">/home/dwf1m12/soclabs_git_new/nanosoc/Cortex-M0/nanosoc/systems/mcu/fpga_imp/ip_repo/axi_stream_io_1.0</xilinx:tag>
+        <xilinx:tag xilinx:name="ui.data.coregen.df@4699d16c_ARCHIVE_LOCATION">/home/dwf1m12/soclabs_git_new/nanosoc/Cortex-M0/nanosoc/systems/mcu/fpga_imp/ip_repo/axi_stream_io_1.0</xilinx:tag>
+        <xilinx:tag xilinx:name="ui.data.coregen.df@5a5c28d_ARCHIVE_LOCATION">/home/dwf1m12/soclabs_git_new/nanosoc/Cortex-M0/nanosoc/systems/mcu/fpga_imp/ip_repo/axi_stream_io_1.0</xilinx:tag>
+        <xilinx:tag xilinx:name="ui.data.coregen.df@2076db69_ARCHIVE_LOCATION">/home/dwf1m12/soclabs_git_new/nanosoc/Cortex-M0/nanosoc/systems/mcu/fpga_imp/ip_repo/axi_stream_io_1.0</xilinx:tag>
+        <xilinx:tag xilinx:name="ui.data.coregen.df@6fb8f114_ARCHIVE_LOCATION">/home/dwf1m12/soclabs_git_new/nanosoc/Cortex-M0/nanosoc/systems/mcu/fpga_imp/ip_repo/axi_stream_io_1.0</xilinx:tag>
+        <xilinx:tag xilinx:name="ui.data.coregen.df@164ee9fb_ARCHIVE_LOCATION">/home/dwf1m12/soclabs_git_new/nanosoc/Cortex-M0/nanosoc/systems/mcu/fpga_imp/ip_repo/axi_stream_io_1.0</xilinx:tag>
+        <xilinx:tag xilinx:name="ui.data.coregen.df@50207a00_ARCHIVE_LOCATION">/home/dwf1m12/soclabs_git_new/nanosoc/Cortex-M0/nanosoc/systems/mcu/fpga_imp/ip_repo/axi_stream_io_1.0</xilinx:tag>
+        <xilinx:tag xilinx:name="ui.data.coregen.df@5557cbaa_ARCHIVE_LOCATION">/home/dwf1m12/soclabs_git_new/nanosoc/Cortex-M0/nanosoc/systems/mcu/fpga_imp/ip_repo/axi_stream_io_1.0</xilinx:tag>
+        <xilinx:tag xilinx:name="ui.data.coregen.df@7e647370_ARCHIVE_LOCATION">/home/dwf1m12/soclabs_git_new/nanosoc/Cortex-M0/nanosoc/systems/mcu/fpga_imp/ip_repo/axi_stream_io_1.0</xilinx:tag>
+        <xilinx:tag xilinx:name="ui.data.coregen.df@4790eff9_ARCHIVE_LOCATION">/home/dwf1m12/soclabs_git_new/nanosoc/Cortex-M0/nanosoc/systems/mcu/fpga_imp/ip_repo/axi_stream_io_1.0</xilinx:tag>
+        <xilinx:tag xilinx:name="ui.data.coregen.df@33f18dbe_ARCHIVE_LOCATION">/home/dwf1m12/soclabs_git_new/nanosoc/Cortex-M0/nanosoc/systems/mcu/fpga_imp/ip_repo/axi_stream_io_1.0</xilinx:tag>
+        <xilinx:tag xilinx:name="ui.data.coregen.df@7c2a61f0_ARCHIVE_LOCATION">/home/dwf1m12/soclabs_git_new/nanosoc/Cortex-M0/nanosoc/systems/mcu/fpga_imp/ip_repo/axi_stream_io_1.0</xilinx:tag>
+        <xilinx:tag xilinx:name="ui.data.coregen.df@5928464b_ARCHIVE_LOCATION">/home/dwf1m12/soclabs_git_new/nanosoc/Cortex-M0/nanosoc/systems/mcu/fpga_imp/ip_repo/axi_stream_io_1.0</xilinx:tag>
       </xilinx:tags>
     </xilinx:coreExtensions>
     <xilinx:packagingInfo>
       <xilinx:xilinxVersion>2021.1</xilinx:xilinxVersion>
       <xilinx:checksum xilinx:scope="busInterfaces" xilinx:value="5562313f"/>
-      <xilinx:checksum xilinx:scope="memoryMaps" xilinx:value="d6592117"/>
+      <xilinx:checksum xilinx:scope="memoryMaps" xilinx:value="6ce5b224"/>
       <xilinx:checksum xilinx:scope="fileGroups" xilinx:value="f0ec23b4"/>
       <xilinx:checksum xilinx:scope="ports" xilinx:value="7c2aad6e"/>
       <xilinx:checksum xilinx:scope="hdlParameters" xilinx:value="cd9ec9b5"/>
diff --git a/Cortex-M0/nanosoc/systems/mcu/fpga_imp/ip_repo/axi_stream_io_1.0/soclabs.org_user_axi_stream_io_1.0.zip b/Cortex-M0/nanosoc/systems/mcu/fpga_imp/ip_repo/axi_stream_io_1.0/soclabs.org_user_axi_stream_io_1.0.zip
index 6427293a7e3a842cbc0c6c8b2efec11dd4817b08..514814910f7ea87bc53616f4e6c0c41f3af6976c 100644
GIT binary patch
delta 8167
zcmZ2lx2=J(KERuqMTCKYfrCMBaY>jy&*2y6<ro;Eb~7^YGB7YC=jRsW=cVSA=vCzA
zyp6pb9Bnzd{{KI&uJ*O>t2tiOo%Fk*+Hxjfb~NM6nRmsfuX}PuV)j<v#=oz_kKZ^x
zeQ`2hkK)@Yo=ZJSGE2ADWtDncUDE$wSbg*EPR{1Ui|_Z|JX&9!QLg?a=DzseZu8yo
z=kM<i+Wo)qLw|f*_|XLtd&~ZwUR|gE#m#zURQ``&+g^z6y=}hxzT4u}*MI-MzrX(e
zZvR`}s^#jf?_TSP?D8-AdvAligy{9@)qf8j{Wo9Ue$LMPhnL>WueG$awY-1a>0>yH
zqV3WWYaOu@HOn7&t>l<@wXQz&OPliL;>7O{<gKlP&*eLv|IW^Sc;9O&Yn|19H|?Kc
z8ond?Mx*2%*%<!A3$)C9=V)Iyp8oK_9kIC&GX&10E`Jfe^mruq+y2m+2_`nzKh)le
zF|4+=dD(kNK}x(W)y?j;U3%xl&F3D@S2tyw<}v4fZ0lUsgZJN@E5EsDLw;FzX8q*Q
zFwY-n^CtZ&3aeps_<j1UT5CVsvEHE0t!DQndv@tYN|c@TUD_A<DRsvi{&#k>R$mra
z-tz47y*GVRt=#ih-D7PEE(+&7yYkVJ$3~W$dn`A6)#pmz6(7|3^Ucz8wZDHqY@b|y
z^PcSVwE?r1hkg9`HgCr1^NuSoZ#!#qG4k7{H}%=Ur(VAN_;C0Cx)}%AviyU*Zkv5}
ziFeS<k2bpD@Yd5S^LE<27u*_8KlD$F$W!>PvUW?JiT_vEE0;DsmO5b@sH-b|Hn>)B
zYmMdKntuk(yjSL}m|B+mtaD#O(7%fEin<>L^}I*sEtx#c_gUt?2Cqvo1>c?~{*&sk
z^;FfJedcmaJ>yiFdE1%`nYXIHT#`Gxa*_UmDVL{xc3|GBuDKM-KYaOc`FlV4v<;27
zCQrEpa{2UtQ}S;mau$3uS-K_1*#C>_luOs1=P7(QS-U0I#Q!Vnl}p!l=PdZ9vUW=@
zM0V44sTH=qn!2~o2-h+$mDx6zN9u&Fr}kRu`m@2cj9dQ{meu|G262}r*j<cM_vAj0
zGZUzu<P~K$bNNpuEz4Z-784l%=8{QIzhq6_lys3N$a}HDiM8>5pNlr#<zF`W|H~;k
z<^L=y%l}0if1dnB`tsg&VNJ>P1(|O7WxN00bKSZi`iJ@M{QdLh?)g7y&$jyhxhX#T
z<lgsw-MsxqSm@!}*W!9T({tbdzxh(^aG<+OyXCc_?+uf>)))S^TzZwYb`GCi?cW=g
zw*S8V6g9|Pp;Z_8rR((T)8@N#riJKDp6)3#S*tLiN_=5V`+Sq~1M|W))8qHo{H&>}
zyY_QR%&PPCCHLxVZKDO(taY}%sTO|VN&P92=EUQyJ{=n>z9-~$FI(&O%JTBt*_m#&
z|I@UxZPPtln{Th#_w3dB!uZr1Mcz*<%Szk&?_OECRB!h7C_lbD-fPt><<H%|`IIe5
zR626AZG6(DmvbkYD}OGiu58-;CUxWW<^9v-;+VIpYpC=dKV*L=VcsL}j3ucW7aZPl
zN=dTRKYlNlXW+llQ~C5u>6hAb{{39k=VY7SYkVNXn)!*v4wJ(!%ct$>xfSKdm&)s0
zv{E_l+LK<hgHQH8SrVbe@@vVDMZpd$C%hF2F!5o0Zhuk4z-(so>(zl_k;N%;+1>3&
zUC*D<$@45tT5$SWRMeyWhT?1T<iF$;e0urk$Cod!r;FBqd{fo_J4>LayIJO4`tkYa
z{LcB;*;~dZN~*u)PPVmPqrLV0*^9Lq8QHlT)WhD()mZ%d`@{M9_Q~<-W$ecU=IhLn
zul=!p&7^C#$6~j?|CeRC?V9br<GJ=pIr}Tt+`q#4xaqa*75<XnJ8Vt_)>f2#`}yL@
zhd)1JpMUxBrlM7J&XRh2n=R?PZbUEJ7oDp!_5bfLKQ{h$xp>URZg$4wq}`fR>TP$`
z+Uk9(IQYu)wYitKSH0hE6OO|l7XRrhyglLVrBg>gr*HJuuBwY+U6T3h)6c^XUsmnu
zWi@@{%W3~2uOf9~c*XYzA2cjAj?d+v|G%Ph;@q<m;j_GAY9AP=Zk@C5j&QxPLCV%h
zUf1`RUr6rLP5)Lk{cf}Q8N1z)Zzg0KX16{3Fz-UhLGFk5?%X>QbJ1$<N4@ZQOwLgu
zF2|m}y1HMy?u%}G?Xd$p0`|UBh!IIunB;tWuh_pgd+aO!?{pO2d}yCUT<O`n%YR#0
zbC*8*Toiiv0&myqOFD9UjFmSBueJ|Y2(GWcG<|-u&$AB<cNfjP(j7T-*WpM1Kh2u2
zb}OmGOiE;LH~+$N!(ZRh!gX72r~Z|>JG<_BPgkCW1n;`TIU2sf#-=^RsuridP7MDW
zSH8{7=;VnI$=m;b_U!y7eO+OeIZt`o<HF8QF~5vrqL^R);dF>v_c=mg?tfo}vt_f*
zMLg~Y*B@GQ&1llKi)+)Lw?AKdPT<V<*tM6Gt-j@?xLrRyS2NlFUG&zMwZDy}Iv0Pw
z%-`=8y!Mjvg_0}pd)fZJyWc+fc8SGWGtmhjwyb$+slM)1)Cd08E4%H|?zg{N@^8vX
zrJD7YKT{vcR8PKQ==9!syC2v7E|GIQ@2eK)Cr0o{C(L2~SpWWeX!*IU(#;w3CUNYY
zEi7NPSV_#&aq_qGzpgWj3+*>Q_WikCQGINB&c?dl8uQ9I*VQcN3ZDwytF<^Rb<J7B
z&93#IR{rFDx1evQZra~~sVhVKIaj48PH~zd^CQTA_U|rUsrOUnUeWAS(K)+g?W(I6
zr)C%2x>KZZd4l!)oh&_*>gO)bKls;l&%PXo!!>h%A3SJt+@|fOTh`|pCqD$7pRKr4
z$%6f<`{CPd`OlWU;P)wyh>4qiZR!2&3Aw75UQfNw`PJ&{e3sXiU-J{^pNtlN)Be}u
zS039z{;t`U{0|eC%=guLw<mhdPmUSSC;Y9=@0`ruF!%K<QG;la@5>#+3VJ-d>JKQs
z{`TroRhp(8+m-8+=kh;WS8w~eV?X=S+gJYFlVN|&dMRSpd?x!FLC&Qc5<Vo?ra#%m
z`{(%t<8Kqo?}<KB+PFdO%Z*9T=EX1Csm62H`$zEt_kcw!Ch0fMYhB`b(Cfgzgb?nm
zQ%80!JEmk?QkNX{quMZHO4_7%!M`dtzfQQARPP&X9O@PH^xBQx0^+|kqLVfrSaU)n
zwf|z^w6(X^21#d4<<kD_{ltVtocq+=X|*Oh=luU>@N|_+GgHyeVy&1H>mH`dvFJ8@
zyx@6W*C6Ze^|m|b8GA(4<K{Dpn`^%QXSb&+&iqJVooQBD*J-1lx0)Y4igx~bGwIrn
zfUw)8$BZ26?>bcm{^JSReCq7#g0}&2rC~d5r*;4Q+AA7xj{9oBqLtp;cC1)kuy#kq
z3*%+qc4Xu}{uE?7CF9j(U4vIzG1dmxjJ|K(D*jb6ZQAy^zouoII_GykiOgz!@^#1e
z+=X+*S1oi2o}N<}82&J-@Z*Dv?{y7k&CF2yewiWp>CM}^X0vA2gLnzaSGU%_Zg;!O
zJoBmPF1O1^93{T(Hh*|_9e?=3aJ|&<$jc(--_yR&51sY;_lNU`{(ruICba&?dwKi)
z*8dFZRerB9zUX-Az~A<{-&y~ET|YP6`bYe3_ANqLuP5cY2Zq*9+GWrcc1M;wMMU<@
zxs|yW_qY~=1RI`(UJtHcBY&>)pp=(M>1i?PQc*i@v#?m7i*nMpO}EV#kXfB~E1$o2
zTiRl~n`b^rr5}9$O*MUbi_Y&!J0@jW|IGs%Ze`yUcIVyhg^M#}4`<Z7=RV$~_9nmm
zl1^!zMy~8lU6W@)&lhg|n!NqS4F9=@kF7fWWIm(R*PUt8u3NCm=lrcdnffF5qK)@l
z_s>;o2d@>J<GvQKXl3-a8!J|Su-ve5USz>*g}*fyB7UB_`D<a|{Oq*K-pLP=A79W~
zn<}yEu4K%rt31EoYRp=y*R$yDxrBKedBV15#7(hpzP6_5vsR6m$@=5dbGV=HN#IqT
zwJWu|cNf=uR_WItRks%&^XKRb&A(W0%WU#$^I4tsg;F(n=|-EEZ@ep&bKq~8#Mz+d
z?H9`uH#MRe$!D_u_{<z$6eF3XUl*!vZ#>rKkgS*)RIhdE$D(ceU%kUN-L&3*IBCsi
z^WBsG2wCr+F1~xpovHQd@8(F(G<x`N;eu|18})0Gb9(md;{MKHB%bGZ*YdXI9^JBI
z;`09k?|rjvKPh_sk4gNk$j>4APWn7&G=6BU-qXCVRsGf<r_iapR@`Hs@;~J0IkBku
z3vPV+RVL9jxAWo;g->34%~JXl_s=l*o2hcgUSfku#yjEZyR+9^xf7fkxz#_r_1@Ri
zm2H<Q&OJ=EtFN5+_vbPBlNY`;F1^N+dM|O6;kH%J{&aKcYRm2a{dGriRZ-ce%(AT?
zlUMDt|MMX+_3l=UqE96**{*(ZGb*~&jQfMHWc~A<DHeY{Py0&AmA*r{Qjed0J^lHk
zXYX+_lcZU8hij$;DNhnC(R^8F<3CC5`yyT5`<}0iqLT}y_q6<}pPFOIIyH4!ruUY1
z=I!};-RGWMy0R$#?(AEV@9w6o)Vrj6_TMAf4WUc5c87hel3;tke5d<<S^2-$Z(i@8
zdu!`r?xV|$&IZT7YG75hi`#73p80snADLg7#ey%DLyP>gW(1zDd+DRI?0xL7_H_;s
z4X0{8%Ct$X@;y?$qRj2^d4*5)hqrr$+0O5>W9Yidbl&`{6Vr6%M~i=IPuVIjV0^rA
z)jws6xHk)DexI4X=M~HM?N!eeBh$BbKlD6by1rJUTW6o`h8bTcMa?qYe>G_FG^@iG
zdKVkW{GIYD%A@MkpUsc{J#zQ6erkJqrd*|9cJxont=>K1-w!ywo4>!#_T`_tnyRw;
zPd|gx#b!O#ShH0<>@L%v6LuTw?*IClwP)#y)0y0LKmS-8Yi_&0(<D6n;B@`)ne+7H
zoi>**-cZ~>d+x{HJx`@8MNckG&sr8T{XN&ZrTW@=Yq}R#-{0{0+lMzhK8C~{{c%Xh
zbJY&xJ1axa=uGf=oj%=t)%5&V*($2n#HP86g}aH>TdwE&#%{-R@69Kzh2OUEscN3t
zRcrrqrA2&<?@YD6_*XXjWLx8Yo_Y3%>B-)+Gc<oJ5&ymUO=RN*<89J<&iRR_GpEJ#
z^dDFKbIxR;(AOWAAKvCaF5hoI_xe*?3HF}-Z}fvB6B1|5e!TG1883ri?=a@jZ$kUz
z*moCsKJeVII<%%f^M<cvMBCg7j<SqTn-e#zesVYC##jCIzxE#SU4G=G*9F~%WvV7(
zEA*L}-^*RO+bF~FZ&}CIsXwMBJqz1=J6AnLbZgbw>aE|hddzbb*SI_K=kTlv3fP_7
z_&n%Bb2MY+-z&l5b0)PtG?QGl&Yt6R<>osNzlQGIDfXwjcxKQtX}0>$u1PbC&9|D|
zRcc#oece~7Ua}=To~^dt_MYQi+aLRP-}@gIU%I}1>dYPMf0=u(>z^gr(-plluj=ks
z!9S}@B(I-**z(|3<eoU|gI^z|&2T$);>)!aCub*Zs55)s@$cKW$G=|8+Nxapm&;W9
zSlQG&8S|E%?LCvb|N8zjQtLeL#Y)z%EZx^4Qc=szY%I+k`mbnp>7w9CpNo%f^4`#{
z#k5m1by8{mn)_!(EndsNtuZKLTU|9#r+58wdA@zUZsF^{f8SsKf1mlA-Fb^PU6+s1
z3Dn}&3)E0=y<8AHrT7rzwb0hqFH5bihl?{mF77H@_Wi5f=f4Z;Eh8sL+FOO3>sl`^
zQvbCo&fi;f`tQV@M=Rg;3+)y1IQf|Kx$7lC$CiCgUql_Bv+Py-V;cB>vqJb<H(oDs
z$(up1M9wVjpQ!dLX?;xReQnRUmV5KQ|L=6=nWufn(#H1J+q(0gUwruU<n!{o%-^g2
zzupk@@bkv%>#yI&t6q379zNG`$1DA{hG(_aw*E2+tM@2~Qh3U^LCLiDP7ueO04E(m
zDF$sNfn`k13q(&h@d+}i_i(&k^N1lru`&4k6qW;B2ka#6Qy4cKYU*TL$k8C`$8755
zbbw3DMf;IrhU+H{PYxai?TDEPGVKZBEJE|RIG8)M+M7~27_?)!bd?MRA`W^e%g8W<
zv3yc7(r4IE@5K9&t+`;%oabk{7#f5ZW_}XTVA*fxvdD%de!lcN%`|}$r!69rG&nx<
zUz~VCL4il!XRorC^M}xi1xiU0`?xM$^jyNQVbL1XOU@nKoZmEcOavA<sUEgT;z*9<
zcpqfJb}%>TqLhj)OIXuVwIU8<fnui?4MiS>V;diZ2r#TEsQ2RVzsJQ8wxQc2lf_Z{
zjN0lXCKm4YrGjR@9Sji*MH2g1S>*d}H3W7DY*FHwb}53RtaZTwCicWfNwa1cHX2N;
zE!w!V(Lmhj@sx*xhkiU%^LS&^a+T*%P|68Smi+k_OvI&F4$e-AVs&<Sv)5pC5QmDR
z&LP3)i;oJp2^gN>=BZDT?}&V?Atvyxaf4acEe=QR7=e{jTN^}uRul^z`L@)h$>NOS
zkKaLBol}|<eymKK!@`uv!YW?Evax#Rn|;r^96Ii<ERPW8Oe)tg=vQWYXes#G<hejZ
zVqajRB+L2E3mrR41)TT~8GN4Acw_P+HI8n@2n(61pRPG=(4Lem*^pEJimUZfLz{tN
zuukf%Rt24PCsML383m1kQ)~)(n!<J%HfAs<8VLJtc)-V!qxsp$h@(&|HE8(?$wM+N
zE8S;#aYQVfp{^{hn9&-2ctfH<!t2%oE@uZ_!zgRUr1<HDT{`TAF)kTzEz<-7x>fbB
zdnv9-O`fWj_S_-CRj}W(S)g7ft9uH=#vm_|r}HW}ycT*Wbu0ex4N7>}$t2kCdWyqH
zAmZUINncZzuoa6BRS2Bsu=sGrR>4nMKq$w=;94b1zeh92jE!HfE%)SL(3av<;b_T>
zEI5_Q@KABXfkkZvB96D7C{!>deLt$g-<Zka)~eYT{DM)DNl3Ay=qERWc0|46x}F9D
z#+?!-yaH*dezF^xS^^K==n#<Q2%FN$sVQ*GNUdoyLz23whmb|1K$(DQ!50IwR}xM$
znj!+ydyKs-ST;M^rrA|+@Xaykk=9h0A$n5w_^f6FZ8^gyN-a-$+?Q+>YigW4W3_?-
z%L;?Jhsu%^c@`|FnZnrA=q=ae*ir9fP|)KcCE9V7N3Qp~meUPZA-`Z{$2C4el1$<P
zd`bp~JB2x%{wK^)b6TwU!<Q#HPHr31fvzt+*36IYs02q<yDMg}21md9?|guZQ?ux~
z!n&>nU6JArI+Hd%n3~Mh^w>o}h{c-2uE~JU^Oa*nw5rBMg?*n7@KvVjww!2IZmr)E
zBCuv{&poTP4mU*4bnr_Ynq{@oB#JL7E$yO<n<mQ|7VViL0zJClGC3**ZtKsfI?CHo
zJXu8Y<cvlGL*Z3Q+zNe40!ucCOC9QR>pI@#b5EBctmE>X<{SUg8LQ=aSi(5?ycTdA
zycVQ5;i%9d9v5ekkmiV(gNLMA5_R5lyY<vFY@FJ)v&>77W5dytFT7ckd}EJ^umlSH
zvvWHa#QA7<-YHAd8;%lZOm?L_R$*CN&^Onaqsd;=(om%#B2?T&%Sn}`ev*~4Eo)(*
z?DIncClwP~-B(RuS}1z3kju_t&cy=<E6+I82rXIbu~Cs_ML=HXafz1aM>3@x`I;gR
zp5u0{H(^<ku#huQ;T<Q}xrq!(+oO$M&S80Y^U{M2Z5so$7NtrwJLncpsp3xZogk<Z
zV4z^t5#T1$!M8}M<%CYl!Jg8BiBTL;59et=VdA*q=DDR?AVP79&>M#z9CNaoZJGq6
zvz#X|70zW3HDlp@l&kHtQzWd}U|Ub|X_c0*wNAZ?^%BR}H`yqpC%l>9soKl-v4nMT
zP!Lnn=Dx~CWu}j<mTD(=hH@NI<ULmKfvII{s)x}j$2lR-CmmnlXj7uZ`lzX?;_fM7
zk-5zYIg-JPO#U!L2ucXPa?COG&NfL`IA-*;FDgk<$I?)UIY=SFJErpfhQ@*r+07D~
zjRGtuA9Orts&DEJ_{AO~$k8Y4cX3l0<Drxe+f*+$4rY%G;Zl}D*)0nLvzZUw{chBH
zMyRRX!NmDmlf_Cu*`*RqwTpc!j`OsrmI^W%vK+ar6eO@Lrs08Eq4JWC3g@&hc^L31
z<kc;VP~>&ij`{fMoj8Yb$HWH{Tm_yv9o<{3!1vk1HRuiBqk0}G;aSHXIGkzqh-h|<
zX;#~Dozd~bhST~6y^J5vO*7f@=afuKqw$Hu6(6~|)q;As4z3dDlMpiCOR;YEVEO1d
zVZ){x9noV#O#TmzI=1gJRLeACDGY1zZkhN+fT=ubM(~lQ3tiuoq9oie=<rQ!uJ{oV
z<-fD_fuezP(EkRDFqQh$qD{Q54-O?xsi{4xC=spLwDnAL!JH|@VNE|i%*)o>!u)ZU
zs91*v=i}6@(=DGB)>SQOTD8EGMZVE}IWMQcH=d=RU9u$BFE!E>VJ-}F(UR3^+^|i5
z@><brjuNNuXsPtJ8b}wV>K;?DTa|oovw#iD6(N^E1Fl0k9xNXZHQy+yzwVXAzOdRN
zIWU+<v1EFemAK=b3A!_%-aGU`P1kHrlZE+7C$8YBZ4cf(PFOruuIawZ6sJQ998rma
z?#xM1$7Z>mbEqj;6#9hkNcjRAi8XT@8KU0p*kb6gVXMz30n4@x3LUavTbh16naC|8
zT%?%LnyBYgG?!t6(&FyErix{Kg7qg2+Y=seIO!w^-2d;cB+?VUQr3;{;E$9U#gYac
zi^I%H`Peot)?U#a)@bq4+xF@iR*tBL9a$=y`9I6-HPF6tJ0a%Vnm^u~4=MFJJ&*~D
zn<d)WTHNOt(Y)A2OWom4ko(q8I!zJlmUda5bEsL?ExCPGQ^fkGje;qLEtQc%DHG}$
zKK|L{62UHUx^c>m2P!=$F1$*xXg$ECEzf&gVa-|-O|vb0PJ4WUV_pcfCp;42*K6RI
z&bs*NQc-~b?FnIF%{#U@6+FEp&*7-W-;u%kxGp}?;<>^;3BNqu>x@Ub)`lGW&5<;}
zuWDJ-0)dFcISOwbVg#qe+-4EuIv6|AaEF9reU5(ctCB-pEuAxiQ)L)GF5O*lBa-bA
zqmST{MJ^5zbEkAzwL0vvZ|i+Br(s63irFbHzJsTi&8iZ1n6pXMDN9L{rM{J0oAbCp
zO?2OyFg7=rV}eNr3EoQ%I5mF=U-3}KLgIb@#Rij(QkJH@513r$Xf=x+^y1i@xaH|<
zPk|bXyn2)COwKc=uN1$eHSKm|WoB4G!9h!be|Ci-YRAQz!c>+!aSAX>ZssdaRs8Y$
z<jf`4ns+cNeC@j|b>wRD40frE7K5e@B`k)V2VE7sl$jr^MIRFU$mMA8hw1aDGfEt5
z6#8|z1hzDtHqYp3c#z^Pxz|h~Z+}XQn~LL`^5UhvZHD#6(XA^T1QsN%*fhmK!hTAz
zn_)-(O53zU%@s{EZ)t2~Elil_;Vqn_c&63n$R`J;j*6L;lDZwi+bmk&IW|O`(7SJw
zcFZBd^})TH9u76$zM4U2JULEtoGDza)Ui5#QlR2f-kS^&2X%sSIaziq86KPB$q}d}
z>ayHJ^iatO!!W1%#)5|~ORjN9toPG8yhd5T?1V<3%FmkuHqnATB0|Ts)j1S<99>oh
zaY!e`OqH7a)LbFYb{U6elS538f}lQs2lE3LmUd4Afi@%0VxuI1WvTOOL{B;Hd8E>-
zcxZ+Ed*5UKeeMdoev51QoB#LphWGp3YdTN<+wgwZF~0AQueRRYU$2?h^WNS%->7x%
ziOF}OZuF=3S;}v@V0rlS<C%w9j-J@;U2Z?m^3bGu9}m47e?OivOq=w1;@+y?$Bo^c
z0wU7or~dhP#;|qjbFpU`y6fdP8&-?o>QCphK5MA7Q{(M%WA~X!9%=Uv{Q7uisfV?a
zXJc7*<*U0=3zo4&&;AoSV~?hEePxHiOye7zVu^jBCzCn^SNI=N@?};!WTGPT`ap8o
zS-sOS&lgFQRz3V(cmB&S&D{Sh>?K-nhsy^}HQFQHcj#%s|4Xs`t}jKVho9GMdgAi*
zdXl*-)0qjU?R9n-3T3RF#5^;4@l6rIj%i+!^KZx95D{GDf3fu2xmmsw6-u2<RDRdn
z9b49MAf>>g!&mNXh?jEiw+&a8br}3xb|`KCqI)8O8649ty-}Sit;{4OGV@K_<z*cQ
zg1($N<mS)qV(o62FWb*3(kQ7Sd-~nq{2mT5Z<VWR{jHyr6jnvNo~qZNG^KBq&%#G+
z-3KCfK00Am88;z_<K-ha{`8leS8pyiH*;n2tY5iBDQ6SM4P)`m{u^_;SPmtx)VZG$
zKRc*dz;yPT>~4pq%NFGY3CS)Umt3ao)l3d{Ip9$svw8jWye<wF<uxJSw!QWhY~)(P
z<T_hMFTrWclCsIJ0#>|fIcAk{0_QB&+<JeCL8Q?$+2r)SioKdjEN4UhF)j6-*kF({
z<3wG@Ud?)?2M-J$FZ(K|;2=2T!mZ?uC)qls-*wzdkr7mB-G1}-HZxZi!L?l$)sY{U
zbu_SYJLZ4+#OluJm9}`U&AFW=*K$6&&E{$H)H2^GKI6&?o9fL6l>($Te!5w{!rYbR
zWryI;<@RQ-EbBUxm~M!juetTXZljl0rTsqH)_WUXd|x(mvcVqh$N!APUEe=iBK})+
zqvx}~>+c_4u%^O6;9&KRMZ0F~47ps({ciokuTMi}I$z)Kb!&2>tW^D^Td>(sDb0sW
z+gmnVTat8<cR$~+>!m@0tnMpv{a<N)&Fl5ztbXj8;rn#<`#QsBmV-;yN|`<{Ex7gR
z+Ld)uo}AB{mWTO!hTe^4KBoWs@am+1p1Auh^WO76V+>8*`R{4ye(|cs&Gmom5i{ic
zD}uw`#s~Ut{w?b#!K}BqWV4Ui3|2nWiSx;yti73j$xXJm@nV{wGudBPcJc}v2c|4t
zFms2t@MI}lT_zX3$^N>UlZ$M%m}clt_SaRMyx-Q6$=w*r<eRK%r_J;b#^s$XWz0Rf
z-;M`l>EwBK(o6y7lXu&>E0<a_FeIhuC#C3>B<BQpv$8QTFfed2a50!OGcdfg0r3Fn
C$Sl<W

delta 7879
zcmdniz__%oKERuqMTCKYfrH`sir}#76Yfg;WEmJLmN7E$GB7YC=jRsW=cVSA=vCzA
zyp4@6mNuVOH$Q&irNh_GIIG;zzZbE2laBhTk84#dPoCrE4&SLQvQkwua#sBQjINwG
zDc`LkU3NtmS56U*;p4Nbv3Smq!DRpc^S4dAi-p+^FS=j7x4!%Pg?D~0cJ9-!5?^1w
zf6o5jo^Stsevog^zrM@Su<Gfr>EVClUi6j)ZN2y5YVJkds_pB`_xHJlumARaf9>yW
z<@2{p_j>2Yb@zI#M#=mqzxF298)&W5|Ng7F`>(y-9{b|>!%J`4|E?*jD%#iI`p90e
z<x9w=w;Lh^KKJ%%FH@=rtN*=xk-5ywdEC3%>u=wjnN=rTwa?x{;#=(X8;Ox`pZ`6&
zX6K>1hxpDsc=w=6f-Q7o=A)RM^LFyEKil?#$Gtg0&)RjrmhHKyjC!7rj!qTp9{%34
zGwEAZ#U<%hM-x4s(>*oUYR^qlN}qe!-Y<(wr_*BpZZ2zX+4{ZK_9@+SYxhRi`^;Xm
z$?M?y^5FIQ=|{ymw(P%?!&GBpkT=C^&DNji60YQ~JhUM@Ps<|h<n)J|?05W5Sm)<F
zhijI9^<HbXQonm5_gEW)3&T6lu6&g8z{qlQkL9MX`dsO|<_CBFe6#dm?dRJMe^1_i
z^P=qZwGp$XhrRsxHE+i0^MNZbZ#%o^Lgcri`uo?}PQ85j@!{?NwGju|GX0sB=FYBM
zD9!NH*PB&(i7n@pZMn}{^BATaz8_t*)A7#afXurYaj)DGGA#>uAI;<NKJE57$eii)
z^UMCv`L%B-yzN}ECEHlPgn7ZAf8Rd*`H=Wms>POb@-*LPsd)^Oo^YSDvtJY6yg}XZ
z(x#Jp&hR?a7ggNqJH~ryUW?~#v(HZE45u=^?Jp?2^<1ze7i^5oJh^?f)xS10@m`w8
z;ssX2c<TLIk(>$NOah{|%@p6o8F1^^9o|Rt+PrRq+``~}`^6^5TayDaZ>Pn*P;<z%
z%;LQ?kIm~e#Q4PM^a~2_JXdVVGtn<)-cbLiuB`6YGl(;%K%Hs+_RwjzME|BGsgo;b
zN;f>&a#v}I<BiD*nKx77(u7q`zr3oKx^$7`l4)*<6K?OH^X%!bGW(f+|L$sDefOvC
z)3-m@)1IooG+$O7`<CVSzXz9k;@+42-rJq!y#2%a^7}QG)|KBaU32BFPR^*YtiLDy
zc=PrfVWEd>--_$?Y|nlFfAeMCw#9uNe8p>?zGGCK8u$2H@q(+?zbts{>V96ZwEg$=
zC*us05YhcQRY#wGefm1q%v)>w$<r!*o>MIh_I3xnJM2HpI^jI`shiW!&$pjDZ+@xW
zvI(y)zn^O!?{_{-=h`(!|7|BlO?Da`O}J6WSTC%kbI*2$^`gvf58L#r8soDo=HK`E
z9d$mksi0u?(d>2qq|S%7>Gp@rdmfVh<A(Fxs8^dRS3iC7;#$Jq>Bk=KnH!rY5Vmrn
z>Fv*|YR&f~D~*l#w@(+hI34%y+piB9k`GNis+klr?Zo~)Wcw^+-so|9sYCM?bp<1i
zWA|<EB*Z1v3oD&|sc#f!@i%#KqmylVuUx{GuMC#FdS?wzu2j|EylvX#<jBKQVx&6G
z&f0U)+n{oGNtdd^g}IO1VjVb7Tw@jC)qC)Vy@)Y+vgM9_QmF@L34e}=w$ah6N=qyB
zUMb8RyY1Q~q5rJ$8+O%RxcA`6<DVa2zMOtu``YH$bKkA@G|;Q(E7~<*w%*3t(*Eb$
zCpE39bC&3z`TAzdx`g|)C;z^1<=U+T|26k)E9(E;{`mXcdiDKh-thHk+TFCUulm1U
z$K&<9$LnsF*KeB>{d(U0$J^u$x0~;~mM_&(c<`&=EB3b97`Z2F>};%mmy{G$)cx63
zTvb!H=Mb0QCHZ-`jCH<ETl&5}jNSX`|Js^AcWRTaAG5NHzJBaz+2x>rS6_U)y5q!S
z>#*~Y`vaqx{#w4hq`-6ddzbaGT<2}x+UDoyAJtnc@v~5L!m^j2mw#_x{<_mlEaAp%
zt~!G|A5JN)|M2eM!$7WpKI`}PfA@9HoO@OxeAc%ezZwsRTq*kX$>Yq439g%Gb=_ND
zf77@oxa!-l33n%(pQ$U`Y@u*D=^D@BhkF-j9^gK`cjxArI~SE&J`P^Dhox=Hik6<!
zS6A0-|9O$U@0U+w;lirBjyp6?wR-gBe%JVOv9kQryI^La&4>0$#Fd`Cd;GVRHFxQ=
z&qbk!FYtD)zN90!$5eT9@M`;Th2VOlY4ekOo_%1bzq=@Mz4&IM()OeEQWK6(ov`VQ
zOwrYhD+{uDU;Pwzh+X$NBH;Xgr4^eehc8$#Z?62j?N(>!xvvX*DY#)?@0k}>JB&l$
zoIIiR;)LAX`TOckHf{ClclfsAzBKQzyZiap{?@yoXKwX8b=4YH_Avk0lBQbuU6X%J
zUNT#$X0@wgYEo@Q{qg2f`RKBsnusM8*%jBNYk3bR-7r|R^W&el`(B-kT$@*xuw2RM
z{j($O_f~YcGG$!)7x};Hfzze$$A0{~v%Vnys%Z3@c;WlLdLM78thbmLb9J>*R_L*e
zzNxyuCf`4F?*ZSd8Ml+n_(Eq!eT^tN94WC>LhJY<lS|L`B{4smTQtF{e(8iGhi7gJ
z-D<VFh}Um+bl(=KqUXlbI|5e~e=*%*-+p~MZ_bSM#qvBx=MDQ4%PwseQ9hSB|Kh@V
z=E+5>1%0Rbmu=^bKkIu@e#W~EJNCSrbt%T=ORnnW*Hf>1e%<v&zU8&$kL_E|KUv%T
z?Qoq;t#R`M_M>O#Y_6H{GJSHFb-s9Zy<O8Y%e4C2(U+buCOvPfVm&Li`?s@!w#6|O
z*9S97t4j-QH;eEKzdC*LTy^pF{quN_#4o;-n^l+Z*Zfr|^UiMhCi@#f&ZQd?ek9kX
zKiS3m>-h}hzKP}c#GWaw+@SXDM$of)@soC{@!kFY;dny-0+&El^MmtRmn`+&TU5Sv
z+X~Hk;nyC$yT4pu{JiDE_M{CrW_#}PfBE?Ck7n0yQ{S^8nyyo;zvny0NG#6jJj%3L
zY4H@>H227DS=+sGSA;T!J)3?eGa^Q(!CLosM&ZsMZxc_3cCs-P{rp_L@bgX6e`h8y
zU^SHcC6epibL+!a!SBfe$w$>I&mZWXJ*BihG2C{&^rL!>{ZCDdkEYJ7dFxpCaqGfg
zIm|UN8r@~F8+ih^hs3?9Z(9{v@L6Ep+*7OVmgSs(np9Vx%sTb++$@cYCMwZ!R}^Ek
z_2queb*+xuvaRrEoavMdsmZ#AuLRc3mB{{BoBP)F?%^|^wyn$G8D{)-o6o$ZVLoyG
z75Ar|`soK!I!U))|CPYHsp9-~vv;YwZ5BHFs7@kj%^!<`)4ge`vyT2XxD!#j{>HDB
zf&C6?mAwluniLAO{e9<KvG?`i&=*sqZ-!noIeK^Ry}#8{pZ&7?v-d;&fBoXC^8dcK
z`{(!HKVNTLb!BG41c4p@pWduJSpO&a`EuDm{dbw8O0%RV<)#OQ)=#S6WzZcKlgF7N
zCVQq%duQtBX=g+KdcI<s9sakj?r+Jt@-+)xE^o-$8QA_Ia>vG3(?7r6x$$oDZ^n}w
zUuk{#b|oX*?A5unY1dz{&bOX6=Wfyl8SiuZmfhQR|E<odSN=iI(=T?tc8`Cd6Ls9=
z*8RZSrIEtlw+ClVv$CJMt?|t?sp6IOpRe3FwlO;I%<^-E$yal)pLgipwSMMP(_IgC
z#y`)U`vBq`o7vYNvqWFEyuYzc$oKH3r*5)`o<BHNwdaAE!>^AkHhz*^_BD9%yX>^e
zUcV0;UtiE#`_!nU+Gt0}>Y3keN1AxY&Tzdw`QV-;$#r=*_uTl;6TSJtGsPM)v-RrJ
z>T|rG*BqDfGT}WvO}dn0eyjBBPSx$Nd*mm`td=`n#g=tt?^&Jo7kTZ<4Q5(iz9GkJ
z_My(YH*MwT%Ne^3Z!U;vTODnt|IPmJHJu%m9P^vczUEZJbZ67aw@!~+1CkXpgX(WB
z{pgxI|Mm1WDVxjl+K<*te7?SW@}Ei8`=^TUo^osI|8s{djg3+d{q<H8Puvjw{KkyR
zuLAEF)AV9Eb`@_cu84lqlfU@y-aUO4eUr7<{fyl4rK)sEm0(q3g4@CH$fv3|b(JnY
zQ!iO{#kE47;s445=ggw!Gvrk6H{nT0znf9Bu~c;(@66;=`p<fU)i}SK&#Kq=o%Q?3
z(}z;cv#Px{xqoj7dl4Hy&0xy0;y(S)C%a#rH~;6+x=jDTmN1Ra0Y1JPLrtHrugQ=6
z_~Whq@wt~LZ=T%0Il4|h`0L$=zrSn0UdMXk<lS#;8|TC{{ufa(-v0c0*1w~6x_19>
zZwtO0Y0b4gv#+1+dSYE|(B+M-Ju~j4&!~@IdZi`BYS)w!`}yjgldCUITlQY1G;(cW
zx%8rzKT~ro8%`Nr-lBT*aN}+B?XKxXnOPUtzw>>|^F41<koePSY4soZZmbHL8oRo}
zmZ!P=@}0%;{r&$+zddzcUiS8d)5gsC&z9=*9$@O|cQ+F^*lRIiKJ$Dt@riaqld1y`
z^XU9etvA>>V_*48`CUwjjar|N7RzL<Fnf8=d8;vpz4LVWeW9DAeujKu3|jN<Lrt*s
zs{%`9yBYS*k-r=Bo|*Vv-QRw!TiK-B?sHdo^MikvUf5i@9{Dz@;!^S5Z2414>`Ond
z*3wJM6<Rv;Q}h(6z*juZ=6#0>zBnJ+I^m1R|ILs7J#ybwKljtTr)N5Hj@$|>^m{Ax
z_^R@T3BQl)$NO3Bmz_UvZq2V7Gj-1v30<=iTAjyO_e3IMfBxSp!Tg(7pKfX0QS<NQ
z)GgcY?=%SyKREq7=gfKf^RqUUFWyjme)il~E5CR>xzw#2yz+E8>-9_18>N#AOXQ`?
z?#axPHLsf*uDNf6>m;pr^*rTSqQ=rHmw(-SD;V8#&aGK#yL(VkZen#xVR}m7=T!;y
z4-P;0s<&QfmDs)Zdq-cqejV#|$>{aByHEU={(O{o%B1kmlm{Q*YJ53W&hXq^;eGBg
zo(GfT-kjf*&gyjjM&1sdy{*d2BkK%p<febHzTC2E^>KOr`+MyF75w?Q=idG1`j1T?
zpZ`tO<ks>jF18Apc~kC8!bzooRQ->y3%6)*XPM`+JL;(K<-An~jNTq`-r_vjUcaX-
zv_9VCEx2cRX<6{66xEkv9+xLcabKF=*;vm1>Y+m)OZ~>~t#f}&y?f?u)pl#Y6HHsH
z&R3gOnI4_pCvc7V0y8`FYKE+Goewb#^|lov6OJ#Rw@YA(iO=?vA*FvEBhJl!%C~;~
zsl!_z+@E=Rijl3s41J-~b9S#>`clkL=I+kCSD&6c{&@L$!Ta^c)mQ9h|G)F~-}_%f
zzgI=f?EJl|KJdw}B{L7M*fI6>wCl0+57?icP&il0k7Zr#(brqKWAyXeGMDxE<o9~q
z6KVds+Ol5#%XM@4YwFk6%zgQq{mPmdw?m5-SI#msH`@L;?!Qs?4z<eir(SD6TP|t6
ze%-)e^Ui>$`rD(#twb%~Yfp1-vJK%pv2%*&wY?kbtivCyso(PX-VMpMuUt17?VGdD
z{)d%R?A}}V|9^XX``(84yF5?D)fa43S*f!_Wnl@|@`uYbY7f;jhK07aepzaDJzSjm
zaj}E-<=;i~f974-KPTrzkG!nb-bbrh7sQ=?yd|WtQf6B8oa_HIPHJ~fQJPl}r_#fr
z^hMpJ?$EC}55hh69eQ)0`|ql&D*|6CUEV&$O0`%rS;am6%~b1;)k{xwU%37GU;T!T
zgT<}Z?aSTw-<w}4Cp&L`&9C|$)eqv{)=N&auCXh7U$yt|YL{PsAFVRx2>-j(c3EXY
z&}#qSR+i<gL2?aRL6=YHwl3gQJtDM_afK37qLu;2iU_fi4gr%ymxy#x_61y=bE=l9
zFod#vJNZMA+d)*!$ArU`VO4?Dia;Tz@C^!4g8Yo4Cl{+I8ZfL%NNp;VX^O2E^r+BM
z@KIPL!!=EjVO4?VmX0G10j$cs1qBQtf+r@Q*u$`Z%k+pek5WO=JY#Jp2H%!tnobJ@
z9^De?{3MW6o3~@x495d48Ja4A0)O}~PCTKY;3My|SJ}(CBeY_HQj)|*u1gm^moThY
zw8r$3bA-6io6DOnI4t0r%JaEH@l2{>{T}brh8&5)-PaUeDy|UHF`elA!Ql+2;G!0T
zMv3EH!Hx_o4rwadxN0+m9Mn@<D##Kt!#C_G3x^n=w{lKV2Sdn0k;FdM7Ky%F4S^j3
z0fKDanK~@HodOaXn+*yLEz^7y&ZN$F%E?ps;gmMV$i``g{T-Ihx$PTfJH|vw7I7)o
z-%>aE>C~*?GTCQ!0!PPY@wCt=CQpIc1xJ2n7`8~d@O)xwwqQ@XX3@pkQmnA1cafQs
zLo2t^)=dICnm9}Snk@EB@epXYY^jL%Qk_^Nz+-RPGuc7m%z_6^eF}d1lkZ-S5#-1&
ze<gd(rO85;`^@7GM;E^%R%b0)LT4n0B(N#g7b%$}<;k`zWlx+@dDdZ$XP|J)Q2`y9
zKCjAb#T%k0H}W{}m9{!%Iyo1d5%He6N1)}b=u977b%kkXL?r!Xnj5&x)dX@Ce9{(i
zirr~kpqm=!#+EqOYvz^At2_tU6JJeSCd3r3@$BRYSB@10*%D?vOu2gn{1Q3VsJdmV
zJIr}qZ{#=ese+xjU{rOVB+Ip=lc)Cvaa7-oP(A)ehGU(^Bg1q7vG!X^st#|a2)XW5
zmt)cp@k}vn+2P5hV-u)wEqS6*6Aw%1jxx7kUPsYaD-7h0m@)C$@bY)87v$hHlalyt
z)8xLyQD?@+uh-PoSsX-rS%g@cqQ&MENjkW2=xkV#qgd0Wkjo`t!&vw$DX8Uu3CrR`
zBF8gdGA6RBI0-!cCe9GL!6`<P@gU<)2@_s{Jx0s>A{Y;?NXT*N;A_!3b>xT$N3o>v
zK~ILlNm44Da~vYd1XK&Y81TK4aGKF{BOtxU*vo=tvy*L_T?Gf@WJM8?`nNppOSXzN
zHBO$fTET#2mBHL;Z;v?5aB%#o!OX%uU5TYxpf%xv#6%M<f!&feQtv}s3b<6}EOTqR
zF;m5eMNgro;{cDkp906@=E9;DH|LJo636!Zxxv+-b;<Y*Pse+;nU`)^b1{ng<W~OU
zZ`4*<GS!;BFq9?q%r1tc$x~R@%hU%8FsV09P`KgPA=pyr5yXG!mX>2D+ed5uHxt6I
zIYm?!ESWHkt7+@hi_yzPId(Tmeq?mM5v)GV?X+V>nwW3O6sHGX8zy-&9=wq>f7t}~
z!as*rhTm!UkvB<6S<+ZQ#(1IDCWc4BEKMTcoSbi5^mx5dA-IIwLG+QycZI(Hkq7S8
zvokx2HZ==rIBnP(!jZDE<w0XcM^l!-Z0(4MW`mx$wFf%{75ah<uls2-HEy$ztX=8w
zX65M_VvZs%d-^AC4r%%kYyNbO)Efn#G^yB4g+fePbCRD6Gzs{7`SEZnlwD=*?F!&j
zoVVnhhreS?$nl*9E=3$M4<~9Zaaf>a;n&SyFK|EO!2_E#g*u@nYdx}^IYJiR5$ZSW
zIMI38q*;b#bJJY$t_+TlgHFPW9PS8<%u!}MlDR$Qk|n3orlkiHd6O51xSTd%I~esy
z<Ez+_c?!xN3lbc71Qzya2r#?2a!icmm@N7FfznoifQR$6pD=OUa`W8MEfAtOMd*#g
z5so=o&Gj}-8_ce>DX>1W;$M}+A$8<-*o-30HEfAFlFz4ka{T_?BIRt*BY)yk!<@!K
zC$*_2Qb#U}_IP=6b{w{P#@femME{JT=fSm30(O@Yc-ZwFBBI+=7Rwx&{wn5^gh@xc
z-x7zI0D<+<l}(F^1$uOoy{5FuH)t^_JK1(9r)Bm&<EcLqv+Pcww@!<$x?7S17fWuZ
z_IqhF0lU!SI&NMHI!!4BM~WF0T{Ipuui|Jqz`6YDrZUDR<0JEoRGC{iRkn0mHSOTL
zbz#L;M!|R0GpC&qa%yofalY2{BWSLbmm$k<x0xUMBsrpADX}DRbS!sWqTsWWK{4l%
zo5y3vn)M#a2QBIwcKmEjYBk{r+41P<U44Nx0p){=-3mXPj_xg1uzNPKYspsYj{FNV
zE|{>f9}-te<Yg=5o%JA&okj7GUVURGPe=K-B@3UfKjSE2(QMNrzJEi4(%L}92+>1=
z&P>PHZ=O>Wa{Qy>5fN!OjVqbEarslDj_tb))lNz_{RnIEZkhO{UO?>K5rgF&tc_jY
zl%gc&FNl;;V*mJI<Cb|v+=@;KZA(5fevF(rMe~H2h!aP9VAogC_Jo{Pj%!BzN(DjZ
zA~_$me~&3%DBE#;?FI)IPYM0tXtg=)g;$kDLs-`;9^tUD%Jpa{NYj|B9(1@ucdF+?
ziH>~NC6^8gaa8{{x*3%yTi>$t%vz^Q5ghj>XlEO;eOzqy%$ED0bAqm;2<u{n3TLGb
zak(Q4cZUU8a~wV_**z<X!@GRtiekYdyf-IBzSHf=xRi8Qv*W#5q{r!yrHU=TEpB8i
zZ5J>XTspykgGo#0QHH~g)HRt;c#iP<ZRxtx_(N8MpDjCGVZt<Py<8rF9NqfKIxc;R
zIUGsuwhI;NKAm9g>)a`@<B);4VyhoR$i$1T?v6IW$2*?Pa5gAlQ4}-ixc}c>Nu(!y
zrK}s@!5=3Lo*N|y%#XThVj*#)bKL^HDAq^b@vl~<={Y#GDzBP&#_mk<mc-B%+Yjz|
zv;EWTuvS;8)&rL7a-u{#TZ{V~Z!|BichORJxD({Q^^;E1jde@AEYCUo@ew!9GiBWv
zf0|kOL=s0`q)^HPhL3+XxkRu_+-{t*<AF-g)P+|M7H~O=hS^E=IYvZhUb=O`isN<a
ztZS`&g&b;rA0IGvJl&MAWzQBSrfk+rr?Ld5hjFZn`Ne)nX)3$RmZrk}>kZ}<3+$Kh
zORU$u&UmD6ZOF0T9FOMoRV`~;AP|x`N8znQjNlZf+b&{UiZK%ncStzO=m)<ldBnwX
z{LD(DzJ?!5cNg4<WP8NuBe-Odi^Gk%Q#!0#9roC_^*))?@WD|?I+e9uAT`)`FQ>x3
zO{z{=N}4Sdt=!t2#|4t2`__c99qZ~*K9X=@nnz=OE1Tf@fWwgm2KVF_GiD0>=3uEl
z$l6i5iYJOiTe0GB#_8*m6^<0#$ymqQ_F(!-@k?6MtQ&7`(X!a_K&GQ&zJ*qB0ym@R
z$&~?2N1A#f+jnjfc=T7qC+M}~9fk>R$1`~!y)rz*%xmH_!!g3DX-12HlEBi5jfInS
zA9hr<DoE5d)>r;KtHiNRp<jnfAmHFrX%jaGj!jE@;-m$(#~V2*Pf|Fyd*>y$!ynFs
zC29$<tddxzqbl%>|LL4So=4lS$QeI$v^nULJLN{xkA!(1-om+xKb+)}emXLBd^P%P
z6eSRU^U;<Pex@UCWj~)88nYeJWBPv1jp@<$D^rw?&S}}udqAe%T&rovFI7p=pnDT|
z9YoJ4U7hBzL0c%<XJ*R=ucb{dwgk04;IlmDr6Hg=r{jtg<KwHIsWVDh4lzoqb}g}x
zc1qE1n&@<>;wg(_i(yCTDv?8M65&garTpaWi0;>P>QWF8SN1q^n*Ru6hEmgE6$y^u
znJV*pBv`he30~u5*%3aceu<%r#Mi%zPyVpatXOp7UiXIoTk9pi{oUT7Z+KH4H1G7V
zZqF`*-{wbqKmJX>?z=2i`;*Fc@o#^pCZA*1Ejjn0rv9mcqv5AF*Y17~@7o|EFFYyw
zO<ny{31iJ4C*t=0{X11zQDe>Key_Uvr!x+nD&{WUHtl-<%^7>S-~QHapZly{V&WaG
zx4*UBXC`^1-9PZ_->Icj%UmWg$zJ=kx;(pKmQYS^S9s#9WjRk24~3jdP>*P_3|H+|
zbX#D^*=^$6!Et#)!5ZfNo3^{x6wU2Uy7IC$|F`Ys*UPv3UHmUWB(MHg!>TC{?-q#Y
zwf~;}uIkQIzrxC|b7CjVS@9?CjrU8&v=jAD<;7|YZ7)PEWiZ<A{yAuu!<LX!Kkj@y
z<o(j=OJ?cZy_=sc{i49@WTNuh?wI#WrpX5t72`hTEDMs#+$`_CcZyz5eQ@ID{fp`}
zV;3k!cx|2@vTuf-g5$)Kau$21=xx|imG;neH|wIgi)U<)>t}q!Wb9!z&GvV_VeEzo
zrIm4?V(K;YnHF_zz4wyoMypZ4)XbGXnsy(E-1+!K+@|;mK^!k1b<aC@NqE&}|NK2u
z^gO(liat~=XRLmf^i6Zx^h?YSH-=2x|0H5|P_uxkzU4KsMwaD;?+!P<zux+D%fs5F
zsUffGYOJ~TCSH8+Yph-we(Z0iUe~>&p8DUk6DObfy}ypTxqj0lMn{(S54~O`Jqz;v
z4jJPOHfUd0KlQ?v>xU=b)8JWDn7G6G>>k6rucw^csUUKB$L{+<w^Db!;eTg0WA!Wz
z{T*r&r>`way2!hq=hyYpKtWdb6{%}oW0ziB>p8Jc;<0On?$g!p>&%*64z`5(&iZU+
zc;VBvOY5XuIiEKz4^#Gc4LuyKeC+)1!>f}5dgAW3%zMxOj59QK=f9_+`^BpkH}C(u
z`KMf>1oN{M!JA{vXRz|2P7F_Gw)JLuDLXm9){CiLdvb!F?Bt!c4os0cVCG33;mO)|
zx=hBplN0nbCpX(^F}3SWPS8`Fe8J9=$;=4K<eO||ug!D;#^s%?ZNfcyfjtk%(#h-X
vrJ3x_CZDl)S5C2DU`R^QPfF1%NzMuIW@TewU|`^4;9@XmW?;Bs4dMX+Q4`bB

diff --git a/Cortex-M0/nanosoc/systems/mcu/fpga_imp/scripts/build_mcu_fpga_ip.tcl b/Cortex-M0/nanosoc/systems/mcu/fpga_imp/scripts/build_mcu_fpga_ip.tcl
index 59baedb..64e58fc 100644
--- a/Cortex-M0/nanosoc/systems/mcu/fpga_imp/scripts/build_mcu_fpga_ip.tcl
+++ b/Cortex-M0/nanosoc/systems/mcu/fpga_imp/scripts/build_mcu_fpga_ip.tcl
@@ -79,6 +79,7 @@ read_verilog  $soc_vlog/cmsdk_mcu_pin_mux.v
 read_verilog  $soc_vlog/cmsdk_mcu_stclkctrl.v
 read_verilog  $soc_vlog/cmsdk_mcu_sysctrl.v
 ##read_verilog  $soc_vlog/cmsdk_uart_capture.v
+read_verilog  $soc_vlog/soclabs_ahb_aes128_ctrl.v
 read_verilog  $soc_vlog/nanosoc_cpu.v
 read_verilog  $soc_vlog/nanosoc_sys_ahb_decode.v
 read_verilog  $soc_vlog/nanosoc_sysio.v
diff --git a/Cortex-M0/nanosoc/systems/mcu/fpga_imp/target_fpga_zcu104/design_1_wrapper.v b/Cortex-M0/nanosoc/systems/mcu/fpga_imp/target_fpga_zcu104/design_1_wrapper.v
index ce586c7..84df780 100644
--- a/Cortex-M0/nanosoc/systems/mcu/fpga_imp/target_fpga_zcu104/design_1_wrapper.v
+++ b/Cortex-M0/nanosoc/systems/mcu/fpga_imp/target_fpga_zcu104/design_1_wrapper.v
@@ -17,18 +17,17 @@ module design_1_wrapper
     PMOD0_4,
     PMOD0_5,
     PMOD0_6,
-    PMOD0_7
-    );
-//    PMOD1_0,
-//    PMOD1_1,
-//    PMOD1_2,
-//    PMOD1_3,
-//    PMOD1_4,
-//    PMOD1_5,
-//    PMOD1_6,
-//    PMOD1_7,
-//    dip_switch_4bits_tri_i,
-//    led_4bits_tri_o);
+    PMOD0_7,
+    PMOD1_0,
+    PMOD1_1,
+    PMOD1_2,
+    PMOD1_3,
+    PMOD1_4,
+    PMOD1_5,
+    PMOD1_6,
+    PMOD1_7,
+    DIPSW4,
+    LED4);
 
   inout wire PMOD0_0;
   inout wire PMOD0_1;
@@ -38,17 +37,17 @@ module design_1_wrapper
   inout wire PMOD0_5;
   inout wire PMOD0_6;
   inout wire PMOD0_7;
-//  inout wire PMOD1_0;
-//  inout wire PMOD1_1;
-//  inout wire PMOD1_2;
-//  inout wire PMOD1_3;
-//  inout wire PMOD1_4;
-//  inout wire PMOD1_5;
-//  inout wire PMOD1_6;
-//  inout wire PMOD1_7;
+  inout wire PMOD1_0;
+  inout wire PMOD1_1;
+  inout wire PMOD1_2;
+  inout wire PMOD1_3;
+  inout wire PMOD1_4;
+  inout wire PMOD1_5;
+  inout wire PMOD1_6;
+  inout wire PMOD1_7;
 
-//  input wire [3:0]dip_switch_4bits_tri_i;
-//  output wire [3:0]led_4bits_tri_o;
+  input wire [3:0]DIPSW4;
+  output wire [3:0]LED4;
 
   wire [7:0]PMOD0_tri_i;
   wire [7:0]PMOD0_tri_o;
@@ -72,27 +71,34 @@ module design_1_wrapper
   assign PMOD0_6 = PMOD0_tri_z[6] ? 1'bz : PMOD0_tri_o[6];
   assign PMOD0_7 = PMOD0_tri_z[7] ? 1'bz : PMOD0_tri_o[7];
 
-//  wire [7:0]PMOD1_tri_i;
-//  wire [7:0]PMOD1_tri_o;
-//  wire [7:0]PMOD1_tri_z;
-  
-//  assign PMOD1_tri_i[0] = PMOD1_0;
-//  assign PMOD1_tri_i[1] = PMOD1_1;
-//  assign PMOD1_tri_i[2] = PMOD1_2;
-//  assign PMOD1_tri_i[3] = PMOD1_3;
-//  assign PMOD1_tri_i[4] = PMOD1_4;
-//  assign PMOD1_tri_i[5] = PMOD1_5;
-//  assign PMOD1_tri_i[6] = PMOD1_6;
-//  assign PMOD1_tri_i[7] = PMOD1_7;
-  
-//  assign PMOD1_0 = PMOD1_tri_z[0] ? 1'bz : PMOD1_tri_o[0];
-//  assign PMOD1_1 = PMOD1_tri_z[1] ? 1'bz : PMOD1_tri_o[1];
-//  assign PMOD1_2 = PMOD1_tri_z[2] ? 1'bz : PMOD1_tri_o[2];
-//  assign PMOD1_3 = PMOD1_tri_z[3] ? 1'bz : PMOD1_tri_o[3];
-//  assign PMOD1_4 = PMOD1_tri_z[4] ? 1'bz : PMOD1_tri_o[4];
-//  assign PMOD1_5 = PMOD1_tri_z[5] ? 1'bz : PMOD1_tri_o[5];
-//  assign PMOD1_6 = PMOD1_tri_z[6] ? 1'bz : PMOD1_tri_o[6];
-//  assign PMOD1_7 = PMOD1_tri_z[7] ? 1'bz : PMOD1_tri_o[7];
+  wire [7:0]PMOD1_tri_i;
+  wire [7:0]PMOD1_tri_o;
+  wire [7:0]PMOD1_tri_z;
+
+  assign PMOD1_tri_i[0] = PMOD1_0;
+  assign PMOD1_tri_i[1] = PMOD1_1;
+  assign PMOD1_tri_i[2] = PMOD1_2;
+  assign PMOD1_tri_i[3] = PMOD1_3;
+  assign PMOD1_tri_i[4] = PMOD1_4;
+  assign PMOD1_tri_i[5] = PMOD1_5;
+  assign PMOD1_tri_i[6] = PMOD1_6;
+  assign PMOD1_tri_i[7] = PMOD1_7;
+
+  assign PMOD1_0 = PMOD1_tri_z[0] ? 1'bz : PMOD1_tri_o[0];
+  assign PMOD1_1 = PMOD1_tri_z[1] ? 1'bz : PMOD1_tri_o[1];
+  assign PMOD1_2 = PMOD1_tri_z[2] ? 1'bz : PMOD1_tri_o[2];
+  assign PMOD1_3 = PMOD1_tri_z[3] ? 1'bz : PMOD1_tri_o[3];
+  assign PMOD1_4 = PMOD1_tri_z[4] ? 1'bz : PMOD1_tri_o[4];
+  assign PMOD1_5 = PMOD1_tri_z[5] ? 1'bz : PMOD1_tri_o[5];
+  assign PMOD1_6 = PMOD1_tri_z[6] ? 1'bz : PMOD1_tri_o[6];
+  assign PMOD1_7 = PMOD1_tri_z[7] ? 1'bz : PMOD1_tri_o[7];
+
+// loop connect to preserve IOs
+assign PMOD1_tri_o = {DIPSW4,DIPSW4};
+assign PMOD1_tri_z = {DIPSW4,DIPSW4};
+
+// loop connect to presrve IOs
+assign LED4 = DIPSW4;
 
   design_1 design_1_i
        (.pmoda_tri_i(PMOD0_tri_i),
diff --git a/Cortex-M0/nanosoc/systems/mcu/fpga_imp/target_fpga_zcu104/fpga_pinmap.xdc b/Cortex-M0/nanosoc/systems/mcu/fpga_imp/target_fpga_zcu104/fpga_pinmap.xdc
index 4a635dd..bb79e54 100644
--- a/Cortex-M0/nanosoc/systems/mcu/fpga_imp/target_fpga_zcu104/fpga_pinmap.xdc
+++ b/Cortex-M0/nanosoc/systems/mcu/fpga_imp/target_fpga_zcu104/fpga_pinmap.xdc
@@ -932,31 +932,31 @@ set_property PULLUP true [get_ports PMOD0_7]
 
 set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets PMOD0_7_IBUF_inst/O]
 
-#set_property IOSTANDARD LVCMOS33 [get_ports PMOD1_0]
-#set_property IOSTANDARD LVCMOS33 [get_ports PMOD1_1]
-#set_property IOSTANDARD LVCMOS33 [get_ports PMOD1_2]
-#set_property IOSTANDARD LVCMOS33 [get_ports PMOD1_3]
-#set_property IOSTANDARD LVCMOS33 [get_ports PMOD1_4]
-#set_property IOSTANDARD LVCMOS33 [get_ports PMOD1_5]
-#set_property IOSTANDARD LVCMOS33 [get_ports PMOD1_6]
-#set_property IOSTANDARD LVCMOS33 [get_ports PMOD1_7]
-#set_property PACKAGE_PIN J9  [get_ports PMOD1_0]
-#set_property PACKAGE_PIN K9  [get_ports PMOD1_1]
-#set_property PACKAGE_PIN K8  [get_ports PMOD1_2]
-#set_property PACKAGE_PIN L8  [get_ports PMOD1_3]
-#set_property PACKAGE_PIN L10 [get_ports PMOD1_4]
-#set_property PACKAGE_PIN M10 [get_ports PMOD1_5]
-#set_property PACKAGE_PIN M8  [get_ports PMOD1_6]
-#set_property PACKAGE_PIN M9  [get_ports PMOD1_7]
+set_property IOSTANDARD LVCMOS33 [get_ports PMOD1_0]
+set_property IOSTANDARD LVCMOS33 [get_ports PMOD1_1]
+set_property IOSTANDARD LVCMOS33 [get_ports PMOD1_2]
+set_property IOSTANDARD LVCMOS33 [get_ports PMOD1_3]
+set_property IOSTANDARD LVCMOS33 [get_ports PMOD1_4]
+set_property IOSTANDARD LVCMOS33 [get_ports PMOD1_5]
+set_property IOSTANDARD LVCMOS33 [get_ports PMOD1_6]
+set_property IOSTANDARD LVCMOS33 [get_ports PMOD1_7]
+set_property PACKAGE_PIN J9  [get_ports PMOD1_0]
+set_property PACKAGE_PIN K9  [get_ports PMOD1_1]
+set_property PACKAGE_PIN K8  [get_ports PMOD1_2]
+set_property PACKAGE_PIN L8  [get_ports PMOD1_3]
+set_property PACKAGE_PIN L10 [get_ports PMOD1_4]
+set_property PACKAGE_PIN M10 [get_ports PMOD1_5]
+set_property PACKAGE_PIN M8  [get_ports PMOD1_6]
+set_property PACKAGE_PIN M9  [get_ports PMOD1_7]
 
-#set_property PULLUP true [get_ports PMOD1_7]
-#set_property PULLUP true [get_ports PMOD1_6]
-#set_property PULLUP true [get_ports PMOD1_5]
-#set_property PULLUP true [get_ports PMOD1_4]
-#set_property PULLUP true [get_ports PMOD1_3]
-#set_property PULLUP true [get_ports PMOD1_2]
-#set_property PULLUP true [get_ports PMOD1_1]
-#set_property PULLUP true [get_ports PMOD1_0]
+set_property PULLUP true [get_ports PMOD1_7]
+set_property PULLUP true [get_ports PMOD1_6]
+set_property PULLUP true [get_ports PMOD1_5]
+set_property PULLUP true [get_ports PMOD1_4]
+set_property PULLUP true [get_ports PMOD1_3]
+set_property PULLUP true [get_ports PMOD1_2]
+set_property PULLUP true [get_ports PMOD1_1]
+set_property PULLUP true [get_ports PMOD1_0]
 
 
 #PMODA pin0 to FTCLK
@@ -983,13 +983,31 @@ set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets PMOD0_7_IBUF_inst/O]
 
 
 # LED0 to P0[0]
-#set_property PACKAGE_PIN D5 [get_ports {P0[0]}]
+set_property IOSTANDARD LVCMOS33 [get_ports {LED4[0]}]
+set_property PACKAGE_PIN D5 [get_ports {LED4[0]}]
 # LED1 to P0[1]
-#set_property PACKAGE_PIN D6 [get_ports {P0[1]}]
+set_property IOSTANDARD LVCMOS33 [get_ports {LED4[1]}]
+set_property PACKAGE_PIN D6 [get_ports {LED4[1]}]
 # LED2 to P0[2]
-#set_property PACKAGE_PIN A5 [get_ports {P0[2]}]
+set_property IOSTANDARD LVCMOS33 [get_ports {LED4[2]}]
+set_property PACKAGE_PIN A5 [get_ports {LED4[2]}]
 # LED3 to P0[3]
-#set_property PACKAGE_PIN B5 [get_ports {P0[3]}]
+set_property IOSTANDARD LVCMOS33 [get_ports {LED4[3]}]
+set_property PACKAGE_PIN B5 [get_ports {LED4[3]}]
+
+
+# SW0 to P0[0]
+set_property IOSTANDARD LVCMOS33 [get_ports {DIPSW4[0]}]
+set_property PACKAGE_PIN E4 [get_ports {DIPSW4[0]}]
+# SW1 to P0[1]
+set_property IOSTANDARD LVCMOS33 [get_ports {DIPSW4[1]}]
+set_property PACKAGE_PIN D4 [get_ports {DIPSW4[1]}]
+# SW2 to P0[2]
+set_property IOSTANDARD LVCMOS33 [get_ports {DIPSW4[2]}]
+set_property PACKAGE_PIN F5 [get_ports {DIPSW4[2]}]
+# SW3 to P0[3]
+set_property IOSTANDARD LVCMOS33 [get_ports {DIPSW4[3]}]
+set_property PACKAGE_PIN F4 [get_ports {DIPSW4[3]}]
 
 # SW0 to NRST (Down for active low)
 #set_property PACKAGE_PIN B4 [get_ports NRST]
diff --git a/Cortex-M0/nanosoc/systems/mcu/rtl_sim/adp.cmd b/Cortex-M0/nanosoc/systems/mcu/rtl_sim/adp.cmd
index f0a2c33..5fbccc1 100644
--- a/Cortex-M0/nanosoc/systems/mcu/rtl_sim/adp.cmd
+++ b/Cortex-M0/nanosoc/systems/mcu/rtl_sim/adp.cmd
@@ -7,13 +7,18 @@ A
 S 7e
 A 
 a 1000000
-r 10
+r 8
 a 20000000
 r
 r
 a 30000000
 r
 r
+a 30000000
+w 12345678
+w 87654321
+a 30000000
+r 2
 a 40006000
 r
 r
@@ -23,7 +28,7 @@ A
 
 v 0xe5e5e5e5
 a 80000000
-f 4000
+f 200
 A
 a 90000000
 U 4
@@ -31,9 +36,36 @@ U 4
 A
 A 0x90000000
 R 5
-A b0000000
-w 1
-r
+A 0x60000000
+r 0x14
+A 0x60000010
+w f8
+A 0x60000034
+w 07
+A 0x60000044
+w 0f
+A 0x60000010
+r 0x10
+A 0x60007FF0
+F 4
+A 0x60007FF0
+R 4
+A 0x60000010
+r 0x10
+A 0x6000BFF0
+F 4
+A 0x6000BFF0
+R 4
+A 0x60000010
+r 0x10
+A 0x6000FFF0
+R 4
+A 0x60000010
+r 0x10
+A 0x60000018
+w 0x40
+A 0x6000FFF0
+R 4
 A
 A 0x10000000
 R 
diff --git a/Cortex-M0/nanosoc/systems/mcu/rtl_sim/makefile b/Cortex-M0/nanosoc/systems/mcu/rtl_sim/makefile
index 9254704..69b6280 100644
--- a/Cortex-M0/nanosoc/systems/mcu/rtl_sim/makefile
+++ b/Cortex-M0/nanosoc/systems/mcu/rtl_sim/makefile
@@ -91,7 +91,7 @@ SIMULATOR   = mti
 
 # MTI option
 #DF#MTI_OPTIONS    = -novopt
-MTI_OPTIONS    = 
+MTI_OPTIONS    = -suppress 2892
 MTI_VC_OPTIONS = -f $(TBENCH_VC)
 
 # VCS option
diff --git a/Cortex-M0/nanosoc/systems/mcu/verilog/nanosoc_chip.v b/Cortex-M0/nanosoc/systems/mcu/verilog/nanosoc_chip.v
index 7209c10..2474888 100644
--- a/Cortex-M0/nanosoc/systems/mcu/verilog/nanosoc_chip.v
+++ b/Cortex-M0/nanosoc/systems/mcu/verilog/nanosoc_chip.v
@@ -821,44 +821,50 @@ localparam    CORTEX_M0 = 1;
 // ************************************************
 // ************************************************
 //
-//  ADD YOUR EXPERIMENTAL AHB-MAPPED I/O HERE
+//  ADD YOUR EXPERIMENTAL AHB-MAPPED WRAPPER HERE
 //
 //
 // ************************************************
 
-
-//
-// dummy interface of the form:
-//  experimental_ip u_exp (
-//    .HCLK        (HCLK),
-//    .HRESETn     (HRESETn),
-//    .HSEL        (HSEL_exp),
-//    .HADDR       (HADDR_exp),
-//    .HTRANS      (HTRANS_exp),
-//    .HWRITE      (HWRITE_exp),
-//    .HSIZE       (HSIZE_exp),
-//    .HBURST      (HBURST_exp),
-//    .HPROT       (HPROT_exp),
-//    .HWDATA      (HWDATA_exp),
-//    .HMASTLOCK   (HMASTLOCK_exp),
-//    .HREADY      (HREADYMUX_exp),
-//    .HRDATA      (HRDATA_exp),
-//    .HREADYOUT   (HREADYOUT_exp),
-//    .HRESP       (HRESP_exp)
-//  );
- 
-  // Default slave
-  cmsdk_ahb_default_slave u_ahb_exp (
-    .HCLK         (HCLK),
-    .HRESETn      (HRESETn),
-    .HSEL         (HSEL_exp),
-    .HTRANS       (HTRANS_exp),
-    .HREADY       (HREADYMUX_exp),
-    .HREADYOUT    (HREADYOUT_exp),
-    .HRESP        (HRESP_exp)
+  soclabs_ahb_aes128_ctrl u_exp_aes128 (
+    .ahb_hclk        (HCLK),
+    .ahb_hresetn     (HRESETn),
+    .ahb_hsel        (HSEL_exp),
+    .ahb_haddr16     (HADDR_exp[15:0]),
+    .ahb_htrans      (HTRANS_exp),
+    .ahb_hwrite      (HWRITE_exp),
+    .ahb_hsize       (HSIZE_exp),
+//    .ahb_hburst      (HBURST_exp),
+    .ahb_hprot       (HPROT_exp),
+    .ahb_hwdata      (HWDATA_exp),
+//    .ahb_hmastlock   (HMASTLOCK_exp),
+    .ahb_hready      (HREADYMUX_exp),
+    .ahb_hrdata      (HRDATA_exp),
+    .ahb_hreadyout   (HREADYOUT_exp),
+    .ahb_hresp       (HRESP_exp),
+    .drq_ipdma128    ( ),
+    .dlast_ipdma128  (1'b0),
+    .drq_opdma128    ( ),
+    .dlast_opdma128  (1'b0),
+    .irq_key128      ( ),
+    .irq_ip128       ( ),
+    .irq_op128       ( ),
+    .irq_error       ( ),
+    .irq_merged      ( )
   );
+ 
+//  // Default slave
+//  cmsdk_ahb_default_slave u_ahb_exp (
+//    .HCLK         (HCLK),
+//    .HRESETn      (HRESETn),
+//    .HSEL         (HSEL_exp),
+//    .HTRANS       (HTRANS_exp),
+//    .HREADY       (HREADYMUX_exp),
+//    .HREADYOUT    (HREADYOUT_exp),
+//    .HRESP        (HRESP_exp)
+// );
+//  assign   HRDATA_exp = 32'heaedeaed; // Tie off Expansion Address Expansion Data
 
-  assign   HRDATA_exp = 32'heaedeaed; // Tie off Expansion Address Expansion Data
   assign   HRUSER_exp = 2'b00;
   
 // ************************************************
diff --git a/Cortex-M0/nanosoc/systems/mcu/verilog/soclabs_ahb_aes128_ctrl.v b/Cortex-M0/nanosoc/systems/mcu/verilog/soclabs_ahb_aes128_ctrl.v
new file mode 100644
index 0000000..27796a3
--- /dev/null
+++ b/Cortex-M0/nanosoc/systems/mcu/verilog/soclabs_ahb_aes128_ctrl.v
@@ -0,0 +1,3015 @@
+ //-----------------------------------------------------------------------------
+// top-level soclabs example AHB interface
+// 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 soclabs_ahb_aes128_ctrl(
+// -------------------------------------------------------
+// MCU interface
+// -------------------------------------------------------
+  input  wire        ahb_hclk,      // Clock
+  input  wire        ahb_hresetn,   // Reset
+  input  wire        ahb_hsel,      // Device select
+  input  wire [15:0] ahb_haddr16,   // Address for byte select
+  input  wire  [1:0] ahb_htrans,    // Transfer control
+  input  wire  [2:0] ahb_hsize,     // Transfer size
+  input  wire  [3:0] ahb_hprot,     // Protection control
+  input  wire        ahb_hwrite,    // Write control
+  input  wire        ahb_hready,    // Transfer phase done
+  input  wire [31:0] ahb_hwdata,    // Write data
+  output wire        ahb_hreadyout, // Device ready
+  output wire [31:0] ahb_hrdata,    // Read data output
+  output wire        ahb_hresp,     // Device response
+// stream data
+  output wire        drq_ipdma128,  // (to) DMAC input burst request
+  input  wire        dlast_ipdma128,// (from) DMAC input burst end (last transfer)
+  output wire        drq_opdma128,  // (to) DMAC output dma burst request
+  input  wire        dlast_opdma128,// (from) DMAC output burst end (last transfer)
+  output wire        irq_key128,
+  output wire        irq_ip128,
+  output wire        irq_op128,
+  output wire        irq_error,
+  output wire        irq_merged     // combined interrrupt request (to CPU)
+  );
+
+  //----------------------------------------------------------------
+  // Internal parameter definitions.
+  //----------------------------------------------------------------
+
+///typedef struct {
+///	__I  uint32_t CORE_NAME0;     /* 0x0000 */
+///	__I  uint32_t CORE_NAME1;     /* 0x0004 */
+///	__I  uint32_t CORE_VERSION;   /* 0x0008 */
+///	     uint32_t RESRV0C;        /* 0x000C */
+///	__IO uint32_t CONTROL;        /* 0x0010 */
+///	__O  uint32_t CONTROL_SET;    /* 0x0014 */
+///	__O  uint32_t CONTROL_CLR;    /* 0x0018 */
+///	__I  uint32_t STATUS;         /* 0x001c */
+///	__I  uint32_t QUALIFIER;      /* 0x0020 */
+///	     uint32_t RESRV24[3];     /* 0x0024 - 2F*/
+///	__IO uint32_t DRQ_MSK;        /* 0x0030 */
+///	__O  uint32_t DRQ_MSK_SET;    /* 0x0034 */
+///	__O  uint32_t DRQ_MSK_CLR;    /* 0x0038 */
+///	__I  uint32_t DRQ_STATUS;     /* 0x003C */
+///	__IO uint32_t IRQ_MSK;        /* 0x0040 */
+///	__O  uint32_t IRQ_MSK_SET;    /* 0x0044 */
+///	__O  uint32_t IRQ_MSK_CLR;    /* 0x0048 */
+///	__I  uint32_t IRQ_STATUS;     /* 0x004C */
+///          uint32_t RESRV50[1024-80] /* 0x0050-0x3FFC (1024-(20*4)) */
+///     __IO unit32_t KYBUF128[1020];  /* 0x4000-7FEF */ (1024-4)
+///     __IO unit32_t KYBUF128END;     /* 0x7FF0-7FFF */
+///     __IO unit32_t IPBUF128[1020];  /* 0x8000-BFEF */ (1024-4)
+///     __IO unit32_t IPBUF128END;     /* 0xBFF0-BFFF */
+///     __IO unit32_t OPBUF128[1020];  /* 0xC000-FFEF */ (1024-4)
+///     __IO unit32_t OPBUF128END;     /* 0xFFF0-FFFF */
+///} AES128_TypeDef;
+
+
+// CORE ID
+  localparam ADDR_CORE_NAME0  = 16'h0000;
+  localparam ADDR_CORE_NAME1  = 16'h0004;
+  localparam ADDR_CORE_VERSION= 16'h0008;
+  localparam CORE_NAME0       = 32'h61657331; // "aes1"
+  localparam CORE_NAME1       = 32'h32382020; // "28  "
+  localparam CORE_VERSION     = 32'h302e3630; // "0.01"
+
+// CTRL control register with bit-set/bit-clear options
+  localparam ADDR_CTRL        = 16'h0010;
+  localparam ADDR_CTRL_SET    = 16'h0014;
+  localparam ADDR_CTRL_CLR    = 16'h0018;
+  localparam CTRL_REG_WIDTH   = 8;
+  localparam CTRL_BIT_MAX     = (CTRL_REG_WIDTH-1);
+  localparam CTRL_KEY_REQ_BIT = 0;
+  localparam CTRL_IP_REQ_BIT  = 1;
+  localparam CTRL_OP_REQ_BIT  = 2;
+  localparam CTRL_ERR_REQ_BIT = 3;
+  localparam CTRL_KEYOK_BIT   = 4;
+  localparam CTRL_VALID_BIT   = 5;
+  localparam CTRL_BYPASS_BIT  = 6;
+  localparam CTRL_ENCODE_BIT  = 7;
+// STAT status regisyer 
+  localparam ADDR_STAT        = 16'h001c;
+  localparam STAT_REG_WIDTH   = 8;
+  localparam STAT_BIT_MAX     = (STAT_REG_WIDTH-1);
+  localparam STAT_KEYREQ_BIT  = 0;
+  localparam STAT_INPREQ_BIT  = 1;
+  localparam STAT_OUTREQ_BIT  = 2;
+  localparam STAT_ERROR_BIT   = 3;
+  localparam STAT_KEYOK_BIT   = 4;
+  localparam STAT_VALID_BIT   = 5;
+
+// QUAL qualifier field
+  localparam ADDR_QUAL        = 16'h0020;
+  localparam QUAL_REG_WIDTH   = 32;
+  localparam QUAL_BIT_MAX     = (QUAL_REG_WIDTH-1);
+
+// DREQ DMAC request control with bit-set/bit-clear options
+  localparam ADDR_DREQ        = 16'h0030;
+  localparam ADDR_DREQ_SET    = 16'h0034;
+  localparam ADDR_DREQ_CLR    = 16'h0038;
+  localparam ADDR_DREQ_ACT    = 16'h003c;
+  localparam DREQ_REG_WIDTH   = 3;
+  localparam DREQ_BIT_MAX     = (DREQ_REG_WIDTH-1);
+  localparam  REQ_KEYBUF_BIT  = 0;
+  localparam  REQ_IP_BUF_BIT  = 1;
+  localparam  REQ_OP_BUF_BIT  = 2;
+
+// IREQ CPU interrupt request control with bit-set/bit-clear options
+  localparam ADDR_IREQ        = 16'h0040;
+  localparam ADDR_IREQ_SET    = 16'h0044;
+  localparam ADDR_IREQ_CLR    = 16'h0048;
+  localparam ADDR_IREQ_ACT    = 16'h004c;
+  localparam IREQ_REG_WIDTH   = 4;
+  localparam IREQ_BIT_MAX     = (IREQ_REG_WIDTH-1);
+  localparam  REQ_ERROR_BIT   = 3;
+
+  localparam ADDR_KEY_BASE    = 16'h4000;
+  localparam ADDR_KEY0        = 16'h4000;
+  localparam ADDR_KEY3        = 16'h400c;
+  localparam ADDR_KEY7        = 16'h401c;
+
+  localparam ADDR_IBUF_BASE   = 16'h8000;
+  localparam ADDR_IBUF_0      = 16'h8000;
+  localparam ADDR_IBUF_3      = 16'h800c;
+
+  localparam ADDR_OBUF_BASE   = 16'hc000;
+  localparam ADDR_OBUF_3      = 16'hc00c;
+
+ 
+ // --------------------------------------------------------------------------
+  // Internal regs/wires
+  // --------------------------------------------------------------------------
+
+  reg   [15:0] addr16_r;
+  reg          sel_r;
+  reg          wcyc_r;
+  reg          rcyc_r;
+  reg    [3:0] byte4_r;
+
+  wire         key128_load_ack;
+  wire         ip128_load_ack;
+  wire         op128_load_ack;
+
+  // --------------------------------------------------------------------------
+  // AHB slave byte buffer interface, support for unaligned data transfers
+  // --------------------------------------------------------------------------
+
+  wire   [1:0] byt_adr = ahb_haddr16[1:0];
+  // generate next byte enable decodes for Word/Half/Byte CPU/DMA accesses
+  wire   [3:0] byte_nxt;
+  assign byte_nxt[0] = (ahb_hsize[1])|((ahb_hsize[0])&(!byt_adr[1]))|(byt_adr[1:0]==2'b00);
+  assign byte_nxt[1] = (ahb_hsize[1])|((ahb_hsize[0])&(!byt_adr[1]))|(byt_adr[1:0]==2'b01);
+  assign byte_nxt[2] = (ahb_hsize[1])|((ahb_hsize[0])&( byt_adr[1]))|(byt_adr[1:0]==2'b10);
+  assign byte_nxt[3] = (ahb_hsize[1])|((ahb_hsize[0])&( byt_adr[1]))|(byt_adr[1:0]==2'b11);
+
+  // de-pipelined registered access signals
+  always @(posedge ahb_hclk or negedge ahb_hresetn)
+    if (!ahb_hresetn)
+    begin
+      addr16_r <= 16'h0000;
+      sel_r    <= 1'b0;
+      wcyc_r   <= 1'b0;
+      rcyc_r   <= 1'b0;
+      byte4_r  <= 4'b0000;
+    end else if (ahb_hready)
+    begin
+      addr16_r <= (ahb_hsel & ahb_htrans[1]) ?  ahb_haddr16 : addr16_r;
+      sel_r    <= (ahb_hsel & ahb_htrans[1]);
+      wcyc_r   <= (ahb_hsel & ahb_htrans[1]  &  ahb_hwrite);
+      rcyc_r   <= (ahb_hsel & ahb_htrans[1]  & !ahb_hwrite);
+      byte4_r  <= (ahb_hsel & ahb_htrans[1]) ?  byte_nxt[3:0] : 4'b0000;
+    end 
+
+
+// pipelined "early" last access decodes, for PL230 dma_ack timing to deassert dma requests
+//  wire ahb128_last  = ahb_hsel &  ahb_htrans[1] & ahb_hready & ahb_haddr16[3] & ahb_haddr16[2] & byte_nxt[3];
+//  wire ahb128_wlast = ahb_last &  ahb_hwrite & |ahb_haddr[15:14]; // address phase of last write transfer
+//  wire ahb128_rlast = ahb_last & !ahb_hwrite & |ahb_haddr[15:14]; // address phase of last read transfer
+  
+  wire wlast128     = |ahb_haddr16[15:14] & addr16_r[3] & addr16_r[2] & byte4_r[3] & wcyc_r; // write last pulse
+  wire rlast128     = &ahb_haddr16[15:14] & addr16_r[3] & addr16_r[2] & byte4_r[3] & rcyc_r; // read last pulse
+
+  //----------------------------------------------------------------
+  // API register state and wiring
+  //
+  //----------------------------------------------------------------
+
+  reg   [CTRL_BIT_MAX:0] control;
+  reg   [QUAL_BIT_MAX:0] param;
+  reg   [DREQ_BIT_MAX:0] drq_enable;
+  reg   [IREQ_BIT_MAX:0] irq_enable;
+
+  wire  [STAT_BIT_MAX:0] status;
+  wire  [DREQ_BIT_MAX:0] drq_active;
+  wire  [IREQ_BIT_MAX:0] irq_active;
+
+  wire [31:0] rd_keybuf;
+  wire [31:0] rd_ipbuf;
+  wire [31:0] rd_opbuf;
+ 
+  //----------------------------------------------------------------
+  // API write decoder
+  //
+  //----------------------------------------------------------------
+
+  wire sel_mode   = sel_r & (addr16_r[15: 8] == 0);
+  wire sel_keybuf = sel_r & (addr16_r[15:14] == 1);
+  wire sel_ipbuf  = sel_r & (addr16_r[15:14] == 2);
+  wire sel_opbuf  = sel_r & (addr16_r[15:14] == 3);
+// add address map "last" transfer signalling when last (byte) of alias map is written 
+  wire alast_key128 = sel_keybuf & wcyc_r & (&addr16_r[13:2]) & byte4_r[3];
+  wire alast_ip128  = sel_ipbuf  & wcyc_r & (&addr16_r[13:2]) & byte4_r[3];
+  wire alast_op128  = sel_opbuf  & rcyc_r & (&addr16_r[13:2]) & byte4_r[3];
+
+  always @(posedge ahb_hclk or negedge ahb_hresetn)
+   if (!ahb_hresetn) begin
+     control    <= {CTRL_REG_WIDTH{1'b0}};
+     param      <= {QUAL_REG_WIDTH{1'b0}};
+     drq_enable <= {DREQ_REG_WIDTH{1'b0}};
+     irq_enable <= {IREQ_REG_WIDTH{1'b0}};
+     end
+   else if (sel_mode & wcyc_r & byte4_r[0])
+     case (addr16_r)
+       ADDR_CTRL    : control    <=  ahb_hwdata[CTRL_BIT_MAX:0];              // overwrite ctl reg
+       ADDR_CTRL_SET: control    <=  ahb_hwdata[CTRL_BIT_MAX:0] | control;    // bit set ctl mask pattern
+       ADDR_CTRL_CLR: control    <= ~ahb_hwdata[CTRL_BIT_MAX:0] & control;    // bit clear ctl mask pattern
+       ADDR_QUAL    : param      <=  ahb_hwdata[QUAL_BIT_MAX:0];              // write qual pattern
+       ADDR_DREQ    : drq_enable <=  ahb_hwdata[DREQ_BIT_MAX:0];              // overwrite dreq reg
+       ADDR_DREQ_SET: drq_enable <=  ahb_hwdata[DREQ_BIT_MAX:0] | drq_enable; // bit set dreq mask pattern
+       ADDR_DREQ_CLR: drq_enable <= ~ahb_hwdata[DREQ_BIT_MAX:0] & drq_enable; // bit clear dreq mask pattern
+       ADDR_IREQ    : irq_enable <=  ahb_hwdata[IREQ_BIT_MAX:0];              // overwrite ireq reg
+       ADDR_IREQ_SET: irq_enable <=  ahb_hwdata[IREQ_BIT_MAX:0] | irq_enable; // bit set ireq mask pattern
+       ADDR_IREQ_CLR: irq_enable <= ~ahb_hwdata[IREQ_BIT_MAX:0] & irq_enable; // bit clear ireq mask pattern
+       default: ;
+     endcase
+   else if (sel_keybuf & wcyc_r & (dlast_ipdma128 | alast_key128)) // key terminate
+     drq_enable[0] <= 1'b0;
+   else if (sel_ipbuf  & wcyc_r & (dlast_ipdma128 | alast_ip128)) // ip-buffer terminate
+     drq_enable[1] <= 1'b0;
+   else if (sel_opbuf & rcyc_r  & (dlast_opdma128 | alast_op128)) // op-buffer complete
+     drq_enable[2] <= 1'b0;
+
+  //----------------------------------------------------------------
+  // API read decoder
+  //
+  //----------------------------------------------------------------
+
+reg [31:0] rdata32; // mux read data
+
+  always @*
+    begin : read_decoder
+      rdata32  = 32'hbad0bad;
+      if (sel_r & rcyc_r)
+        case (addr16_r)
+          ADDR_CORE_NAME0   : rdata32 = CORE_NAME0; 
+          ADDR_CORE_NAME1   : rdata32 = CORE_NAME1; 
+          ADDR_CORE_VERSION : rdata32 = CORE_VERSION;
+          ADDR_CTRL     : rdata32 = {{(32-CTRL_REG_WIDTH){1'b0}}, control};
+          ADDR_STAT     : rdata32 = {{(32-STAT_REG_WIDTH){1'b0}}, status};
+          ADDR_QUAL     : rdata32 = {{(32-QUAL_REG_WIDTH){1'b0}}, param};
+          ADDR_DREQ     : rdata32 = {{(32-DREQ_REG_WIDTH){1'b0}}, drq_enable};
+          ADDR_DREQ_ACT : rdata32 = {{(32-DREQ_REG_WIDTH){1'b0}}, drq_active};
+          ADDR_IREQ     : rdata32 = {{(32-IREQ_REG_WIDTH){1'b0}}, irq_enable};
+          ADDR_IREQ_ACT : rdata32 = {{(32-DREQ_REG_WIDTH){1'b0}}, irq_active};
+        default:
+          if      (sel_keybuf) rdata32 = rd_keybuf;
+          else if (sel_ipbuf)  rdata32 = rd_ipbuf;
+          else if (sel_opbuf)  rdata32 = rd_opbuf;
+        endcase
+    end // read_decoder
+
+  assign ahb_hrdata = rdata32;
+
+  assign ahb_hreadyout = 1'b1; // zero wait state interface
+  assign ahb_hresp     = 1'b0;
+    
+  // --------------------------------------------------------------------------
+  // Key Input Buffer - keybuf
+  // --------------------------------------------------------------------------
+
+  wire [127:0] key128_be;
+
+  soclabs_iobuf_reg128
+  #(.WRITE_ONLY     (1),
+    .WRITE_ZPAD     (0))
+  u_reg128_key
+  (
+    .clk         (ahb_hclk        ), // Clock
+    .rst_b       (ahb_hresetn     ), // Reset
+    .sel_r       (sel_keybuf      ), // Bank decode select
+    .wcyc_r      (wcyc_r          ), // Write cycle (wdata32 valid)
+    .rcyc_r      (rcyc_r          ), // Read cycle (return rdata32)
+    .word2_r     (addr16_r[3:2]   ), // Address for word select
+    .byte4_r     (byte4_r[3:0]    ), // Byte select decoded (up to 4 enabled)
+    .wdata32     (ahb_hwdata[31:0]), // Write data (byte lane qualified)
+    .rdata32     (rd_keybuf       ), // Read data output
+    .dma128_ack  (key128_load_ack ), // DMA burst acknowledge
+    .out128_le   (                ), // Big-Endian 128-bit value
+    .out128_be   (key128_be       )  // Big-Endian 128-bit value
+  );
+
+  // --------------------------------------------------------------------------
+  // Data Input Buffer - ipbuf
+  // --------------------------------------------------------------------------
+
+  wire [127:0] ip128_le;
+  wire [127:0] ip128_be;
+
+  soclabs_iobuf_reg128
+  #(.WRITE_ONLY     (0),
+    .WRITE_ZPAD     (1))
+  u_reg128_ip
+  (
+    .clk         (ahb_hclk        ), // Clock
+    .rst_b       (ahb_hresetn     ), // Reset
+    .sel_r       (sel_ipbuf       ), // Bank decode select
+    .wcyc_r      (wcyc_r          ), // Write cycle (wdata32 valid)
+    .rcyc_r      (rcyc_r          ), // Read cycle (return rdata32)
+    .word2_r     (addr16_r[3:2]   ), // Address for word select
+    .byte4_r     (byte4_r[3:0]    ), // Byte select decoded (up to 4 enabled)
+    .wdata32     (ahb_hwdata[31:0]), // Write data (byte lane qualified)
+    .rdata32     (rd_ipbuf        ), // Read data output
+    .dma128_ack  (ip128_load_ack  ), // DMA burst acknowledge
+    .out128_le   (ip128_le        ), // Big-Endian 128-bit value
+    .out128_be   (ip128_be        )  // Big-Endian 128-bit value
+  );
+
+  // --------------------------------------------------------------------------
+  // Data Output Buffer - opbufsel_keybuf
+  // --------------------------------------------------------------------------
+
+  wire [127:0] op128_be;
+  wire [127:0] op128_muxed = (control[CTRL_BYPASS_BIT]) ? ip128_be : op128_be;
+  
+  wire [31:0] op_slice32 [0:3];
+  assign op_slice32[3] = {op128_muxed[  7:  0],op128_muxed[ 15:  8],op128_muxed[ 23: 16],op128_muxed[ 31: 24]};
+  assign op_slice32[2] = {op128_muxed[ 39: 32],op128_muxed[ 47: 40],op128_muxed[ 55: 48],op128_muxed[ 63: 56]};
+  assign op_slice32[1] = {op128_muxed[ 71: 64],op128_muxed[ 79: 72],op128_muxed[ 87: 80],op128_muxed[ 95: 88]};
+  assign op_slice32[0] = {op128_muxed[103: 96],op128_muxed[111:104],op128_muxed[119:112],op128_muxed[127:120]};
+
+  // 32-bit addressed read data
+  assign rd_opbuf = op_slice32[addr16_r[3:2]];
+
+  assign op128_load_ack = (sel_opbuf & rcyc_r & addr16_r[3] & addr16_r[2] & byte4_r[3]);
+
+  // --------------------------------------------------------------------------
+  // example aes128 engine timing
+  // --------------------------------------------------------------------------
+  // --------------------------------------------------------------------------
+  // AES-specific control interface
+  // --------------------------------------------------------------------------
+
+wire aes128_encode = control[CTRL_ENCODE_BIT];
+wire aes256_keysize = 1'b0;
+
+wire aes_keyloaded_pulse = key128_load_ack; // pulse on last byte load of key128
+wire aes_dataloaded_pulse= ip128_load_ack;  // pulse on last byte load of text128
+wire aes_ready;
+wire aes_valid;
+
+// state machine control
+reg  aes_ready_del;
+reg  aes_init;
+reg  aes_next;
+reg  aes_key_busy;
+reg  aes_key_rdy;
+reg  aes_res_busy;
+reg  aes_res_rdy;
+
+  always @(posedge ahb_hclk or negedge ahb_hresetn)
+    if (!ahb_hresetn) begin
+      aes_ready_del <= 1'b0;
+      aes_init      <= 1'b0;
+      aes_next      <= 1'b0;
+      aes_key_busy  <= 1'b0;
+      aes_key_rdy   <= 1'b0;
+      aes_res_busy  <= 1'b0;
+      aes_res_rdy   <= 1'b0;
+    end else begin
+      aes_ready_del <= aes_ready; // delay for rising edge detect
+      aes_init      <= aes_keyloaded_pulse;
+      aes_next      <= aes_dataloaded_pulse;
+      aes_key_busy  <= (aes_init) | (aes_key_busy & !(aes_ready & !aes_ready_del)); // hold until key expansion done
+      aes_key_rdy   <= (aes_key_busy & aes_ready & !aes_ready_del) // expanded key ready
+                     | (aes_key_rdy & !(sel_keybuf & wcyc_r));     // hold until any key update
+      aes_res_busy  <= (aes_next) | (aes_res_busy & !(aes_ready & !aes_ready_del)); // hold until block processing done
+      aes_res_rdy   <= (aes_res_busy & aes_ready & !aes_ready_del) // block ready
+                     | (aes_res_rdy & !op128_load_ack);           // hold until output transferred
+    end
+
+  assign drq_active[REQ_KEYBUF_BIT] = control[CTRL_KEY_REQ_BIT] | (!aes_key_busy & !aes_key_rdy & !wlast128);
+  assign drq_active[REQ_IP_BUF_BIT] = control[CTRL_IP_REQ_BIT] | (!aes_res_busy & !aes_res_rdy & aes_key_rdy & !wlast128);
+  assign drq_active[REQ_OP_BUF_BIT] = control[CTRL_OP_REQ_BIT] | (!aes_res_busy &  aes_res_rdy & !rlast128);
+
+// input DMA channel shared by Key and Data-In
+  assign drq_ipdma128 = (drq_enable[REQ_KEYBUF_BIT] & drq_active[REQ_KEYBUF_BIT]) // if key DMA enabled
+                      | (drq_enable[REQ_IP_BUF_BIT] & drq_active[REQ_IP_BUF_BIT]) // if ip128 DMA requested
+                      ;
+                      
+// output DMA channel for Data-Out
+  assign drq_opdma128 = (drq_enable[REQ_OP_BUF_BIT]  & drq_active[REQ_OP_BUF_BIT]); // if op128 DMA requested
+
+// and Interrupt requests are masked out if corresponding DMA requests are enabled
+  assign irq_active[REQ_KEYBUF_BIT] = drq_active[REQ_KEYBUF_BIT] & !drq_enable[REQ_KEYBUF_BIT];
+  assign irq_active[REQ_IP_BUF_BIT] = drq_active[REQ_IP_BUF_BIT] & !drq_enable[REQ_IP_BUF_BIT];
+  assign irq_active[REQ_OP_BUF_BIT] = drq_active[REQ_OP_BUF_BIT] & !drq_enable[REQ_OP_BUF_BIT];
+  assign irq_active[REQ_ERROR_BIT ] = control[CTRL_ERR_REQ_BIT]  | (!aes_res_busy & !aes_key_rdy); // error raised in SW
+
+  assign irq_key128 = irq_active[REQ_KEYBUF_BIT] & !drq_active[REQ_KEYBUF_BIT];
+  assign irq_ip128  = irq_active[REQ_IP_BUF_BIT] & !drq_active[REQ_IP_BUF_BIT];
+  assign irq_op128  = irq_active[REQ_OP_BUF_BIT] & !drq_active[REQ_OP_BUF_BIT];
+  assign irq_error  = irq_active[REQ_ERROR_BIT ];
+// merge and mask if not DRQ
+  assign irq_merged = irq_key128 | irq_ip128 | irq_op128 | irq_error;
+  
+
+// wire up status port  
+  assign status[2:0]            = control [2:0];
+  assign status[STAT_ERROR_BIT] = (!aes_res_busy & !aes_key_rdy);
+  assign status[STAT_KEYOK_BIT] = aes_key_rdy;
+  assign status[STAT_VALID_BIT] = aes_res_rdy;
+  assign status[7:6]            = control [7:6];
+
+  //----------------------------------------------------------------
+  // core instantiation.
+  //----------------------------------------------------------------
+  aes_core core(
+                .clk(ahb_hclk),
+                .reset_n(ahb_hresetn),
+
+                .encdec(aes128_encode),
+                .init(aes_init),
+                .next(aes_next),
+                .ready(aes_ready),
+
+                .key({key128_be,key128_be}),
+                .keylen(aes256_keysize),
+
+                .block(ip128_be),
+                .result(op128_be),
+                .result_valid(aes_valid)
+               );
+                             
+endmodule
+
+module soclabs_iobuf_reg128
+ #(
+  parameter  WRITE_ONLY = 0,
+  parameter  WRITE_ZPAD = 0
+  ) (
+// -------------------------------------------------------
+// de-pipelined register interface
+// -------------------------------------------------------
+// ahb
+  input  wire         clk,        // Clock
+  input  wire         rst_b,      // Reset
+  input  wire         sel_r,      // Bank decode select
+  input  wire         wcyc_r,     // Write cycle (wdata32 valid)
+  input  wire         rcyc_r,     // Read cycle (return rdata32)
+  input  wire   [1:0] word2_r,    // Address for word select
+  input  wire   [3:0] byte4_r,    // Byte select decoded (up to 4 enabled)
+  input  wire  [31:0] wdata32,    // Write data (byte lae qualified)
+  output wire  [31:0] rdata32,    // Read data output
+  output wire         dma128_ack, // DMA burst acknowledge
+  output wire [127:0] out128_le,  // Litte-Endian 128-bit value
+  output wire [127:0] out128_be   // Big-Endian 128-bit value
+) ;
+
+  reg   [7:0] byte0 [0:3];
+  reg   [7:0] byte1 [0:3];
+  reg   [7:0] byte2 [0:3];
+  reg   [7:0] byte3 [0:3];
+  reg         ack128;
+
+  wire zpad_cfg = (WRITE_ZPAD==0) ? 1'b0 : 1'b1;
+
+// byte-0 array; flush on write to word-0, byte-0
+// else addressed word byte-0 write
+  always @(posedge clk or negedge rst_b)
+    if (!rst_b)
+      begin byte0[0] <= 8'h00; byte0[1] <= 8'h00; byte0[2] <= 8'h00; byte0[3] <= 8'h00; end
+    else if (zpad_cfg & sel_r & wcyc_r & byte4_r[0] & !word2_r[1] & !word2_r[0]) // Z-PAD rest
+      begin byte0[0] <= wdata32[ 7: 0]; byte0[1] <= 8'h00; byte0[2] <= 8'h00; byte0[3] <= 8'h00; end
+    else if (sel_r & wcyc_r & byte4_r[0])
+      byte0[word2_r[1:0]] <= wdata32[ 7: 0];
+   
+// byte-1 array; flush on write to word-0, byte-0 if byte-1 not also written
+// flush rest on write to word-0, byte-0 and byte-1 also written
+// else address word byte-1 write
+  always @(posedge clk or negedge rst_b)
+    if (!rst_b)
+      begin byte1[0] <= 8'h00; byte1[1] <= 8'h00; byte1[2] <= 8'h00; byte1[3] <= 8'h00; end
+    else if (zpad_cfg & sel_r & wcyc_r & !byte4_r[1] & !word2_r[1] & !word2_r[0] & byte4_r[0]) // Z-PAD
+      begin byte1[0] <= 8'h00; byte1[1] <= 8'h00; byte1[2] <= 8'h00; byte1[3] <= 8'h00; end
+    else if (zpad_cfg & sel_r & wcyc_r &  byte4_r[1] & !word2_r[1] & !word2_r[0] & byte4_r[0]) // Z-PAD rest
+      begin byte1[0] <= wdata32[15: 8]; byte1[1] <= 8'h00; byte1[2] <= 8'h00; byte1[3] <= 8'h00; end
+    else if (sel_r & wcyc_r & byte4_r[1])
+      byte1[word2_r[1:0]] <= wdata32[15: 8];
+   
+// byte-2 array; flush on write to word-0, byte-0 if byte-2 not also written
+// flush rest on write to word-0, byte-0 and byte-2 also written
+// else address word byte-2 write
+  always @(posedge clk or negedge rst_b)
+    if (!rst_b)
+      begin byte2[0] <= 8'h00; byte2[1] <= 8'h00; byte2[2] <= 8'h00; byte2[3] <= 8'h00; end
+    else if (zpad_cfg & sel_r & wcyc_r & !byte4_r[2] & !word2_r[1] & !word2_r[0] & byte4_r[0]) // Z-PAD
+      begin byte2[0] <= 8'h00; byte2[1] <= 8'h00; byte2[2] <= 8'h00; byte2[3] <= 8'h00; end
+    else if (zpad_cfg & sel_r & wcyc_r &  byte4_r[2] & !word2_r[1] & !word2_r[0] & byte4_r[0]) // Z-PAD rest
+      begin byte2[0] <= wdata32[23:16]; byte2[1] <= 8'h00; byte2[2] <= 8'h00; byte2[3] <= 8'h00; end
+    else if (sel_r & wcyc_r & byte4_r[2])
+      byte2[word2_r[1:0]] <= wdata32[23:16];
+   
+// byte-3 array; flush on write to word-0, byte-0 if byte-3 not also written
+// flush rest on write to word-0, byte-0 and byte-3 also written
+// else address word byte-3 write
+  always @(posedge clk or negedge rst_b)
+    if (!rst_b)
+      begin byte3[0] <= 8'h00; byte3[1] <= 8'h00; byte3[2] <= 8'h00; byte3[3] <= 8'h00; end
+    else if (zpad_cfg & sel_r & wcyc_r & !byte4_r[3] & !word2_r[1] & !word2_r[0] & byte4_r[0]) // Z-PAD
+      begin byte3[0] <= 8'h00; byte3[1] <= 8'h00; byte3[2] <= 8'h00; byte3[3] <= 8'h00; end
+    else if (zpad_cfg & sel_r & wcyc_r &  byte4_r[3] & !word2_r[1] & !word2_r[0] & byte4_r[0]) // Z-PAD rest
+      begin byte3[0] <= wdata32[31:24]; byte3[1] <= 8'h00; byte3[2] <= 8'h00; byte3[3] <= 8'h00; end
+    else if (sel_r & wcyc_r & byte4_r[3])
+      byte3[word2_r[1:0]] <= wdata32[31:24];
+
+  // ack on write to final byte [15]   
+  always @(posedge clk or negedge rst_b)
+    if (!rst_b)
+      ack128 <= 1'b0;
+    else
+      ack128 <= sel_r & wcyc_r & word2_r[1] & word2_r[0] & byte4_r[3];
+
+  assign dma128_ack = ack128;
+
+// byte reverse per word for Big Endian AES engine
+  assign out128_be = {byte0[0], byte1[0], byte2[0], byte3[0],
+                      byte0[1], byte1[1], byte2[1], byte3[1],
+                      byte0[2], byte1[2], byte2[2], byte3[2],
+                      byte0[3], byte1[3], byte2[3], byte3[3]};
+                   
+// byte reverse per word for Big Endian AES engine
+  assign out128_le = {byte3[3], byte2[3], byte1[3], byte0[3],
+                      byte3[2], byte2[2], byte1[2], byte0[2],
+                      byte3[1], byte2[1], byte1[1], byte0[1],
+                      byte3[0], byte2[0], byte1[0], byte0[0]};
+                   
+// little-endian read data (if not Write-Only)
+  assign rdata32   = (sel_r & rcyc_r & (WRITE_ONLY == 0))
+                   ? {byte3[word2_r[1:0]], byte2[word2_r[1:0]],
+                      byte1[word2_r[1:0]], byte0[word2_r[1:0]]}
+                   : 32'h00000000;
+
+endmodule
+
+//======================================================================
+//
+// aes_core.v
+// ----------
+// The AES core. This core supports key size of 128, and 256 bits.
+// Most of the functionality is within the submodules.
+//
+//
+// Author: Joachim Strombergson
+// Copyright (c) 2013, 2014, Secworks Sweden AB
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or
+// without modification, are permitted provided that the following
+// conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright
+//    notice, this list of conditions and the following disclaimer.
+//
+// 2. Redistributions in binary form must reproduce the above copyright
+//    notice, this list of conditions and the following disclaimer in
+//    the documentation and/or other materials provided with the
+//    distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+//======================================================================
+
+`default_nettype none
+
+module aes_core(
+                input wire            clk,
+                input wire            reset_n,
+
+                input wire            encdec,
+                input wire            init,
+                input wire            next,
+                output wire           ready,
+
+                input wire [255 : 0]  key,
+                input wire            keylen,
+
+                input wire [127 : 0]  block,
+                output wire [127 : 0] result,
+                output wire           result_valid
+               );
+
+
+
+
+  //----------------------------------------------------------------
+  // Internal constant and parameter definitions.
+  //----------------------------------------------------------------
+  localparam CTRL_IDLE  = 2'h0;
+  localparam CTRL_INIT  = 2'h1;
+  localparam CTRL_NEXT  = 2'h2;
+
+
+  //----------------------------------------------------------------
+  // Registers including update variables and write enable.
+  //----------------------------------------------------------------
+  reg [1 : 0] aes_core_ctrl_reg;
+  reg [1 : 0] aes_core_ctrl_new;
+  reg         aes_core_ctrl_we;
+
+  reg         result_valid_reg;
+  reg         result_valid_new;
+  reg         result_valid_we;
+
+  reg         ready_reg;
+  reg         ready_new;
+  reg         ready_we;
+
+
+  //----------------------------------------------------------------
+  // Wires.
+  //----------------------------------------------------------------
+  reg            init_state;
+
+  wire [127 : 0] round_key;
+  wire           key_ready;
+
+  reg            enc_next;
+  wire [3 : 0]   enc_round_nr;
+  wire [127 : 0] enc_new_block;
+  wire           enc_ready;
+  wire [31 : 0]  enc_sboxw;
+
+  reg            dec_next;
+  wire [3 : 0]   dec_round_nr;
+  wire [127 : 0] dec_new_block;
+  wire           dec_ready;
+
+  reg [127 : 0]  muxed_new_block;
+  reg [3 : 0]    muxed_round_nr;
+  reg            muxed_ready;
+
+  wire [31 : 0]  keymem_sboxw;
+
+/* verilator lint_off UNOPTFLAT */
+  reg [31 : 0]   muxed_sboxw;
+  wire [31 : 0]  new_sboxw;
+/* verilator lint_on UNOPTFLAT */
+
+
+  //----------------------------------------------------------------
+  // Instantiations.
+  //----------------------------------------------------------------
+  aes_encipher_block enc_block(
+                               .clk(clk),
+                               .reset_n(reset_n),
+
+                               .next(enc_next),
+
+                               .keylen(keylen),
+                               .round(enc_round_nr),
+                               .round_key(round_key),
+
+                               .sboxw(enc_sboxw),
+                               .new_sboxw(new_sboxw),
+
+                               .block(block),
+                               .new_block(enc_new_block),
+                               .ready(enc_ready)
+                              );
+
+
+  aes_decipher_block dec_block(
+                               .clk(clk),
+                               .reset_n(reset_n),
+
+                               .next(dec_next),
+
+                               .keylen(keylen),
+                               .round(dec_round_nr),
+                               .round_key(round_key),
+
+                               .block(block),
+                               .new_block(dec_new_block),
+                               .ready(dec_ready)
+                              );
+
+
+  aes_key_mem keymem(
+                     .clk(clk),
+                     .reset_n(reset_n),
+
+                     .key(key),
+                     .keylen(keylen),
+                     .init(init),
+
+                     .round(muxed_round_nr),
+                     .round_key(round_key),
+                     .ready(key_ready),
+
+                     .sboxw(keymem_sboxw),
+                     .new_sboxw(new_sboxw)
+                    );
+
+
+  aes_sbox sbox_inst(.sboxw(muxed_sboxw), .new_sboxw(new_sboxw));
+
+
+  //----------------------------------------------------------------
+  // Concurrent connectivity for ports etc.
+  //----------------------------------------------------------------
+  assign ready        = ready_reg;
+  assign result       = muxed_new_block;
+  assign result_valid = result_valid_reg;
+
+
+  //----------------------------------------------------------------
+  // reg_update
+  //
+  // Update functionality for all registers in the core.
+  // All registers are positive edge triggered with asynchronous
+  // active low reset. All registers have write enable.
+  //----------------------------------------------------------------
+  always @ (posedge clk or negedge reset_n)
+    begin: reg_update
+      if (!reset_n)
+        begin
+          result_valid_reg  <= 1'b0;
+          ready_reg         <= 1'b1;
+          aes_core_ctrl_reg <= CTRL_IDLE;
+        end
+      else
+        begin
+          if (result_valid_we)
+            result_valid_reg <= result_valid_new;
+
+          if (ready_we)
+            ready_reg <= ready_new;
+
+          if (aes_core_ctrl_we)
+            aes_core_ctrl_reg <= aes_core_ctrl_new;
+        end
+    end // reg_update
+
+
+  //----------------------------------------------------------------
+  // sbox_mux
+  //
+  // Controls which of the encipher datapath or the key memory
+  // that gets access to the sbox.
+  //----------------------------------------------------------------
+  always @*
+    begin : sbox_mux
+      if (init_state)
+        begin
+          muxed_sboxw = keymem_sboxw;
+        end
+      else
+        begin
+          muxed_sboxw = enc_sboxw;
+        end
+    end // sbox_mux
+
+
+  //----------------------------------------------------------------
+  // encdex_mux
+  //
+  // Controls which of the datapaths that get the next signal, have
+  // access to the memory as well as the block processing result.
+  //----------------------------------------------------------------
+  always @*
+    begin : encdec_mux
+      enc_next = 1'b0;
+      dec_next = 1'b0;
+
+      if (encdec)
+        begin
+          // Encipher operations
+          enc_next        = next;
+          muxed_round_nr  = enc_round_nr;
+          muxed_new_block = enc_new_block;
+          muxed_ready     = enc_ready;
+        end
+      else
+        begin
+          // Decipher operations
+          dec_next        = next;
+          muxed_round_nr  = dec_round_nr;
+          muxed_new_block = dec_new_block;
+          muxed_ready     = dec_ready;
+        end
+    end // encdec_mux
+
+
+  //----------------------------------------------------------------
+  // aes_core_ctrl
+  //
+  // Control FSM for aes core. Basically tracks if we are in
+  // key init, encipher or decipher modes and connects the
+  // different submodules to shared resources and interface ports.
+  //----------------------------------------------------------------
+  always @*
+    begin : aes_core_ctrl
+      init_state        = 1'b0;
+      ready_new         = 1'b0;
+      ready_we          = 1'b0;
+      result_valid_new  = 1'b0;
+      result_valid_we   = 1'b0;
+      aes_core_ctrl_new = CTRL_IDLE;
+      aes_core_ctrl_we  = 1'b0;
+
+      case (aes_core_ctrl_reg)
+        CTRL_IDLE:
+          begin
+            if (init)
+              begin
+                init_state        = 1'b1;
+                ready_new         = 1'b0;
+                ready_we          = 1'b1;
+                result_valid_new  = 1'b0;
+                result_valid_we   = 1'b1;
+                aes_core_ctrl_new = CTRL_INIT;
+                aes_core_ctrl_we  = 1'b1;
+              end
+            else if (next)
+              begin
+                init_state        = 1'b0;
+                ready_new         = 1'b0;
+                ready_we          = 1'b1;
+                result_valid_new  = 1'b0;
+                result_valid_we   = 1'b1;
+                aes_core_ctrl_new = CTRL_NEXT;
+                aes_core_ctrl_we  = 1'b1;
+              end
+          end
+
+        CTRL_INIT:
+          begin
+            init_state = 1'b1;
+
+            if (key_ready)
+              begin
+                ready_new         = 1'b1;
+                ready_we          = 1'b1;
+                aes_core_ctrl_new = CTRL_IDLE;
+                aes_core_ctrl_we  = 1'b1;
+              end
+          end
+
+        CTRL_NEXT:
+          begin
+            init_state = 1'b0;
+
+            if (muxed_ready)
+              begin
+                ready_new         = 1'b1;
+                ready_we          = 1'b1;
+                result_valid_new  = 1'b1;
+                result_valid_we   = 1'b1;
+                aes_core_ctrl_new = CTRL_IDLE;
+                aes_core_ctrl_we  = 1'b1;
+             end
+          end
+
+        default:
+          begin
+
+          end
+      endcase // case (aes_core_ctrl_reg)
+
+    end // aes_core_ctrl
+endmodule // aes_core
+
+//======================================================================
+// EOF aes_core.v
+//======================================================================
+
+//======================================================================
+//
+// aes_encipher_block.v
+// --------------------
+// The AES encipher round. A pure combinational module that implements
+// the initial round, main round and final round logic for
+// enciper operations.
+//
+//
+// Author: Joachim Strombergson
+// Copyright (c) 2013, 2014, Secworks Sweden AB
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or
+// without modification, are permitted provided that the following
+// conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright
+//    notice, this list of conditions and the following disclaimer.
+//
+// 2. Redistributions in binary form must reproduce the above copyright
+//    notice, this list of conditions and the following disclaimer in
+//    the documentation and/or other materials provided with the
+//    distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+//======================================================================
+
+`default_nettype none
+
+module aes_encipher_block(
+                          input wire            clk,
+                          input wire            reset_n,
+
+                          input wire            next,
+
+                          input wire            keylen,
+                          output wire [3 : 0]   round,
+                          input wire [127 : 0]  round_key,
+
+                          output wire [31 : 0]  sboxw,
+                          input wire  [31 : 0]  new_sboxw,
+
+                          input wire [127 : 0]  block,
+                          output wire [127 : 0] new_block,
+                          output wire           ready
+                         );
+
+
+  //----------------------------------------------------------------
+  // Internal constant and parameter definitions.
+  //----------------------------------------------------------------
+  localparam AES_128_BIT_KEY = 1'h0;
+  localparam AES_256_BIT_KEY = 1'h1;
+
+  localparam AES128_ROUNDS = 4'ha;
+  localparam AES256_ROUNDS = 4'he;
+
+  localparam NO_UPDATE    = 3'h0;
+  localparam INIT_UPDATE  = 3'h1;
+  localparam SBOX_UPDATE  = 3'h2;
+  localparam MAIN_UPDATE  = 3'h3;
+  localparam FINAL_UPDATE = 3'h4;
+
+  localparam CTRL_IDLE  = 2'h0;
+  localparam CTRL_INIT  = 2'h1;
+  localparam CTRL_SBOX  = 2'h2;
+  localparam CTRL_MAIN  = 2'h3;
+
+
+  //----------------------------------------------------------------
+  // Round functions with sub functions.
+  //----------------------------------------------------------------
+  function [7 : 0] gm2(input [7 : 0] op);
+    begin
+      gm2 = {op[6 : 0], 1'b0} ^ (8'h1b & {8{op[7]}});
+    end
+  endfunction // gm2
+
+  function [7 : 0] gm3(input [7 : 0] op);
+    begin
+      gm3 = gm2(op) ^ op;
+    end
+  endfunction // gm3
+
+  function [31 : 0] mixw(input [31 : 0] w);
+    reg [7 : 0] b0, b1, b2, b3;
+    reg [7 : 0] mb0, mb1, mb2, mb3;
+    begin
+      b0 = w[31 : 24];
+      b1 = w[23 : 16];
+      b2 = w[15 : 08];
+      b3 = w[07 : 00];
+
+      mb0 = gm2(b0) ^ gm3(b1) ^ b2      ^ b3;
+      mb1 = b0      ^ gm2(b1) ^ gm3(b2) ^ b3;
+      mb2 = b0      ^ b1      ^ gm2(b2) ^ gm3(b3);
+      mb3 = gm3(b0) ^ b1      ^ b2      ^ gm2(b3);
+
+      mixw = {mb0, mb1, mb2, mb3};
+    end
+  endfunction // mixw
+
+  function [127 : 0] mixcolumns(input [127 : 0] data);
+    reg [31 : 0] w0, w1, w2, w3;
+    reg [31 : 0] ws0, ws1, ws2, ws3;
+    begin
+      w0 = data[127 : 096];
+      w1 = data[095 : 064];
+      w2 = data[063 : 032];
+      w3 = data[031 : 000];
+
+      ws0 = mixw(w0);
+      ws1 = mixw(w1);
+      ws2 = mixw(w2);
+      ws3 = mixw(w3);
+
+      mixcolumns = {ws0, ws1, ws2, ws3};
+    end
+  endfunction // mixcolumns
+
+  function [127 : 0] shiftrows(input [127 : 0] data);
+    reg [31 : 0] w0, w1, w2, w3;
+    reg [31 : 0] ws0, ws1, ws2, ws3;
+    begin
+      w0 = data[127 : 096];
+      w1 = data[095 : 064];
+      w2 = data[063 : 032];
+      w3 = data[031 : 000];
+
+      ws0 = {w0[31 : 24], w1[23 : 16], w2[15 : 08], w3[07 : 00]};
+      ws1 = {w1[31 : 24], w2[23 : 16], w3[15 : 08], w0[07 : 00]};
+      ws2 = {w2[31 : 24], w3[23 : 16], w0[15 : 08], w1[07 : 00]};
+      ws3 = {w3[31 : 24], w0[23 : 16], w1[15 : 08], w2[07 : 00]};
+
+      shiftrows = {ws0, ws1, ws2, ws3};
+    end
+  endfunction // shiftrows
+
+  function [127 : 0] addroundkey(input [127 : 0] data, input [127 : 0] rkey);
+    begin
+      addroundkey = data ^ rkey;
+    end
+  endfunction // addroundkey
+
+
+  //----------------------------------------------------------------
+  // Registers including update variables and write enable.
+  //----------------------------------------------------------------
+  reg [1 : 0]   sword_ctr_reg;
+  reg [1 : 0]   sword_ctr_new;
+  reg           sword_ctr_we;
+  reg           sword_ctr_inc;
+  reg           sword_ctr_rst;
+
+  reg [3 : 0]   round_ctr_reg;
+  reg [3 : 0]   round_ctr_new;
+  reg           round_ctr_we;
+  reg           round_ctr_rst;
+  reg           round_ctr_inc;
+
+  reg [127 : 0] block_new;
+  reg [31 : 0]  block_w0_reg;
+  reg [31 : 0]  block_w1_reg;
+  reg [31 : 0]  block_w2_reg;
+  reg [31 : 0]  block_w3_reg;
+  reg           block_w0_we;
+  reg           block_w1_we;
+  reg           block_w2_we;
+  reg           block_w3_we;
+
+  reg           ready_reg;
+  reg           ready_new;
+  reg           ready_we;
+
+  reg [1 : 0]   enc_ctrl_reg;
+  reg [1 : 0]   enc_ctrl_new;
+  reg           enc_ctrl_we;
+
+
+  //----------------------------------------------------------------
+  // Wires.
+  //----------------------------------------------------------------
+  reg [2 : 0]  update_type;
+  reg [31 : 0] muxed_sboxw;
+
+
+  //----------------------------------------------------------------
+  // Concurrent connectivity for ports etc.
+  //----------------------------------------------------------------
+  assign round     = round_ctr_reg;
+  assign sboxw     = muxed_sboxw;
+  assign new_block = {block_w0_reg, block_w1_reg, block_w2_reg, block_w3_reg};
+  assign ready     = ready_reg;
+
+
+  //----------------------------------------------------------------
+  // reg_update
+  //
+  // Update functionality for all registers in the core.
+  // All registers are positive edge triggered with asynchronous
+  // active low reset. All registers have write enable.
+  //----------------------------------------------------------------
+  always @ (posedge clk or negedge reset_n)
+    begin: reg_update
+      if (!reset_n)
+        begin
+          block_w0_reg  <= 32'h0;
+          block_w1_reg  <= 32'h0;
+          block_w2_reg  <= 32'h0;
+          block_w3_reg  <= 32'h0;
+          sword_ctr_reg <= 2'h0;
+          round_ctr_reg <= 4'h0;
+          ready_reg     <= 1'b1;
+          enc_ctrl_reg  <= CTRL_IDLE;
+        end
+      else
+        begin
+          if (block_w0_we)
+            block_w0_reg <= block_new[127 : 096];
+
+          if (block_w1_we)
+            block_w1_reg <= block_new[095 : 064];
+
+          if (block_w2_we)
+            block_w2_reg <= block_new[063 : 032];
+
+          if (block_w3_we)
+            block_w3_reg <= block_new[031 : 000];
+
+          if (sword_ctr_we)
+            sword_ctr_reg <= sword_ctr_new;
+
+          if (round_ctr_we)
+            round_ctr_reg <= round_ctr_new;
+
+          if (ready_we)
+            ready_reg <= ready_new;
+
+          if (enc_ctrl_we)
+            enc_ctrl_reg <= enc_ctrl_new;
+        end
+    end // reg_update
+
+
+  //----------------------------------------------------------------
+  // round_logic
+  //
+  // The logic needed to implement init, main and final rounds.
+  //----------------------------------------------------------------
+  always @*
+    begin : round_logic
+      reg [127 : 0] old_block, shiftrows_block, mixcolumns_block;
+      reg [127 : 0] addkey_init_block, addkey_main_block, addkey_final_block;
+
+      block_new   = 128'h0;
+      muxed_sboxw = 32'h0;
+      block_w0_we = 1'b0;
+      block_w1_we = 1'b0;
+      block_w2_we = 1'b0;
+      block_w3_we = 1'b0;
+
+      old_block          = {block_w0_reg, block_w1_reg, block_w2_reg, block_w3_reg};
+      shiftrows_block    = shiftrows(old_block);
+      mixcolumns_block   = mixcolumns(shiftrows_block);
+      addkey_init_block  = addroundkey(block, round_key);
+      addkey_main_block  = addroundkey(mixcolumns_block, round_key);
+      addkey_final_block = addroundkey(shiftrows_block, round_key);
+
+      case (update_type)
+        INIT_UPDATE:
+          begin
+            block_new    = addkey_init_block;
+            block_w0_we  = 1'b1;
+            block_w1_we  = 1'b1;
+            block_w2_we  = 1'b1;
+            block_w3_we  = 1'b1;
+          end
+
+        SBOX_UPDATE:
+          begin
+            block_new = {new_sboxw, new_sboxw, new_sboxw, new_sboxw};
+
+            case (sword_ctr_reg)
+              2'h0:
+                begin
+                  muxed_sboxw = block_w0_reg;
+                  block_w0_we = 1'b1;
+                end
+
+              2'h1:
+                begin
+                  muxed_sboxw = block_w1_reg;
+                  block_w1_we = 1'b1;
+                end
+
+              2'h2:
+                begin
+                  muxed_sboxw = block_w2_reg;
+                  block_w2_we = 1'b1;
+                end
+
+              2'h3:
+                begin
+                  muxed_sboxw = block_w3_reg;
+                  block_w3_we = 1'b1;
+                end
+            endcase // case (sbox_mux_ctrl_reg)
+          end
+
+        MAIN_UPDATE:
+          begin
+            block_new    = addkey_main_block;
+            block_w0_we  = 1'b1;
+            block_w1_we  = 1'b1;
+            block_w2_we  = 1'b1;
+            block_w3_we  = 1'b1;
+          end
+
+        FINAL_UPDATE:
+          begin
+            block_new    = addkey_final_block;
+            block_w0_we  = 1'b1;
+            block_w1_we  = 1'b1;
+            block_w2_we  = 1'b1;
+            block_w3_we  = 1'b1;
+          end
+
+        default:
+          begin
+          end
+      endcase // case (update_type)
+    end // round_logic
+
+
+  //----------------------------------------------------------------
+  // sword_ctr
+  //
+  // The subbytes word counter with reset and increase logic.
+  //----------------------------------------------------------------
+  always @*
+    begin : sword_ctr
+      sword_ctr_new = 2'h0;
+      sword_ctr_we  = 1'b0;
+
+      if (sword_ctr_rst)
+        begin
+          sword_ctr_new = 2'h0;
+          sword_ctr_we  = 1'b1;
+        end
+      else if (sword_ctr_inc)
+        begin
+          sword_ctr_new = sword_ctr_reg + 1'b1;
+          sword_ctr_we  = 1'b1;
+        end
+    end // sword_ctr
+
+
+  //----------------------------------------------------------------
+  // round_ctr
+  //
+  // The round counter with reset and increase logic.
+  //----------------------------------------------------------------
+  always @*
+    begin : round_ctr
+      round_ctr_new = 4'h0;
+      round_ctr_we  = 1'b0;
+
+      if (round_ctr_rst)
+        begin
+          round_ctr_new = 4'h0;
+          round_ctr_we  = 1'b1;
+        end
+      else if (round_ctr_inc)
+        begin
+          round_ctr_new = round_ctr_reg + 1'b1;
+          round_ctr_we  = 1'b1;
+        end
+    end // round_ctr
+
+
+  //----------------------------------------------------------------
+  // encipher_ctrl
+  //
+  // The FSM that controls the encipher operations.
+  //----------------------------------------------------------------
+  always @*
+    begin: encipher_ctrl
+      reg [3 : 0] num_rounds;
+
+      // Default assignments.
+      sword_ctr_inc = 1'b0;
+      sword_ctr_rst = 1'b0;
+      round_ctr_inc = 1'b0;
+      round_ctr_rst = 1'b0;
+      ready_new     = 1'b0;
+      ready_we      = 1'b0;
+      update_type   = NO_UPDATE;
+      enc_ctrl_new  = CTRL_IDLE;
+      enc_ctrl_we   = 1'b0;
+
+      if (keylen == AES_256_BIT_KEY)
+        begin
+          num_rounds = AES256_ROUNDS;
+        end
+      else
+        begin
+          num_rounds = AES128_ROUNDS;
+        end
+
+      case(enc_ctrl_reg)
+        CTRL_IDLE:
+          begin
+            if (next)
+              begin
+                round_ctr_rst = 1'b1;
+                ready_new     = 1'b0;
+                ready_we      = 1'b1;
+                enc_ctrl_new  = CTRL_INIT;
+                enc_ctrl_we   = 1'b1;
+              end
+          end
+
+        CTRL_INIT:
+          begin
+            round_ctr_inc = 1'b1;
+            sword_ctr_rst = 1'b1;
+            update_type   = INIT_UPDATE;
+            enc_ctrl_new  = CTRL_SBOX;
+            enc_ctrl_we   = 1'b1;
+          end
+
+        CTRL_SBOX:
+          begin
+            sword_ctr_inc = 1'b1;
+            update_type   = SBOX_UPDATE;
+            if (sword_ctr_reg == 2'h3)
+              begin
+                enc_ctrl_new  = CTRL_MAIN;
+                enc_ctrl_we   = 1'b1;
+              end
+          end
+
+        CTRL_MAIN:
+          begin
+            sword_ctr_rst = 1'b1;
+            round_ctr_inc = 1'b1;
+            if (round_ctr_reg < num_rounds)
+              begin
+                update_type   = MAIN_UPDATE;
+                enc_ctrl_new  = CTRL_SBOX;
+                enc_ctrl_we   = 1'b1;
+              end
+            else
+              begin
+                update_type  = FINAL_UPDATE;
+                ready_new    = 1'b1;
+                ready_we     = 1'b1;
+                enc_ctrl_new = CTRL_IDLE;
+                enc_ctrl_we  = 1'b1;
+              end
+          end
+
+        default:
+          begin
+            // Empty. Just here to make the synthesis tool happy.
+          end
+      endcase // case (enc_ctrl_reg)
+    end // encipher_ctrl
+
+endmodule // aes_encipher_block
+
+//======================================================================
+// EOF aes_encipher_block.v
+//======================================================================
+
+//======================================================================
+//
+// aes_decipher_block.v
+// --------------------
+// The AES decipher round. A pure combinational module that implements
+// the initial round, main round and final round logic for
+// decciper operations.
+//
+//
+// Author: Joachim Strombergson
+// Copyright (c) 2013, 2014, Secworks Sweden AB
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or
+// without modification, are permitted provided that the following
+// conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright
+//    notice, this list of conditions and the following disclaimer.
+//
+// 2. Redistributions in binary form must reproduce the above copyright
+//    notice, this list of conditions and the following disclaimer in
+//    the documentation and/or other materials provided with the
+//    distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+//======================================================================
+
+`default_nettype none
+
+module aes_decipher_block(
+                          input wire            clk,
+                          input wire            reset_n,
+
+                          input wire            next,
+
+                          input wire            keylen,
+                          output wire [3 : 0]   round,
+                          input wire [127 : 0]  round_key,
+
+                          input wire [127 : 0]  block,
+                          output wire [127 : 0] new_block,
+                          output wire           ready
+                         );
+
+
+  //----------------------------------------------------------------
+  // Internal constant and parameter definitions.
+  //----------------------------------------------------------------
+  localparam AES_128_BIT_KEY = 1'h0;
+  localparam AES_256_BIT_KEY = 1'h1;
+
+  localparam AES128_ROUNDS = 4'ha;
+  localparam AES256_ROUNDS = 4'he;
+
+  localparam NO_UPDATE    = 3'h0;
+  localparam INIT_UPDATE  = 3'h1;
+  localparam SBOX_UPDATE  = 3'h2;
+  localparam MAIN_UPDATE  = 3'h3;
+  localparam FINAL_UPDATE = 3'h4;
+
+  localparam CTRL_IDLE  = 2'h0;
+  localparam CTRL_INIT  = 2'h1;
+  localparam CTRL_SBOX  = 2'h2;
+  localparam CTRL_MAIN  = 2'h3;
+
+
+  //----------------------------------------------------------------
+  // Gaolis multiplication functions for Inverse MixColumn.
+  //----------------------------------------------------------------
+  function [7 : 0] gm2(input [7 : 0] op);
+    begin
+      gm2 = {op[6 : 0], 1'b0} ^ (8'h1b & {8{op[7]}});
+    end
+  endfunction // gm2
+
+  function [7 : 0] gm3(input [7 : 0] op);
+    begin
+      gm3 = gm2(op) ^ op;
+    end
+  endfunction // gm3
+
+  function [7 : 0] gm4(input [7 : 0] op);
+    begin
+      gm4 = gm2(gm2(op));
+    end
+  endfunction // gm4
+
+  function [7 : 0] gm8(input [7 : 0] op);
+    begin
+      gm8 = gm2(gm4(op));
+    end
+  endfunction // gm8
+
+  function [7 : 0] gm09(input [7 : 0] op);
+    begin
+      gm09 = gm8(op) ^ op;
+    end
+  endfunction // gm09
+
+  function [7 : 0] gm11(input [7 : 0] op);
+    begin
+      gm11 = gm8(op) ^ gm2(op) ^ op;
+    end
+  endfunction // gm11
+
+  function [7 : 0] gm13(input [7 : 0] op);
+    begin
+      gm13 = gm8(op) ^ gm4(op) ^ op;
+    end
+  endfunction // gm13
+
+  function [7 : 0] gm14(input [7 : 0] op);
+    begin
+      gm14 = gm8(op) ^ gm4(op) ^ gm2(op);
+    end
+  endfunction // gm14
+
+  function [31 : 0] inv_mixw(input [31 : 0] w);
+    reg [7 : 0] b0, b1, b2, b3;
+    reg [7 : 0] mb0, mb1, mb2, mb3;
+    begin
+      b0 = w[31 : 24];
+      b1 = w[23 : 16];
+      b2 = w[15 : 08];
+      b3 = w[07 : 00];
+
+      mb0 = gm14(b0) ^ gm11(b1) ^ gm13(b2) ^ gm09(b3);
+      mb1 = gm09(b0) ^ gm14(b1) ^ gm11(b2) ^ gm13(b3);
+      mb2 = gm13(b0) ^ gm09(b1) ^ gm14(b2) ^ gm11(b3);
+      mb3 = gm11(b0) ^ gm13(b1) ^ gm09(b2) ^ gm14(b3);
+
+      inv_mixw = {mb0, mb1, mb2, mb3};
+    end
+  endfunction // mixw
+
+  function [127 : 0] inv_mixcolumns(input [127 : 0] data);
+    reg [31 : 0] w0, w1, w2, w3;
+    reg [31 : 0] ws0, ws1, ws2, ws3;
+    begin
+      w0 = data[127 : 096];
+      w1 = data[095 : 064];
+      w2 = data[063 : 032];
+      w3 = data[031 : 000];
+
+      ws0 = inv_mixw(w0);
+      ws1 = inv_mixw(w1);
+      ws2 = inv_mixw(w2);
+      ws3 = inv_mixw(w3);
+
+      inv_mixcolumns = {ws0, ws1, ws2, ws3};
+    end
+  endfunction // inv_mixcolumns
+
+  function [127 : 0] inv_shiftrows(input [127 : 0] data);
+    reg [31 : 0] w0, w1, w2, w3;
+    reg [31 : 0] ws0, ws1, ws2, ws3;
+    begin
+      w0 = data[127 : 096];
+      w1 = data[095 : 064];
+      w2 = data[063 : 032];
+      w3 = data[031 : 000];
+
+      ws0 = {w0[31 : 24], w3[23 : 16], w2[15 : 08], w1[07 : 00]};
+      ws1 = {w1[31 : 24], w0[23 : 16], w3[15 : 08], w2[07 : 00]};
+      ws2 = {w2[31 : 24], w1[23 : 16], w0[15 : 08], w3[07 : 00]};
+      ws3 = {w3[31 : 24], w2[23 : 16], w1[15 : 08], w0[07 : 00]};
+
+      inv_shiftrows = {ws0, ws1, ws2, ws3};
+    end
+  endfunction // inv_shiftrows
+
+  function [127 : 0] addroundkey(input [127 : 0] data, input [127 : 0] rkey);
+    begin
+      addroundkey = data ^ rkey;
+    end
+  endfunction // addroundkey
+
+
+  //----------------------------------------------------------------
+  // Registers including update variables and write enable.
+  //----------------------------------------------------------------
+  reg [1 : 0]   sword_ctr_reg;
+  reg [1 : 0]   sword_ctr_new;
+  reg           sword_ctr_we;
+  reg           sword_ctr_inc;
+  reg           sword_ctr_rst;
+
+  reg [3 : 0]   round_ctr_reg;
+  reg [3 : 0]   round_ctr_new;
+  reg           round_ctr_we;
+  reg           round_ctr_set;
+  reg           round_ctr_dec;
+
+  reg [127 : 0] block_new;
+  reg [31 : 0]  block_w0_reg;
+  reg [31 : 0]  block_w1_reg;
+  reg [31 : 0]  block_w2_reg;
+  reg [31 : 0]  block_w3_reg;
+  reg           block_w0_we;
+  reg           block_w1_we;
+  reg           block_w2_we;
+  reg           block_w3_we;
+
+  reg           ready_reg;
+  reg           ready_new;
+  reg           ready_we;
+
+  reg [1 : 0]   dec_ctrl_reg;
+  reg [1 : 0]   dec_ctrl_new;
+  reg           dec_ctrl_we;
+
+
+  //----------------------------------------------------------------
+  // Wires.
+  //----------------------------------------------------------------
+  reg [31 : 0]  tmp_sboxw;
+  wire [31 : 0] new_sboxw;
+  reg [2 : 0]   update_type;
+
+
+  //----------------------------------------------------------------
+  // Instantiations.
+  //----------------------------------------------------------------
+  aes_inv_sbox inv_sbox_inst(.sboxw(tmp_sboxw), .new_sboxw(new_sboxw));
+
+
+  //----------------------------------------------------------------
+  // Concurrent connectivity for ports etc.
+  //----------------------------------------------------------------
+  assign round     = round_ctr_reg;
+  assign new_block = {block_w0_reg, block_w1_reg, block_w2_reg, block_w3_reg};
+  assign ready     = ready_reg;
+
+
+  //----------------------------------------------------------------
+  // reg_update
+  //
+  // Update functionality for all registers in the core.
+  // All registers are positive edge triggered with synchronous
+  // active low reset. All registers have write enable.
+  //----------------------------------------------------------------
+  always @ (posedge clk or negedge reset_n)
+    begin: reg_update
+      if (!reset_n)
+        begin
+          block_w0_reg  <= 32'h0;
+          block_w1_reg  <= 32'h0;
+          block_w2_reg  <= 32'h0;
+          block_w3_reg  <= 32'h0;
+          sword_ctr_reg <= 2'h0;
+          round_ctr_reg <= 4'h0;
+          ready_reg     <= 1'b1;
+          dec_ctrl_reg  <= CTRL_IDLE;
+        end
+      else
+        begin
+          if (block_w0_we)
+            block_w0_reg <= block_new[127 : 096];
+
+          if (block_w1_we)
+            block_w1_reg <= block_new[095 : 064];
+
+          if (block_w2_we)
+            block_w2_reg <= block_new[063 : 032];
+
+          if (block_w3_we)
+            block_w3_reg <= block_new[031 : 000];
+
+          if (sword_ctr_we)
+            sword_ctr_reg <= sword_ctr_new;
+
+          if (round_ctr_we)
+            round_ctr_reg <= round_ctr_new;
+
+          if (ready_we)
+            ready_reg <= ready_new;
+
+          if (dec_ctrl_we)
+            dec_ctrl_reg <= dec_ctrl_new;
+        end
+    end // reg_update
+
+
+  //----------------------------------------------------------------
+  // round_logic
+  //
+  // The logic needed to implement init, main and final rounds.
+  //----------------------------------------------------------------
+  always @*
+    begin : round_logic
+      reg [127 : 0] old_block, inv_shiftrows_block, inv_mixcolumns_block;
+      reg [127 : 0] addkey_block;
+
+      inv_shiftrows_block  = 128'h0;
+      inv_mixcolumns_block = 128'h0;
+      addkey_block         = 128'h0;
+      block_new            = 128'h0;
+      tmp_sboxw            = 32'h0;
+      block_w0_we          = 1'b0;
+      block_w1_we          = 1'b0;
+      block_w2_we          = 1'b0;
+      block_w3_we          = 1'b0;
+
+      old_block            = {block_w0_reg, block_w1_reg, block_w2_reg, block_w3_reg};
+
+      // Update based on update type.
+      case (update_type)
+        // InitRound
+        INIT_UPDATE:
+          begin
+            old_block           = block;
+            addkey_block        = addroundkey(old_block, round_key);
+            inv_shiftrows_block = inv_shiftrows(addkey_block);
+            block_new           = inv_shiftrows_block;
+            block_w0_we         = 1'b1;
+            block_w1_we         = 1'b1;
+            block_w2_we         = 1'b1;
+            block_w3_we         = 1'b1;
+          end
+
+        SBOX_UPDATE:
+          begin
+            block_new = {new_sboxw, new_sboxw, new_sboxw, new_sboxw};
+
+            case (sword_ctr_reg)
+              2'h0:
+                begin
+                  tmp_sboxw   = block_w0_reg;
+                  block_w0_we = 1'b1;
+                end
+
+              2'h1:
+                begin
+                  tmp_sboxw   = block_w1_reg;
+                  block_w1_we = 1'b1;
+                end
+
+              2'h2:
+                begin
+                  tmp_sboxw   = block_w2_reg;
+                  block_w2_we = 1'b1;
+                end
+
+              2'h3:
+                begin
+                  tmp_sboxw   = block_w3_reg;
+                  block_w3_we = 1'b1;
+                end
+            endcase // case (sbox_mux_ctrl_reg)
+          end
+
+        MAIN_UPDATE:
+          begin
+            addkey_block         = addroundkey(old_block, round_key);
+            inv_mixcolumns_block = inv_mixcolumns(addkey_block);
+            inv_shiftrows_block  = inv_shiftrows(inv_mixcolumns_block);
+            block_new            = inv_shiftrows_block;
+            block_w0_we          = 1'b1;
+            block_w1_we          = 1'b1;
+            block_w2_we          = 1'b1;
+            block_w3_we          = 1'b1;
+          end
+
+        FINAL_UPDATE:
+          begin
+            block_new    = addroundkey(old_block, round_key);
+            block_w0_we  = 1'b1;
+            block_w1_we  = 1'b1;
+            block_w2_we  = 1'b1;
+            block_w3_we  = 1'b1;
+          end
+
+        default:
+          begin
+          end
+      endcase // case (update_type)
+    end // round_logic
+
+
+  //----------------------------------------------------------------
+  // sword_ctr
+  //
+  // The subbytes word counter with reset and increase logic.
+  //----------------------------------------------------------------
+  always @*
+    begin : sword_ctr
+      sword_ctr_new = 2'h0;
+      sword_ctr_we  = 1'b0;
+
+      if (sword_ctr_rst)
+        begin
+          sword_ctr_new = 2'h0;
+          sword_ctr_we  = 1'b1;
+        end
+      else if (sword_ctr_inc)
+        begin
+          sword_ctr_new = sword_ctr_reg + 1'b1;
+          sword_ctr_we  = 1'b1;
+        end
+    end // sword_ctr
+
+
+  //----------------------------------------------------------------
+  // round_ctr
+  //
+  // The round counter with reset and increase logic.
+  //----------------------------------------------------------------
+  always @*
+    begin : round_ctr
+      round_ctr_new = 4'h0;
+      round_ctr_we  = 1'b0;
+
+      if (round_ctr_set)
+        begin
+          if (keylen == AES_256_BIT_KEY)
+            begin
+              round_ctr_new = AES256_ROUNDS;
+            end
+          else
+            begin
+              round_ctr_new = AES128_ROUNDS;
+            end
+          round_ctr_we  = 1'b1;
+        end
+      else if (round_ctr_dec)
+        begin
+          round_ctr_new = round_ctr_reg - 1'b1;
+          round_ctr_we  = 1'b1;
+        end
+    end // round_ctr
+
+
+  //----------------------------------------------------------------
+  // decipher_ctrl
+  //
+  // The FSM that controls the decipher operations.
+  //----------------------------------------------------------------
+  always @*
+    begin: decipher_ctrl
+      sword_ctr_inc = 1'b0;
+      sword_ctr_rst = 1'b0;
+      round_ctr_dec = 1'b0;
+      round_ctr_set = 1'b0;
+      ready_new     = 1'b0;
+      ready_we      = 1'b0;
+      update_type   = NO_UPDATE;
+      dec_ctrl_new  = CTRL_IDLE;
+      dec_ctrl_we   = 1'b0;
+
+      case(dec_ctrl_reg)
+        CTRL_IDLE:
+          begin
+            if (next)
+              begin
+                round_ctr_set = 1'b1;
+                ready_new     = 1'b0;
+                ready_we      = 1'b1;
+                dec_ctrl_new  = CTRL_INIT;
+                dec_ctrl_we   = 1'b1;
+              end
+          end
+
+        CTRL_INIT:
+          begin
+            sword_ctr_rst = 1'b1;
+            update_type   = INIT_UPDATE;
+            dec_ctrl_new  = CTRL_SBOX;
+            dec_ctrl_we   = 1'b1;
+          end
+
+        CTRL_SBOX:
+          begin
+            sword_ctr_inc = 1'b1;
+            update_type   = SBOX_UPDATE;
+            if (sword_ctr_reg == 2'h3)
+              begin
+                round_ctr_dec = 1'b1;
+                dec_ctrl_new  = CTRL_MAIN;
+                dec_ctrl_we   = 1'b1;
+              end
+          end
+
+        CTRL_MAIN:
+          begin
+            sword_ctr_rst = 1'b1;
+            if (round_ctr_reg > 0)
+              begin
+                update_type   = MAIN_UPDATE;
+                dec_ctrl_new  = CTRL_SBOX;
+                dec_ctrl_we   = 1'b1;
+              end
+            else
+              begin
+                update_type  = FINAL_UPDATE;
+                ready_new    = 1'b1;
+                ready_we     = 1'b1;
+                dec_ctrl_new = CTRL_IDLE;
+                dec_ctrl_we  = 1'b1;
+              end
+          end
+
+        default:
+          begin
+            // Empty. Just here to make the synthesis tool happy.
+          end
+      endcase // case (dec_ctrl_reg)
+    end // decipher_ctrl
+
+endmodule // aes_decipher_block
+
+//======================================================================
+// EOF aes_decipher_block.v
+//======================================================================
+
+//======================================================================
+//
+// aes_key_mem.v
+// -------------
+// The AES key memory including round key generator.
+//
+//
+// Author: Joachim Strombergson
+// Copyright (c) 2013 Secworks Sweden AB
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or
+// without modification, are permitted provided that the following
+// conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright
+//    notice, this list of conditions and the following disclaimer.
+//
+// 2. Redistributions in binary form must reproduce the above copyright
+//    notice, this list of conditions and the following disclaimer in
+//    the documentation and/or other materials provided with the
+//    distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+//======================================================================
+
+`default_nettype none
+
+module aes_key_mem(
+                   input wire            clk,
+                   input wire            reset_n,
+
+                   input wire [255 : 0]  key,
+                   input wire            keylen,
+                   input wire            init,
+
+                   input wire    [3 : 0] round,
+                   output wire [127 : 0] round_key,
+                   output wire           ready,
+
+
+                   output wire [31 : 0]  sboxw,
+                   input wire  [31 : 0]  new_sboxw
+                  );
+
+
+  //----------------------------------------------------------------
+  // Parameters.
+  //----------------------------------------------------------------
+  localparam AES_128_BIT_KEY = 1'h0;
+  localparam AES_256_BIT_KEY = 1'h1;
+
+  localparam AES_128_NUM_ROUNDS = 10;
+  localparam AES_256_NUM_ROUNDS = 14;
+
+  localparam CTRL_IDLE     = 3'h0;
+  localparam CTRL_INIT     = 3'h1;
+  localparam CTRL_GENERATE = 3'h2;
+  localparam CTRL_DONE     = 3'h3;
+
+
+  //----------------------------------------------------------------
+  // Registers.
+  //----------------------------------------------------------------
+  reg [127 : 0] key_mem [0 : 14];
+  reg [127 : 0] key_mem_new;
+  reg           key_mem_we;
+
+  reg [127 : 0] prev_key0_reg;
+  reg [127 : 0] prev_key0_new;
+  reg           prev_key0_we;
+
+  reg [127 : 0] prev_key1_reg;
+  reg [127 : 0] prev_key1_new;
+  reg           prev_key1_we;
+
+  reg [3 : 0] round_ctr_reg;
+  reg [3 : 0] round_ctr_new;
+  reg         round_ctr_rst;
+  reg         round_ctr_inc;
+  reg         round_ctr_we;
+
+  reg [2 : 0] key_mem_ctrl_reg;
+  reg [2 : 0] key_mem_ctrl_new;
+  reg         key_mem_ctrl_we;
+
+  reg         ready_reg;
+  reg         ready_new;
+  reg         ready_we;
+
+  reg [7 : 0] rcon_reg;
+  reg [7 : 0] rcon_new;
+  reg         rcon_we;
+  reg         rcon_set;
+  reg         rcon_next;
+
+
+  //----------------------------------------------------------------
+  // Wires.
+  //----------------------------------------------------------------
+  reg [31 : 0]  tmp_sboxw;
+  reg           round_key_update;
+  reg [127 : 0] tmp_round_key;
+
+
+  //----------------------------------------------------------------
+  // Concurrent assignments for ports.
+  //----------------------------------------------------------------
+  assign round_key = tmp_round_key;
+  assign ready     = ready_reg;
+  assign sboxw     = tmp_sboxw;
+
+
+  //----------------------------------------------------------------
+  // reg_update
+  //
+  // Update functionality for all registers in the core.
+  // All registers are positive edge triggered with asynchronous
+  // active low reset. All registers have write enable.
+  //----------------------------------------------------------------
+  always @ (posedge clk or negedge reset_n)
+    begin: reg_update
+      integer i;
+
+      if (!reset_n)
+        begin
+          for (i = 0 ; i <= AES_256_NUM_ROUNDS ; i = i + 1)
+            key_mem [i] <= 128'h0;
+
+          ready_reg        <= 1'b0;
+          rcon_reg         <= 8'h0;
+          round_ctr_reg    <= 4'h0;
+          prev_key0_reg    <= 128'h0;
+          prev_key1_reg    <= 128'h0;
+          key_mem_ctrl_reg <= CTRL_IDLE;
+        end
+      else
+        begin
+          if (ready_we)
+            ready_reg <= ready_new;
+
+          if (rcon_we)
+            rcon_reg <= rcon_new;
+
+          if (round_ctr_we)
+            round_ctr_reg <= round_ctr_new;
+
+          if (key_mem_we)
+            key_mem[round_ctr_reg] <= key_mem_new;
+
+          if (prev_key0_we)
+            prev_key0_reg <= prev_key0_new;
+
+          if (prev_key1_we)
+            prev_key1_reg <= prev_key1_new;
+
+          if (key_mem_ctrl_we)
+            key_mem_ctrl_reg <= key_mem_ctrl_new;
+        end
+    end // reg_update
+
+
+  //----------------------------------------------------------------
+  // key_mem_read
+  //
+  // Combinational read port for the key memory.
+  //----------------------------------------------------------------
+  always @*
+    begin : key_mem_read
+      tmp_round_key = key_mem[round];
+    end // key_mem_read
+
+
+  //----------------------------------------------------------------
+  // round_key_gen
+  //
+  // The round key generator logic for AES-128 and AES-256.
+  //----------------------------------------------------------------
+  always @*
+    begin: round_key_gen
+      reg [31 : 0] w0, w1, w2, w3, w4, w5, w6, w7;
+      reg [31 : 0] k0, k1, k2, k3;
+      reg [31 : 0] rconw, rotstw, tw, trw;
+
+      // Default assignments.
+      key_mem_new   = 128'h0;
+      key_mem_we    = 1'b0;
+      prev_key0_new = 128'h0;
+      prev_key0_we  = 1'b0;
+      prev_key1_new = 128'h0;
+      prev_key1_we  = 1'b0;
+
+      k0 = 32'h0;
+      k1 = 32'h0;
+      k2 = 32'h0;
+      k3 = 32'h0;
+
+      rcon_set   = 1'b1;
+      rcon_next  = 1'b0;
+
+      // Extract words and calculate intermediate values.
+      // Perform rotation of sbox word etc.
+      w0 = prev_key0_reg[127 : 096];
+      w1 = prev_key0_reg[095 : 064];
+      w2 = prev_key0_reg[063 : 032];
+      w3 = prev_key0_reg[031 : 000];
+
+      w4 = prev_key1_reg[127 : 096];
+      w5 = prev_key1_reg[095 : 064];
+      w6 = prev_key1_reg[063 : 032];
+      w7 = prev_key1_reg[031 : 000];
+
+      rconw = {rcon_reg, 24'h0};
+      tmp_sboxw = w7;
+      rotstw = {new_sboxw[23 : 00], new_sboxw[31 : 24]};
+      trw = rotstw ^ rconw;
+      tw = new_sboxw;
+
+      // Generate the specific round keys.
+      if (round_key_update)
+        begin
+          rcon_set   = 1'b0;
+          key_mem_we = 1'b1;
+          case (keylen)
+            AES_128_BIT_KEY:
+              begin
+                if (round_ctr_reg == 0)
+                  begin
+                    key_mem_new   = key[255 : 128];
+                    prev_key1_new = key[255 : 128];
+                    prev_key1_we  = 1'b1;
+                    rcon_next     = 1'b1;
+                  end
+                else
+                  begin
+                    k0 = w4 ^ trw;
+                    k1 = w5 ^ w4 ^ trw;
+                    k2 = w6 ^ w5 ^ w4 ^ trw;
+                    k3 = w7 ^ w6 ^ w5 ^ w4 ^ trw;
+
+                    key_mem_new   = {k0, k1, k2, k3};
+                    prev_key1_new = {k0, k1, k2, k3};
+                    prev_key1_we  = 1'b1;
+                    rcon_next     = 1'b1;
+                  end
+              end
+
+            AES_256_BIT_KEY:
+              begin
+                if (round_ctr_reg == 0)
+                  begin
+                    key_mem_new   = key[255 : 128];
+                    prev_key0_new = key[255 : 128];
+                    prev_key0_we  = 1'b1;
+                  end
+                else if (round_ctr_reg == 1)
+                  begin
+                    key_mem_new   = key[127 : 0];
+                    prev_key1_new = key[127 : 0];
+                    prev_key1_we  = 1'b1;
+                    rcon_next     = 1'b1;
+                  end
+                else
+                  begin
+                    if (round_ctr_reg[0] == 0)
+                      begin
+                        k0 = w0 ^ trw;
+                        k1 = w1 ^ w0 ^ trw;
+                        k2 = w2 ^ w1 ^ w0 ^ trw;
+                        k3 = w3 ^ w2 ^ w1 ^ w0 ^ trw;
+                      end
+                    else
+                      begin
+                        k0 = w0 ^ tw;
+                        k1 = w1 ^ w0 ^ tw;
+                        k2 = w2 ^ w1 ^ w0 ^ tw;
+                        k3 = w3 ^ w2 ^ w1 ^ w0 ^ tw;
+                        rcon_next = 1'b1;
+                      end
+
+                    // Store the generated round keys.
+                    key_mem_new   = {k0, k1, k2, k3};
+                    prev_key1_new = {k0, k1, k2, k3};
+                    prev_key1_we  = 1'b1;
+                    prev_key0_new = prev_key1_reg;
+                    prev_key0_we  = 1'b1;
+                  end
+              end
+
+            default:
+              begin
+              end
+          endcase // case (keylen)
+        end
+    end // round_key_gen
+
+
+  //----------------------------------------------------------------
+  // rcon_logic
+  //
+  // Caclulates the rcon value for the different key expansion
+  // iterations.
+  //----------------------------------------------------------------
+  always @*
+    begin : rcon_logic
+      reg [7 : 0] tmp_rcon;
+      rcon_new = 8'h00;
+      rcon_we  = 1'b0;
+
+      tmp_rcon = {rcon_reg[6 : 0], 1'b0} ^ (8'h1b & {8{rcon_reg[7]}});
+
+      if (rcon_set)
+        begin
+          rcon_new = 8'h8d;
+          rcon_we  = 1'b1;
+        end
+
+      if (rcon_next)
+        begin
+          rcon_new = tmp_rcon[7 : 0];
+          rcon_we  = 1'b1;
+        end
+    end
+
+
+  //----------------------------------------------------------------
+  // round_ctr
+  //
+  // The round counter logic with increase and reset.
+  //----------------------------------------------------------------
+  always @*
+    begin : round_ctr
+      round_ctr_new = 4'h0;
+      round_ctr_we  = 1'b0;
+
+      if (round_ctr_rst)
+        begin
+          round_ctr_new = 4'h0;
+          round_ctr_we  = 1'b1;
+        end
+
+      else if (round_ctr_inc)
+        begin
+          round_ctr_new = round_ctr_reg + 1'b1;
+          round_ctr_we  = 1'b1;
+        end
+    end
+
+
+  //----------------------------------------------------------------
+  // key_mem_ctrl
+  //
+  //
+  // The FSM that controls the round key generation.
+  //----------------------------------------------------------------
+  always @*
+    begin: key_mem_ctrl
+      reg [3 : 0] num_rounds;
+
+      // Default assignments.
+      ready_new        = 1'b0;
+      ready_we         = 1'b0;
+      round_key_update = 1'b0;
+      round_ctr_rst    = 1'b0;
+      round_ctr_inc    = 1'b0;
+      key_mem_ctrl_new = CTRL_IDLE;
+      key_mem_ctrl_we  = 1'b0;
+
+      if (keylen == AES_128_BIT_KEY)
+        num_rounds = AES_128_NUM_ROUNDS;
+      else
+        num_rounds = AES_256_NUM_ROUNDS;
+
+      case(key_mem_ctrl_reg)
+        CTRL_IDLE:
+          begin
+            if (init)
+              begin
+                ready_new        = 1'b0;
+                ready_we         = 1'b1;
+                key_mem_ctrl_new = CTRL_INIT;
+                key_mem_ctrl_we  = 1'b1;
+              end
+          end
+
+        CTRL_INIT:
+          begin
+            round_ctr_rst    = 1'b1;
+            key_mem_ctrl_new = CTRL_GENERATE;
+            key_mem_ctrl_we  = 1'b1;
+          end
+
+        CTRL_GENERATE:
+          begin
+            round_ctr_inc    = 1'b1;
+            round_key_update = 1'b1;
+            if (round_ctr_reg == num_rounds)
+              begin
+                key_mem_ctrl_new = CTRL_DONE;
+                key_mem_ctrl_we  = 1'b1;
+              end
+          end
+
+        CTRL_DONE:
+          begin
+            ready_new        = 1'b1;
+            ready_we         = 1'b1;
+            key_mem_ctrl_new = CTRL_IDLE;
+            key_mem_ctrl_we  = 1'b1;
+          end
+
+        default:
+          begin
+          end
+      endcase // case (key_mem_ctrl_reg)
+
+    end // key_mem_ctrl
+endmodule // aes_key_mem
+
+//======================================================================
+// EOF aes_key_mem.v
+//======================================================================
+
+//======================================================================
+//
+// aes_sbox.v
+// ----------
+// The AES S-box. Basically a 256 Byte ROM. This implementation
+// contains four parallel S-boxes to handle a 32 bit word.
+//
+//
+// Author: Joachim Strombergson
+// Copyright (c) 2014, Secworks Sweden AB
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or
+// without modification, are permitted provided that the following
+// conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright
+//    notice, this list of conditions and the following disclaimer.
+//
+// 2. Redistributions in binary form must reproduce the above copyright
+//    notice, this list of conditions and the following disclaimer in
+//    the documentation and/or other materials provided with the
+//    distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+//======================================================================
+
+`default_nettype none
+
+module aes_sbox(
+                input wire [31 : 0]  sboxw,
+                output wire [31 : 0] new_sboxw
+               );
+
+
+  //----------------------------------------------------------------
+  // The sbox array.
+  //----------------------------------------------------------------
+  wire [7 : 0] sbox [0 : 255];
+
+
+  //----------------------------------------------------------------
+  // Four parallel muxes.
+  //----------------------------------------------------------------
+  assign new_sboxw[31 : 24] = sbox[sboxw[31 : 24]];
+  assign new_sboxw[23 : 16] = sbox[sboxw[23 : 16]];
+  assign new_sboxw[15 : 08] = sbox[sboxw[15 : 08]];
+  assign new_sboxw[07 : 00] = sbox[sboxw[07 : 00]];
+
+
+  //----------------------------------------------------------------
+  // Creating the sbox array contents.
+  //----------------------------------------------------------------
+  assign sbox[8'h00] = 8'h63;
+  assign sbox[8'h01] = 8'h7c;
+  assign sbox[8'h02] = 8'h77;
+  assign sbox[8'h03] = 8'h7b;
+  assign sbox[8'h04] = 8'hf2;
+  assign sbox[8'h05] = 8'h6b;
+  assign sbox[8'h06] = 8'h6f;
+  assign sbox[8'h07] = 8'hc5;
+  assign sbox[8'h08] = 8'h30;
+  assign sbox[8'h09] = 8'h01;
+  assign sbox[8'h0a] = 8'h67;
+  assign sbox[8'h0b] = 8'h2b;
+  assign sbox[8'h0c] = 8'hfe;
+  assign sbox[8'h0d] = 8'hd7;
+  assign sbox[8'h0e] = 8'hab;
+  assign sbox[8'h0f] = 8'h76;
+  assign sbox[8'h10] = 8'hca;
+  assign sbox[8'h11] = 8'h82;
+  assign sbox[8'h12] = 8'hc9;
+  assign sbox[8'h13] = 8'h7d;
+  assign sbox[8'h14] = 8'hfa;
+  assign sbox[8'h15] = 8'h59;
+  assign sbox[8'h16] = 8'h47;
+  assign sbox[8'h17] = 8'hf0;
+  assign sbox[8'h18] = 8'had;
+  assign sbox[8'h19] = 8'hd4;
+  assign sbox[8'h1a] = 8'ha2;
+  assign sbox[8'h1b] = 8'haf;
+  assign sbox[8'h1c] = 8'h9c;
+  assign sbox[8'h1d] = 8'ha4;
+  assign sbox[8'h1e] = 8'h72;
+  assign sbox[8'h1f] = 8'hc0;
+  assign sbox[8'h20] = 8'hb7;
+  assign sbox[8'h21] = 8'hfd;
+  assign sbox[8'h22] = 8'h93;
+  assign sbox[8'h23] = 8'h26;
+  assign sbox[8'h24] = 8'h36;
+  assign sbox[8'h25] = 8'h3f;
+  assign sbox[8'h26] = 8'hf7;
+  assign sbox[8'h27] = 8'hcc;
+  assign sbox[8'h28] = 8'h34;
+  assign sbox[8'h29] = 8'ha5;
+  assign sbox[8'h2a] = 8'he5;
+  assign sbox[8'h2b] = 8'hf1;
+  assign sbox[8'h2c] = 8'h71;
+  assign sbox[8'h2d] = 8'hd8;
+  assign sbox[8'h2e] = 8'h31;
+  assign sbox[8'h2f] = 8'h15;
+  assign sbox[8'h30] = 8'h04;
+  assign sbox[8'h31] = 8'hc7;
+  assign sbox[8'h32] = 8'h23;
+  assign sbox[8'h33] = 8'hc3;
+  assign sbox[8'h34] = 8'h18;
+  assign sbox[8'h35] = 8'h96;
+  assign sbox[8'h36] = 8'h05;
+  assign sbox[8'h37] = 8'h9a;
+  assign sbox[8'h38] = 8'h07;
+  assign sbox[8'h39] = 8'h12;
+  assign sbox[8'h3a] = 8'h80;
+  assign sbox[8'h3b] = 8'he2;
+  assign sbox[8'h3c] = 8'heb;
+  assign sbox[8'h3d] = 8'h27;
+  assign sbox[8'h3e] = 8'hb2;
+  assign sbox[8'h3f] = 8'h75;
+  assign sbox[8'h40] = 8'h09;
+  assign sbox[8'h41] = 8'h83;
+  assign sbox[8'h42] = 8'h2c;
+  assign sbox[8'h43] = 8'h1a;
+  assign sbox[8'h44] = 8'h1b;
+  assign sbox[8'h45] = 8'h6e;
+  assign sbox[8'h46] = 8'h5a;
+  assign sbox[8'h47] = 8'ha0;
+  assign sbox[8'h48] = 8'h52;
+  assign sbox[8'h49] = 8'h3b;
+  assign sbox[8'h4a] = 8'hd6;
+  assign sbox[8'h4b] = 8'hb3;
+  assign sbox[8'h4c] = 8'h29;
+  assign sbox[8'h4d] = 8'he3;
+  assign sbox[8'h4e] = 8'h2f;
+  assign sbox[8'h4f] = 8'h84;
+  assign sbox[8'h50] = 8'h53;
+  assign sbox[8'h51] = 8'hd1;
+  assign sbox[8'h52] = 8'h00;
+  assign sbox[8'h53] = 8'hed;
+  assign sbox[8'h54] = 8'h20;
+  assign sbox[8'h55] = 8'hfc;
+  assign sbox[8'h56] = 8'hb1;
+  assign sbox[8'h57] = 8'h5b;
+  assign sbox[8'h58] = 8'h6a;
+  assign sbox[8'h59] = 8'hcb;
+  assign sbox[8'h5a] = 8'hbe;
+  assign sbox[8'h5b] = 8'h39;
+  assign sbox[8'h5c] = 8'h4a;
+  assign sbox[8'h5d] = 8'h4c;
+  assign sbox[8'h5e] = 8'h58;
+  assign sbox[8'h5f] = 8'hcf;
+  assign sbox[8'h60] = 8'hd0;
+  assign sbox[8'h61] = 8'hef;
+  assign sbox[8'h62] = 8'haa;
+  assign sbox[8'h63] = 8'hfb;
+  assign sbox[8'h64] = 8'h43;
+  assign sbox[8'h65] = 8'h4d;
+  assign sbox[8'h66] = 8'h33;
+  assign sbox[8'h67] = 8'h85;
+  assign sbox[8'h68] = 8'h45;
+  assign sbox[8'h69] = 8'hf9;
+  assign sbox[8'h6a] = 8'h02;
+  assign sbox[8'h6b] = 8'h7f;
+  assign sbox[8'h6c] = 8'h50;
+  assign sbox[8'h6d] = 8'h3c;
+  assign sbox[8'h6e] = 8'h9f;
+  assign sbox[8'h6f] = 8'ha8;
+  assign sbox[8'h70] = 8'h51;
+  assign sbox[8'h71] = 8'ha3;
+  assign sbox[8'h72] = 8'h40;
+  assign sbox[8'h73] = 8'h8f;
+  assign sbox[8'h74] = 8'h92;
+  assign sbox[8'h75] = 8'h9d;
+  assign sbox[8'h76] = 8'h38;
+  assign sbox[8'h77] = 8'hf5;
+  assign sbox[8'h78] = 8'hbc;
+  assign sbox[8'h79] = 8'hb6;
+  assign sbox[8'h7a] = 8'hda;
+  assign sbox[8'h7b] = 8'h21;
+  assign sbox[8'h7c] = 8'h10;
+  assign sbox[8'h7d] = 8'hff;
+  assign sbox[8'h7e] = 8'hf3;
+  assign sbox[8'h7f] = 8'hd2;
+  assign sbox[8'h80] = 8'hcd;
+  assign sbox[8'h81] = 8'h0c;
+  assign sbox[8'h82] = 8'h13;
+  assign sbox[8'h83] = 8'hec;
+  assign sbox[8'h84] = 8'h5f;
+  assign sbox[8'h85] = 8'h97;
+  assign sbox[8'h86] = 8'h44;
+  assign sbox[8'h87] = 8'h17;
+  assign sbox[8'h88] = 8'hc4;
+  assign sbox[8'h89] = 8'ha7;
+  assign sbox[8'h8a] = 8'h7e;
+  assign sbox[8'h8b] = 8'h3d;
+  assign sbox[8'h8c] = 8'h64;
+  assign sbox[8'h8d] = 8'h5d;
+  assign sbox[8'h8e] = 8'h19;
+  assign sbox[8'h8f] = 8'h73;
+  assign sbox[8'h90] = 8'h60;
+  assign sbox[8'h91] = 8'h81;
+  assign sbox[8'h92] = 8'h4f;
+  assign sbox[8'h93] = 8'hdc;
+  assign sbox[8'h94] = 8'h22;
+  assign sbox[8'h95] = 8'h2a;
+  assign sbox[8'h96] = 8'h90;
+  assign sbox[8'h97] = 8'h88;
+  assign sbox[8'h98] = 8'h46;
+  assign sbox[8'h99] = 8'hee;
+  assign sbox[8'h9a] = 8'hb8;
+  assign sbox[8'h9b] = 8'h14;
+  assign sbox[8'h9c] = 8'hde;
+  assign sbox[8'h9d] = 8'h5e;
+  assign sbox[8'h9e] = 8'h0b;
+  assign sbox[8'h9f] = 8'hdb;
+  assign sbox[8'ha0] = 8'he0;
+  assign sbox[8'ha1] = 8'h32;
+  assign sbox[8'ha2] = 8'h3a;
+  assign sbox[8'ha3] = 8'h0a;
+  assign sbox[8'ha4] = 8'h49;
+  assign sbox[8'ha5] = 8'h06;
+  assign sbox[8'ha6] = 8'h24;
+  assign sbox[8'ha7] = 8'h5c;
+  assign sbox[8'ha8] = 8'hc2;
+  assign sbox[8'ha9] = 8'hd3;
+  assign sbox[8'haa] = 8'hac;
+  assign sbox[8'hab] = 8'h62;
+  assign sbox[8'hac] = 8'h91;
+  assign sbox[8'had] = 8'h95;
+  assign sbox[8'hae] = 8'he4;
+  assign sbox[8'haf] = 8'h79;
+  assign sbox[8'hb0] = 8'he7;
+  assign sbox[8'hb1] = 8'hc8;
+  assign sbox[8'hb2] = 8'h37;
+  assign sbox[8'hb3] = 8'h6d;
+  assign sbox[8'hb4] = 8'h8d;
+  assign sbox[8'hb5] = 8'hd5;
+  assign sbox[8'hb6] = 8'h4e;
+  assign sbox[8'hb7] = 8'ha9;
+  assign sbox[8'hb8] = 8'h6c;
+  assign sbox[8'hb9] = 8'h56;
+  assign sbox[8'hba] = 8'hf4;
+  assign sbox[8'hbb] = 8'hea;
+  assign sbox[8'hbc] = 8'h65;
+  assign sbox[8'hbd] = 8'h7a;
+  assign sbox[8'hbe] = 8'hae;
+  assign sbox[8'hbf] = 8'h08;
+  assign sbox[8'hc0] = 8'hba;
+  assign sbox[8'hc1] = 8'h78;
+  assign sbox[8'hc2] = 8'h25;
+  assign sbox[8'hc3] = 8'h2e;
+  assign sbox[8'hc4] = 8'h1c;
+  assign sbox[8'hc5] = 8'ha6;
+  assign sbox[8'hc6] = 8'hb4;
+  assign sbox[8'hc7] = 8'hc6;
+  assign sbox[8'hc8] = 8'he8;
+  assign sbox[8'hc9] = 8'hdd;
+  assign sbox[8'hca] = 8'h74;
+  assign sbox[8'hcb] = 8'h1f;
+  assign sbox[8'hcc] = 8'h4b;
+  assign sbox[8'hcd] = 8'hbd;
+  assign sbox[8'hce] = 8'h8b;
+  assign sbox[8'hcf] = 8'h8a;
+  assign sbox[8'hd0] = 8'h70;
+  assign sbox[8'hd1] = 8'h3e;
+  assign sbox[8'hd2] = 8'hb5;
+  assign sbox[8'hd3] = 8'h66;
+  assign sbox[8'hd4] = 8'h48;
+  assign sbox[8'hd5] = 8'h03;
+  assign sbox[8'hd6] = 8'hf6;
+  assign sbox[8'hd7] = 8'h0e;
+  assign sbox[8'hd8] = 8'h61;
+  assign sbox[8'hd9] = 8'h35;
+  assign sbox[8'hda] = 8'h57;
+  assign sbox[8'hdb] = 8'hb9;
+  assign sbox[8'hdc] = 8'h86;
+  assign sbox[8'hdd] = 8'hc1;
+  assign sbox[8'hde] = 8'h1d;
+  assign sbox[8'hdf] = 8'h9e;
+  assign sbox[8'he0] = 8'he1;
+  assign sbox[8'he1] = 8'hf8;
+  assign sbox[8'he2] = 8'h98;
+  assign sbox[8'he3] = 8'h11;
+  assign sbox[8'he4] = 8'h69;
+  assign sbox[8'he5] = 8'hd9;
+  assign sbox[8'he6] = 8'h8e;
+  assign sbox[8'he7] = 8'h94;
+  assign sbox[8'he8] = 8'h9b;
+  assign sbox[8'he9] = 8'h1e;
+  assign sbox[8'hea] = 8'h87;
+  assign sbox[8'heb] = 8'he9;
+  assign sbox[8'hec] = 8'hce;
+  assign sbox[8'hed] = 8'h55;
+  assign sbox[8'hee] = 8'h28;
+  assign sbox[8'hef] = 8'hdf;
+  assign sbox[8'hf0] = 8'h8c;
+  assign sbox[8'hf1] = 8'ha1;
+  assign sbox[8'hf2] = 8'h89;
+  assign sbox[8'hf3] = 8'h0d;
+  assign sbox[8'hf4] = 8'hbf;
+  assign sbox[8'hf5] = 8'he6;
+  assign sbox[8'hf6] = 8'h42;
+  assign sbox[8'hf7] = 8'h68;
+  assign sbox[8'hf8] = 8'h41;
+  assign sbox[8'hf9] = 8'h99;
+  assign sbox[8'hfa] = 8'h2d;
+  assign sbox[8'hfb] = 8'h0f;
+  assign sbox[8'hfc] = 8'hb0;
+  assign sbox[8'hfd] = 8'h54;
+  assign sbox[8'hfe] = 8'hbb;
+  assign sbox[8'hff] = 8'h16;
+
+endmodule // aes_sbox
+
+//======================================================================
+// EOF aes_sbox.v
+//======================================================================
+
+//======================================================================
+//
+// aes_inv_sbox.v
+// --------------
+// The inverse AES S-box. Basically a 256 Byte ROM.
+//
+//
+// Copyright (c) 2013 Secworks Sweden AB
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or
+// without modification, are permitted provided that the following
+// conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright
+//    notice, this list of conditions and the following disclaimer.
+//
+// 2. Redistributions in binary form must reproduce the above copyright
+//    notice, this list of conditions and the following disclaimer in
+//    the documentation and/or other materials provided with the
+//    distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+//======================================================================
+
+`default_nettype none
+
+module aes_inv_sbox(
+                    input wire  [31 : 0] sboxw,
+                    output wire [31 : 0] new_sboxw
+                   );
+
+
+  //----------------------------------------------------------------
+  // The inverse sbox array.
+  //----------------------------------------------------------------
+  wire [7 : 0] inv_sbox [0 : 255];
+
+
+  //----------------------------------------------------------------
+  // Four parallel muxes.
+  //----------------------------------------------------------------
+  assign new_sboxw[31 : 24] = inv_sbox[sboxw[31 : 24]];
+  assign new_sboxw[23 : 16] = inv_sbox[sboxw[23 : 16]];
+  assign new_sboxw[15 : 08] = inv_sbox[sboxw[15 : 08]];
+  assign new_sboxw[07 : 00] = inv_sbox[sboxw[07 : 00]];
+
+
+  //----------------------------------------------------------------
+  // Creating the contents of the array.
+  //----------------------------------------------------------------
+  assign inv_sbox[8'h00] = 8'h52;
+  assign inv_sbox[8'h01] = 8'h09;
+  assign inv_sbox[8'h02] = 8'h6a;
+  assign inv_sbox[8'h03] = 8'hd5;
+  assign inv_sbox[8'h04] = 8'h30;
+  assign inv_sbox[8'h05] = 8'h36;
+  assign inv_sbox[8'h06] = 8'ha5;
+  assign inv_sbox[8'h07] = 8'h38;
+  assign inv_sbox[8'h08] = 8'hbf;
+  assign inv_sbox[8'h09] = 8'h40;
+  assign inv_sbox[8'h0a] = 8'ha3;
+  assign inv_sbox[8'h0b] = 8'h9e;
+  assign inv_sbox[8'h0c] = 8'h81;
+  assign inv_sbox[8'h0d] = 8'hf3;
+  assign inv_sbox[8'h0e] = 8'hd7;
+  assign inv_sbox[8'h0f] = 8'hfb;
+  assign inv_sbox[8'h10] = 8'h7c;
+  assign inv_sbox[8'h11] = 8'he3;
+  assign inv_sbox[8'h12] = 8'h39;
+  assign inv_sbox[8'h13] = 8'h82;
+  assign inv_sbox[8'h14] = 8'h9b;
+  assign inv_sbox[8'h15] = 8'h2f;
+  assign inv_sbox[8'h16] = 8'hff;
+  assign inv_sbox[8'h17] = 8'h87;
+  assign inv_sbox[8'h18] = 8'h34;
+  assign inv_sbox[8'h19] = 8'h8e;
+  assign inv_sbox[8'h1a] = 8'h43;
+  assign inv_sbox[8'h1b] = 8'h44;
+  assign inv_sbox[8'h1c] = 8'hc4;
+  assign inv_sbox[8'h1d] = 8'hde;
+  assign inv_sbox[8'h1e] = 8'he9;
+  assign inv_sbox[8'h1f] = 8'hcb;
+  assign inv_sbox[8'h20] = 8'h54;
+  assign inv_sbox[8'h21] = 8'h7b;
+  assign inv_sbox[8'h22] = 8'h94;
+  assign inv_sbox[8'h23] = 8'h32;
+  assign inv_sbox[8'h24] = 8'ha6;
+  assign inv_sbox[8'h25] = 8'hc2;
+  assign inv_sbox[8'h26] = 8'h23;
+  assign inv_sbox[8'h27] = 8'h3d;
+  assign inv_sbox[8'h28] = 8'hee;
+  assign inv_sbox[8'h29] = 8'h4c;
+  assign inv_sbox[8'h2a] = 8'h95;
+  assign inv_sbox[8'h2b] = 8'h0b;
+  assign inv_sbox[8'h2c] = 8'h42;
+  assign inv_sbox[8'h2d] = 8'hfa;
+  assign inv_sbox[8'h2e] = 8'hc3;
+  assign inv_sbox[8'h2f] = 8'h4e;
+  assign inv_sbox[8'h30] = 8'h08;
+  assign inv_sbox[8'h31] = 8'h2e;
+  assign inv_sbox[8'h32] = 8'ha1;
+  assign inv_sbox[8'h33] = 8'h66;
+  assign inv_sbox[8'h34] = 8'h28;
+  assign inv_sbox[8'h35] = 8'hd9;
+  assign inv_sbox[8'h36] = 8'h24;
+  assign inv_sbox[8'h37] = 8'hb2;
+  assign inv_sbox[8'h38] = 8'h76;
+  assign inv_sbox[8'h39] = 8'h5b;
+  assign inv_sbox[8'h3a] = 8'ha2;
+  assign inv_sbox[8'h3b] = 8'h49;
+  assign inv_sbox[8'h3c] = 8'h6d;
+  assign inv_sbox[8'h3d] = 8'h8b;
+  assign inv_sbox[8'h3e] = 8'hd1;
+  assign inv_sbox[8'h3f] = 8'h25;
+  assign inv_sbox[8'h40] = 8'h72;
+  assign inv_sbox[8'h41] = 8'hf8;
+  assign inv_sbox[8'h42] = 8'hf6;
+  assign inv_sbox[8'h43] = 8'h64;
+  assign inv_sbox[8'h44] = 8'h86;
+  assign inv_sbox[8'h45] = 8'h68;
+  assign inv_sbox[8'h46] = 8'h98;
+  assign inv_sbox[8'h47] = 8'h16;
+  assign inv_sbox[8'h48] = 8'hd4;
+  assign inv_sbox[8'h49] = 8'ha4;
+  assign inv_sbox[8'h4a] = 8'h5c;
+  assign inv_sbox[8'h4b] = 8'hcc;
+  assign inv_sbox[8'h4c] = 8'h5d;
+  assign inv_sbox[8'h4d] = 8'h65;
+  assign inv_sbox[8'h4e] = 8'hb6;
+  assign inv_sbox[8'h4f] = 8'h92;
+  assign inv_sbox[8'h50] = 8'h6c;
+  assign inv_sbox[8'h51] = 8'h70;
+  assign inv_sbox[8'h52] = 8'h48;
+  assign inv_sbox[8'h53] = 8'h50;
+  assign inv_sbox[8'h54] = 8'hfd;
+  assign inv_sbox[8'h55] = 8'hed;
+  assign inv_sbox[8'h56] = 8'hb9;
+  assign inv_sbox[8'h57] = 8'hda;
+  assign inv_sbox[8'h58] = 8'h5e;
+  assign inv_sbox[8'h59] = 8'h15;
+  assign inv_sbox[8'h5a] = 8'h46;
+  assign inv_sbox[8'h5b] = 8'h57;
+  assign inv_sbox[8'h5c] = 8'ha7;
+  assign inv_sbox[8'h5d] = 8'h8d;
+  assign inv_sbox[8'h5e] = 8'h9d;
+  assign inv_sbox[8'h5f] = 8'h84;
+  assign inv_sbox[8'h60] = 8'h90;
+  assign inv_sbox[8'h61] = 8'hd8;
+  assign inv_sbox[8'h62] = 8'hab;
+  assign inv_sbox[8'h63] = 8'h00;
+  assign inv_sbox[8'h64] = 8'h8c;
+  assign inv_sbox[8'h65] = 8'hbc;
+  assign inv_sbox[8'h66] = 8'hd3;
+  assign inv_sbox[8'h67] = 8'h0a;
+  assign inv_sbox[8'h68] = 8'hf7;
+  assign inv_sbox[8'h69] = 8'he4;
+  assign inv_sbox[8'h6a] = 8'h58;
+  assign inv_sbox[8'h6b] = 8'h05;
+  assign inv_sbox[8'h6c] = 8'hb8;
+  assign inv_sbox[8'h6d] = 8'hb3;
+  assign inv_sbox[8'h6e] = 8'h45;
+  assign inv_sbox[8'h6f] = 8'h06;
+  assign inv_sbox[8'h70] = 8'hd0;
+  assign inv_sbox[8'h71] = 8'h2c;
+  assign inv_sbox[8'h72] = 8'h1e;
+  assign inv_sbox[8'h73] = 8'h8f;
+  assign inv_sbox[8'h74] = 8'hca;
+  assign inv_sbox[8'h75] = 8'h3f;
+  assign inv_sbox[8'h76] = 8'h0f;
+  assign inv_sbox[8'h77] = 8'h02;
+  assign inv_sbox[8'h78] = 8'hc1;
+  assign inv_sbox[8'h79] = 8'haf;
+  assign inv_sbox[8'h7a] = 8'hbd;
+  assign inv_sbox[8'h7b] = 8'h03;
+  assign inv_sbox[8'h7c] = 8'h01;
+  assign inv_sbox[8'h7d] = 8'h13;
+  assign inv_sbox[8'h7e] = 8'h8a;
+  assign inv_sbox[8'h7f] = 8'h6b;
+  assign inv_sbox[8'h80] = 8'h3a;
+  assign inv_sbox[8'h81] = 8'h91;
+  assign inv_sbox[8'h82] = 8'h11;
+  assign inv_sbox[8'h83] = 8'h41;
+  assign inv_sbox[8'h84] = 8'h4f;
+  assign inv_sbox[8'h85] = 8'h67;
+  assign inv_sbox[8'h86] = 8'hdc;
+  assign inv_sbox[8'h87] = 8'hea;
+  assign inv_sbox[8'h88] = 8'h97;
+  assign inv_sbox[8'h89] = 8'hf2;
+  assign inv_sbox[8'h8a] = 8'hcf;
+  assign inv_sbox[8'h8b] = 8'hce;
+  assign inv_sbox[8'h8c] = 8'hf0;
+  assign inv_sbox[8'h8d] = 8'hb4;
+  assign inv_sbox[8'h8e] = 8'he6;
+  assign inv_sbox[8'h8f] = 8'h73;
+  assign inv_sbox[8'h90] = 8'h96;
+  assign inv_sbox[8'h91] = 8'hac;
+  assign inv_sbox[8'h92] = 8'h74;
+  assign inv_sbox[8'h93] = 8'h22;
+  assign inv_sbox[8'h94] = 8'he7;
+  assign inv_sbox[8'h95] = 8'had;
+  assign inv_sbox[8'h96] = 8'h35;
+  assign inv_sbox[8'h97] = 8'h85;
+  assign inv_sbox[8'h98] = 8'he2;
+  assign inv_sbox[8'h99] = 8'hf9;
+  assign inv_sbox[8'h9a] = 8'h37;
+  assign inv_sbox[8'h9b] = 8'he8;
+  assign inv_sbox[8'h9c] = 8'h1c;
+  assign inv_sbox[8'h9d] = 8'h75;
+  assign inv_sbox[8'h9e] = 8'hdf;
+  assign inv_sbox[8'h9f] = 8'h6e;
+  assign inv_sbox[8'ha0] = 8'h47;
+  assign inv_sbox[8'ha1] = 8'hf1;
+  assign inv_sbox[8'ha2] = 8'h1a;
+  assign inv_sbox[8'ha3] = 8'h71;
+  assign inv_sbox[8'ha4] = 8'h1d;
+  assign inv_sbox[8'ha5] = 8'h29;
+  assign inv_sbox[8'ha6] = 8'hc5;
+  assign inv_sbox[8'ha7] = 8'h89;
+  assign inv_sbox[8'ha8] = 8'h6f;
+  assign inv_sbox[8'ha9] = 8'hb7;
+  assign inv_sbox[8'haa] = 8'h62;
+  assign inv_sbox[8'hab] = 8'h0e;
+  assign inv_sbox[8'hac] = 8'haa;
+  assign inv_sbox[8'had] = 8'h18;
+  assign inv_sbox[8'hae] = 8'hbe;
+  assign inv_sbox[8'haf] = 8'h1b;
+  assign inv_sbox[8'hb0] = 8'hfc;
+  assign inv_sbox[8'hb1] = 8'h56;
+  assign inv_sbox[8'hb2] = 8'h3e;
+  assign inv_sbox[8'hb3] = 8'h4b;
+  assign inv_sbox[8'hb4] = 8'hc6;
+  assign inv_sbox[8'hb5] = 8'hd2;
+  assign inv_sbox[8'hb6] = 8'h79;
+  assign inv_sbox[8'hb7] = 8'h20;
+  assign inv_sbox[8'hb8] = 8'h9a;
+  assign inv_sbox[8'hb9] = 8'hdb;
+  assign inv_sbox[8'hba] = 8'hc0;
+  assign inv_sbox[8'hbb] = 8'hfe;
+  assign inv_sbox[8'hbc] = 8'h78;
+  assign inv_sbox[8'hbd] = 8'hcd;
+  assign inv_sbox[8'hbe] = 8'h5a;
+  assign inv_sbox[8'hbf] = 8'hf4;
+  assign inv_sbox[8'hc0] = 8'h1f;
+  assign inv_sbox[8'hc1] = 8'hdd;
+  assign inv_sbox[8'hc2] = 8'ha8;
+  assign inv_sbox[8'hc3] = 8'h33;
+  assign inv_sbox[8'hc4] = 8'h88;
+  assign inv_sbox[8'hc5] = 8'h07;
+  assign inv_sbox[8'hc6] = 8'hc7;
+  assign inv_sbox[8'hc7] = 8'h31;
+  assign inv_sbox[8'hc8] = 8'hb1;
+  assign inv_sbox[8'hc9] = 8'h12;
+  assign inv_sbox[8'hca] = 8'h10;
+  assign inv_sbox[8'hcb] = 8'h59;
+  assign inv_sbox[8'hcc] = 8'h27;
+  assign inv_sbox[8'hcd] = 8'h80;
+  assign inv_sbox[8'hce] = 8'hec;
+  assign inv_sbox[8'hcf] = 8'h5f;
+  assign inv_sbox[8'hd0] = 8'h60;
+  assign inv_sbox[8'hd1] = 8'h51;
+  assign inv_sbox[8'hd2] = 8'h7f;
+  assign inv_sbox[8'hd3] = 8'ha9;
+  assign inv_sbox[8'hd4] = 8'h19;
+  assign inv_sbox[8'hd5] = 8'hb5;
+  assign inv_sbox[8'hd6] = 8'h4a;
+  assign inv_sbox[8'hd7] = 8'h0d;
+  assign inv_sbox[8'hd8] = 8'h2d;
+  assign inv_sbox[8'hd9] = 8'he5;
+  assign inv_sbox[8'hda] = 8'h7a;
+  assign inv_sbox[8'hdb] = 8'h9f;
+  assign inv_sbox[8'hdc] = 8'h93;
+  assign inv_sbox[8'hdd] = 8'hc9;
+  assign inv_sbox[8'hde] = 8'h9c;
+  assign inv_sbox[8'hdf] = 8'hef;
+  assign inv_sbox[8'he0] = 8'ha0;
+  assign inv_sbox[8'he1] = 8'he0;
+  assign inv_sbox[8'he2] = 8'h3b;
+  assign inv_sbox[8'he3] = 8'h4d;
+  assign inv_sbox[8'he4] = 8'hae;
+  assign inv_sbox[8'he5] = 8'h2a;
+  assign inv_sbox[8'he6] = 8'hf5;
+  assign inv_sbox[8'he7] = 8'hb0;
+  assign inv_sbox[8'he8] = 8'hc8;
+  assign inv_sbox[8'he9] = 8'heb;
+  assign inv_sbox[8'hea] = 8'hbb;
+  assign inv_sbox[8'heb] = 8'h3c;
+  assign inv_sbox[8'hec] = 8'h83;
+  assign inv_sbox[8'hed] = 8'h53;
+  assign inv_sbox[8'hee] = 8'h99;
+  assign inv_sbox[8'hef] = 8'h61;
+  assign inv_sbox[8'hf0] = 8'h17;
+  assign inv_sbox[8'hf1] = 8'h2b;
+  assign inv_sbox[8'hf2] = 8'h04;
+  assign inv_sbox[8'hf3] = 8'h7e;
+  assign inv_sbox[8'hf4] = 8'hba;
+  assign inv_sbox[8'hf5] = 8'h77;
+  assign inv_sbox[8'hf6] = 8'hd6;
+  assign inv_sbox[8'hf7] = 8'h26;
+  assign inv_sbox[8'hf8] = 8'he1;
+  assign inv_sbox[8'hf9] = 8'h69;
+  assign inv_sbox[8'hfa] = 8'h14;
+  assign inv_sbox[8'hfb] = 8'h63;
+  assign inv_sbox[8'hfc] = 8'h55;
+  assign inv_sbox[8'hfd] = 8'h21;
+  assign inv_sbox[8'hfe] = 8'h0c;
+  assign inv_sbox[8'hff] = 8'h7d;
+
+endmodule // aes_inv_sbox
+
+//======================================================================
+// EOF aes_inv_sbox.v
+//======================================================================
diff --git a/IPLIB/ADPcontrol_v1_0/ADPmanager.v b/IPLIB/ADPcontrol_v1_0/ADPmanager.v
index 26705e8..f056b75 100755
--- a/IPLIB/ADPcontrol_v1_0/ADPmanager.v
+++ b/IPLIB/ADPcontrol_v1_0/ADPmanager.v
@@ -71,8 +71,8 @@ localparam CMD_A   = 4'b0001;  // set Address
 localparam CMD_C   = 4'b0010;  // Control
 localparam CMD_R   = 4'b0011;  // Read word, addr++
 localparam CMD_S   = 4'b0100;  // Status/STDIN
-localparam CMD_W   = 4'b0100;  // Write word, addr++
-localparam CMD_X   = 4'b0101;  // eXit
+localparam CMD_W   = 4'b0101;  // Write word, addr++
+localparam CMD_X   = 4'b0110;  // eXit
 `ifndef ADPBASIC
 localparam CMD_F   = 4'b1000;  // Fill (wordocunt) from addr++
 localparam CMD_M   = 4'b1001;  // set read Mask
-- 
GitLab