From f68c3e62bd2dd914b49e7000fb0f226fcb01a8a7 Mon Sep 17 00:00:00 2001
From: dwf1m12 <d.w.flynn@soton.ac.uk>
Date: Tue, 16 May 2023 16:25:06 +0100
Subject: [PATCH] makefile and aes128 integration updates

---
 system/aes/src/nanosoc_acc_wrapper.v          |   75 +
 system/aes/src/nanosoc_exp_wrapper.v          |   76 +
 system/aes/src/soclabs_ahb_aes128_ctrl.v      | 2460 +----------------
 system/fpga_imp/scripts/build_mcu_fpga_ip.tcl |    7 +-
 system/makefile                               |   47 +-
 system/src/verilog/nanosoc_chip.v             |   58 +-
 system/test_io/verilog/nanosoc_adp_manager.v  |   16 +-
 system/testcodes/aes128_tests/aes128.h        |   71 +
 system/testcodes/aes128_tests/aes128_tests.c  |  688 +++++
 .../testcodes/aes128_tests/dma_pl230_driver.c |  163 ++
 .../testcodes/aes128_tests/dma_pl230_driver.h |  198 ++
 system/testcodes/aes128_tests/makefile        |  263 ++
 system/verif/verilog/nanosoc_tb.v             |   68 +-
 13 files changed, 1669 insertions(+), 2521 deletions(-)
 create mode 100644 system/aes/src/nanosoc_acc_wrapper.v
 create mode 100644 system/aes/src/nanosoc_exp_wrapper.v
 create mode 100644 system/testcodes/aes128_tests/aes128.h
 create mode 100644 system/testcodes/aes128_tests/aes128_tests.c
 create mode 100644 system/testcodes/aes128_tests/dma_pl230_driver.c
 create mode 100644 system/testcodes/aes128_tests/dma_pl230_driver.h
 create mode 100644 system/testcodes/aes128_tests/makefile

