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 8b1054692e746f6c07edeebdb9718ef729fa8d6f..d347000535fa8b2d9232201a6f0e02317550bdac 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
Binary files a/Cortex-M0/nanosoc/systems/mcu/fpga_imp/ip_repo/ADPcontrol_1.0/soclabs.org_user_ADPcontrol_1.0.zip and b/Cortex-M0/nanosoc/systems/mcu/fpga_imp/ip_repo/ADPcontrol_1.0/soclabs.org_user_ADPcontrol_1.0.zip differ
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 5c6ec0be32e8ca76a5537aa727ae65a67208560c..f056b758da2934853412de02fee680584c3b9fc8 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 5696e415cb8e30efb4743373a5ca6747614422b3..072555fa4217d51616f18117e9347b12bbb239f7 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
Binary files a/Cortex-M0/nanosoc/systems/mcu/fpga_imp/ip_repo/axi_stream_io_1.0/soclabs.org_user_axi_stream_io_1.0.zip and b/Cortex-M0/nanosoc/systems/mcu/fpga_imp/ip_repo/axi_stream_io_1.0/soclabs.org_user_axi_stream_io_1.0.zip differ
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 59baedbdea1dc8fa83d4525e6067114f604c5da4..64e58fcc85c37cf980dd6a133ba5daa7d53ecfb8 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 ce586c7af967a217fedd3c4fae7ef758794c7931..84df7801f9b75f45b920d5b43daba417d6918fd1 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 4a635dde3eeee4ba52cd771abdd9df48b7e59231..bb79e54b827d8aa070bd65525dbdaa9bc2a3d59e 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 f0a2c33db6e118d6a903def9ec49aa1dc4dea594..5fbccc17c1f65441a3ebf2451c6bb5b74075089c 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 9254704ac7aadf747555a32559438f5d205e1db2..69b6280dade46c7e5a95b6073fc1ae1742559a27 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 7209c105abd57a0d750f616dbed4d3c5164e0abb..2474888b5e032a3238fe5045202cbee9c34aa222 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 0000000000000000000000000000000000000000..27796a35dc05fe84ee5c0d2752ef3a9758f3af35
--- /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 26705e8c7b593a8f8c1c7dce1016a197cdb91f00..f056b758da2934853412de02fee680584c3b9fc8 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