UPDATE: add ciphering mechanism to SRAM wrapper
diff --git a/verilog/rtl/sram/sram_wb_wrapper.sv b/verilog/rtl/sram/sram_wb_wrapper.sv
index 9b5769f..fb17ed0 100644
--- a/verilog/rtl/sram/sram_wb_wrapper.sv
+++ b/verilog/rtl/sram/sram_wb_wrapper.sv
@@ -19,6 +19,8 @@
 //          initial version
 //    0.2 - 16 March 2022, Sukru Uzun
 //          remove SRAM design
+//    0.3 - 20 March 2022, Emre Goncu
+//          adding ciphering mechanism
 //-----------------------------------------------------------------------------
 
 module sram_wb_wrapper #(
@@ -26,80 +28,363 @@
   parameter SRAM_DATA_WD = 32
 ) (
 `ifdef USE_POWER_PINS
-  input  wire                      vccd1      , // User area 1 1.8V supply
-  input  wire                      vssd1      , // User area 1 digital ground
+  input  wire                      vccd1           , // User area 1 1.8V supply
+  input  wire                      vssd1           , // User area 1 digital ground
 `endif
-  input  wire                      rst        ,
+  input  wire                      rst             ,
   // Wishbone Interface
-  input  wire                      wb_clk_i   , // System clock
-  input  wire                      wb_cyc_i   , // strobe/request
-  input  wire                      wb_stb_i   , // strobe/request
-  input  wire [  SRAM_ADDR_WD-1:0] wb_adr_i   , // address
-  input  wire                      wb_we_i    , // write
-  input  wire [  SRAM_DATA_WD-1:0] wb_dat_i   , // data output
-  input  wire [SRAM_DATA_WD/8-1:0] wb_sel_i   , // byte enable
-  // output  wire  [SRAM_DATA_WD-1:0]    wb_dat_o,  // data input
-  output reg                       wb_ack_o   , // acknowlegement
+  input  wire                      wb_clk_i        , // System clock
+  input  wire                      wb_cyc_i        , // strobe/request
+  input  wire                      wb_stb_i        , // strobe/request
+  input  wire [  SRAM_ADDR_WD-1:0] wb_adr_i        , // address
+  input  wire                      wb_we_i         , // write
+  input  wire [  SRAM_DATA_WD-1:0] wb_dat_i        , // data output
+  input  wire [SRAM_DATA_WD/8-1:0] wb_sel_i        , // byte enable
+  output wire [  SRAM_DATA_WD-1:0] wb_dat_o        , // data input
+  output reg                       wb_ack_o        , // acknowlegement
   // SRAM Interface
   // Port A
-  output wire                      sram_csb_a ,
-  output wire [  SRAM_ADDR_WD-1:0] sram_addr_a,
+  output wire                      sram_csb_a      ,
+  output wire [  SRAM_ADDR_WD-1:0] sram_addr_a     ,
+  input  wire [  SRAM_DATA_WD-1:0] sram_dout_a     ,
   // Port B
-  output wire                      sram_csb_b ,
-  output wire                      sram_web_b ,
-  output wire [SRAM_DATA_WD/8-1:0] sram_mask_b,
-  output wire [  SRAM_ADDR_WD-1:0] sram_addr_b,
-  output wire [  SRAM_DATA_WD-1:0] sram_din_b
+  output reg                       sram_csb_b      ,
+  output reg                       sram_web_b      ,
+  output reg  [SRAM_DATA_WD/8-1:0] sram_mask_b     ,
+  output reg  [  SRAM_ADDR_WD-1:0] sram_addr_b     ,
+  output reg  [  SRAM_DATA_WD-1:0] sram_din_b      ,
+  input  wire [              31:0] trng_i          ,
+  input  wire                      alarm
 );
 
-// // Port A
-// wire                      sram_clk_a;
-// wire                      sram_csb_a;
-// wire [SRAM_ADDR_WD-1:0]   sram_addr_a;
-// wire [SRAM_DATA_WD-1:0]   sram_dout_a;
 
-// // Port B
-// wire                      sram_clk_b;
-// wire                      sram_csb_b;
-// wire                      sram_web_b;
-// wire [SRAM_DATA_WD/8-1:0] sram_mask_b;
-// wire [SRAM_ADDR_WD-1:0]   sram_addr_b;
-// wire [SRAM_DATA_WD-1:0]   sram_din_b;
+  logic         master_key_en        ;
+  logic [ 31:0] master_key_array[3:0];
+  logic [127:0] master_key           ;
+  logic [  1:0] counter              ;
+  logic [  4:0] trng_count           ;
 