diff --git a/system/aes/src/nanosoc_acc_wrapper.v b/system/aes/src/nanosoc_acc_wrapper.v
new file mode 100644
index 0000000..4a3d1af
--- /dev/null
+++ b/system/aes/src/nanosoc_acc_wrapper.v
@@ -0,0 +1,75 @@
+//-----------------------------------------------------------------------------
+// SoC Labs Basic Example Accelerator Wrapper
+// A joint work commissioned on behalf of SoC Labs; under Arm Academic Access license.
+//
+// Contributors
+//
+// David Mapstone (d.a.mapstone@soton.ac.uk)
+// David Flynn    (d.w.flynn@soton.ac.uk)
+//
+// Copyright (C) 2023; SoC Labs (www.soclabs.org)
+//-----------------------------------------------------------------------------
+
+module nanosoc_acc_wrapper #(
+  parameter AHBADDRWIDTH=16,
+  parameter INPACKETWIDTH=128,
+  parameter CFGSIZEWIDTH=64,
+  parameter CFGSCHEMEWIDTH=2,
+  parameter OUTPACKETWIDTH=128,
+  parameter CFGNUMIRQ=4
+  ) (
+    input  wire                      HCLK,       // Clock
+    input  wire                      HRESETn,    // Reset
+
+    // AHB connection to Initiator
+    input  wire                      HSELS,
+    input  wire   [AHBADDRWIDTH-1:0] HADDRS,
+    input  wire   [1:0]              HTRANSS,
+    input  wire   [2:0]              HSIZES,
+    input  wire   [3:0]              HPROTS,
+    input  wire                      HWRITES,
+    input  wire                      HREADYS,
+    input  wire   [31:0]             HWDATAS,
+
+    output wire                      HREADYOUTS,
+    output wire                      HRESPS,
+    output wire   [31:0]             HRDATAS,
+
+    // Input Data Request Signal to DMAC
+    output wire                      exp_drq_ip_o,
+    input  wire                      exp_dlast_ip_i,
+
+    // Output Data Request Signal to DMAC
+    output wire                      exp_drq_op_o,
+    input  wire                      exp_dlast_op_i,
+    
+    // Interrupts
+    output wire   [CFGNUMIRQ-1:0]    exp_irq_o
+  );
+  
+  soclabs_ahb_aes128_ctrl u_exp_aes128 (
+    .ahb_hclk        (HCLK),
+    .ahb_hresetn     (HRESETn),
+    .ahb_hsel        (HSELS),
+    .ahb_haddr16     (HADDRS[15:0]),
+    .ahb_htrans      (HTRANSS),
+    .ahb_hwrite      (HWRITES),
+    .ahb_hsize       (HSIZES),
+    .ahb_hprot       (HPROTS),
+    .ahb_hwdata      (HWDATAS),
+    .ahb_hready      (HREADYS),
+    .ahb_hrdata      (HRDATAS),
+    .ahb_hreadyout   (HREADYOUTS),
+    .ahb_hresp       (HRESPS),
+    .drq_ipdma128    (exp_drq_ip_o),
+    .dlast_ipdma128  (1'b0),
+    .drq_opdma128    (exp_drq_op_o),
+    .dlast_opdma128  (1'b0),
+    .irq_key128      (exp_irq_o[0]),
+    .irq_ip128       (exp_irq_o[1]),
+    .irq_op128       (exp_irq_o[2]),
+    .irq_error       (exp_irq_o[3]),
+    .irq_merged      ( )
+  );
+
+endmodule
diff --git a/system/aes/src/nanosoc_exp_wrapper.v b/system/aes/src/nanosoc_exp_wrapper.v
new file mode 100644
index 0000000..860ed3b
--- /dev/null
+++ b/system/aes/src/nanosoc_exp_wrapper.v
@@ -0,0 +1,76 @@
+//-----------------------------------------------------------------------------
+// SoC Labs Basic Example Accelerator Wrapper
+// A joint work commissioned on behalf of SoC Labs; under Arm Academic Access license.
+//
+// Contributors
+//
+// David Mapstone (d.a.mapstone@soton.ac.uk)
+// David Flynn    (d.w.flynn@soton.ac.uk)
+//
+// Copyright (C) 2023; SoC Labs (www.soclabs.org)
+//-----------------------------------------------------------------------------
+
+module nanosoc_exp_wrapper #(
+  parameter AHBADDRWIDTH=16,
+  parameter INPACKETWIDTH=128,
+  parameter CFGSIZEWIDTH=64,
+  parameter CFGSCHEMEWIDTH=2,
+  parameter OUTPACKETWIDTH=128,
+  parameter CFGNUMIRQ=4
+  ) (
+    input  wire                      HCLK,       // Clock
+    input  wire                      HRESETn,    // Reset
+
+    // AHB connection to Initiator
+    input  wire                      HSEL_i,
+    input  wire   [AHBADDRWIDTH-1:0] HADDR_i,
+    input  wire   [1:0]              HTRANS_i,
+    input  wire   [2:0]              HSIZE_i,
+    input  wire   [3:0]              HPROT_i,
+    input  wire                      HWRITE_i,
+    input  wire                      HREADY_i,
+    input  wire   [31:0]             HWDATA_i,
+
+    output wire                      HREADYOUT_o,
+    output wire                      HRESP_o,
+    output wire   [31:0]             HRDATA_o,
+
+    // Input Data Request Signal to DMAC
+    output wire                      exp_drq_ip_o,
+    input  wire                      exp_dlast_ip_i,
+
+    // Output Data Request Signal to DMAC
+    output wire                      exp_drq_op_o,
+    input  wire                      exp_dlast_op_i,
+    
+    // Interrupts
+    output wire   [CFGNUMIRQ-1:0]    exp_irq_o
+
+  );
+  
+  soclabs_ahb_aes128_ctrl u_exp_aes128 (
+    .ahb_hclk        (HCLK),
+    .ahb_hresetn     (HRESETn),
+    .ahb_hsel        (HSEL_i),
+    .ahb_haddr16     (HADDR_i[15:0]),
+    .ahb_htrans      (HTRANS_i),
+    .ahb_hwrite      (HWRITE_i),
+    .ahb_hsize       (HSIZE_i),
+    .ahb_hprot       (HPROT_i),
+    .ahb_hwdata      (HWDATA_i),
+    .ahb_hready      (HREADY_i),
+    .ahb_hrdata      (HRDATA_o),
+    .ahb_hreadyout   (HREADYOUT_o),
+    .ahb_hresp       (HRESP_o),
+    .drq_ipdma128    (exp_drq_ip_o),
+    .dlast_ipdma128  (1'b0),
+    .drq_opdma128    (exp_drq_op_o),
+    .dlast_opdma128  (1'b0),
+    .irq_key128      (exp_irq_o[0]),
+    .irq_ip128       (exp_irq_o[1]),
+    .irq_op128       (exp_irq_o[2]),
+    .irq_error       (exp_irq_o[3]),
+    .irq_merged      ( )
+  );
+
+endmodule
diff --git a/system/aes/src/soclabs_ahb_aes128_ctrl.v b/system/aes/src/soclabs_ahb_aes128_ctrl.v
index ea3d362..63b2bc3 100644
--- a/system/aes/src/soclabs_ahb_aes128_ctrl.v
+++ b/system/aes/src/soclabs_ahb_aes128_ctrl.v
@@ -567,2449 +567,17 @@ module soclabs_iobuf_reg128
 
 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
-//======================================================================
+// include SecWorks IP but fix up default_nettype issues that breaks elsewhere
+
+`include "aes_core.v"
+`default_nettype wire
+`include "aes_encipher_block.v"
+`default_nettype wire
+`include "aes_decipher_block.v"
+`default_nettype wire
+`include "aes_key_mem.v"
+`default_nettype wire
+`include "aes_sbox.v"
+`default_nettype wire
+`include "aes_inv_sbox.v"
+`default_nettype wire
diff --git a/system/fpga_imp/scripts/build_mcu_fpga_ip.tcl b/system/fpga_imp/scripts/build_mcu_fpga_ip.tcl
index eb8b0e0..49e571a 100644
--- a/system/fpga_imp/scripts/build_mcu_fpga_ip.tcl
+++ b/system/fpga_imp/scripts/build_mcu_fpga_ip.tcl
@@ -84,11 +84,14 @@ read_verilog  $soc_vlog/verilog/nanosoc_mcu_sysctrl.v
 read_verilog  $soc_vlog/verilog/nanosoc_cpu.v
 read_verilog  $soc_vlog/verilog/nanosoc_sys_ahb_decode.v
 read_verilog  $soc_vlog/verilog/nanosoc_sysio.v
-read_verilog  ../aes/src/soclabs_ahb_aes128_ctrl.v 
+read_verilog  ../aes/src/nanosoc_acc_wrapper.v 
 read_verilog  $soc_vlog/verilog/nanosoc_chip.v
 read_verilog  $soc_vlog/verilog/nanosoc_chip_pads.v
+set search_path [ concat $search_path ../../../secworks-aes/src/rtl ]
+read_verilog  ../aes/src/soclabs_ahb_aes128_ctrl.v 
 
-set_property generic {NANOSOC_EXPANSION_REGION=1} [current_fileset]
+#set_property generic {NANOSOC_EXPANSION_REGION=1} [current_fileset]
+set_property verilog_define {NANOSOC_EXPANSION_REGION=1} [current_fileset]
 set_property top nanosoc_chip [current_fileset]
 
 # FPGA specific timing constraints
diff --git a/system/makefile b/system/makefile
index 636a0e6..124d256 100644
--- a/system/makefile
+++ b/system/makefile
@@ -6,7 +6,7 @@
 #
 # David Flynn (d.w.flynn@soton.ac.uk)
 #
-# Copyright � 2021-3, SoC Labs (www.soclabs.org)
+# Copyright (C) 2021-3, SoC Labs (www.soclabs.org)
 #-----------------------------------------------------------------------------
 
 #-----------------------------------------------------------------------------
@@ -81,21 +81,21 @@ BOOTROM_HEX       ?= $(NANOSOC_TECH_DIR)/system/testcodes/bootloader/$(BOOTLOADE
 BOOTROM_BUILD_DIR ?= $(NANOSOC_TECH_DIR)/system/src/bootrom
 
 
-NANSOC_EXPANSION_REGION ?= yes
+NANOSOC_EXPANSION_REGION ?= yes
 
 # Simulator Defines
 DEFINES_VC  += $(MEM_INIT) +define+CORTEX_M0 +define+USE_TARMAC 
 
-ifeq ($(NANSOC_EXPANSION_REGION),yes)
-	DEFINES_VC += +define+NANSOC_EXPANSION_REGION
+ifeq ($(NANOSOC_EXPANSION_REGION),yes)
+	DEFINES_VC += +define+NANOSOC_EXPANSION_REGION
 endif
 
 # Simulator Command file to specify RTL source files
-TBENCH_VC   ?= -f $(PROJECT_DIR)/flist/project/system.flist
+TBENCH_VC   ?= $(PROJECT_DIR)/flist/project/system.flist
 
 
 # Simulator type (mti/vcs/xm)
-SIMULATOR   = xm
+SIMULATOR   = mti
 
 # Directory to put simulation files
 SIM_TOP_DIR ?= $(PROJECT_DIR)/simulate/sim
@@ -105,16 +105,16 @@ SIM_DIR = $(SIM_TOP_DIR)/$(TESTNAME)
 # MTI option
 #DF#MTI_OPTIONS    = -novopt
 MTI_OPTIONS    = -suppress 2892
-MTI_VC_OPTIONS = -f $(TBENCH_VC) $(ACCELERATOR_VC)
+MTI_VC_OPTIONS = -f $(TBENCH_VC) $(ACCELERATOR_VC) $(ADP_OPTIONS)
 
 # VCS option
 VCS_OPTIONS    = +vcs+lic+wait +v2k +lint=all,noTMR,noVCDE -debug
 VCS_SIM_OPTION = +vcs+lic+wait +vcs+flush+log -assert nopostproc
-VCS_VC_OPTIONS = -f $(TBENCH_VC) $(ACCELERATOR_VC)
+VCS_VC_OPTIONS = -f $(TBENCH_VC) $(ACCELERATOR_VC)  $(ADP_OPTIONS)
 
 # XM verilog option
 XMSIM_OPTIONS  = -unbuffered -status -LICQUEUE -f xmsim.args -cdslib cds.lib -hdlvar hdl.var -NBASYNC
-XM_VC_OPTIONS  = $(TBENCH_VC) $(ACCELERATOR_VC) $(ADP_OPTIONS) 
+XM_VC_OPTIONS  = -f $(TBENCH_VC) $(ACCELERATOR_VC) $(ADP_OPTIONS) 
 
 
 # Debug Tester image
@@ -142,7 +142,7 @@ all     : all_$(SIMULATOR)
 
 # Compile RTL
 compile_vcs :
-	vcs $(VCS_OPTIONS) $(VCS_VC_OPTIONS) | tee compile_vcs.log
+	vcs $(VCS_OPTIONS) $(VCS_VC_OPTIONS) $(DEFINES_VC)  | tee compile_vcs.log
 
 
 # Run simulation in batch mode
@@ -227,31 +227,37 @@ all_xm : compile_xm bootrom debugtester
 # ------- MTI -----------
 
 # Compile RTL
-compile_mti :
+compile_mti : bootrom
+	@echo ADP_FILE
+	@echo $(ADP_OPTIONS)
+	cd $(SIM_DIR)
 	@if [ -d work ] ; then \
           true ; \
 	else \
 	  vlib work; \
 	fi
-	vlog -incr -lint +v2k $(MTI_OPTIONS) $(MTI_VC_OPTIONS) | tee compile_mti.log
+	cd $(SIM_DIR); vlog -incr -lint +v2k $(MTI_OPTIONS) $(MTI_VC_OPTIONS) $(DEFINES_VC) | tee compile_mti.log
 
 # Run simulation in batch mode
-run_mti : code
-	@if [ ! -d logs ] ; then \
-	  mkdir logs; \
+run_mti : code compile_mti
+	@if [ ! -d $(SIM_DIR)/logs ] ; then \
+	  mkdir $(SIM_DIR)/logs; \
 	fi
-	vsim $(MTI_OPTIONS) -c tb_cmsdk_mcu -do "radix hex;run -all;quit -f" | tee logs/run_$(TESTNAME).log ;
+	@echo "run -all" > $(SIM_DIR)/run.tcl.tmp
+	@echo "quit -f" >> $(SIM_DIR)/run.tcl.tmp
+	@mv  $(SIM_DIR)/run.tcl.tmp $(SIM_DIR)/run.tcl
+	cd $(SIM_DIR); vsim $(MTI_OPTIONS) -c nanosoc_tb -do run.tcl | tee logs/run_$(TESTNAME).log ;
 
 # Run simulation in interactive mode
-sim_mti : code
-	vsim $(MTI_OPTIONS) -gui tb_cmsdk_mcu &
+sim_mti : code compile_mti
+	vsim $(MTI_OPTIONS) -gui nanosoc_tb &
 
 # Create work directory
 lib_mti :
 	vlib work
 
 # Compile RTL, and run all tests in batch mode
-all_mti : compile_mti bootrom debugtester
+all_mti : bootrom compile_mti debugtester
 	@if [ ! -d logs ] ; then \
 	  mkdir logs; \
 	fi
@@ -320,6 +326,7 @@ endif
 	    if [ -e  $(TESTNAME).hex ] ; then \
 		  mkdir -p $(SIM_DIR) ; \
 	      cp $(TESTNAME).hex $(SIM_DIR)/image.hex ; \
+	      cp $(TESTNAME).hex ../../image.hex ; \
 	    else \
 	      echo Problem reading hex file ;\
 	      exit 1; \
@@ -427,7 +434,7 @@ v2html:
 	fi
 	@(cd $(NANOSOC_HTML_DIR)/build; \
 	rm *.html; rm *.gif; rm *.gz; \
-	~/tools/v2html -f $(VERILOG_DIR)/v2html_M0.vc -ht nanosoc_chip ; \
+	~/tools/v2html -f $(PROJECT_DIR)/flist/project/v2html_system.flist -ht nanosoc_chip ; \
 	cp -p nanosoc_tb.v.html hierarchy.html ; \
 	cd $(SIM_DIR) ; )
 	gtar zcvf $(NANOSOC_HTML_DIR)/v2html_doc.tgz $(NANOSOC_HTML_DIR)/build
diff --git a/system/src/verilog/nanosoc_chip.v b/system/src/verilog/nanosoc_chip.v
index 4d9fa6a..213f784 100644
--- a/system/src/verilog/nanosoc_chip.v
+++ b/system/src/verilog/nanosoc_chip.v
@@ -833,17 +833,24 @@ localparam    CORTEX_M0 = 1;
 //
 // ************************************************
 
-  wire   exp_ip_req;
-  wire   exp_op_req;
-  wire   exp_irq;
-  
-//----------------------------------------
+  wire   exp_drq_ip;
+  wire   exp_drq_op;
+  wire   [3:0] exp_irq;
+  wire   exp_merged_irq;
+  assign exp_irq0 = exp_irq[0];
+  assign exp_irq1 = exp_irq[1];
+  assign exp_irq2 = exp_irq[2];
+  assign exp_irq3 = exp_irq[3];
+
+  //----------------------------------------
 // Expansion Region "exp" instance
 //----------------------------------------
 
-`ifdef NANSOC_EXPANSION_REGION
-nanosoc_exp #(.ADDRWIDTH(29)
-) u_nanosoc_exp (
+`ifdef NANOSOC_EXPANSION_REGION
+nanosoc_acc_wrapper #(
+  .AHBADDRWIDTH(29),
+  .CFGNUMIRQ(4)
+) u_nanosoc_exp_wrapper (
   .HCLK        (HCLK),
   .HRESETn     (HRESETn),
 
@@ -860,8 +867,11 @@ nanosoc_exp #(.ADDRWIDTH(29)
   .HREADYOUTS  (HREADYOUT_exp),
   .HRESPS      (HRESP_exp),
   .HRDATAS     (HRDATA_exp),
-  .ip_data_req (exp_ip_req),
-  .op_data_req (exp_op_req)
+  .exp_drq_ip_o  (exp_drq_ip),
+  .exp_dlast_ip_i(1'b0),
+  .exp_drq_op_o  (exp_drq_op),
+  .exp_dlast_op_i(1'b0),
+  .exp_irq_o     (exp_irq)
 );
 `else
  // Default slave - if no expansion region
@@ -876,6 +886,30 @@ nanosoc_exp #(.ADDRWIDTH(29)
 );
  assign   HRDATA_exp = 32'heaedeaed; // Tie off Expansion Address Expansion Data
 
+//nanosoc_exp_wrapper #(.AHBADDRWIDTH(29)
+//) u_nanosoc_exp_wrapper (
+//  .HCLK        (HCLK),
+//  .HRESETn     (HRESETn),
+//
+//  //  Input slave port: 32 bit data bus interface
+//  .HSEL_i       (HSEL_exp),
+//  .HADDR_i      (HADDR_exp[28:0]),
+//  .HTRANS_i     (HTRANS_exp),
+//  .HSIZE_i      (HSIZE_exp),
+//  .HPROT_i      (HPROT_exp),
+//  .HWRITE_i     (HWRITE_exp),
+//  .HREADY_i     (HREADYMUX_exp),
+//  .HWDATA_i     (HWDATA_exp),
+//
+//  .HREADYOUT_o  (HREADYOUT_exp),
+//  .HRESP_o      (HRESP_exp),
+//  .HRDATA_o     (HRDATA_exp),
+//  .exp_drq_ip_o  (exp_drq_ip),
+//  .exp_dlast_ip_i(1'b0),
+//  .exp_drq_op_o  (exp_drq_op),
+//  .exp_dlast_op_i(1'b0),
+//  .exp_irq_o    (exp_irq)
+//);
 `endif
 
   assign   HRUSER_exp = 2'b00;
@@ -1262,8 +1296,8 @@ localparam AWRAM9 = ADDR_WIDTH_RAM; // Address width - to match RAM instance siz
   wire  [DMA_CHANNEL_NUM-1:0] dma230_req;  // tie off signal.
   wire  [DMA_CHANNEL_NUM-1:0] dma230_tie0 = {DMA_CHANNEL_NUM{1'b0}};
 
-  assign dma230_req[0] = exp_ip_req;
-  assign dma230_req[1] = exp_op_req;
+  assign dma230_req[0] = exp_drq_ip;
+  assign dma230_req[1] = exp_drq_op;
 
 
   // DMA done per channel
diff --git a/system/test_io/verilog/nanosoc_adp_manager.v b/system/test_io/verilog/nanosoc_adp_manager.v
index 827491b..25ba253 100755
--- a/system/test_io/verilog/nanosoc_adp_manager.v
+++ b/system/test_io/verilog/nanosoc_adp_manager.v
@@ -11,7 +11,7 @@
 
 
 //`define ADPBASIC 1
-`begin_keywords "1364-2001"
+//`begin_keywords "1364-2001"
 
 module nanosoc_adp_manager // AHB initiator interface
    #(parameter PROMPT_CHAR          = "]"
@@ -181,8 +181,8 @@ endfunction
 
 function [63:0] FNBuild_param64_byte;
 input [63:0] param64;
-input [7:0] byte;
-  FNBuild_param64_byte = {byte[7:0], param64[63:08]};
+input [7:0] octet;
+  FNBuild_param64_byte = {octet[7:0], param64[63:08]};
 endfunction
 
 function [31:0] FNBuild_param32_hexdigit;
@@ -221,8 +221,8 @@ endfunction
 
 function [31:0] FNBuild_param32_byte;
 input [31:0] param32;
-input [7:0] byte;
-  FNBuild_param32_byte = {byte[7:0], param32[31:08]};
+input [7:0] octet;
+  FNBuild_param32_byte = {octet[7:0], param32[31:08]};
 endfunction
 
 
@@ -453,8 +453,8 @@ 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
+input [7:0] octet;
+  begin com_tx_req<= 1; com_tx_byte <= octet; end
 endtask
 
 task com_rx_nxt; com_rx_ack <=1; endtask
@@ -764,7 +764,7 @@ always @(posedge HCLK or negedge HRESETn)
 
 endmodule
 
-`end_keywords
+//`end_keywords
 
 ////AHBLITE_ADPMASTER instancing
 //ADPmaster
diff --git a/system/testcodes/aes128_tests/aes128.h b/system/testcodes/aes128_tests/aes128.h
new file mode 100644
index 0000000..202adf4
--- /dev/null
+++ b/system/testcodes/aes128_tests/aes128.h
@@ -0,0 +1,71 @@
+#ifndef _AES128_H_
+#define _AES128_H_
+
+#include <stdint.h>
+
+// define the API addresses here. 
+
+#define AES128_BASE        (0x60000000)
+
+// byte address I/O buffers
+#define AES128_BUF_SIZE   (0x4000)
+
+typedef struct {
+     __I  uint32_t CORE_NAME[2];   /* 0x0000-0007 */
+     __I  uint32_t CORE_VERSION;   /* 0x0008-000B */
+          uint32_t RESRV0C;        /* 0x000C */
+     __IO uint32_t CTRL;           /* 0x0010 */
+     __O  uint32_t CTRL_SET;       /* 0x0014 */
+     __O  uint32_t CTRLL_CLR;      /* 0x0018 */
+     __I  uint32_t STATUS;         /* 0x001c */
+     __IO uint32_t QUAL;           /* 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 */
+          uint8_t RESRV50[AES128_BUF_SIZE - 0x50];/* 0x0050-0x3FFC (4096-20 words) */
+     __IO uint8_t KEY128[AES128_BUF_SIZE];   /* 0x4000-7FFF (0x3FFF is last alias) */
+     __IO uint8_t TXTIP128[AES128_BUF_SIZE]; /* 0x8000-BFFF (0x3FFF is last alias) */
+     __I  uint8_t TXTOP128[AES128_BUF_SIZE]; /* 0xC000-FFFF (0x3FFF is last alias) */
+} AES128_TypeDef;
+
+#define AES128             ((AES128_TypeDef *) AES128_BASE )
+
+#define AES_BLOCK_SIZE 16
+
+#define AES_KEY_LEN_128 16
+
+#define HW32_REG(ADDRESS)  (*((volatile unsigned long  *)(ADDRESS)))
+
+#define  AES128_CTRL_REG_WIDTH   ( 8)
+#define  AES128_CTRL_BIT_MAX     ( (CTRL_REG_WIDTH-1)
+#define  AES128_CTRL_KEY_REQ_BIT (1<<0)
+#define  AES128_CTRL_IP_REQ_BIT  (1<<1)
+#define  AES128_CTRL_OP_REQ_BIT  (1<<2)
+#define  AES128_CTRL_ERR_REQ_BIT (1<<3)
+#define  AES128_CTRL_BYPASS_BIT  (1<<6)
+#define  AES128_CTRL_ENCODE_BIT  (1<<7)
+#define  AES128_STAT_REG_WIDTH   ( 8)
+#define  AES128_STAT_KEY_REQ_BIT (1<<0)
+#define  AES128_STAT_IP_REQ_BIT  (1<<1)
+#define  AES128_STAT_OP_REQ_BIT  (1<<2)
+#define  AES128_STAT_ERR_REQ_BIT (1<<3)
+#define  AES128_STAT_KEYOK_BIT   (1<<4)
+#define  AES128_STAT_VALID_BIT   (1<<5)
+#define  AES128_STAT_BYPASS_BIT  (1<<6)
+#define  AES128_STAT_ENCODE_BIT  (1<<7)
+#define  AES128_KEY_REQ_BIT (1<<0)
+#define  AES128_IP_REQ_BIT  (1<<1)
+#define  AES128_OP_REQ_BIT  (1<<2)
+#define  AES128_ERR_REQ_BIT (1<<3)
+#define  AES128_KEYOK_BIT   (1<<4)
+#define  AES128_VALID_BIT   (1<<5)
+#define  AES128_BYPASS_BIT  (1<<6)
+#define  AES128_ENCODE_BIT  (1<<7)
+
+#endif // _AES128_H_
diff --git a/system/testcodes/aes128_tests/aes128_tests.c b/system/testcodes/aes128_tests/aes128_tests.c
new file mode 100644
index 0000000..3dbccad
--- /dev/null
+++ b/system/testcodes/aes128_tests/aes128_tests.c
@@ -0,0 +1,688 @@
+#include "CMSDK_CM0.h"
+#include "aes128.h"
+#include <string.h>
+#include "uart_stdout.h"
+#include <stdio.h>
+// memcopy implememtation
+#define os_memcpy memcpy
+#define os_memset memset
+// PL230DMA implementation
+#include "dma_pl230_driver.h"
+
+
+static volatile dma_pl230_channel_data aes_ip_chain[2];
+static volatile dma_pl230_channel_data aes_op_chain[2];
+
+// associate DMA channel numbers
+#define DMA_CHAN_AES128_IP (0)
+#define DMA_CHAN_AES128_OP (1)
+
+volatile int dma_done_irq_occurred;
+volatile int dma_done_irq_expected;
+volatile int dma_error_irq_occurred;
+volatile int dma_error_irq_expected;
+volatile int aes_key_irq_occurred;
+volatile int aes_key_irq_expected;
+volatile int aes_ip_irq_occurred;
+volatile int aes_ip_irq_expected;
+volatile int aes_op_irq_occurred;
+volatile int aes_op_irq_expected;
+volatile int aes_err_irq_occurred;
+volatile int aes_err_irq_expected;
+
+  uint8_t _test_key128[AES_KEY_LEN_128] = {  
+    0x75, 0x46, 0x20, 0x67,
+    0x6e, 0x75, 0x4b, 0x20,
+    0x79, 0x6d, 0x20, 0x73,
+    0x74, 0x61, 0x68, 0x54 };
+
+  uint8_t test_key128[AES_KEY_LEN_128] = {  
+    0x54, 0x68, 0x61, 0x74,
+    0x73, 0x20, 0x6d, 0x79,
+    0x20, 0x4b, 0x75, 0x6e,
+    0x67, 0x20, 0x46, 0x75 };
+	
+  uint8_t buf128[AES_BLOCK_SIZE] = {
+    0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00 };
+
+  uint8_t _test_text128[AES_BLOCK_SIZE] = {
+    0x6f, 0x77, 0x54, 0x20,
+    0x65, 0x6e, 0x69, 0x4e,
+    0x20, 0x65, 0x6e, 0x4f,
+    0x20, 0x6f, 0x77, 0x54 };
+
+  uint8_t test_text128[AES_BLOCK_SIZE] = {
+    0x54, 0x77, 0x6f, 0x20,
+    0x4f, 0x6e, 0x65, 0x20,
+    0x4e, 0x69, 0x6e, 0x65,
+    0x20, 0x54, 0x77, 0x6f };
+
+  uint8_t test_exp128[AES_BLOCK_SIZE] = {
+    0x29, 0xc3, 0x50, 0x5f,
+    0x57, 0x14, 0x20, 0xf6,
+    0x40, 0x22, 0x99, 0xb3,
+    0x1a, 0x02, 0xd7, 0x3a };
+
+// add extra block[128] with all zeros to toggle bits low
+  uint8_t shift_patt[129*16] = {
+ 0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xfe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xff,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xff,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xff,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xff,0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xff,0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xff,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xff,0xfe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xff,0xff,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xff,0xff,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xff,0xff,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xff,0xff,0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xff,0xff,0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xff,0xff,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xff,0xff,0xfe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xff,0xff,0xff,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xff,0xff,0xff,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xff,0xff,0xff,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xff,0xff,0xff,0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xff,0xff,0xff,0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xff,0xff,0xff,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xff,0xff,0xff,0xfe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xff,0xff,0xff,0xff,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xff,0xff,0xff,0xff,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xff,0xff,0xff,0xff,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xff,0xff,0xff,0xff,0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xff,0xff,0xff,0xff,0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xff,0xff,0xff,0xff,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xff,0xff,0xff,0xff,0xfe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xff,0xff,0xff,0xff,0xff,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xff,0xff,0xff,0xff,0xff,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xff,0xff,0xff,0xff,0xff,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xff,0xff,0xff,0xff,0xff,0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xff,0xff,0xff,0xff,0xff,0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xff,0xff,0xff,0xff,0xff,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xff,0xff,0xff,0xff,0xff,0xfe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x80,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf0,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf8,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x80,0x00,0x00,0x00,0x00,0x00,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xc0,0x00,0x00,0x00,0x00,0x00,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xe0,0x00,0x00,0x00,0x00,0x00,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf0,0x00,0x00,0x00,0x00,0x00,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf8,0x00,0x00,0x00,0x00,0x00,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc,0x00,0x00,0x00,0x00,0x00,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0x00,0x00,0x00,0x00,0x00,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x80,0x00,0x00,0x00,0x00,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xc0,0x00,0x00,0x00,0x00,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xe0,0x00,0x00,0x00,0x00,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf0,0x00,0x00,0x00,0x00,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf8,0x00,0x00,0x00,0x00,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc,0x00,0x00,0x00,0x00,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0x00,0x00,0x00,0x00,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x80,0x00,0x00,0x00,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xc0,0x00,0x00,0x00,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xe0,0x00,0x00,0x00,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf0,0x00,0x00,0x00,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf8,0x00,0x00,0x00,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc,0x00,0x00,0x00,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0x00,0x00,0x00,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x80,0x00,0x00,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xc0,0x00,0x00,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xe0,0x00,0x00,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf0,0x00,0x00,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf8,0x00,0x00,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc,0x00,0x00,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0x00,0x00,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x80,0x00,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xc0,0x00,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xe0,0x00,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf0,0x00,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf8,0x00,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc,0x00,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0x00,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x80,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xc0,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xe0,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf0,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf8,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,//127
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//128
+ };    
+
+  uint8_t shift_buf1[sizeof(shift_patt)];
+  uint8_t shift_buf2[sizeof(shift_patt)];
+
+
+/* Note:  Hardware supports byte, half-word or word accesses
+   So memcpy() can be used to load/save data
+   And memset() can be used to pad out data-in to 128-bits
+   mode =0 (bypass), =1 (encode) or =2 (decode)
+*/
+void aes128_driver_memcpy(uint8_t *key, uint32_t nbytes, uint8_t *input,
+                          uint8_t *result, uint8_t mode)
+{
+    // Reset engine
+    AES128->DRQ_MSK = 0;
+    AES128->IRQ_MSK = 0;
+    AES128->QUAL    = 0;
+    AES128->CTRL    = AES128_CTRL_KEY_REQ_BIT | AES128_CTRL_IP_REQ_BIT | AES128_CTRL_OP_REQ_BIT | AES128_CTRL_ERR_REQ_BIT;
+
+    // Set up parameters
+    if (mode == 1)
+      AES128->CTRL_SET = AES128_ENCODE_BIT; // ENCODE mode
+    if (mode == 0)
+      AES128->CTRL_SET = AES128_BYPASS_BIT; // BYPASS mode
+
+    AES128->IRQ_MSK_SET = (AES128_ERR_REQ_BIT | AES128_KEY_REQ_BIT | AES128_IP_REQ_BIT | AES128_OP_REQ_BIT);
+    
+    // Program Key
+    os_memcpy((uint8_t *)AES128->KEY128, key, AES_KEY_LEN_128);
+    while (!(AES128->STATUS & AES128_KEYOK_BIT))
+         ;
+
+    /* payload */
+    while(nbytes) {
+       uint8_t len = (nbytes > AES_BLOCK_SIZE) ? AES_BLOCK_SIZE : nbytes;            
+       /* Align/pad input and load into hardware */
+       os_memcpy((uint8_t *)AES128->TXTIP128, input, len);
+       //patch up any zero-padding
+       if (len < AES_BLOCK_SIZE)
+           os_memset((uint8_t *)&(AES128->TXTIP128[len]), 0, AES_BLOCK_SIZE-len);
+       /* Auto-started! - no need for manual start */
+       /* Poll until completed */
+       while (!(AES128->STATUS & AES128_VALID_BIT))
+         ;
+       os_memcpy(result, (uint8_t *)AES128->TXTOP128, AES_BLOCK_SIZE);
+       /* Accounting */
+       input   += len;
+       result  += len;
+       nbytes -= len;
+       AES128->IRQ_MSK_SET = (AES128_IP_REQ_BIT | AES128_OP_REQ_BIT);
+    }
+    AES128->CTRL    = 0;
+}
+
+// wrapper functions
+
+void aes128_bypass_memcpy(uint8_t *key, uint32_t nbytes, uint8_t *input, uint8_t *result)
+       { aes128_driver_memcpy(key, nbytes, input, result, 0); }
+
+void aes128_encrypt_memcpy(uint8_t *key, uint32_t nbytes, uint8_t *input, uint8_t *result)
+       { aes128_driver_memcpy(key, nbytes, input, result, 1); }
+
+void aes128_decrypt_memcpy(uint8_t *key, uint32_t nbytes, uint8_t *input, uint8_t *result)
+       { aes128_driver_memcpy(key, nbytes, input, result, 2); }
+
+
+int aes128_buffer_verify(uint32_t buflen, uint8_t *buf_A, uint8_t *buf_B)
+{
+    int i, j, fail = 0;
+        for (i=0 ; i < buflen; i++) {
+            if (buf_A[i] != buf_B[i]){
+                fail = 1;
+                break;
+            }
+        }
+        if (fail) {
+            j=i; // print offending block
+            for (i=(j - (j%16)) ; i < (j-(j%16)+16); i++) {
+               if (i%16==0)
+                   printf(" //%03d\n", (i>>4));
+               printf("0x%02x,", buf_A[i]);
+           }
+        }
+        if (fail){
+            i=j;
+            printf("Verify compare FAIL\n      EXPECTED_RESULT[%2d]= 0x%02x, ACTUAL_RESULT= 0x%02x \n",i, buf_B[i], buf_A[i]);
+            return(-1);
+        }
+        return(0);
+}
+
+void aes128_driver_aligned_dma32(uint8_t *key, uint32_t nbytes, uint8_t *input,
+                                 uint8_t *result, uint8_t mode)
+{
+    int c;
+    // Reset engine
+    AES128->DRQ_MSK = 0;
+    AES128->IRQ_MSK = 0;
+    AES128->QUAL    = 0;
+    AES128->CTRL    = AES128_CTRL_KEY_REQ_BIT | AES128_CTRL_IP_REQ_BIT | AES128_CTRL_OP_REQ_BIT;
+
+    // Set up parameters
+    if (mode == 1)
+      AES128->CTRL_SET = AES128_ENCODE_BIT; // ENCODE mode
+    if (mode == 0)
+      AES128->CTRL_SET = AES128_BYPASS_BIT; // BYPASS mode
+    
+    dma_pl230_data_struct_init(); // initialize
+    
+    // program DMA transfers in multiples of 4 words (nbytes scaled >>2 for words)
+    aes_ip_chain[0].SrcEndPointer = DMA_PL230_PTR_END(key,PL230_XFER_W,4);
+    aes_ip_chain[0].DstEndPointer = DMA_PL230_PTR_END(&(AES128->KEY128[AES128_BUF_SIZE-16]),PL230_XFER_W,4);
+    aes_ip_chain[0].Control = DMA_PL230_CTRL(PL230_CTRL_CYCLE_DEV_CHAIN_ALT,PL230_XFER_W,4,PL230_CTRL_RPWR_4);
+
+    aes_ip_chain[1].SrcEndPointer = DMA_PL230_PTR_END(input,PL230_XFER_W,(nbytes>>2));
+    aes_ip_chain[1].DstEndPointer = DMA_PL230_PTR_END(&(AES128->TXTIP128[AES128_BUF_SIZE-nbytes]),PL230_XFER_W,(nbytes>>2));
+    aes_ip_chain[1].Control = DMA_PL230_CTRL(PL230_CTRL_CYCLE_BASIC,PL230_XFER_W,(nbytes>>2),PL230_CTRL_RPWR_4);
+
+    c=DMA_CHAN_AES128_IP;
+    dma_pl230_table->Primary[c].SrcEndPointer  = DMA_PL230_PTR_END(&(aes_ip_chain[0].SrcEndPointer), PL230_XFER_W,(2*4));
+    dma_pl230_table->Primary[c].DstEndPointer  = DMA_PL230_PTR_END(&(dma_pl230_table->Alternate[c]), PL230_XFER_W,(1*4));
+    dma_pl230_table->Primary[c].Control= DMA_PL230_CTRL_DSTFIX(PL230_CTRL_CYCLE_DEV_CHAIN_PRI,PL230_XFER_W,(2*4),PL230_CTRL_RPWR_4);
+
+    aes_op_chain[0].SrcEndPointer = DMA_PL230_PTR_END(&(AES128->TXTOP128[AES128_BUF_SIZE-nbytes]),PL230_XFER_W,(nbytes>>2));
+    aes_op_chain[0].DstEndPointer = DMA_PL230_PTR_END(result,PL230_XFER_W,(nbytes>>2));
+    aes_op_chain[0].Control = DMA_PL230_CTRL(PL230_CTRL_CYCLE_BASIC,PL230_XFER_W,(nbytes>>2),PL230_CTRL_RPWR_4);
+
+    c=DMA_CHAN_AES128_OP;        
+    dma_pl230_table->Primary[c].SrcEndPointer  = DMA_PL230_PTR_END(&(aes_op_chain[0].SrcEndPointer), PL230_XFER_W,(1*4));
+    dma_pl230_table->Primary[c].DstEndPointer  = DMA_PL230_PTR_END(&(dma_pl230_table->Alternate[c]), PL230_XFER_W,(1*4));
+    dma_pl230_table->Primary[c].Control= DMA_PL230_CTRL_DSTFIX(PL230_CTRL_CYCLE_DEV_CHAIN_PRI,PL230_XFER_W,(1*4),PL230_CTRL_RPWR_4);
+ 
+    // enable DMA controller channels
+    dma_pl230_init((1<<DMA_CHAN_AES128_OP) | (1<<DMA_CHAN_AES128_IP)); // two active
+
+    // and enable DMA requests
+    AES128->DRQ_MSK_SET = (AES128_KEY_REQ_BIT | AES128_IP_REQ_BIT | AES128_OP_REQ_BIT);
+    AES128->IRQ_MSK_SET = (AES128_ERR_REQ_BIT | AES128_KEY_REQ_BIT | AES128_IP_REQ_BIT | AES128_OP_REQ_BIT);
+    // test to ensure output DMA has started                            
+    while (!(dma_pl230_channel_active((1<<DMA_CHAN_AES128_OP))))
+      ;
+    while (dma_pl230_channel_active((1<<DMA_CHAN_AES128_OP)))
+      ;
+    while (dma_pl230_channel_active((1<<DMA_CHAN_AES128_OP)))
+      ;
+    AES128->DRQ_MSK = 0;
+    AES128->IRQ_MSK = 0;
+    DMA_PL230_DMAC->DMA_CFG = 0; /* Disable DMA controller for initialization */
+    dma_pl230_init(0); // none active
+    return;
+}
+
+void aes128_driver_dma8(uint8_t *key, uint32_t nbytes, uint8_t *input,
+                          uint8_t *result, uint8_t mode)
+{
+    int c;
+    // Reset engine
+    AES128->DRQ_MSK = 0;
+    AES128->IRQ_MSK = 0;
+    AES128->QUAL    = 0;
+    AES128->CTRL    = AES128_CTRL_KEY_REQ_BIT | AES128_CTRL_IP_REQ_BIT | AES128_CTRL_OP_REQ_BIT;
+
+    // Set up parameters
+    if (mode == 1)
+      AES128->CTRL_SET = AES128_ENCODE_BIT; // ENCODE mode
+    if (mode == 0)
+      AES128->CTRL_SET = AES128_BYPASS_BIT; // BYPASS mode
+    
+    dma_pl230_data_struct_init(); // initialize
+    
+    // program DMA transfers in multiples of 16 bytes
+    aes_ip_chain[0].SrcEndPointer = DMA_PL230_PTR_END(key,PL230_XFER_B,16);
+    aes_ip_chain[0].DstEndPointer = DMA_PL230_PTR_END(&(AES128->KEY128[AES128_BUF_SIZE-16]),PL230_XFER_B,16);
+    aes_ip_chain[0].Control = DMA_PL230_CTRL(PL230_CTRL_CYCLE_DEV_CHAIN_ALT,PL230_XFER_B,16,PL230_CTRL_RPWR_16);
+
+    aes_ip_chain[1].SrcEndPointer = DMA_PL230_PTR_END(input,PL230_XFER_B,(nbytes));
+    aes_ip_chain[1].DstEndPointer = DMA_PL230_PTR_END(&(AES128->TXTIP128[AES128_BUF_SIZE-nbytes]),PL230_XFER_B,(nbytes));
+    aes_ip_chain[1].Control = DMA_PL230_CTRL(PL230_CTRL_CYCLE_BASIC,PL230_XFER_B,(nbytes),PL230_CTRL_RPWR_16);
+
+    c=DMA_CHAN_AES128_IP;
+    dma_pl230_table->Primary[c].SrcEndPointer  = DMA_PL230_PTR_END(&(aes_ip_chain[0].SrcEndPointer), PL230_XFER_W, (2*4));
+    dma_pl230_table->Primary[c].DstEndPointer  = DMA_PL230_PTR_END(&(dma_pl230_table->Alternate[c]), PL230_XFER_W, (1*4));
+    dma_pl230_table->Primary[c].Control= DMA_PL230_CTRL_DSTFIX(PL230_CTRL_CYCLE_DEV_CHAIN_PRI,PL230_XFER_W,(2*4),PL230_CTRL_RPWR_4);
+
+    aes_op_chain[0].SrcEndPointer = DMA_PL230_PTR_END(&(AES128->TXTOP128[AES128_BUF_SIZE-nbytes]),PL230_XFER_B,(nbytes));
+    aes_op_chain[0].DstEndPointer = DMA_PL230_PTR_END(result,PL230_XFER_B,(nbytes));
+    aes_op_chain[0].Control = DMA_PL230_CTRL(PL230_CTRL_CYCLE_BASIC,PL230_XFER_B,(nbytes),PL230_CTRL_RPWR_16);
+
+    c=DMA_CHAN_AES128_OP;        
+    dma_pl230_table->Primary[c].SrcEndPointer  = DMA_PL230_PTR_END(&(aes_op_chain[0].SrcEndPointer), PL230_XFER_W,(1*4));
+    dma_pl230_table->Primary[c].DstEndPointer  = DMA_PL230_PTR_END(&(dma_pl230_table->Alternate[c]), PL230_XFER_W,(1*4));
+    dma_pl230_table->Primary[c].Control= DMA_PL230_CTRL_DSTFIX(PL230_CTRL_CYCLE_DEV_CHAIN_PRI,PL230_XFER_W,(1*4),PL230_CTRL_RPWR_4);
+ 
+    // enable DMA controller channels
+    dma_pl230_init((1<<DMA_CHAN_AES128_OP) | (1<<DMA_CHAN_AES128_IP)); // two active
+
+    // and enable DMA requests
+    AES128->DRQ_MSK_SET = (AES128_KEY_REQ_BIT | AES128_IP_REQ_BIT | AES128_OP_REQ_BIT);
+    AES128->IRQ_MSK_SET = (AES128_ERR_REQ_BIT | AES128_KEY_REQ_BIT | AES128_IP_REQ_BIT | AES128_OP_REQ_BIT);
+    // test to ensure output DMA has started                            
+    while (!(dma_pl230_channel_active(1<<DMA_CHAN_AES128_OP)))
+      ;
+    while (dma_pl230_channel_active(1<<DMA_CHAN_AES128_OP))
+      ;
+    while (dma_pl230_channel_active(1<<DMA_CHAN_AES128_OP))
+      ;
+    AES128->DRQ_MSK = 0;
+    AES128->IRQ_MSK = 0;
+    DMA_PL230_DMAC->DMA_CFG = 0; /* Disable DMA controller for initialization */
+    dma_pl230_init(0); // none active
+    return;
+}
+
+// wrapper functions
+
+void aes128_alignchk_block_dma(uint8_t *key, uint32_t nbytes, uint8_t *input, uint8_t *result, uint8_t mode)
+       { uint32_t dma_max = DMA_PL230_MAX_XFERS; // default to 1 K bytes
+         if (((((long)key) & 3)==0) && ((((long)input) & 3)==0) && ((((long)result) & 3)==0)) dma_max=(DMA_PL230_MAX_XFERS<<2);
+         while (nbytes >dma_max) {
+            if (dma_max == DMA_PL230_MAX_XFERS) // 1K bytes DMA
+              aes128_driver_dma8(key, dma_max, input, result, mode);
+            else // 1K words DMA
+              aes128_driver_aligned_dma32(key, dma_max, input, result, mode);
+           nbytes -= dma_max; input  += dma_max; result += dma_max;
+         }
+         if (dma_max == DMA_PL230_MAX_XFERS) // up to 1K bytes remaining
+           aes128_driver_dma8(key, nbytes, input, result, mode);
+         else // up to 1K words remaining
+           aes128_driver_aligned_dma32(key, nbytes, input, result, mode);
+       }
+
+void aes128_bypass_dma(uint8_t *key, uint32_t nbytes, uint8_t *input, uint8_t *result) 
+       { aes128_alignchk_block_dma (key, nbytes, input, result, 0); }
+
+void aes128_encrypt_dma(uint8_t *key, uint32_t nbytes, uint8_t *input, uint8_t *result)
+       { aes128_alignchk_block_dma (key, nbytes, input, result, 1); }
+
+void aes128_decrypt_dma(uint8_t *key, uint32_t nbytes, uint8_t *input, uint8_t *result)
+       { aes128_alignchk_block_dma (key, nbytes, input, result, 2); }
+
+
+int main(void) {
+	char rx_char [256] = "soclabs AES128v1"; // init to 0
+	unsigned char id_string [16] = {0};
+	int  i, fail=0;
+        unsigned char * p;
+        
+		UartStdOutInit();
+		printf("%s\n",rx_char);
+		printf("AES128 test program\n");
+		printf("  AES128 ID: ");
+ 	        // iterate over 3 32-bit fields
+                p = (unsigned char *)AES128->CORE_NAME;
+	        for (i = 0; i < 12; i++) {
+                  id_string[i^3]=*p; // fix byte ordering per word
+                  p+=1;
+                  }
+                id_string[12] = 0; 
+		printf("%s\n",id_string);
+
+                aes_key_irq_occurred = 0;
+                aes_key_irq_expected = 1;
+                NVIC_ClearPendingIRQ(EXP0_IRQn);
+                NVIC_EnableIRQ(EXP0_IRQn);
+                aes_ip_irq_occurred = 0;
+                aes_ip_irq_expected = 1;
+                NVIC_ClearPendingIRQ(EXP1_IRQn);
+                NVIC_EnableIRQ(EXP1_IRQn);
+                aes_op_irq_occurred = 0;
+                aes_op_irq_expected = 1;
+                NVIC_ClearPendingIRQ(EXP2_IRQn);
+                NVIC_EnableIRQ(EXP2_IRQn);
+                aes_err_irq_occurred = 0;
+                aes_err_irq_expected = 1;
+                NVIC_ClearPendingIRQ(EXP3_IRQn);
+                NVIC_EnableIRQ(EXP3_IRQn);
+
+		printf("AES128 SW (memcpy) tests...\n");
+ 		printf("  AES128 reference pattern test\n");
+
+ 		printf("    AES128 input/output bypass test\n");
+                aes128_bypass_memcpy(test_key128, sizeof(test_text128), test_text128, buf128);
+                fail += aes128_buffer_verify(AES_BLOCK_SIZE, buf128, test_text128);
+
+               if (aes_key_irq_occurred != 1){ fail++;
+                   printf("    ++ AES key request IRQ count = %d\n", aes_key_irq_occurred); }
+               if (aes_ip_irq_occurred != 2){ fail++;
+                   printf("    ++ AES inp request missing: IRQ count = %d\n", aes_ip_irq_occurred); }
+               if (aes_op_irq_occurred != 1){ fail++;
+                   printf("    ++ AES out request missing: IRQ count = %d\n", aes_op_irq_occurred); }
+               if (aes_err_irq_occurred != 0){ fail++;
+                   printf("    ++ AES err request missing: IRQ count = %d\n", aes_err_irq_occurred); }
+
+		printf("    AES128 encrypt test\n");
+                aes128_encrypt_memcpy(test_key128, sizeof(test_text128), test_text128, buf128); 
+                fail += aes128_buffer_verify(AES_BLOCK_SIZE, buf128, test_exp128);
+
+ 		printf("    AES128 decrypt test\n");
+                aes128_decrypt_memcpy(test_key128, sizeof(buf128), buf128, buf128);
+                fail += aes128_buffer_verify(AES_BLOCK_SIZE, buf128, test_text128);
+
+                aes_key_irq_occurred = 0;
+                aes_ip_irq_occurred = 0;
+                aes_op_irq_occurred = 0;
+                aes_err_irq_occurred = 0;
+
+ 		printf("  AES128 logic toggle test\n");
+		printf("    AES128 input/output pattern test\n");
+                aes128_bypass_memcpy(test_key128, sizeof(shift_patt), shift_patt, shift_buf1); 
+                fail += aes128_buffer_verify(sizeof(shift_patt), shift_buf1, shift_patt);
+
+               if (aes_key_irq_occurred != 1){ fail++;
+                   printf("    ++ AES key request IRQ count = %d\n", aes_key_irq_occurred); }
+               if (aes_ip_irq_occurred != (129+1)){ fail++;
+                   printf("    ++ AES inp request missing: IRQ count = %d\n", aes_ip_irq_occurred); }
+               if (aes_op_irq_occurred != 129){ fail++;
+                   printf("    ++ AES out request missing: IRQ count = %d\n", aes_op_irq_occurred); }
+               if (aes_err_irq_occurred != 0){ fail++;
+                   printf("    ++ AES err request missing: IRQ count = %d\n", aes_err_irq_occurred); }
+
+		printf("    AES128 pattern encrypt test\n");
+                aes128_encrypt_memcpy(test_key128, sizeof(shift_patt), shift_patt, shift_buf1); 
+ 		printf("    AES128 pattern decrypt test\n");
+                aes128_decrypt_memcpy(test_key128, sizeof(shift_patt), shift_buf1, shift_buf2); 
+                fail += aes128_buffer_verify(sizeof(shift_patt), shift_buf2, shift_patt);
+
+		printf("AES128 DMA tests...\n");
+
+                aes_key_irq_occurred = 0;
+                aes_ip_irq_occurred = 0;
+                aes_op_irq_occurred = 0;
+                aes_err_irq_occurred = 0;
+                dma_error_irq_expected = 0;
+                dma_error_irq_occurred = 0;
+                dma_done_irq_expected = 1;
+                dma_done_irq_occurred = 0;
+                NVIC_ClearPendingIRQ(DMA_IRQn);
+                NVIC_EnableIRQ(DMA_IRQn);
+
+ 		printf("  AES128 dma input/output bypass test\n");
+                aes128_bypass_dma(test_key128, sizeof(test_text128), test_text128, buf128);
+                fail += aes128_buffer_verify(AES_BLOCK_SIZE, buf128, test_text128);
+
+               if (dma_done_irq_occurred < 2){
+                  puts ("ERROR: DMA err IRQ missing");
+                  fail++;
+                 } else
+                   printf("    ++ DMA_DONE IRQ count = %d\n", dma_done_irq_occurred);
+
+		printf("  AES128 dma encrypt test\n");
+                aes128_encrypt_dma(test_key128, sizeof(test_text128), test_text128, buf128); 
+                fail += aes128_buffer_verify(AES_BLOCK_SIZE, buf128, test_exp128);
+
+ 		printf("  AES128 dma decrypt test\n");
+                aes128_decrypt_dma(test_key128, sizeof(buf128), buf128, buf128);
+                fail += aes128_buffer_verify(AES_BLOCK_SIZE, buf128, test_text128);
+
+               if (dma_done_irq_occurred < 6){
+                  puts ("ERROR: DMA err IRQ missing");
+                  fail++;
+                 } else
+                   printf("    ++ DMA_DONE IRQ count = %d\n", dma_done_irq_occurred);
+
+		printf("  AES128 dma unaligned pattern test\n");
+                aes128_bypass_dma(test_key128,(16*63), shift_patt, shift_buf1+3); 
+                fail += aes128_buffer_verify((16*63), shift_buf1+3, shift_patt);
+
+		printf("  AES128 dma input/output pattern test\n");
+                aes128_bypass_dma(test_key128, sizeof(shift_patt), shift_patt, shift_buf1); 
+                fail += aes128_buffer_verify(sizeof(shift_patt), shift_buf1, shift_patt);
+		printf("  AES128 dma pattern encrypt test\n");
+                aes128_encrypt_dma(test_key128, sizeof(shift_patt), shift_patt, shift_buf1); 
+ 		printf("  AES128 dma pattern decrypt test\n");
+                aes128_decrypt_dma(test_key128, sizeof(shift_patt), shift_buf1, shift_buf2); 
+                fail += aes128_buffer_verify(sizeof(shift_patt), shift_buf2, shift_patt);
+
+               if (dma_done_irq_occurred < (2*7)){
+                  puts ("ERROR: DMA err IRQ missing");
+                  fail++;
+                 } else
+                   printf("    ++ DMA_DONE IRQ count = %d\n", dma_done_irq_occurred);
+
+               // check IRQ masked by DRQs - except when Iinput buffer empty after DMA done
+               if (aes_key_irq_occurred != 0){ fail++;
+                   printf("    ++ AES key request IRQ count = %d\n", aes_key_irq_occurred); }
+               if (aes_ip_irq_occurred != 7){ fail++;
+                   printf("    ++ AES inp request missing: IRQ count = %d\n", aes_ip_irq_occurred); }
+               if (aes_op_irq_occurred != 0){ fail++;
+                   printf("    ++ AES out request missing: IRQ count = %d\n", aes_op_irq_occurred); }
+               if (aes_err_irq_occurred != 0){ fail++;
+                   printf("    ++ AES err request missing: IRQ count = %d\n", aes_err_irq_occurred); }
+
+                NVIC_DisableIRQ(DMA_IRQn);
+                NVIC_DisableIRQ(EXP0_IRQn);
+                NVIC_DisableIRQ(EXP1_IRQn);
+                NVIC_DisableIRQ(EXP2_IRQn);
+                NVIC_DisableIRQ(EXP3_IRQn);
+
+  		printf ("Data retrieved from the AES is: %s\n", id_string);
+		printf ("Data expected from the AES is: %s\n", rx_char);
+		if (fail >0)
+		  printf("** AES TESTS FAILED (%d)  **\n", fail);
+                else
+		  printf("** AES TEST PASSED **\n");
+		// End simulation
+
+
+  		UartEndSimulation();
+
+  	return 0;
+
+}
+	
+/* --------------------------------------------------------------- */
+/*  Interrupt handlers                                         */
+/* --------------------------------------------------------------- */
+
+void DMA_Handler(void)
+{
+if ((DMA_PL230_DMAC->ERR_CLR & 1) != 0)  {
+  /* DMA interrupt is caused by DMA error */
+  dma_error_irq_occurred ++;
+  DMA_PL230_DMAC->ERR_CLR = 1; /* Clear dma_err */
+  if (dma_error_irq_expected==0) {
+    puts ("ERROR : Unexpected DMA error interrupt occurred.\n");
+    UartEndSimulation();
+    while (1);
+    }
+  }
+else {
+  // DMA interrupt is caused by DMA done
+  dma_done_irq_occurred ++;
+  if (dma_done_irq_expected==0) {
+    puts ("ERROR : Unexpected DMA done interrupt occurred.\n");
+    UartEndSimulation();
+    while (1);
+    }
+  }
+}
+
+void EXP0_Handler(void)
+{
+  // AES128 interrupt is caused by Key buffer empty IRQ
+  aes_key_irq_occurred ++;
+  AES128->IRQ_MSK_CLR = AES128_KEY_REQ_BIT;
+  if (aes_key_irq_expected==0) {
+    puts ("ERROR : Unexpected AES128 Key buffer empty request interrupt occurred.\n");
+    UartEndSimulation();
+    while (1);
+    }
+}
+
+void EXP1_Handler(void)
+{
+  // AES128 interrupt is caused by Input buffer empty IRQ
+  aes_ip_irq_occurred ++;
+  AES128->IRQ_MSK_CLR = AES128_IP_REQ_BIT;
+  if (aes_ip_irq_expected==0) {
+    puts ("ERROR : Unexpected AES128 Input buffer empty reqest interrupt occurred.\n");
+    UartEndSimulation();
+    while (1);
+    }
+}
+
+void EXP2_Handler(void)
+{
+  // AES128 interrupt is caused by Output buffer full IRQ
+  aes_op_irq_occurred ++;
+  AES128->IRQ_MSK_CLR = AES128_OP_REQ_BIT;
+  if (aes_op_irq_expected==0) {
+    puts ("ERROR : Unexpected AES128 Output buffer full reqest interrupt occurred.\n");
+    UartEndSimulation();
+    while (1);
+    }
+}
+
+void EXP3_Handler(void)
+{
+  // AES128 interrupt is caused by Error IRQ
+  aes_err_irq_occurred ++;
+  AES128->IRQ_MSK_CLR = AES128_ERR_REQ_BIT;
+  if (aes_err_irq_expected==0) {
+    puts ("ERROR : Unexpected AES128 Error interrupt occurred.\n");
+    UartEndSimulation();
+    while (1);
+    }
+}
+
diff --git a/system/testcodes/aes128_tests/dma_pl230_driver.c b/system/testcodes/aes128_tests/dma_pl230_driver.c
new file mode 100644
index 0000000..8781465
--- /dev/null
+++ b/system/testcodes/aes128_tests/dma_pl230_driver.c
@@ -0,0 +1,163 @@
+#include <stdio.h>
+#include <string.h>
+#include "dma_pl230_driver.h"
+
+#define DEBUG_PRINTF(...) do {} while(0); 
+//#define cpu_to_be32(__x) __x
+//#define be32_to_cpu(__x) __x
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+static int g_dma_pl230_initialised = 0;
+
+static dma_pl230_data_structure priv_dma __attribute__((aligned(256)));
+//
+dma_pl230_data_structure *dma_pl230_table = &priv_dma; 
+
+/* --------------------------------------------------------------- */
+/*  Initialize DMA data structure                                  */
+/* --------------------------------------------------------------- */
+void dma_pl230_data_struct_init(void)
+{
+  int          i;   /* loop counter */
+
+//  printf ("dma structure block address = %x\n", dma_pl230_table);
+  for (i=0; i<MAX_NUM_OF_DMA_CHANNELS; i++) {
+    dma_pl230_table->Primary[i].SrcEndPointer   = 0;
+    dma_pl230_table->Primary[i].DstEndPointer   = 0;
+    dma_pl230_table->Primary[i].Control         = 0;
+    dma_pl230_table->Alternate[i].SrcEndPointer = 0;
+    dma_pl230_table->Alternate[i].DstEndPointer = 0;
+    dma_pl230_table->Alternate[i].Control       = 0;
+    }
+  g_dma_pl230_initialised = 1;
+  return;
+}
+
+void dma_pl230_data_struct_init_dbg(void)
+{
+  int          i;   /* loop counter */
+  unsigned int ptr;
+
+  int          ch_num;         /* number of channels */
+  unsigned int blksize;        /* Size of DMA data structure in bytes */
+  unsigned int blkmask;        /* address mask */
+
+
+  ch_num  = (((DMA_PL230_DMAC->DMA_STATUS) >> 16) & 0x1F)+1;
+  blksize = ch_num * 32;
+  if      (ch_num > 16) blkmask = 0x3FF; /* 17 to 32 */
+  else if (ch_num > 8)  blkmask = 0x1FF; /*  9 to 16 */
+  else if (ch_num > 4)  blkmask = 0x0FF; /*  5 to 8 */
+  else if (ch_num > 2)  blkmask = 0x07F; /*  3 to 4 */
+  else if (ch_num > 1)  blkmask = 0x03F; /*       2 */
+  else                  blkmask = 0x01F; /*       1 */
+
+
+  /* Create DMA data structure in RAM after stack
+  In the linker script, a 1KB memory stack above stack is reserved
+  so we can use this space for putting the DMA data structure.
+  */
+
+//  ptr     = HW32_REG(0);                     /* Read Top of Stack */
+  ptr     = (0x80000000); // force for now as no reserved RAM available
+  
+  /* the DMA data structure must be aligned to the size of the data structure */
+  if ((ptr & blkmask) != 0x0)
+    ptr     = (ptr + blksize) & ~blkmask;
+
+///  if ((ptr + blksize) > (RAM_ADDRESS_MAX + 1)) {
+///    puts ("ERROR : Not enough RAM space for DMA data structure.");
+///    UartEndSimulation();
+///    }
+
+  /* Set pointer to the reserved space */
+  dma_pl230_table = (dma_pl230_data_structure *) ptr;
+  ptr = (unsigned long) &(dma_pl230_table->Primary[0].SrcEndPointer);
+
+  printf ("dma structure block address = %x\n", ptr);
+
+  for (i=0; i<MAX_NUM_OF_DMA_CHANNELS; i++) {
+    dma_pl230_table->Primary[i].SrcEndPointer   = 0;
+    dma_pl230_table->Primary[i].DstEndPointer   = 0;
+    dma_pl230_table->Primary[i].Control         = 0;
+    dma_pl230_table->Alternate[i].SrcEndPointer = 0;
+    dma_pl230_table->Alternate[i].DstEndPointer = 0;
+    dma_pl230_table->Alternate[i].Control       = 0;
+    }
+  g_dma_pl230_initialised = 1;
+  return;
+}
+/* --------------------------------------------------------------- */
+/*  Initialize DMA PL230                                           */
+/* --------------------------------------------------------------- */
+void dma_pl230_init_dbg(unsigned int chan_mask)
+{
+  unsigned int current_state;
+  puts ("Initialize PL230");
+  current_state = DMA_PL230_DMAC->DMA_STATUS;
+  printf ("- # of channels allowed : %d\n",(((current_state) >> 16) & 0x1F)+1);
+  /* Debugging printfs: */
+  printf ("- Current status        : %x\n",(((current_state) >> 4)  & 0xF));
+  printf ("- Current master enable : %x\n",(((current_state) >> 0)  & 0x1));
+
+  /* Wait until current DMA complete */
+  current_state = (DMA_PL230_DMAC->DMA_STATUS >> 4)  & 0xF;
+  if (!((current_state==0) || (current_state==0x8) || (current_state==0x9))) {
+    puts ("- wait for DMA IDLE/STALLED/DONE");
+    current_state = (DMA_PL230_DMAC->DMA_STATUS >> 4)  & 0xF;
+    printf ("- Current status        : %x\n",(((current_state) >> 4)  & 0xF));
+
+    }
+  while (!((current_state==0) || (current_state==0x8) || (current_state==0x9))){
+    /* Wait if not IDLE/STALLED/DONE */
+    current_state = (DMA_PL230_DMAC->DMA_STATUS >> 4)  & 0xF;
+    printf ("- Current status        : %x\n",(((current_state) >> 4)  & 0xF));
+    }
+  DMA_PL230_DMAC->DMA_CFG = 0; /* Disable DMA controller for initialization */
+  DMA_PL230_DMAC->CTRL_BASE_PTR = (unsigned long) &(dma_pl230_table->Primary->SrcEndPointer);
+                           /* Set DMA data structure address */
+  DMA_PL230_DMAC->CHNL_ENABLE_CLR = 0xFFFFFFFF; /* Disable all channels */
+  DMA_PL230_DMAC->CHNL_PRI_ALT_CLR = ((1<<MAX_NUM_OF_DMA_CHANNELS)-1); /* Disable all alt channels */
+  DMA_PL230_DMAC->CHNL_ENABLE_SET = (chan_mask & ((1<<MAX_NUM_OF_DMA_CHANNELS)-1)); /* Enable channel */
+  DMA_PL230_DMAC->CHNL_USEBURST_SET = (chan_mask & ((1<<MAX_NUM_OF_DMA_CHANNELS)-1)); /* Enable bursts */
+  if (chan_mask)
+    DMA_PL230_DMAC->DMA_CFG = 1;              /* Enable DMA controller if enabled channel*/
+  return;
+}
+
+void dma_pl230_init(unsigned int chan_mask)
+{
+  unsigned int current_state;
+  if (g_dma_pl230_initialised ==0)
+    dma_pl230_data_struct_init();
+  /* Wait until current DMA complete */
+  current_state = (DMA_PL230_DMAC->DMA_STATUS >> 4)  & 0xF;
+  while (!((current_state==0) || (current_state==0x8) || (current_state==0x9))){
+    /* Wait if not IDLE/STALLED/DONE */
+    puts ("- wait for DMA IDLE/STALLED/DONE");
+    current_state = (DMA_PL230_DMAC->DMA_STATUS >> 4)  & 0xF;
+    }
+  DMA_PL230_DMAC->DMA_CFG = 0; /* Disable DMA controller for initialization */
+  DMA_PL230_DMAC->CTRL_BASE_PTR = (unsigned long) &(dma_pl230_table->Primary->SrcEndPointer);
+                           /* Set DMA data structure address */
+  DMA_PL230_DMAC->CHNL_ENABLE_CLR  = ((1<<MAX_NUM_OF_DMA_CHANNELS)-1); /* Disable all channels */
+  DMA_PL230_DMAC->CHNL_PRI_ALT_CLR = ((1<<MAX_NUM_OF_DMA_CHANNELS)-1); /* Disable all alt channels */
+  DMA_PL230_DMAC->CHNL_ENABLE_SET  = (chan_mask & ((1<<MAX_NUM_OF_DMA_CHANNELS)-1)); /* Enable channel */
+  DMA_PL230_DMAC->CHNL_USEBURST_SET = (chan_mask & ((1<<MAX_NUM_OF_DMA_CHANNELS)-1)); /* Enable bursts */
+  g_dma_pl230_initialised = 2;
+  if (chan_mask)
+    DMA_PL230_DMAC->DMA_CFG = 1;              /* Enable DMA controller if enabled channel*/
+  return;
+}
+
+unsigned int dma_pl230_channel_active(unsigned int chan_mask)
+{
+  return(DMA_PL230_DMAC->CHNL_ENABLE_SET & chan_mask & ((1<<MAX_NUM_OF_DMA_CHANNELS)-1)); /* Enabled channels */
+}
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/system/testcodes/aes128_tests/dma_pl230_driver.h b/system/testcodes/aes128_tests/dma_pl230_driver.h
new file mode 100644
index 0000000..082b196
--- /dev/null
+++ b/system/testcodes/aes128_tests/dma_pl230_driver.h
@@ -0,0 +1,198 @@
+#ifndef __DMA_PL230_MCU_H
+#define __DMA_PL230_MCU_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+#include  "CMSDK_CM0.h"
+
+#define DMA_PL230_BASE        (CMSDK_APB_BASE + 0xF000UL)
+
+#define MAX_NUM_OF_DMA_CHANNELS   2
+
+/*------------- PL230 uDMA (PL230) --------------------------------------*/
+/** @addtogroup DMA_PL230 CMSDK uDMA controller
+  @{
+*/
+typedef struct
+{
+  __I    uint32_t  DMA_STATUS;           /*!< Offset: 0x000 DMA status Register (R/W) */
+  __O    uint32_t  DMA_CFG;              /*!< Offset: 0x004 DMA configuration Register ( /W) */
+  __IO   uint32_t  CTRL_BASE_PTR;        /*!< Offset: 0x008 Channel Control Data Base Pointer Register  (R/W) */
+  __I    uint32_t  ALT_CTRL_BASE_PTR;    /*!< Offset: 0x00C Channel Alternate Control Data Base Pointer Register  (R/ ) */
+  __I    uint32_t  DMA_WAITONREQ_STATUS; /*!< Offset: 0x010 Channel Wait On Request Status Register  (R/ ) */
+  __O    uint32_t  CHNL_SW_REQUEST;      /*!< Offset: 0x014 Channel Software Request Register  ( /W) */
+  __IO   uint32_t  CHNL_USEBURST_SET;    /*!< Offset: 0x018 Channel UseBurst Set Register  (R/W) */
+  __O    uint32_t  CHNL_USEBURST_CLR;    /*!< Offset: 0x01C Channel UseBurst Clear Register  ( /W) */
+  __IO   uint32_t  CHNL_REQ_MASK_SET;    /*!< Offset: 0x020 Channel Request Mask Set Register  (R/W) */
+  __O    uint32_t  CHNL_REQ_MASK_CLR;    /*!< Offset: 0x024 Channel Request Mask Clear Register  ( /W) */
+  __IO   uint32_t  CHNL_ENABLE_SET;      /*!< Offset: 0x028 Channel Enable Set Register  (R/W) */
+  __O    uint32_t  CHNL_ENABLE_CLR;      /*!< Offset: 0x02C Channel Enable Clear Register  ( /W) */
+  __IO   uint32_t  CHNL_PRI_ALT_SET;     /*!< Offset: 0x030 Channel Primary-Alterante Set Register  (R/W) */
+  __O    uint32_t  CHNL_PRI_ALT_CLR;     /*!< Offset: 0x034 Channel Primary-Alterante Clear Register  ( /W) */
+  __IO   uint32_t  CHNL_PRIORITY_SET;    /*!< Offset: 0x038 Channel Priority Set Register  (R/W) */
+  __O    uint32_t  CHNL_PRIORITY_CLR;    /*!< Offset: 0x03C Channel Priority Clear Register  ( /W) */
+         uint32_t  RESERVED0[3];
+  __IO   uint32_t  ERR_CLR;              /*!< Offset: 0x04C Bus Error Clear Register  (R/W) */
+
+} DMA_PL230_TypeDef;
+
+#define PL230_DMA_CHNL_BITS 0
+
+#define DMA_PL230_DMA_STATUS_MSTREN_Pos          0                                                          /*!< DMA_PL230 DMA STATUS: MSTREN Position */
+#define DMA_PL230_DMA_STATUS_MSTREN_Msk          (0x00000001ul << DMA_PL230_DMA_STATUS_MSTREN_Pos)        /*!< DMA_PL230 DMA STATUS: MSTREN Mask */
+
+#define DMA_PL230_DMA_STATUS_STATE_Pos           0                                                          /*!< DMA_PL230 DMA STATUS: STATE Position */
+#define DMA_PL230_DMA_STATUS_STATE_Msk           (0x0000000Ful << DMA_PL230_DMA_STATUS_STATE_Pos)         /*!< DMA_PL230 DMA STATUS: STATE Mask */
+
+#define DMA_PL230_DMA_STATUS_CHNLS_MINUS1_Pos    0                                                          /*!< DMA_PL230 DMA STATUS: CHNLS_MINUS1 Position */
+#define DMA_PL230_DMA_STATUS_CHNLS_MINUS1_Msk    (0x0000001Ful << DMA_PL230_DMA_STATUS_CHNLS_MINUS1_Pos)  /*!< DMA_PL230 DMA STATUS: CHNLS_MINUS1 Mask */
+
+#define DMA_PL230_DMA_STATUS_TEST_STATUS_Pos     0                                                          /*!< DMA_PL230 DMA STATUS: TEST_STATUS Position */
+#define DMA_PL230_DMA_STATUS_TEST_STATUS_Msk     (0x00000001ul << DMA_PL230_DMA_STATUS_TEST_STATUS_Pos)   /*!< DMA_PL230 DMA STATUS: TEST_STATUS Mask */
+
+#define DMA_PL230_DMA_CFG_MSTREN_Pos             0                                                          /*!< DMA_PL230 DMA CFG: MSTREN Position */
+#define DMA_PL230_DMA_CFG_MSTREN_Msk             (0x00000001ul << DMA_PL230_DMA_CFG_MSTREN_Pos)           /*!< DMA_PL230 DMA CFG: MSTREN Mask */
+
+#define DMA_PL230_DMA_CFG_CPCCACHE_Pos           2                                                          /*!< DMA_PL230 DMA CFG: CPCCACHE Position */
+#define DMA_PL230_DMA_CFG_CPCCACHE_Msk           (0x00000001ul << DMA_PL230_DMA_CFG_CPCCACHE_Pos)         /*!< DMA_PL230 DMA CFG: CPCCACHE Mask */
+
+#define DMA_PL230_DMA_CFG_CPCBUF_Pos             1                                                          /*!< DMA_PL230 DMA CFG: CPCBUF Position */
+#define DMA_PL230_DMA_CFG_CPCBUF_Msk             (0x00000001ul << DMA_PL230_DMA_CFG_CPCBUF_Pos)           /*!< DMA_PL230 DMA CFG: CPCBUF Mask */
+
+#define DMA_PL230_DMA_CFG_CPCPRIV_Pos            0                                                          /*!< DMA_PL230 DMA CFG: CPCPRIV Position */
+#define DMA_PL230_DMA_CFG_CPCPRIV_Msk            (0x00000001ul << DMA_PL230_DMA_CFG_CPCPRIV_Pos)          /*!< DMA_PL230 DMA CFG: CPCPRIV Mask */
+
+#define DMA_PL230_CTRL_BASE_PTR_Pos              PL230_DMA_CHNL_BITS + 5                                    /*!< DMA_PL230 STATUS: BASE_PTR Position */
+#define DMA_PL230_CTRL_BASE_PTR_Msk              (0x0FFFFFFFul << DMA_PL230_CTRL_BASE_PTR_Pos)            /*!< DMA_PL230 STATUS: BASE_PTR Mask */
+
+#define DMA_PL230_ALT_CTRL_BASE_PTR_Pos          0                                                          /*!< DMA_PL230 STATUS: MSTREN Position */
+#define DMA_PL230_ALT_CTRL_BASE_PTR_Msk          (0xFFFFFFFFul << DMA_PL230_ALT_CTRL_BASE_PTR_Pos)        /*!< DMA_PL230 STATUS: MSTREN Mask */
+
+#define DMA_PL230_DMA_WAITONREQ_STATUS_Pos       0                                                          /*!< DMA_PL230 DMA_WAITONREQ_STATUS: DMA_WAITONREQ_STATUS Position */
+#define DMA_PL230_DMA_WAITONREQ_STATUS_Msk       (0xFFFFFFFFul << DMA_PL230_DMA_WAITONREQ_STATUS_Pos)     /*!< DMA_PL230 DMA_WAITONREQ_STATUS: DMA_WAITONREQ_STATUS Mask */
+
+#define DMA_PL230_CHNL_SW_REQUEST_Pos            0                                                          /*!< DMA_PL230 CHNL_SW_REQUEST: CHNL_SW_REQUEST Position */
+#define DMA_PL230_CHNL_SW_REQUEST_Msk            (0xFFFFFFFFul << DMA_PL230_CHNL_SW_REQUEST_Pos)          /*!< DMA_PL230 CHNL_SW_REQUEST: CHNL_SW_REQUEST Mask */
+
+#define DMA_PL230_CHNL_USEBURST_SET_Pos          0                                                          /*!< DMA_PL230 CHNL_USEBURST: SET Position */
+#define DMA_PL230_CHNL_USEBURST_SET_Msk          (0xFFFFFFFFul << DMA_PL230_CHNL_USEBURST_SET_Pos)        /*!< DMA_PL230 CHNL_USEBURST: SET Mask */
+
+#define DMA_PL230_CHNL_USEBURST_CLR_Pos          0                                                          /*!< DMA_PL230 CHNL_USEBURST: CLR Position */
+#define DMA_PL230_CHNL_USEBURST_CLR_Msk          (0xFFFFFFFFul << DMA_PL230_CHNL_USEBURST_CLR_Pos)        /*!< DMA_PL230 CHNL_USEBURST: CLR Mask */
+
+#define DMA_PL230_CHNL_REQ_MASK_SET_Pos          0                                                          /*!< DMA_PL230 CHNL_REQ_MASK: SET Position */
+#define DMA_PL230_CHNL_REQ_MASK_SET_Msk          (0xFFFFFFFFul << DMA_PL230_CHNL_REQ_MASK_SET_Pos)        /*!< DMA_PL230 CHNL_REQ_MASK: SET Mask */
+
+#define DMA_PL230_CHNL_REQ_MASK_CLR_Pos          0                                                          /*!< DMA_PL230 CHNL_REQ_MASK: CLR Position */
+#define DMA_PL230_CHNL_REQ_MASK_CLR_Msk          (0xFFFFFFFFul << DMA_PL230_CHNL_REQ_MASK_CLR_Pos)        /*!< DMA_PL230 CHNL_REQ_MASK: CLR Mask */
+
+#define DMA_PL230_CHNL_ENABLE_SET_Pos            0                                                          /*!< DMA_PL230 CHNL_ENABLE: SET Position */
+#define DMA_PL230_CHNL_ENABLE_SET_Msk            (0xFFFFFFFFul << DMA_PL230_CHNL_ENABLE_SET_Pos)          /*!< DMA_PL230 CHNL_ENABLE: SET Mask */
+
+#define DMA_PL230_CHNL_ENABLE_CLR_Pos            0                                                          /*!< DMA_PL230 CHNL_ENABLE: CLR Position */
+#define DMA_PL230_CHNL_ENABLE_CLR_Msk            (0xFFFFFFFFul << DMA_PL230_CHNL_ENABLE_CLR_Pos)          /*!< DMA_PL230 CHNL_ENABLE: CLR Mask */
+
+#define DMA_PL230_CHNL_PRI_ALT_SET_Pos           0                                                          /*!< DMA_PL230 CHNL_PRI_ALT: SET Position */
+#define DMA_PL230_CHNL_PRI_ALT_SET_Msk           (0xFFFFFFFFul << DMA_PL230_CHNL_PRI_ALT_SET_Pos)         /*!< DMA_PL230 CHNL_PRI_ALT: SET Mask */
+
+#define DMA_PL230_CHNL_PRI_ALT_CLR_Pos           0                                                          /*!< DMA_PL230 CHNL_PRI_ALT: CLR Position */
+#define DMA_PL230_CHNL_PRI_ALT_CLR_Msk           (0xFFFFFFFFul << DMA_PL230_CHNL_PRI_ALT_CLR_Pos)         /*!< DMA_PL230 CHNL_PRI_ALT: CLR Mask */
+
+#define DMA_PL230_CHNL_PRIORITY_SET_Pos          0                                                          /*!< DMA_PL230 CHNL_PRIORITY: SET Position */
+#define DMA_PL230_CHNL_PRIORITY_SET_Msk          (0xFFFFFFFFul << DMA_PL230_CHNL_PRIORITY_SET_Pos)        /*!< DMA_PL230 CHNL_PRIORITY: SET Mask */
+
+#define DMA_PL230_CHNL_PRIORITY_CLR_Pos          0                                                          /*!< DMA_PL230 CHNL_PRIORITY: CLR Position */
+#define DMA_PL230_CHNL_PRIORITY_CLR_Msk          (0xFFFFFFFFul << DMA_PL230_CHNL_PRIORITY_CLR_Pos)        /*!< DMA_PL230 CHNL_PRIORITY: CLR Mask */
+
+#define DMA_PL230_ERR_CLR_Pos                    0                                                          /*!< DMA_PL230 ERR: CLR Position */
+#define DMA_PL230_ERR_CLR_Msk                    (0x00000001ul << DMA_PL230_ERR_CLR_Pos)                  /*!< DMA_PL230 ERR: CLR Mask */
+
+
+#define HW32_REG(ADDRESS)  (*((volatile unsigned long  *)(ADDRESS)))
+
+                              /* Maximum to 32 DMA channel */
+                              /* SRAM in example system is 64K bytes */
+#define RAM_ADDRESS_MAX       0x80001fff
+
+typedef struct /* 4 words */
+{
+  volatile unsigned char* SrcEndPointer;
+  volatile unsigned char* DstEndPointer;
+  volatile unsigned long Control;
+  volatile unsigned long unused;
+} dma_pl230_channel_data;
+
+
+typedef struct /* 8 words per channel */
+{ /* was one channel in the example uDMA setup */
+  volatile dma_pl230_channel_data Primary[MAX_NUM_OF_DMA_CHANNELS];
+  volatile dma_pl230_channel_data Alternate[MAX_NUM_OF_DMA_CHANNELS];
+} dma_pl230_data_structure;
+
+
+extern dma_pl230_data_structure *dma_pl230_table;
+
+#define DMA_PL230_DMAC   ((DMA_PL230_TypeDef *)  DMA_PL230_BASE)
+
+#define DMA_PL230_PTR_END(__ptr, __siz, __num) \
+	((unsigned char *) __ptr + ((1<<__siz)*(__num-1)))
+
+#define DMA_PL230_CTRL(__cyc, __siz, __num, __rpwr) \
+	(((unsigned long) __siz << 30)|(__siz << 28)|(__siz << 26)|(__siz << 24)| \
+         (1     << 21)|(1     << 18)|(__rpwr << 14)|(((__num-1)&0x3ff)<<4)| \
+         (1     <<  3)|(__cyc <<  0) )
+
+#define DMA_PL230_CTRL_SRCFIX(__cyc, __siz, __num, __rpwr) \
+	(((unsigned long) __siz << 30)|(__siz << 28)|(0x0c000000UL)|(__siz << 24)| \
+         (1     << 21)|(1     << 18)|(__rpwr << 14)|(((__num-1)&0x3ff)<<4)| \
+         (1     <<  3)|(__cyc <<  0) )
+
+#define DMA_PL230_CTRL_DSTFIX(__cyc, __siz, __num, __rpwr) \
+	((0xc0000000UL)|(__siz << 28)|(__siz << 26)|(__siz << 24)| \
+         (1     << 21)|(1     << 18)|(__rpwr << 14)|(((__num-1)&0x3ff)<<4)| \
+         (1     <<  3)|(__cyc <<  0) )
+
+#define DMA_PL230_MAX_XFERS (0x400)
+
+#define PL230_CTRL_CYCLE_STOP    0
+#define PL230_CTRL_CYCLE_BASIC   1
+#define PL230_CTRL_CYCLE_AUTO    2
+#define PL230_CTRL_CYCLE_PPONG   3
+#define PL230_CTRL_CYCLE_MEM_CHAIN_PRI 4
+#define PL230_CTRL_CYCLE_MEM_CHAIN_ALT 5
+#define PL230_CTRL_CYCLE_DEV_CHAIN_PRI 6
+#define PL230_CTRL_CYCLE_DEV_CHAIN_ALT 7
+
+#define PL230_CTRL_RPWR_1  0
+#define PL230_CTRL_RPWR_2  1
+#define PL230_CTRL_RPWR_4  2
+#define PL230_CTRL_RPWR_8  3
+#define PL230_CTRL_RPWR_16 4
+
+#define PL230_XFER_B    0
+#define PL230_XFER_H    1
+#define PL230_XFER_W    2
+
+/* --------------------------------------------------------------- */
+/*  Initialize DMA data structure                                  */
+/* --------------------------------------------------------------- */
+void dma_pl230_data_struct_init(void);
+
+/* --------------------------------------------------------------- */
+/*  Initialize DMA PL230                                           */
+/* --------------------------------------------------------------- */
+void dma_pl230_init_dbg(unsigned int chan_mask);
+void dma_pl230_init(unsigned int chan_mask);
+
+/* --------------------------------------------------------------- */
+/*  Check DMA PL230 DMA channel(s) active (return 0 when finishes) */
+/* --------------------------------------------------------------- */
+unsigned int dma_pl230_channel_active(unsigned int chan_mask);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __DMA_PL230_MCU_H */
+
diff --git a/system/testcodes/aes128_tests/makefile b/system/testcodes/aes128_tests/makefile
new file mode 100644
index 0000000..af5eb14
--- /dev/null
+++ b/system/testcodes/aes128_tests/makefile
@@ -0,0 +1,263 @@
+#-----------------------------------------------------------------------------
+# The confidential and proprietary information contained in this file may
+# only be used by a person authorised under and to the extent permitted
+# by a subsisting licensing agreement from Arm Limited or its affiliates.
+#
+#            (C) COPYRIGHT 2010-2013 Arm Limited or its affiliates.
+#                ALL RIGHTS RESERVED
+#
+# This entire notice must be reproduced on all copies of this file
+# and copies of this file may only be made by a person if such person is
+# permitted to do so under the terms of a subsisting license agreement
+# from Arm Limited or its affiliates.
+#
+#      SVN Information
+#
+#      Checked In          : $Date: 2017-10-10 15:55:38 +0100 (Tue, 10 Oct 2017) $
+#
+#      Revision            : $Revision: 371321 $
+#
+#      Release Information : Cortex-M System Design Kit-r1p1-00rel0
+#-----------------------------------------------------------------------------
+#
+# Cortex-M System Design Kit software compilation make file
+#
+#-----------------------------------------------------------------------------
+#
+#  Configurations
+#
+# Choose the core instantiated, can be
+#  - CORTEX_M0
+#  - CORTEX_M0PLUS
+CPU_PRODUCT = CORTEX_M0
+
+# Shared software directory
+SOFTWARE_DIR = $(NANOSOC_TECH_DIR)/software
+CMSIS_DIR    = $(SOFTWARE_DIR)/cmsis
+CORE_DIR     = $(CMSIS_DIR)/CMSIS/Include
+
+ifeq ($(CPU_PRODUCT),CORTEX_M0PLUS)
+  DEVICE_DIR   = $(CMSIS_DIR)/Device/ARM/CMSDK_CM0plus
+else
+  DEVICE_DIR   = $(CMSIS_DIR)/Device/ARM/CMSDK_CM0
+endif
+
+# Program file
+TESTNAME     = aes128_tests
+
+# Endian Option
+COMPILE_BIGEND = 0
+
+# Configuration
+ifeq ($(CPU_PRODUCT),CORTEX_M0PLUS)
+  USER_DEFINE    = -DCORTEX_M0PLUS
+else
+  USER_DEFINE    = -DCORTEX_M0
+endif
+
+DEPS_LIST       = makefile
+
+# Tool chain : ds5 / gcc / keil
+TOOL_CHAIN      = ds5
+
+ifeq ($(TOOL_CHAIN),ds5)
+  ifeq ($(CPU_PRODUCT),CORTEX_M0PLUS)
+    CPU_TYPE        = --cpu Cortex-M0plus
+  else
+    CPU_TYPE        = --cpu Cortex-M0
+  endif
+endif
+
+ifeq ($(TOOL_CHAIN),gcc)
+  ifeq ($(CPU_PRODUCT),CORTEX_M0PLUS)
+    CPU_TYPE        = -mcpu=cortex-m0plus
+  else
+    CPU_TYPE        = -mcpu=cortex-m0
+  endif
+endif
+
+# Startup code directory for DS-5
+ifeq ($(TOOL_CHAIN),ds5)
+ STARTUP_DIR  = $(DEVICE_DIR)/Source/ARM
+endif
+
+# Startup code directory for gcc
+ifeq ($(TOOL_CHAIN),gcc)
+ STARTUP_DIR  = $(DEVICE_DIR)/Source/GCC
+endif
+
+ifeq ($(CPU_PRODUCT),CORTEX_M0PLUS)
+  STARTUP_FILE = startup_CMSDK_CM0plus
+  SYSTEM_FILE  = system_CMSDK_CM0plus
+else
+  STARTUP_FILE = startup_CMSDK_CM0
+  SYSTEM_FILE  = system_CMSDK_CM0
+endif
+
+# ---------------------------------------------------------------------------------------
+# DS-5 options
+
+# MicroLIB option
+COMPILE_MICROLIB = 0
+
+# Small Multiply (Cortex-M0/M0+ has small multiplier option)
+COMPILE_SMALLMUL = 0
+
+#ARM_CC_OPTIONS   = -c -O3 -g -Otime -I $(DEVICE_DIR)/Include  -I $(CORE_DIR) \
+#		   -I $(SOFTWARE_DIR)/common/retarget $(USER_DEFINE)
+#ARM_ASM_OPTIONS  = -g
+#ARM_LINK_OPTIONS = "--keep=$(STARTUP_FILE).o(RESET)" "--first=$(STARTUP_FILE).o(RESET)" \
+#		   --rw_base 0x30000000 --ro_base 0x00000000 --map  --info sizes
+
+ARM_CC_OPTIONS   = -c -O3 -Ospace -I $(DEVICE_DIR)/Include  -I $(CORE_DIR) \
+		   -I $(SOFTWARE_DIR)/common/retarget $(USER_DEFINE)
+ARM_ASM_OPTIONS  = 
+ARM_LINK_OPTIONS = "--keep=$(STARTUP_FILE).o(RESET)" "--first=$(STARTUP_FILE).o(RESET)" \
+		   --no_debug --rw_base 0x30000000 --ro_base 0x00000000 --map  --info sizes
+
+ifeq ($(COMPILE_BIGEND),1)
+ # Big Endian
+ ARM_CC_OPTIONS   += --bigend
+ ARM_ASM_OPTIONS  += --bigend
+ ARM_LINK_OPTIONS += --be8
+endif
+
+ifeq ($(COMPILE_MICROLIB),1)
+ # MicroLIB
+ ARM_CC_OPTIONS   += --library_type=microlib
+ ARM_ASM_OPTIONS  += --library_type=microlib --pd "__MICROLIB SETA 1"
+ ARM_LINK_OPTIONS += --library_type=microlib
+endif
+
+ifeq ($(COMPILE_SMALLMUL),1)
+ # In Cortex-M0, small multiply takes 32 cycles
+ ARM_CC_OPTIONS   += --multiply_latency=32
+endif
+
+# ---------------------------------------------------------------------------------------
+# gcc options
+
+GNG_CC      = arm-none-eabi-gcc
+GNU_OBJDUMP = arm-none-eabi-objdump
+GNU_OBJCOPY = arm-none-eabi-objcopy
+
+LINKER_SCRIPT_PATH = $(SOFTWARE_DIR)/common/scripts
+LINKER_SCRIPT = $(LINKER_SCRIPT_PATH)/cmsdk_cm0.ld
+
+GNU_CC_FLAGS = -g -O3 -mthumb $(CPU_TYPE)
+
+ifeq ($(COMPILE_BIGEND),1)
+ # Big Endian
+ GNU_CC_FLAGS   += -mbig-endian
+endif
+
+# ---------------------------------------------------------------------------------------
+all: all_$(TOOL_CHAIN)
+
+# ---------------------------------------------------------------------------------------
+# DS-5
+all_ds5 : $(TESTNAME).hex $(TESTNAME).lst $(TESTNAME).bin
+
+$(TESTNAME).o :  $(TESTNAME).c $(DEPS_LIST)
+	armcc $(ARM_CC_OPTIONS) $(CPU_TYPE) $< -o  $@
+
+dma_pl230_driver.o :  dma_pl230_driver.c $(DEPS_LIST)
+	armcc $(ARM_CC_OPTIONS) $(CPU_TYPE) $< -o $@
+
+$(SYSTEM_FILE).o : $(DEVICE_DIR)/Source/$(SYSTEM_FILE).c $(DEPS_LIST)
+	armcc $(ARM_CC_OPTIONS) $(CPU_TYPE) $< -o  $@
+
+retarget.o : $(SOFTWARE_DIR)/common/retarget/retarget.c $(DEPS_LIST)
+	armcc $(ARM_CC_OPTIONS) $(CPU_TYPE) $< -o  $@
+
+uart_stdout.o : $(SOFTWARE_DIR)/common/retarget/uart_stdout.c $(DEPS_LIST)
+	armcc $(ARM_CC_OPTIONS) $(CPU_TYPE) $< -o  $@
+
+$(STARTUP_FILE).o : $(STARTUP_DIR)/$(STARTUP_FILE).s $(DEPS_LIST)
+	armasm $(ARM_ASM_OPTIONS) $(CPU_TYPE) $< -o  $@
+
+$(TESTNAME).ELF : $(TESTNAME).o dma_pl230_driver.o $(SYSTEM_FILE).o $(STARTUP_FILE).o retarget.o uart_stdout.o
+	armlink $(ARM_LINK_OPTIONS) -o $@ $(TESTNAME).o dma_pl230_driver.o $(SYSTEM_FILE).o $(STARTUP_FILE).o retarget.o uart_stdout.o
+
+$(TESTNAME).hex : $(TESTNAME).ELF
+	fromelf --vhx --8x1 $< --output $@
+	fromelf --vhx --8x1 $< --output ../../image.hex
+
+$(TESTNAME).lst : $(TESTNAME).ELF
+	fromelf -c -d -e -s -z -v $< --output $@
+
+$(TESTNAME).bin : $(TESTNAME).ELF
+	fromelf --bin $< --output $@
+
+
+# ---------------------------------------------------------------------------------------
+# gcc
+all_gcc:
+	$(GNG_CC) $(GNU_CC_FLAGS) $(STARTUP_DIR)/$(STARTUP_FILE).s \
+		$(TESTNAME).c \
+		$(SOFTWARE_DIR)/common/retarget/retarget.c \
+		$(SOFTWARE_DIR)/common/retarget/uart_stdout.c \
+		$(DEVICE_DIR)/Source/$(SYSTEM_FILE).c \
+		-I $(DEVICE_DIR)/Include -I $(CORE_DIR) \
+                -I $(SOFTWARE_DIR)/common/retarget  \
+		-L $(LINKER_SCRIPT_PATH) \
+		-D__STACK_SIZE=0x200 \
+		-D__HEAP_SIZE=0x1000 \
+		$(USER_DEFINE) -T $(LINKER_SCRIPT) -o $(TESTNAME).o
+	# Generate disassembly code
+	$(GNU_OBJDUMP) -S $(TESTNAME).o > $(TESTNAME).lst
+	# Generate binary file
+	$(GNU_OBJCOPY) -S $(TESTNAME).o -O binary $(TESTNAME).bin
+	# Generate hex file
+	$(GNU_OBJCOPY) -S $(TESTNAME).o -O verilog $(TESTNAME).hex
+
+# Note:
+# If the version of object copy you are using does not support verilog hex file output,
+# you can generate the hex file from binary file using the following command
+#       od -v -A n -t x1 --width=1  $(TESTNAME).bin > $(TESTNAME).hex
+
+
+# ---------------------------------------------------------------------------------------
+# Keil MDK
+
+all_keil:
+	@echo "Please compile your project code and press ENTER when ready"
+	@read dummy
+
+# ---------------------------------------------------------------------------------------
+# Binary
+
+all_bin: $(TESTNAME).bin
+	# Generate hex file from binary
+	od -v -A n -t x1 --width=1  $(TESTNAME).bin > $(TESTNAME).hex
+
+# ---------------------------------------------------------------------------------------
+# Clean
+clean :
+	@rm -rf *.o
+	@if [ -e $(TESTNAME).hex ] ; then \
+	  rm -rf $(TESTNAME).hex ; \
+	fi
+	@if [ -e $(TESTNAME).lst ] ; then \
+	  rm -rf $(TESTNAME).lst ; \
+	fi
+	@if [ -e $(TESTNAME).ELF ] ; then \
+	  rm -rf $(TESTNAME).ELF ; \
+	fi
+	@if [ -e $(TESTNAME).bin ] ; then \
+	  rm -rf $(TESTNAME).bin ; \
+	fi
+	@rm -rf *.crf
+	@rm -rf *.plg
+	@rm -rf *.tra
+	@rm -rf *.htm
+	@rm -rf *.map
+	@rm -rf *.dep
+	@rm -rf *.d
+	@rm -rf *.lnp
+	@rm -rf *.bak
+	@rm -rf *.lst
+	@rm -rf *.axf
+	@rm -rf *.sct
+	@rm -rf *.__i
+	@rm -rf *._ia
diff --git a/system/verif/verilog/nanosoc_tb.v b/system/verif/verilog/nanosoc_tb.v
index a432e05..2117f35 100644
--- a/system/verif/verilog/nanosoc_tb.v
+++ b/system/verif/verilog/nanosoc_tb.v
@@ -37,6 +37,8 @@
 //
 `timescale 1ns/1ps
 
+`define CORTEX_M0
+
 module nanosoc_tb;
 
   wire        XTAL1;   // crystal pin 1
@@ -229,7 +231,7 @@ reg baud_clk_del;
   wire uart_clk = (FASTMODE) ? PCLK : baud_clk; //(baud_clk & !baud_clk_del);
 
 
-  nanosoc_uart_capture  #(.LOGFILENAME("uart2.log"))
+  nanosoc_uart_capture  #(.LOGFILENAME("logs/uart2.log"))
     u_nanosoc_uart_capture(
     .RESETn               (NRST),
     .CLK                  (uart_clk), //PCLK),
@@ -317,7 +319,7 @@ nanosoc_ft1248x1_to_axi_streamio_v1_0
   );
 
 nanosoc_axi_stream_io_8_rxd_to_file
-  #(.RXDFILENAME("ft1248_out.log"))
+  #(.RXDFILENAME("logs/ft1248_out.log"))
   u_nanosoc_axi_stream_io_8_rxd_to_file
   (
   .aclk         (XTAL1),
@@ -358,7 +360,7 @@ nanosoc_ft1248x1_track
   .FTDI_IP2UART_o       (ft_txd2uart)   // Transmitted data to UART capture
   );
 
-  nanosoc_uart_capture  #(.LOGFILENAME("ft1248_op.log"))
+  nanosoc_uart_capture  #(.LOGFILENAME("logs/ft1248_op.log"))
     u_nanosoc_uart_capture1(
     .RESETn               (NRST),
     .CLK                  (ft_clk2uart),
@@ -368,7 +370,7 @@ nanosoc_ft1248x1_track
     .AUXCTRL              ()
   );
 
-  nanosoc_uart_capture  #(.LOGFILENAME("ft1248_ip.log"))
+  nanosoc_uart_capture  #(.LOGFILENAME("logs/ft1248_ip.log"))
     u_nanosoc_uart_capture2(
     .RESETn               (NRST),
     .CLK                  (ft_clk2uart),
@@ -453,7 +455,7 @@ nanosoc_ft1248x1_track
           .SE                             (`ARM_CM0IK_PATH.SE));
 
 `define ARM_CM0IK_TRACK u_cortexm0_track
-  cm0_tarmac #(.LOGFILENAME("tarmac0.log"))
+  cm0_tarmac #(.LOGFILENAME("logs/tarmac0.log"))
     u_tarmac_track
       (.enable_i      (1'b1),
 
@@ -559,7 +561,7 @@ nanosoc_ft1248x1_track
 
 `define DMAC_TRACK_PATH u_track_pl230_udma
 
-  nanosoc_dma_log_to_file #(.FILENAME("dma230.log"),.NUM_CHNLS(2),.NUM_CHNL_BITS(1),.TIMESTAMP(1))
+  nanosoc_dma_log_to_file #(.FILENAME("logs/dma230.log"),.NUM_CHNLS(2),.NUM_CHNL_BITS(1),.TIMESTAMP(1))
     u_nanosoc_dma_log_to_file (
     .hclk          (`DMAC_TRACK_PATH.hclk),
     .hresetn       (`DMAC_TRACK_PATH.hresetn),
@@ -595,33 +597,33 @@ nanosoc_ft1248x1_track
  // Tracking AES logging support
  // --------------------------------------------------------------------------------
 
-// `define AES_PATH u_nanosoc_chip_pads.u_nanosoc_chip.u_exp_aes128
-
-//   aes128_log_to_file #(.FILENAME("aes128.log"),.TIMESTAMP(1))
-//     u_aes_log_to_file (
-//     .ahb_hclk        (`AES_PATH.ahb_hclk      ),
-//     .ahb_hresetn     (`AES_PATH.ahb_hresetn   ),
-//     .ahb_hsel        (`AES_PATH.ahb_hsel      ),
-//     .ahb_haddr16     (`AES_PATH.ahb_haddr16   ),
-//     .ahb_htrans      (`AES_PATH.ahb_htrans    ),
-//     .ahb_hwrite      (`AES_PATH.ahb_hwrite    ),
-//     .ahb_hsize       (`AES_PATH.ahb_hsize     ),
-//     .ahb_hprot       (`AES_PATH.ahb_hprot     ),
-//     .ahb_hwdata      (`AES_PATH.ahb_hwdata    ),
-//     .ahb_hready      (`AES_PATH.ahb_hready    ),
-//     .ahb_hrdata      (`AES_PATH.ahb_hrdata    ),
-//     .ahb_hreadyout   (`AES_PATH.ahb_hreadyout ),
-//     .ahb_hresp       (`AES_PATH.ahb_hresp     ),
-//     .drq_ipdma128    (`AES_PATH.drq_ipdma128  ),
-//     .dlast_ipdma128  (`AES_PATH.dlast_ipdma128),
-//     .drq_opdma128    (`AES_PATH.drq_opdma128  ),
-//     .dlast_opdma128  (`AES_PATH.dlast_opdma128),
-//     .irq_key128      (`AES_PATH.irq_key128    ),
-//     .irq_ip128       (`AES_PATH.irq_ip128     ),
-//     .irq_op128       (`AES_PATH.irq_op128     ),
-//     .irq_error       (`AES_PATH.irq_error     ),
-//     .irq_merged      (`AES_PATH.irq_merged    )
-//   );
+ `define AES_PATH u_nanosoc_chip_pads.u_nanosoc_chip.u_nanosoc_exp_wrapper.u_exp_aes128
+
+   aes128_log_to_file #(.FILENAME("logs/aes128.log"),.TIMESTAMP(1))
+     u_aes_log_to_file (
+     .ahb_hclk        (`AES_PATH.ahb_hclk      ),
+     .ahb_hresetn     (`AES_PATH.ahb_hresetn   ),
+     .ahb_hsel        (`AES_PATH.ahb_hsel      ),
+     .ahb_haddr16     (`AES_PATH.ahb_haddr16   ),
+     .ahb_htrans      (`AES_PATH.ahb_htrans    ),
+     .ahb_hwrite      (`AES_PATH.ahb_hwrite    ),
+     .ahb_hsize       (`AES_PATH.ahb_hsize     ),
+     .ahb_hprot       (`AES_PATH.ahb_hprot     ),
+     .ahb_hwdata      (`AES_PATH.ahb_hwdata    ),
+     .ahb_hready      (`AES_PATH.ahb_hready    ),
+     .ahb_hrdata      (`AES_PATH.ahb_hrdata    ),
+     .ahb_hreadyout   (`AES_PATH.ahb_hreadyout ),
+     .ahb_hresp       (`AES_PATH.ahb_hresp     ),
+     .drq_ipdma128    (`AES_PATH.drq_ipdma128  ),
+     .dlast_ipdma128  (`AES_PATH.dlast_ipdma128),
+     .drq_opdma128    (`AES_PATH.drq_opdma128  ),
+     .dlast_opdma128  (`AES_PATH.dlast_opdma128),
+     .irq_key128      (`AES_PATH.irq_key128    ),
+     .irq_ip128       (`AES_PATH.irq_ip128     ),
+     .irq_op128       (`AES_PATH.irq_op128     ),
+     .irq_error       (`AES_PATH.irq_error     ),
+     .irq_merged      (`AES_PATH.irq_merged    )
+   );
 
 
  // --------------------------------------------------------------------------------
-- 
GitLab