-// Memory Write Port
-// assign sram_clk_b  = wb_clk_i;
-  assign sram_csb_b  = !wb_stb_i;
-  assign sram_web_b  = !wb_we_i;
-  assign sram_mask_b = wb_sel_i;
-  assign sram_addr_b = wb_adr_i;
-  assign sram_din_b  = wb_dat_i;
+  assign master_key = {master_key_array[0], master_key_array[1], master_key_array[2], master_key_array[3]};
 
-// Memory Read Port
-// assign sram_clk_a  = wb_clk_i;
-  assign sram_csb_a  = (wb_stb_i == 1'b1 && wb_we_i == 1'b0 && wb_cyc_i == 1'b1) ? 1'b0 : 1'b1;
-  assign sram_addr_a = wb_adr_i;
+  assign master_key_en = rst ? 1'b0 :
+    (alarm || ((wb_adr_i == 32'd0) && wb_cyc_i && wb_stb_i && wb_we_i)) ? 1'b1 : 1'b0;
 
-// assign wb_dat_o    = sram_dout_a;
 
-// sky130_sram_1kbyte_1rw1r_32x256_8 u_sram1_1kb(
-// `ifdef USE_POWER_PINS
-//     .vccd1 (vccd1), // User area 1 1.8V supply
-//     .vssd1 (vssd1), // User area 1 digital ground
-// `endif
-//     // Port 0: RW
-//     .clk0     (sram_clk_b),
-//     .csb0     (sram_csb_b),
-//     .web0     (sram_web_b),
-//     .wmask0   (sram_mask_b),
-//     .addr0    (sram_addr_b),
-//     .din0     (sram_din_b),
-//     .dout0    (),   // dont read from Port B
-//     // Port 1: R
-//     .clk1     (sram_clk_a),
-//     .csb1     (sram_csb_a),
-//     .addr1    (sram_addr_a),
-//     .dout1    (sram_dout_a)
-// );
+
+  always @(posedge wb_clk_i) begin
+    if(rst)
+      begin
+        master_key_array[0] <= 32'd0;
+        master_key_array[1] <= 32'd0;
+        master_key_array[2] <= 32'd0;
+        master_key_array[3] <= 32'd0;
+        counter             <= 2'd0;
+        trng_count          <= 5'd0;
+      end
+    else
+      begin
+        if(master_key_en)
+          begin
+            if(wb_dat_i)
+              begin
+                master_key_array[counter] <= wb_dat_i;
+                counter                   <= counter + 2'd1;
+              end
+            else
+              begin
+                if(trng_count == 5'd0)
+                  begin
+                    master_key_array[counter] <= trng_in;
+                    counter                   <= counter + 2'd1;
+                  end
+                trng_count <= trng_count + 5'd1;
+              end
+          end
+      end
+
+  end
+
+
+  assign wb_dat_o = (wb_adr_i == 9'd1 && wb_cyc_i && wb_stb_i && !wb_we_i) ? SRAM_data_reg :
+    (wb_adr_i == 9'd2 && wb_cyc_i && wb_stb_i && !wb_we_i) ? {30'd0,rd_busy, wr_busy} : 'h0;
+
+
+
+
+
+
+
+  /* FSM for reading ciphered Data from SRAM */
+  /*******************************************/
+
+  localparam INIT           = 0;
+  localparam READ_DATA      = 1;
+  localparam WAIT_AES_READY = 2;
+  localparam WAIT_AES_DONE  = 3;
+  localparam WR_TO_SRAM     = 4;
+
+
+  logic [ 1:0] state_next_rd, state_reg_rd;
+  logic [ 8:0] sram_addr_a_next, sram_addr_a_reg;
+  logic [ 2:0] read_count_next, read_count_reg;
+  logic [31:0] read_data_next  [3:0];
+  logic [31:0] read_data_reg   [3:0];
+  logic [31:0] SRAM_data_next, SRAM_data_reg;
+
+  logic         read       ;
+  logic         aes_init_rd;
+  logic         enc_dec_rd ;
+  logic         aes_next_rd;
+  logic [127:0] aes_ptx_rd ;
+  logic         rd_busy    ;
+  logic         aes_ready  ;
+  logic         aes_valid  ;
+  logic [127:0] aes_ctx    ;
+  always @(posedge wb_clk_i )
+    begin
+      if(reset)
+        begin
+          state_reg_rd     <= 2'd0;
+          sram_addr_a_reg  <= 9'd0;
+          read_data_reg[0] <= 32'd0;
+          read_data_reg[1] <= 32'd0;
+          read_data_reg[2] <= 32'd0;
+          read_data_reg[3] <= 32'd0;
+          SRAM_data_reg    <= 32'd0;
+          read_count_reg   <= 3'd0;
+        end
+      else
+        begin
+          state_reg_rd     <= state_next_rd;
+          sram_addr_a_reg  <= sram_addr_a_next;
+          read_data_reg[0] <= read_data_next[0];
+          read_data_reg[1] <= read_data_next[1];
+          read_data_reg[2] <= read_data_next[2];
+          read_data_reg[3] <= read_data_next[3];
+          SRAM_data_reg    <= SRAM_data_next   ;
+          read_count_reg   <= read_count_next ;
+        end
+
+    end
+
+  assign read = (wb_stb_i == 1'b1 && wb_we_i == 1'b0 && wb_cyc_i == 1'b1 && !wr_busy) ? 1'b0 : 1'b1;
+  always @(*)
+  begin
+    //default assignments
+    rd_busy           = 1'b1;
+    state_next_rd     = state_reg_rd;
+    sram_addr_a_next  = sram_addr_a_reg;
+    sram_csb_a        = 1'b1;
+    read_count_next   = read_count_reg;
+    read_data_next[0] = read_data_reg[0];
+    read_data_next[1] = read_data_reg[1];
+    read_data_next[2] = read_data_reg[2];
+    read_data_next[3] = read_data_reg[3];
+    SRAM_data_next    = SRAM_data_reg;
+    aes_next_rd       = 1'b0;
+    enc_dec_rd        = 1'b0;
+    aes_init_rd       = 1'b0;
+
+
+    case (state_reg_rd)
+      INIT :
+        begin
+          if(read)
+            begin
+              sram_addr_a_next = wb_adr_i;
+              state_next_rd    = READ_DATA;
+            end
+          else
+            rd_busy = 1'b0;
+        end
+      READ_DATA :
+        begin
+          if(read_count_reg < 3'd5)
+            begin
+              sram_addr_a_next = sram_addr_a_reg + 1;
+              sram_csb_a       = 1'b0;
+              read_count_next  = read_count_reg + 1;
+              if(read_count_reg > 3'd0)
+                read_data_next[read_count-1] = sram_dout_a;
+            end
+          else
+            begin
+              state_next_rd   = WAIT_AES_READY;
+              aes_init_rd     = 1'b1;
+              enc_dec_rd      = 1'b0;
+              read_count_next = 3'd0;
+            end
+        end
+      WAIT_AES_READY :
+        begin
+          if(aes_ready)
+            begin
+              state_next_rd = WAIT_AES_DONE;
+              aes_next_rd   = 1'b1;
+              aes_ptx_rd    = read_data_reg;
+            end
+        end
+      WRITE_AES_DONE :
+        begin
+          if(aes_valid)
+            begin
+              rd_busy        = 1'b0;
+              state_next_rd  = INIT;
+              SRAM_data_next = aes_ctx[31:0];
+            end
+        end
+    endcase
+  end
+  /* FSM for reading ciphered Data from SRAM */
+  /*******************************************/
+
+
+
+
+
+  /* FSM for writing ciphered Data to SRAM */
+  /*******************************************/
+
+  logic [ 2:0] state_next_wr, state_reg_wr;
+  logic [ 8:0] sram_addr_b_next, sram_addr_b_reg;
+  logic [ 2:0] wr_count_next, wr_count_reg;
+  logic [31:0] wr_data_next, wr_data_reg;
+  logic [ 8:0] wr_addr_next, wr_addr_reg;
+
+
+  logic        write           ;
+  logic        aes_init_wr     ;
+  logic        enc_dec_wr      ;
+  logic        aes_next_wr     ;
+  logic        aes_ptx_wr      ;
+  logic        wr_busy         ;
+  logic [31:0] aes_ctx_wr [3:0];
+
+  assign aes_ctx_wr[0] = aex_ctx[31:0];
+  assign aes_ctx_wr[1] = aex_ctx[63:32];
+  assign aes_ctx_wr[2] = aex_ctx[95:64];
+  assign aes_ctx_wr[3] = aex_ctx[127:96];
+
+  assign write = (wb_stb_i == 1'b1 && wb_we_i == 1'b1 && wb_cyc_i == 1'b1 && !rd_busy) ? 1'b0 : 1'b1;
+
+  always @(posedge wb_clk_i )
+    begin
+      if(reset)
+        begin
+          state_reg_wr <= INIT;
+          wr_data_reg  <= 32'd0;
+          wr_addr_reg  <= 9'd0;
+          wr_count_reg <= 3'd0;
+        end
+      else
+        begin
+          state_reg_wr <= state_next_wr ;
+          wr_data_reg  <= wr_data_next  ;
+          wr_addr_reg  <= wr_addr_next  ;
+          wr_count_reg <= wr_count_next ;
+        end
+    end
+
+
+
+  always @(*)
+    begin
+      //default assignments
+      wr_busy       = 1'b1;
+      state_next_wr = state_reg_wr;
+      sram_addr_b   = 9'd0;
+      sram_csb_b    = 1'b1;
+      sram_mask_b   = 4'h0;
+      wr_count_next = wr_count_reg;
+      aes_next_wr   = 1'b0;
+      enc_dec_wr    = 1'b0;
+      aes_init_wr   = 1'b0;
+      wr_data_next  = wr_data_reg;
+      wr_addr_next  = wr_addr_reg;
+
+      case (state_reg_rd)
+        INIT :
+          begin
+            if(write)
+              begin
+                aes_init_wr   = 1'b1;
+                enc_dec_wr    = 1'b1;
+                state_next_wr = WAIT_AES_READY;
+                wr_data_next  = wb_dat_i;
+                wr_addr_next  = wb_adr_i;
+              end
+            else
+              wr_busy = 1'b0;
+          end
+        WAIT_AES_READY :
+          begin
+            if(aes_ready)
+              begin
+                state_next_wr = WAIT_AES_DONE;
+                aes_next_wr   = 1'b1;
+                aes_ptx_wr    = wr_data_reg;
+              end
+          end
+        WRITE_AES_DONE :
+          begin
+            if(aes_valid)
+              begin
+                state_next_wr = WR_TO_SRAM;
+                sram_addr_b   = wr_addr_reg;
+                sram_din_b    = aes_ctx_wr[wr_count_reg];
+                sram_csb_b    = 1'b0;
+                sram_web_b    = 1'b0;
+                sram_mask_b   = 4'hF;
+                wr_count_next = wr_count_reg + 1;
+              end
+          end
+        WR_TO_SRAM :
+          begin
+            if(wr_count_reg < 4)
+              begin
+                sram_addr_b   = wr_addr_reg + wr_count_reg;
+                sram_din_b    = aes_ctx_wr[wr_count_reg];
+                sram_csb_b    = 1'b0;
+                sram_web_b    = 1'b0;
+                sram_mask_b   = 4'hF;
+                wr_count_next = wr_count_reg + 1;
+              end
+            else
+              begin
+                wr_busy       = 1'b0;
+                wr_count_next = 3'd0;
+                state_next_wr = INIT;
+              end
+          end
+
+
+      endcase
+    end
+  /* FSM for writing ciphered Data to SRAM */
+  /*******************************************/
+
+  logic         aes_init = (write && !read) ? aes_init_wr : (!write && read) ? aes_init_rd : 'h0;
+  logic         aes_next = (write && !read) ? aes_next_wr : (!write && read) ? aes_next_rd : 'h0;
+  logic [127:0] aes_ptx  = (write && !read) ? aes_ptx_wr : (!write && read) ? aes_ptx_rd : 'h0  ;
+  logic         enc_dec  = (write && !read) ? enc_dec_wr : (!write && read) ? enc_dec_rd : 'h0  ;
+
+
+  aes_core core (
+    .clk         (wb_clk_i            ),
+    .reset_n     (~rst                ),
+    
+    .encdec      (enc_dec             ),
+    .init        (aes_init            ),
+    .next        (aes_next            ),
+    .ready       (aes_ready           ),
+    
+    .key         ({128'd0, master_key}),
+    .keylen      (2'd0                ),
+    
+    .block       (aes_ptx             ),
+    .result      (aes_ctx             ),
+    .result_valid(aes_valid           )
+  );
 
 // Generate once cycle delayed ACK to get the data from SRAM
   always @(posedge wb_clk_i)