Add files via upload
diff --git a/Verilog_Code/clock_mux.v b/Verilog_Code/clock_mux.v
new file mode 100644
index 0000000..20ca430
--- /dev/null
+++ b/Verilog_Code/clock_mux.v
@@ -0,0 +1,83 @@
+//

+// Switch between two clock sources.

+// In this design the output clock stays LOW between switching clocks.

+// After a reset clk1 is selected.

+// sel_clk2 is assumed to have a high/low duration of at least 2 clock

+// periods of the slowest of clk1 or clk2.

+// (If the above rule is not followed, certain pathological patterns of

+//  sel_clk2 against the input clocks will produce low period violations)

+//

+

+// 

+// Design by G.J. van Loo, FenLogic Ltd, 3-January-2017.

+//

+// This program is free software. It comes without any guarantees or

+// warranty to the extent permitted by applicable law. Although the

+// author has attempted to find and correct any bugs in this free software

+// program, the author is not responsible for any damage or losses of any

+// kind caused by the use or misuse of the program. You can redistribute

+// the program and or modify it in any form without obligations, but the

+// author would appreciated if the credits stays in.

+// 

+

+

+module clock_mux

+   (

+   input    clk1,      // Clock 1 supposed to be faster

+   input    clk2,      // Clock 2  supposed to be slower

+   input    reset_n,   // System reset

+   input    sel_clk2,  // Select clock2 when high

+   output   clk1or2    // Selected clock

+   );

+

+reg [1:0] meta1_off,sync1_off;

+reg [1:0] meta1_on, sync1_on;

+reg [1:0] meta2_off,sync2_off;

+reg [1:0] meta2_on, sync2_on;

+

+

+   always @(posedge clk1 or negedge reset_n)

+   begin

+      if (!reset_n)

+      begin

+         meta1_off <= 1'b0;

+         sync1_off <= 1'b0;

+         meta1_on  <= 1'b1;

+         sync1_on  <= 1'b1;

+      end

+      else

+      begin

+         // Switch off when not selected

+         meta1_off <= sel_clk2;

+         sync1_off <= meta1_off;

+         // Switch on when other clock (clk2) is off 

+         meta1_on  <= sync2_off;

+         sync1_on  <= meta1_on;

+      end

+   end

+

+   always @(posedge clk2 or negedge reset_n)

+   begin

+      if (!reset_n)

+      begin

+         meta2_off <= 1'b1;

+         sync2_off <= 1'b1;

+         meta2_on  <= 1'b0;

+         sync2_on  <= 1'b0;

+      end

+      else

+      begin

+         // Switch off when not selected

+         meta2_off <= ~sel_clk2;

+         sync2_off <= meta2_off;

+         // Switch on when other clock (clk1) is off 

+         meta2_on  <= sync1_off;

+         sync2_on  <= meta2_on;

+      end

+   end

+

+   assign clk1or2 = (clk1 & ~sync1_off & sync1_on  ) | 

+                    (clk2 & ~sync2_off & sync2_on  );

+

+endmodule // clock_rnux

+

diff --git a/Verilog_Code/sha256.v b/Verilog_Code/sha256.v
new file mode 100644
index 0000000..c47500c
--- /dev/null
+++ b/Verilog_Code/sha256.v
@@ -0,0 +1,265 @@
+//======================================================================
+//
+// sha256.v
+// --------
+// Top level wrapper for the SHA-256 hash function providing
+// a simple memory like interface with 32 bit data access.
+//
+//
+// Author: Joachim Strombergson
+// Copyright (c) 2013, 201, 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 sha256(
+              // Clock and reset.
+              input wire           clk,
+              input wire           reset_n,
+
+              // Control.
+              input wire           cs,
+              input wire           we,
+
+              // Data ports.
+              input wire  [7 : 0]  address,
+              input wire  [31 : 0] write_data,
+              output wire [31 : 0] read_data,
+              output wire          error
+             );
+
+  //----------------------------------------------------------------
+  // Internal constant and parameter definitions.
+  //----------------------------------------------------------------
+  localparam ADDR_NAME0       = 8'h00;
+  localparam ADDR_NAME1       = 8'h01;
+  localparam ADDR_VERSION     = 8'h02;
+
+  localparam ADDR_CTRL        = 8'h08;
+  localparam CTRL_INIT_BIT    = 0;
+  localparam CTRL_NEXT_BIT    = 1;
+  localparam CTRL_MODE_BIT    = 2;
+
+  localparam ADDR_STATUS      = 8'h09;
+  localparam STATUS_READY_BIT = 0;
+  localparam STATUS_VALID_BIT = 1;
+
+  localparam ADDR_BLOCK0    = 8'h10;
+  localparam ADDR_BLOCK15   = 8'h1f;
+
+  localparam ADDR_DIGEST0   = 8'h20;
+  localparam ADDR_DIGEST7   = 8'h27;
+
+  localparam CORE_NAME0     = 32'h73686132; // "sha2"
+  localparam CORE_NAME1     = 32'h2d323536; // "-256"
+  localparam CORE_VERSION   = 32'h312e3830; // "1.80"
+
+  localparam MODE_SHA_224   = 1'h0;
+  localparam MODE_SHA_256   = 1'h1;
+
+
+  //----------------------------------------------------------------
+  // Registers including update variables and write enable.
+  //----------------------------------------------------------------
+  reg init_reg;
+  reg init_new;
+
+  reg next_reg;
+  reg next_new;
+
+  reg mode_reg;
+  reg mode_new;
+  reg mode_we;
+
+  reg ready_reg;
+
+  reg [31 : 0] block_reg [0 : 15];
+  reg          block_we;
+
+  reg [255 : 0] digest_reg;
+
+  reg digest_valid_reg;
+
+
+  //----------------------------------------------------------------
+  // Wires.
+  //----------------------------------------------------------------
+  wire           core_ready;
+  wire [511 : 0] core_block;
+  wire [255 : 0] core_digest;
+  wire           core_digest_valid;
+
+  reg [31 : 0]   tmp_read_data;
+  reg            tmp_error;
+
+
+  //----------------------------------------------------------------
+  // Concurrent connectivity for ports etc.
+  //----------------------------------------------------------------
+  assign core_block = {block_reg[00], block_reg[01], block_reg[02], block_reg[03],
+                       block_reg[04], block_reg[05], block_reg[06], block_reg[07],
+                       block_reg[08], block_reg[09], block_reg[10], block_reg[11],
+                       block_reg[12], block_reg[13], block_reg[14], block_reg[15]};
+
+  assign read_data = tmp_read_data;
+  assign error     = tmp_error;
+
+
+  //----------------------------------------------------------------
+  // core instantiation.
+  //----------------------------------------------------------------
+  sha256_core core(
+                   .clk(clk),
+                   .reset_n(reset_n),
+
+                   .init(init_reg),
+                   .next(next_reg),
+                   .mode(mode_reg),
+
+                   .block(core_block),
+
+                   .ready(core_ready),
+
+                   .digest(core_digest),
+                   .digest_valid(core_digest_valid)
+                  );
+
+
+  //----------------------------------------------------------------
+  // 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 < 16 ; i = i + 1)
+            block_reg[i] <= 32'h0;
+
+          init_reg         <= 0;
+          next_reg         <= 0;
+          ready_reg        <= 0;
+          mode_reg         <= MODE_SHA_256;
+          digest_reg       <= 256'h0;
+          digest_valid_reg <= 0;
+        end
+      else
+        begin
+          ready_reg        <= core_ready;
+          digest_valid_reg <= core_digest_valid;
+          init_reg         <= init_new;
+          next_reg         <= next_new;
+
+          if (mode_we)
+            mode_reg <= mode_new;
+
+          if (core_digest_valid)
+            digest_reg <= core_digest;
+
+          if (block_we)
+            block_reg[address[3 : 0]] <= write_data;
+        end
+    end // reg_update
+
+
+  //----------------------------------------------------------------
+  // api_logic
+  //
+  // Implementation of the api logic. If cs is enabled will either
+  // try to write to or read from the internal registers.
+  //----------------------------------------------------------------
+  always @*
+    begin : api_logic
+      init_new      = 0;
+      next_new      = 0;
+      mode_new      = 0;
+      mode_we       = 0;
+      block_we      = 0;
+      tmp_read_data = 32'h0;
+      tmp_error     = 0;
+
+      if (cs)
+        begin
+          if (we)
+            begin
+              if (address == ADDR_CTRL)
+                begin
+                  init_new = write_data[CTRL_INIT_BIT];
+                  next_new = write_data[CTRL_NEXT_BIT];
+                  mode_new = write_data[CTRL_MODE_BIT];
+                  mode_we  = 1;
+                end
+
+              if ((address >= ADDR_BLOCK0) && (address <= ADDR_BLOCK15))
+                block_we = 1;
+            end // if (we)
+
+          else
+            begin
+              if ((address >= ADDR_BLOCK0) && (address <= ADDR_BLOCK15))
+                tmp_read_data = block_reg[address[3 : 0]];
+
+              if ((address >= ADDR_DIGEST0) && (address <= ADDR_DIGEST7))
+                tmp_read_data = digest_reg[(7 - (address - ADDR_DIGEST0)) * 32 +: 32];
+
+              case (address)
+                // Read operations.
+                ADDR_NAME0:
+                  tmp_read_data = CORE_NAME0;
+
+                ADDR_NAME1:
+                  tmp_read_data = CORE_NAME1;
+
+                ADDR_VERSION:
+                  tmp_read_data = CORE_VERSION;
+
+                ADDR_CTRL:
+                  tmp_read_data = {29'h0, mode_reg, next_reg, init_reg};
+
+                ADDR_STATUS:
+                  tmp_read_data = {30'h0, digest_valid_reg, ready_reg};
+
+                default:
+                  begin
+                  end
+              endcase // case (address)
+            end
+        end
+    end // addr_decoder
+endmodule // sha256
+
+//======================================================================
+// EOF sha256.v
+//======================================================================
diff --git a/Verilog_Code/sha256_core.v b/Verilog_Code/sha256_core.v
new file mode 100644
index 0000000..b2c880e
--- /dev/null
+++ b/Verilog_Code/sha256_core.v
@@ -0,0 +1,552 @@
+//======================================================================
+//
+// sha256_core.v
+// -------------
+// Verilog 2001 implementation of the SHA-256 hash function.
+// This is the internal core with wide interfaces.
+//
+//
+// 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 sha256_core(
+                   input wire            clk,
+                   input wire            reset_n,
+
+                   input wire            init,
+                   input wire            next,
+                   input wire            mode,
+
+                   input wire [511 : 0]  block,
+
+                   output wire           ready,
+                   output wire [255 : 0] digest,
+                   output wire           digest_valid
+                  );
+
+
+  //----------------------------------------------------------------
+  // Internal constant and parameter definitions.
+  //----------------------------------------------------------------
+  localparam SHA224_H0_0 = 32'hc1059ed8;
+  localparam SHA224_H0_1 = 32'h367cd507;
+  localparam SHA224_H0_2 = 32'h3070dd17;
+  localparam SHA224_H0_3 = 32'hf70e5939;
+  localparam SHA224_H0_4 = 32'hffc00b31;
+  localparam SHA224_H0_5 = 32'h68581511;
+  localparam SHA224_H0_6 = 32'h64f98fa7;
+  localparam SHA224_H0_7 = 32'hbefa4fa4;
+
+  localparam SHA256_H0_0 = 32'h6a09e667;
+  localparam SHA256_H0_1 = 32'hbb67ae85;
+  localparam SHA256_H0_2 = 32'h3c6ef372;
+  localparam SHA256_H0_3 = 32'ha54ff53a;
+  localparam SHA256_H0_4 = 32'h510e527f;
+  localparam SHA256_H0_5 = 32'h9b05688c;
+  localparam SHA256_H0_6 = 32'h1f83d9ab;
+  localparam SHA256_H0_7 = 32'h5be0cd19;
+
+  localparam SHA256_ROUNDS = 63;
+
+  localparam CTRL_IDLE   = 0;
+  localparam CTRL_ROUNDS = 1;
+  localparam CTRL_DONE   = 2;
+
+
+  //----------------------------------------------------------------
+  // Registers including update variables and write enable.
+  //----------------------------------------------------------------
+  reg [31 : 0] a_reg;
+  reg [31 : 0] a_new;
+  reg [31 : 0] b_reg;
+  reg [31 : 0] b_new;
+  reg [31 : 0] c_reg;
+  reg [31 : 0] c_new;
+  reg [31 : 0] d_reg;
+  reg [31 : 0] d_new;
+  reg [31 : 0] e_reg;
+  reg [31 : 0] e_new;
+  reg [31 : 0] f_reg;
+  reg [31 : 0] f_new;
+  reg [31 : 0] g_reg;
+  reg [31 : 0] g_new;
+  reg [31 : 0] h_reg;
+  reg [31 : 0] h_new;
+  reg          a_h_we;
+
+  reg [31 : 0] H0_reg;
+  reg [31 : 0] H0_new;
+  reg [31 : 0] H1_reg;
+  reg [31 : 0] H1_new;
+  reg [31 : 0] H2_reg;
+  reg [31 : 0] H2_new;
+  reg [31 : 0] H3_reg;
+  reg [31 : 0] H3_new;
+  reg [31 : 0] H4_reg;
+  reg [31 : 0] H4_new;
+  reg [31 : 0] H5_reg;
+  reg [31 : 0] H5_new;
+  reg [31 : 0] H6_reg;
+  reg [31 : 0] H6_new;
+  reg [31 : 0] H7_reg;
+  reg [31 : 0] H7_new;
+  reg          H_we;
+
+  reg [5 : 0] t_ctr_reg;
+  reg [5 : 0] t_ctr_new;
+  reg         t_ctr_we;
+  reg         t_ctr_inc;
+  reg         t_ctr_rst;
+
+  reg digest_valid_reg;
+  reg digest_valid_new;
+  reg digest_valid_we;
+
+  reg [1 : 0] sha256_ctrl_reg;
+  reg [1 : 0] sha256_ctrl_new;
+  reg         sha256_ctrl_we;
+
+
+  //----------------------------------------------------------------
+  // Wires.
+  //----------------------------------------------------------------
+  reg digest_init;
+  reg digest_update;
+
+  reg state_init;
+  reg state_update;
+
+  reg first_block;
+
+  reg ready_flag;
+
+  reg [31 : 0] t1;
+  reg [31 : 0] t2;
+
+  wire [31 : 0] k_data;
+
+  reg           w_init;
+  reg           w_next;
+  wire [31 : 0] w_data;
+
+
+  //----------------------------------------------------------------
+  // Module instantiantions.
+  //----------------------------------------------------------------
+  sha256_k_constants k_constants_inst(
+                                      .round(t_ctr_reg),
+                                      .K(k_data)
+                                     );
+
+
+  sha256_w_mem w_mem_inst(
+                          .clk(clk),
+                          .reset_n(reset_n),
+
+                          .block(block),
+
+                          .init(w_init),
+                          .next(w_next),
+                          .w(w_data)
+                         );
+
+
+  //----------------------------------------------------------------
+  // Concurrent connectivity for ports etc.
+  //----------------------------------------------------------------
+  assign ready = ready_flag;
+
+  assign digest = {H0_reg, H1_reg, H2_reg, H3_reg,
+                   H4_reg, H5_reg, H6_reg, H7_reg};
+
+  assign digest_valid = digest_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
+          a_reg            <= 32'h0;
+          b_reg            <= 32'h0;
+          c_reg            <= 32'h0;
+          d_reg            <= 32'h0;
+          e_reg            <= 32'h0;
+          f_reg            <= 32'h0;
+          g_reg            <= 32'h0;
+          h_reg            <= 32'h0;
+          H0_reg           <= 32'h0;
+          H1_reg           <= 32'h0;
+          H2_reg           <= 32'h0;
+          H3_reg           <= 32'h0;
+          H4_reg           <= 32'h0;
+          H5_reg           <= 32'h0;
+          H6_reg           <= 32'h0;
+          H7_reg           <= 32'h0;
+          digest_valid_reg <= 0;
+          t_ctr_reg        <= 6'h0;
+          sha256_ctrl_reg  <= CTRL_IDLE;
+        end
+      else
+        begin
+
+          if (a_h_we)
+            begin
+              a_reg <= a_new;
+              b_reg <= b_new;
+              c_reg <= c_new;
+              d_reg <= d_new;
+              e_reg <= e_new;
+              f_reg <= f_new;
+              g_reg <= g_new;
+              h_reg <= h_new;
+            end
+
+          if (H_we)
+            begin
+              H0_reg <= H0_new;
+              H1_reg <= H1_new;
+              H2_reg <= H2_new;
+              H3_reg <= H3_new;
+              H4_reg <= H4_new;
+              H5_reg <= H5_new;
+              H6_reg <= H6_new;
+              H7_reg <= H7_new;
+            end
+
+          if (t_ctr_we)
+            t_ctr_reg <= t_ctr_new;
+
+          if (digest_valid_we)
+            digest_valid_reg <= digest_valid_new;
+
+          if (sha256_ctrl_we)
+            sha256_ctrl_reg <= sha256_ctrl_new;
+        end
+    end // reg_update
+
+
+  //----------------------------------------------------------------
+  // digest_logic
+  //
+  // The logic needed to init as well as update the digest.
+  //----------------------------------------------------------------
+  always @*
+    begin : digest_logic
+      H0_new = 32'h0;
+      H1_new = 32'h0;
+      H2_new = 32'h0;
+      H3_new = 32'h0;
+      H4_new = 32'h0;
+      H5_new = 32'h0;
+      H6_new = 32'h0;
+      H7_new = 32'h0;
+      H_we = 0;
+
+      if (digest_init)
+        begin
+          H_we = 1;
+          if (mode)
+            begin
+              H0_new = SHA256_H0_0;
+              H1_new = SHA256_H0_1;
+              H2_new = SHA256_H0_2;
+              H3_new = SHA256_H0_3;
+              H4_new = SHA256_H0_4;
+              H5_new = SHA256_H0_5;
+              H6_new = SHA256_H0_6;
+              H7_new = SHA256_H0_7;
+            end
+          else
+            begin
+              H0_new = SHA224_H0_0;
+              H1_new = SHA224_H0_1;
+              H2_new = SHA224_H0_2;
+              H3_new = SHA224_H0_3;
+              H4_new = SHA224_H0_4;
+              H5_new = SHA224_H0_5;
+              H6_new = SHA224_H0_6;
+              H7_new = SHA224_H0_7;
+            end
+        end
+
+      if (digest_update)
+        begin
+          H0_new = H0_reg + a_reg;
+          H1_new = H1_reg + b_reg;
+          H2_new = H2_reg + c_reg;
+          H3_new = H3_reg + d_reg;
+          H4_new = H4_reg + e_reg;
+          H5_new = H5_reg + f_reg;
+          H6_new = H6_reg + g_reg;
+          H7_new = H7_reg + h_reg;
+          H_we = 1;
+        end
+    end // digest_logic
+
+
+  //----------------------------------------------------------------
+  // t1_logic
+  //
+  // The logic for the T1 function.
+  //----------------------------------------------------------------
+  always @*
+    begin : t1_logic
+      reg [31 : 0] sum1;
+      reg [31 : 0] ch;
+
+      sum1 = {e_reg[5  : 0], e_reg[31 :  6]} ^
+             {e_reg[10 : 0], e_reg[31 : 11]} ^
+             {e_reg[24 : 0], e_reg[31 : 25]};
+
+      ch = (e_reg & f_reg) ^ ((~e_reg) & g_reg);
+
+      t1 = h_reg + sum1 + ch + w_data + k_data;
+    end // t1_logic
+
+
+  //----------------------------------------------------------------
+  // t2_logic
+  //
+  // The logic for the T2 function
+  //----------------------------------------------------------------
+  always @*
+    begin : t2_logic
+      reg [31 : 0] sum0;
+      reg [31 : 0] maj;
+
+      sum0 = {a_reg[1  : 0], a_reg[31 :  2]} ^
+             {a_reg[12 : 0], a_reg[31 : 13]} ^
+             {a_reg[21 : 0], a_reg[31 : 22]};
+
+      maj = (a_reg & b_reg) ^ (a_reg & c_reg) ^ (b_reg & c_reg);
+
+      t2 = sum0 + maj;
+    end // t2_logic
+
+
+  //----------------------------------------------------------------
+  // state_logic
+  //
+  // The logic needed to init as well as update the state during
+  // round processing.
+  //----------------------------------------------------------------
+  always @*
+    begin : state_logic
+      a_new  = 32'h0;
+      b_new  = 32'h0;
+      c_new  = 32'h0;
+      d_new  = 32'h0;
+      e_new  = 32'h0;
+      f_new  = 32'h0;
+      g_new  = 32'h0;
+      h_new  = 32'h0;
+      a_h_we = 0;
+
+      if (state_init)
+        begin
+          a_h_we = 1;
+          if (first_block)
+            begin
+              if (mode)
+                begin
+                  a_new  = SHA256_H0_0;
+                  b_new  = SHA256_H0_1;
+                  c_new  = SHA256_H0_2;
+                  d_new  = SHA256_H0_3;
+                  e_new  = SHA256_H0_4;
+                  f_new  = SHA256_H0_5;
+                  g_new  = SHA256_H0_6;
+                  h_new  = SHA256_H0_7;
+                end
+              else
+                begin
+                  a_new  = SHA224_H0_0;
+                  b_new  = SHA224_H0_1;
+                  c_new  = SHA224_H0_2;
+                  d_new  = SHA224_H0_3;
+                  e_new  = SHA224_H0_4;
+                  f_new  = SHA224_H0_5;
+                  g_new  = SHA224_H0_6;
+                  h_new  = SHA224_H0_7;
+                end
+            end
+          else
+            begin
+              a_new  = H0_reg;
+              b_new  = H1_reg;
+              c_new  = H2_reg;
+              d_new  = H3_reg;
+              e_new  = H4_reg;
+              f_new  = H5_reg;
+              g_new  = H6_reg;
+              h_new  = H7_reg;
+            end
+        end
+
+      if (state_update)
+        begin
+          a_new  = t1 + t2;
+          b_new  = a_reg;
+          c_new  = b_reg;
+          d_new  = c_reg;
+          e_new  = d_reg + t1;
+          f_new  = e_reg;
+          g_new  = f_reg;
+          h_new  = g_reg;
+          a_h_we = 1;
+        end
+    end // state_logic
+
+
+  //----------------------------------------------------------------
+  // t_ctr
+  //
+  // Update logic for the round counter, a monotonically
+  // increasing counter with reset.
+  //----------------------------------------------------------------
+  always @*
+    begin : t_ctr
+      t_ctr_new = 0;
+      t_ctr_we  = 0;
+
+      if (t_ctr_rst)
+        begin
+          t_ctr_new = 0;
+          t_ctr_we  = 1;
+        end
+
+      if (t_ctr_inc)
+        begin
+          t_ctr_new = t_ctr_reg + 1'b1;
+          t_ctr_we  = 1;
+        end
+    end // t_ctr
+
+
+  //----------------------------------------------------------------
+  // sha256_ctrl_fsm
+  //
+  // Logic for the state machine controlling the core behaviour.
+  //----------------------------------------------------------------
+  always @*
+    begin : sha256_ctrl_fsm
+      digest_init      = 0;
+      digest_update    = 0;
+
+      state_init       = 0;
+      state_update     = 0;
+
+      first_block      = 0;
+      ready_flag       = 0;
+
+      w_init           = 0;
+      w_next           = 0;
+
+      t_ctr_inc        = 0;
+      t_ctr_rst        = 0;
+
+      digest_valid_new = 0;
+      digest_valid_we  = 0;
+
+      sha256_ctrl_new  = CTRL_IDLE;
+      sha256_ctrl_we   = 0;
+
+
+      case (sha256_ctrl_reg)
+        CTRL_IDLE:
+          begin
+            ready_flag = 1;
+
+            if (init)
+              begin
+                digest_init      = 1;
+                w_init           = 1;
+                state_init       = 1;
+                first_block      = 1;
+                t_ctr_rst        = 1;
+                digest_valid_new = 0;
+                digest_valid_we  = 1;
+                sha256_ctrl_new  = CTRL_ROUNDS;
+                sha256_ctrl_we   = 1;
+              end
+
+            if (next)
+              begin
+                t_ctr_rst        = 1;
+                w_init           = 1;
+                state_init       = 1;
+                digest_valid_new = 0;
+                digest_valid_we  = 1;
+                sha256_ctrl_new  = CTRL_ROUNDS;
+                sha256_ctrl_we   = 1;
+              end
+          end
+
+
+        CTRL_ROUNDS:
+          begin
+            w_next       = 1;
+            state_update = 1;
+            t_ctr_inc    = 1;
+
+            if (t_ctr_reg == SHA256_ROUNDS)
+              begin
+                sha256_ctrl_new = CTRL_DONE;
+                sha256_ctrl_we  = 1;
+              end
+          end
+
+
+        CTRL_DONE:
+          begin
+            digest_update    = 1;
+            digest_valid_new = 1;
+            digest_valid_we  = 1;
+
+            sha256_ctrl_new  = CTRL_IDLE;
+            sha256_ctrl_we   = 1;
+          end
+      endcase // case (sha256_ctrl_reg)
+    end // sha256_ctrl_fsm
+
+endmodule // sha256_core
+
+//======================================================================
+// EOF sha256_core.v
+//======================================================================
diff --git a/Verilog_Code/sha256_k_constants.v b/Verilog_Code/sha256_k_constants.v
new file mode 100644
index 0000000..bae748e
--- /dev/null
+++ b/Verilog_Code/sha256_k_constants.v
@@ -0,0 +1,134 @@
+//======================================================================
+//
+// sha256_k_constants.v
+// --------------------
+// The table K with constants in the SHA-256 hash function.
+//
+//
+// 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 sha256_k_constants(
+                          input wire  [5 : 0] round,
+                          output wire [31 : 0] K
+                         );
+
+  //----------------------------------------------------------------
+  // Wires.
+  //----------------------------------------------------------------
+  reg [31 : 0] tmp_K;
+
+
+  //----------------------------------------------------------------
+  // Concurrent connectivity for ports etc.
+  //----------------------------------------------------------------
+  assign K = tmp_K;
+
+
+  //----------------------------------------------------------------
+  // round_mux
+  //----------------------------------------------------------------
+  always @*
+    begin : round_mux
+      case(round)
+        00: tmp_K = 32'h428a2f98;
+        01: tmp_K = 32'h71374491;
+        02: tmp_K = 32'hb5c0fbcf;
+        03: tmp_K = 32'he9b5dba5;
+        04: tmp_K = 32'h3956c25b;
+        05: tmp_K = 32'h59f111f1;
+        06: tmp_K = 32'h923f82a4;
+        07: tmp_K = 32'hab1c5ed5;
+        08: tmp_K = 32'hd807aa98;
+        09: tmp_K = 32'h12835b01;
+        10: tmp_K = 32'h243185be;
+        11: tmp_K = 32'h550c7dc3;
+        12: tmp_K = 32'h72be5d74;
+        13: tmp_K = 32'h80deb1fe;
+        14: tmp_K = 32'h9bdc06a7;
+        15: tmp_K = 32'hc19bf174;
+        16: tmp_K = 32'he49b69c1;
+        17: tmp_K = 32'hefbe4786;
+        18: tmp_K = 32'h0fc19dc6;
+        19: tmp_K = 32'h240ca1cc;
+        20: tmp_K = 32'h2de92c6f;
+        21: tmp_K = 32'h4a7484aa;
+        22: tmp_K = 32'h5cb0a9dc;
+        23: tmp_K = 32'h76f988da;
+        24: tmp_K = 32'h983e5152;
+        25: tmp_K = 32'ha831c66d;
+        26: tmp_K = 32'hb00327c8;
+        27: tmp_K = 32'hbf597fc7;
+        28: tmp_K = 32'hc6e00bf3;
+        29: tmp_K = 32'hd5a79147;
+        30: tmp_K = 32'h06ca6351;
+        31: tmp_K = 32'h14292967;
+        32: tmp_K = 32'h27b70a85;
+        33: tmp_K = 32'h2e1b2138;
+        34: tmp_K = 32'h4d2c6dfc;
+        35: tmp_K = 32'h53380d13;
+        36: tmp_K = 32'h650a7354;
+        37: tmp_K = 32'h766a0abb;
+        38: tmp_K = 32'h81c2c92e;
+        39: tmp_K = 32'h92722c85;
+        40: tmp_K = 32'ha2bfe8a1;
+        41: tmp_K = 32'ha81a664b;
+        42: tmp_K = 32'hc24b8b70;
+        43: tmp_K = 32'hc76c51a3;
+        44: tmp_K = 32'hd192e819;
+        45: tmp_K = 32'hd6990624;
+        46: tmp_K = 32'hf40e3585;
+        47: tmp_K = 32'h106aa070;
+        48: tmp_K = 32'h19a4c116;
+        49: tmp_K = 32'h1e376c08;
+        50: tmp_K = 32'h2748774c;
+        51: tmp_K = 32'h34b0bcb5;
+        52: tmp_K = 32'h391c0cb3;
+        53: tmp_K = 32'h4ed8aa4a;
+        54: tmp_K = 32'h5b9cca4f;
+        55: tmp_K = 32'h682e6ff3;
+        56: tmp_K = 32'h748f82ee;
+        57: tmp_K = 32'h78a5636f;
+        58: tmp_K = 32'h84c87814;
+        59: tmp_K = 32'h8cc70208;
+        60: tmp_K = 32'h90befffa;
+        61: tmp_K = 32'ha4506ceb;
+        62: tmp_K = 32'hbef9a3f7;
+        63: tmp_K = 32'hc67178f2;
+      endcase // case (round)
+    end // block: round_mux
+endmodule // sha256_k_constants
+
+//======================================================================
+// sha256_k_constants.v
+//======================================================================
diff --git a/Verilog_Code/sha256_w_mem.v b/Verilog_Code/sha256_w_mem.v
new file mode 100644
index 0000000..06f4d46
--- /dev/null
+++ b/Verilog_Code/sha256_w_mem.v
@@ -0,0 +1,272 @@
+//======================================================================
+//
+// sha256_w_mem_regs.v
+// -------------------
+// The W memory. This version uses 16 32-bit registers as a sliding
+// window to generate the 64 words.
+//
+//
+// 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 sha256_w_mem(
+                    input wire           clk,
+                    input wire           reset_n,
+
+                    input wire [511 : 0] block,
+
+                    input wire           init,
+                    input wire           next,
+                    output wire [31 : 0] w
+                   );
+
+
+  //----------------------------------------------------------------
+  // Registers including update variables and write enable.
+  //----------------------------------------------------------------
+  reg [31 : 0] w_mem [0 : 15];
+  reg [31 : 0] w_mem00_new;
+  reg [31 : 0] w_mem01_new;
+  reg [31 : 0] w_mem02_new;
+  reg [31 : 0] w_mem03_new;
+  reg [31 : 0] w_mem04_new;
+  reg [31 : 0] w_mem05_new;
+  reg [31 : 0] w_mem06_new;
+  reg [31 : 0] w_mem07_new;
+  reg [31 : 0] w_mem08_new;
+  reg [31 : 0] w_mem09_new;
+  reg [31 : 0] w_mem10_new;
+  reg [31 : 0] w_mem11_new;
+  reg [31 : 0] w_mem12_new;
+  reg [31 : 0] w_mem13_new;
+  reg [31 : 0] w_mem14_new;
+  reg [31 : 0] w_mem15_new;
+  reg          w_mem_we;
+
+  reg [5 : 0] w_ctr_reg;
+  reg [5 : 0] w_ctr_new;
+  reg         w_ctr_we;
+
+
+  //----------------------------------------------------------------
+  // Wires.
+  //----------------------------------------------------------------
+  reg [31 : 0] w_tmp;
+  reg [31 : 0] w_new;
+
+
+  //----------------------------------------------------------------
+  // Concurrent connectivity for ports etc.
+  //----------------------------------------------------------------
+  assign w = w_tmp;
+
+
+  //----------------------------------------------------------------
+  // 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
+      integer i;
+
+      if (!reset_n)
+        begin
+          for (i = 0 ; i < 16 ; i = i + 1)
+            w_mem[i] <= 32'h0;
+
+          w_ctr_reg <= 6'h0;
+        end
+      else
+        begin
+          if (w_mem_we)
+            begin
+              w_mem[00] <= w_mem00_new;
+              w_mem[01] <= w_mem01_new;
+              w_mem[02] <= w_mem02_new;
+              w_mem[03] <= w_mem03_new;
+              w_mem[04] <= w_mem04_new;
+              w_mem[05] <= w_mem05_new;
+              w_mem[06] <= w_mem06_new;
+              w_mem[07] <= w_mem07_new;
+              w_mem[08] <= w_mem08_new;
+              w_mem[09] <= w_mem09_new;
+              w_mem[10] <= w_mem10_new;
+              w_mem[11] <= w_mem11_new;
+              w_mem[12] <= w_mem12_new;
+              w_mem[13] <= w_mem13_new;
+              w_mem[14] <= w_mem14_new;
+              w_mem[15] <= w_mem15_new;
+            end
+
+          if (w_ctr_we)
+            w_ctr_reg <= w_ctr_new;
+        end
+    end // reg_update
+
+
+  //----------------------------------------------------------------
+  // select_w
+  //
+  // Mux for the external read operation. This is where we exract
+  // the W variable.
+  //----------------------------------------------------------------
+  always @*
+    begin : select_w
+      if (w_ctr_reg < 16)
+        w_tmp = w_mem[w_ctr_reg[3 : 0]];
+      else
+        w_tmp = w_new;
+    end // select_w
+
+
+  //----------------------------------------------------------------
+  // w_new_logic
+  //
+  // Logic that calculates the next value to be inserted into
+  // the sliding window of the memory.
+  //----------------------------------------------------------------
+  always @*
+    begin : w_mem_update_logic
+      reg [31 : 0] w_0;
+      reg [31 : 0] w_1;
+      reg [31 : 0] w_9;
+      reg [31 : 0] w_14;
+      reg [31 : 0] d0;
+      reg [31 : 0] d1;
+
+      w_mem00_new = 32'h0;
+      w_mem01_new = 32'h0;
+      w_mem02_new = 32'h0;
+      w_mem03_new = 32'h0;
+      w_mem04_new = 32'h0;
+      w_mem05_new = 32'h0;
+      w_mem06_new = 32'h0;
+      w_mem07_new = 32'h0;
+      w_mem08_new = 32'h0;
+      w_mem09_new = 32'h0;
+      w_mem10_new = 32'h0;
+      w_mem11_new = 32'h0;
+      w_mem12_new = 32'h0;
+      w_mem13_new = 32'h0;
+      w_mem14_new = 32'h0;
+      w_mem15_new = 32'h0;
+      w_mem_we    = 0;
+
+      w_0  = w_mem[0];
+      w_1  = w_mem[1];
+      w_9  = w_mem[9];
+      w_14 = w_mem[14];
+
+      d0 = {w_1[6  : 0], w_1[31 :  7]} ^
+           {w_1[17 : 0], w_1[31 : 18]} ^
+           {3'b000, w_1[31 : 3]};
+
+      d1 = {w_14[16 : 0], w_14[31 : 17]} ^
+           {w_14[18 : 0], w_14[31 : 19]} ^
+           {10'b0000000000, w_14[31 : 10]};
+
+      w_new = d1 + w_9 + d0 + w_0;
+
+      if (init)
+        begin
+          w_mem00_new = block[511 : 480];
+          w_mem01_new = block[479 : 448];
+          w_mem02_new = block[447 : 416];
+          w_mem03_new = block[415 : 384];
+          w_mem04_new = block[383 : 352];
+          w_mem05_new = block[351 : 320];
+          w_mem06_new = block[319 : 288];
+          w_mem07_new = block[287 : 256];
+          w_mem08_new = block[255 : 224];
+          w_mem09_new = block[223 : 192];
+          w_mem10_new = block[191 : 160];
+          w_mem11_new = block[159 : 128];
+          w_mem12_new = block[127 :  96];
+          w_mem13_new = block[95  :  64];
+          w_mem14_new = block[63  :  32];
+          w_mem15_new = block[31  :   0];
+          w_mem_we    = 1;
+        end
+
+      if (next && (w_ctr_reg > 15))
+        begin
+          w_mem00_new = w_mem[01];
+          w_mem01_new = w_mem[02];
+          w_mem02_new = w_mem[03];
+          w_mem03_new = w_mem[04];
+          w_mem04_new = w_mem[05];
+          w_mem05_new = w_mem[06];
+          w_mem06_new = w_mem[07];
+          w_mem07_new = w_mem[08];
+          w_mem08_new = w_mem[09];
+          w_mem09_new = w_mem[10];
+          w_mem10_new = w_mem[11];
+          w_mem11_new = w_mem[12];
+          w_mem12_new = w_mem[13];
+          w_mem13_new = w_mem[14];
+          w_mem14_new = w_mem[15];
+          w_mem15_new = w_new;
+          w_mem_we    = 1;
+        end
+    end // w_mem_update_logic
+
+
+  //----------------------------------------------------------------
+  // w_ctr
+  // W schedule adress counter. Counts from 0x10 to 0x3f and
+  // is used to expand the block into words.
+  //----------------------------------------------------------------
+  always @*
+    begin : w_ctr
+      w_ctr_new = 6'h0;
+      w_ctr_we  = 1'h0;
+
+      if (init)
+        begin
+          w_ctr_new = 6'h0;
+          w_ctr_we  = 1'h1;
+        end
+
+      if (next)
+        begin
+          w_ctr_new = w_ctr_reg + 6'h01;
+          w_ctr_we  = 1'h1;
+        end
+    end // w_ctr
+endmodule // sha256_w_mem
+
+//======================================================================
+// sha256_w_mem.v
+//======================================================================
diff --git a/Verilog_Code/tb_clock_mux.v b/Verilog_Code/tb_clock_mux.v
new file mode 100644
index 0000000..cf112a8
--- /dev/null
+++ b/Verilog_Code/tb_clock_mux.v
@@ -0,0 +1,142 @@
+//

+// Switch between two clock sources testbench.

+//

+

+// 

+// Design by G.J. van Loo, FenLogic Ltd, 15-January-2017.

+// 

+// This program is free software. It comes without any guarantees or

+// warranty to the extent permitted by applicable law. Although the

+// author has attempted to find and correct any bugs in this free software

+// program, the author is not responsible for any damage or losses of any

+// kind caused by the use or misuse of the program. You can redistribute

+// the program and or modify it in any form without obligations, but the

+// author would appreciated if the credits stays in.

+// 

+module clock_mux_test;

+

+// For specify to work CLK1PERIOD must be <= CLK2PERIOD !!

+localparam CLK1PERIOD = 8,

+           CLK2PERIOD = 10;

+

+reg    clk1;      // Clock 1

+reg    clk2;      // Clock 2

+reg    reset_n;   // System reset

+reg    sel_clk2;  // Select clock2 when high

+wire   clk1or2;   // Selected clock

+

+integer l,r1,r2;

+

+initial

+begin

+   sel_clk2 = 1'b0;

+   reset_n  = 1'b0;

+   #50;

+   reset_n  = 1'b1;

+   #250;

+   sel_clk2 = 1'b1;

+   #250;

+   sel_clk2 = 1'b0;

+   #1000;

+

+   // Test reset release with sel2 high

+   reset_n  = 1'b0;

+   #50;

+   sel_clk2 = 1'b1;

+   #50;

+   reset_n  = 1'b1;

+   #250;

+   // Test reset release and sel2 high at the same time

+   reset_n  = 1'b0;

+   #50;

+   sel_clk2 = 1'b1;

+   reset_n  = 1'b1;

+   #250;

+   

+   #1000;

+   

+      

+   //

+   // Test clock not present

+   //

+   force clk2 = 1'b0;

+   #250;

+   // switch to not running clk2

+   sel_clk2 = 1'b1;

+   #250;

+   // switch back to clk1 

+   sel_clk2 = 1'b0;

+   #250;

+   // switch to not running clk2

+   sel_clk2 = 1'b1;

+   #250;

+   // now clock2 comes on again

+   // whilst it is selected 

+   release clk2;

+   #250;

+   // switch back to clk1 

+   sel_clk2 = 1'b0;

+   #250;

+      

+   // Switch often but never faster then 2xslowest input clock period

+   for (l=0; l<10000; l=l+1)

+   begin

+      r1 = (($random>>3)&32'h1F)+2*CLK2PERIOD;

+      r2 = (($random>>4)&32'h1F)+2*CLK2PERIOD;

+      sel_clk2 = 1'b1;

+      #r1;

+      sel_clk2 = 1'b0;

+      #r2;

+   end

+   #1000;

+   

+   // Really nasty and illegal clock switching.

+   // Causes low period violations.

+	// This gives more confidence that the testbench seems to work.

+   $display("@%0t Illegal 'sel_clk2' pattern hereafter",$time);

+   $display("      gives rise to low period violations.");

+   $display("      Ignore all warnings from here.");   

+   for (l=0; l<500; l=l+1)

+   begin

+      r1 = ($random>>3)&32'h1F+CLK2PERIOD;

+      r2 = ($random>>4)&32'h1F+CLK2PERIOD;

+      sel_clk2 = 1'b1;

+      #r1;

+      sel_clk2 = 1'b0;

+      #r2;

+   end

+   $stop;

+end

+

+initial

+begin

+   clk1 = 1'b0;

+   forever

+      #(CLK1PERIOD/2) clk1 <= ~clk1;

+end

+

+initial

+begin

+   clk2 = 1'b0;

+   forever

+      #(CLK2PERIOD/2) clk2 <= ~clk2;

+end

+

+clock_mux clock_mux0 

+   (

+   .clk1    (clk1),     // Clock 1

+   .clk2    (clk2),     // Clock 2

+   .reset_n (reset_n),  // System reset

+   .sel_clk2(sel_clk2), // Select clock2 when high

+   .clk1or2 (clk1or2)   // Selected clock

+   );

+

+// Now check if time high or low is ever smaller than CLK1PERIOD/2

+// (This is why CLK1PERIOD <= CLK2PERIOD)

+specify

+$width(posedge clk1or2, CLK1PERIOD/2);

+$width(negedge clk1or2, CLK1PERIOD/2);

+endspecify

+

+endmodule // clock_mux_test

+

diff --git a/Verilog_Code/tb_sha256.v b/Verilog_Code/tb_sha256.v
new file mode 100644
index 0000000..3796e73
--- /dev/null
+++ b/Verilog_Code/tb_sha256.v
@@ -0,0 +1,718 @@
+//======================================================================

+//

+// tb_sha256.v

+// -----------

+// Testbench for the SHA-256 top level wrapper.

+//

+//

+// 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 tb_sha256();

+

+  //----------------------------------------------------------------

+  // Internal constant and parameter definitions.

+  //----------------------------------------------------------------

+  parameter DEBUG = 0;

+

+  parameter CLK_HALF_PERIOD = 2;

+  parameter CLK_PERIOD = 2 * CLK_HALF_PERIOD;

+

+  // The address map.

+  parameter ADDR_NAME0       = 8'h00;

+  parameter ADDR_NAME1       = 8'h01;

+  parameter ADDR_VERSION     = 8'h02;

+

+  parameter ADDR_CTRL        = 8'h08;

+  parameter CTRL_INIT_VALUE  = 8'h01;

+  parameter CTRL_NEXT_VALUE  = 8'h02;

+  parameter CTRL_MODE_VALUE  = 8'h04;

+

+  parameter ADDR_STATUS      = 8'h09;

+  parameter STATUS_READY_BIT = 0;

+  parameter STATUS_VALID_BIT = 1;

+

+  parameter ADDR_BLOCK0    = 8'h10;

+  parameter ADDR_BLOCK1    = 8'h11;

+  parameter ADDR_BLOCK2    = 8'h12;

+  parameter ADDR_BLOCK3    = 8'h13;

+  parameter ADDR_BLOCK4    = 8'h14;

+  parameter ADDR_BLOCK5    = 8'h15;

+  parameter ADDR_BLOCK6    = 8'h16;

+  parameter ADDR_BLOCK7    = 8'h17;

+  parameter ADDR_BLOCK8    = 8'h18;

+  parameter ADDR_BLOCK9    = 8'h19;

+  parameter ADDR_BLOCK10   = 8'h1a;

+  parameter ADDR_BLOCK11   = 8'h1b;

+  parameter ADDR_BLOCK12   = 8'h1c;

+  parameter ADDR_BLOCK13   = 8'h1d;

+  parameter ADDR_BLOCK14   = 8'h1e;

+  parameter ADDR_BLOCK15   = 8'h1f;

+

+  parameter ADDR_DIGEST0   = 8'h20;

+  parameter ADDR_DIGEST1   = 8'h21;

+  parameter ADDR_DIGEST2   = 8'h22;

+  parameter ADDR_DIGEST3   = 8'h23;

+  parameter ADDR_DIGEST4   = 8'h24;

+  parameter ADDR_DIGEST5   = 8'h25;

+  parameter ADDR_DIGEST6   = 8'h26;

+  parameter ADDR_DIGEST7   = 8'h27;

+

+  parameter SHA224_MODE    = 0;

+  parameter SHA256_MODE    = 1;

+

+

+  //----------------------------------------------------------------

+  // Register and Wire declarations.

+  //----------------------------------------------------------------

+  reg [31 : 0] cycle_ctr;

+  reg [31 : 0] error_ctr;

+  reg [31 : 0] tc_ctr;

+

+  reg           tb_clk;

+  reg           tb_reset_n;

+  reg           tb_cs;

+  reg           tb_we;

+  reg [7 : 0]   tb_address;

+  reg [31 : 0]  tb_write_data;

+  wire [31 : 0] tb_read_data;

+  wire          tb_error;

+

+  reg [31 : 0]  read_data;

+  reg [255 : 0] digest_data;

+

+

+  //----------------------------------------------------------------

+  // Device Under Test.

+  //----------------------------------------------------------------

+  sha256 dut(

+             .clk(tb_clk),

+             .reset_n(tb_reset_n),

+

+             .cs(tb_cs),

+             .we(tb_we),

+

+

+             .address(tb_address),

+             .write_data(tb_write_data),

+             .read_data(tb_read_data),

+             .error(tb_error)

+            );

+

+

+  //----------------------------------------------------------------

+  // clk_gen

+  //

+  // Clock generator process.

+  //----------------------------------------------------------------

+  always

+    begin : clk_gen

+      #CLK_HALF_PERIOD tb_clk = !tb_clk;

+    end // clk_gen

+

+

+  //----------------------------------------------------------------

+  // sys_monitor

+  //

+  // Generates a cycle counter and displays information about

+  // the dut as needed.

+  //----------------------------------------------------------------

+  always

+    begin : sys_monitor

+      #(2 * CLK_HALF_PERIOD);

+      cycle_ctr = cycle_ctr + 1;

+    end

+

+

+  //----------------------------------------------------------------

+  // dump_dut_state()

+  //

+  // Dump the state of the dump when needed.

+  //----------------------------------------------------------------

+  task dump_dut_state;

+    begin

+      $display("State of DUT");

+      $display("------------");

+      $display("Inputs and outputs:");

+      $display("cs = 0x%01x, we = 0x%01x",

+               dut.cs, dut.we);

+      $display("address = 0x%02x", dut.address);

+      $display("write_data = 0x%08x, read_data = 0x%08x",

+               dut.write_data, dut.read_data);

+      $display("tmp_read_data = 0x%08x", dut.tmp_read_data);

+      $display("");

+

+      $display("Control and status:");

+      $display("ctrl = 0x%02x, status = 0x%02x",

+               {dut.next_reg, dut.init_reg},

+               {dut.digest_valid_reg, dut.ready_reg});

+      $display("");

+

+      $display("Message block:");

+      $display("block0  = 0x%08x, block1  = 0x%08x, block2  = 0x%08x,  block3  = 0x%08x",

+               dut.block_reg[00], dut.block_reg[01], dut.block_reg[02], dut.block_reg[03]);

+//      $display("block4  = 0x%08x, block5  = 0x%08x, block6  = 0x%08x,  block7  = 0x%08x",

+//               dut.block_reg[04], dut.block_reg[05], dut.block_reg[06], dut.block_reg[07]);

+

+      $display("block8  = 0x%08x, block9  = 0x%08x, block10 = 0x%08x,  block11 = 0x%08x",

+               dut.block_reg[08], dut.block_reg[09], dut.block_reg[10], dut.block_reg[11]);

+      $display("block12 = 0x%08x, block13 = 0x%08x, block14 = 0x%08x,  block15 = 0x%08x",

+               dut.block_reg[12], dut.block_reg[13], dut.block_reg[14], dut.block_reg[15]);

+      $display("");

+

+      $display("Digest:");

+      $display("digest = 0x%064x", dut.digest_reg);

+      $display("");

+

+    end

+  endtask // dump_dut_state

+

+

+  //----------------------------------------------------------------

+  // reset_dut()

+  //

+  // Toggles reset to force the DUT into a well defined state.

+  //----------------------------------------------------------------

+  task reset_dut;

+    begin

+      $display("*** Toggle reset.");

+      tb_reset_n = 0;

+      #(4 * CLK_HALF_PERIOD);

+      tb_reset_n = 1;

+    end

+  endtask // reset_dut

+

+

+  //----------------------------------------------------------------

+  // init_sim()

+  //

+  // Initialize all counters and testbed functionality as well

+  // as setting the DUT inputs to defined values.

+  //----------------------------------------------------------------

+  task init_sim;

+    begin

+      cycle_ctr = 32'h0;

+      error_ctr = 32'h0;

+      tc_ctr = 32'h0;

+

+      tb_clk = 0;

+      tb_reset_n = 0;

+      tb_cs = 0;

+      tb_we = 0;

+      tb_address = 6'h0;

+      tb_write_data = 32'h0;

+    end

+  endtask // init_dut

+

+

+  //----------------------------------------------------------------

+  // display_test_result()

+  //

+  // Display the accumulated test results.

+  //----------------------------------------------------------------

+  task display_test_result;

+    begin

+      if (error_ctr == 0)

+        begin

+          $display("*** All %02d test cases completed successfully.", tc_ctr);

+        end

+      else

+        begin

+          $display("*** %02d test cases completed.", tc_ctr);

+          $display("*** %02d errors detected during testing.", error_ctr);

+        end

+    end

+  endtask // display_test_result

+

+

+  //----------------------------------------------------------------

+  // wait_ready()

+  //

+  // Wait for the ready flag in the dut to be set.

+  // (Actually we wait for either ready or valid to be set.)

+  //

+  // Note: It is the callers responsibility to call the function

+  // when the dut is actively processing and will in fact at some

+  // point set the flag.

+  //----------------------------------------------------------------

+  task wait_ready;

+    begin

+      read_data = 0;

+

+      while (read_data == 0)

+        begin

+          read_word(ADDR_STATUS);

+        end

+    end

+  endtask // wait_ready

+

+

+  //----------------------------------------------------------------

+  // write_word()

+  //

+  // Write the given word to the DUT using the DUT interface.

+  //----------------------------------------------------------------

+  task write_word(input [7 : 0]  address,

+                  input [31 : 0] word);

+    begin

+      if (DEBUG)

+        begin

+          $display("*** Writing 0x%08x to 0x%02x.", word, address);

+          $display("");

+        end

+

+      tb_address = address;

+      tb_write_data = word;

+      tb_cs = 1;

+      tb_we = 1;

+      #(CLK_PERIOD);

+      tb_cs = 0;

+      tb_we = 0;

+    end

+  endtask // write_word

+

+

+  //----------------------------------------------------------------

+  // write_block()

+  //

+  // Write the given block to the dut.

+  //----------------------------------------------------------------

+  task write_block(input [511 : 0] block);

+    begin

+      write_word(ADDR_BLOCK0,  block[511 : 480]);

+      write_word(ADDR_BLOCK1,  block[479 : 448]);

+      write_word(ADDR_BLOCK2,  block[447 : 416]);

+      write_word(ADDR_BLOCK3,  block[415 : 384]);

+      write_word(ADDR_BLOCK4,  block[383 : 352]);

+      write_word(ADDR_BLOCK5,  block[351 : 320]);

+      write_word(ADDR_BLOCK6,  block[319 : 288]);

+      write_word(ADDR_BLOCK7,  block[287 : 256]);

+      write_word(ADDR_BLOCK8,  block[255 : 224]);

+      write_word(ADDR_BLOCK9,  block[223 : 192]);

+      write_word(ADDR_BLOCK10, block[191 : 160]);

+      write_word(ADDR_BLOCK11, block[159 : 128]);

+      write_word(ADDR_BLOCK12, block[127 :  96]);

+      write_word(ADDR_BLOCK13, block[95  :  64]);

+      write_word(ADDR_BLOCK14, block[63  :  32]);

+      write_word(ADDR_BLOCK15, block[31  :   0]);

+    end

+  endtask // write_block

+

+

+  //----------------------------------------------------------------

+  // read_word()

+  //

+  // Read a data word from the given address in the DUT.

+  // the word read will be available in the global variable

+  // read_data.

+  //----------------------------------------------------------------

+  task read_word(input [7 : 0]  address);

+    begin

+      tb_address = address;

+      tb_cs = 1;

+      tb_we = 0;

+      #(CLK_PERIOD);

+      read_data = tb_read_data;

+      tb_cs = 0;

+

+      if (DEBUG)

+        begin

+          $display("*** Reading 0x%08x from 0x%02x.", read_data, address);

+          $display("");

+        end

+    end

+  endtask // read_word

+

+

+  //----------------------------------------------------------------

+  // check_name_version()

+  //

+  // Read the name and version from the DUT.

+  //----------------------------------------------------------------

+  task check_name_version;

+    reg [31 : 0] name0;

+    reg [31 : 0] name1;

+    reg [31 : 0] version;

+    begin

+

+      read_word(ADDR_NAME0);

+      name0 = read_data;

+      read_word(ADDR_NAME1);

+      name1 = read_data;

+      read_word(ADDR_VERSION);

+      version = read_data;

+

+      $display("DUT name: %c%c%c%c%c%c%c%c",

+               name0[31 : 24], name0[23 : 16], name0[15 : 8], name0[7 : 0],

+               name1[31 : 24], name1[23 : 16], name1[15 : 8], name1[7 : 0]);

+      $display("DUT version: %c%c%c%c",

+               version[31 : 24], version[23 : 16], version[15 : 8], version[7 : 0]);

+    end

+  endtask // check_name_version

+

+

+  //----------------------------------------------------------------

+  // read_digest()

+  //

+  // Read the digest in the dut. The resulting digest will be

+  // available in the global variable digest_data.

+  //----------------------------------------------------------------

+  task read_digest;

+    begin

+      read_word(ADDR_DIGEST0);

+      digest_data[255 : 224] = read_data;

+      read_word(ADDR_DIGEST1);

+      digest_data[223 : 192] = read_data;

+      read_word(ADDR_DIGEST2);

+      digest_data[191 : 160] = read_data;

+      read_word(ADDR_DIGEST3);

+      digest_data[159 : 128] = read_data;

+      read_word(ADDR_DIGEST4);

+      digest_data[127 :  96] = read_data;

+      read_word(ADDR_DIGEST5);

+      digest_data[95  :  64] = read_data;

+      read_word(ADDR_DIGEST6);

+      digest_data[63  :  32] = read_data;

+      read_word(ADDR_DIGEST7);

+      digest_data[31  :   0] = read_data;

+    end

+  endtask // read_digest

+

+

+  //----------------------------------------------------------------

+  // single_block_test()

+  //

+  //

+  // Perform test of a single block digest.

+  //----------------------------------------------------------------

+  task single_block_test(input           mode,

+                         input [511 : 0] block,

+                         input [255 : 0] expected);

+    begin

+      $display("*** TC%01d - Single block test started.", tc_ctr);

+

+      write_block(block);

+

+      if (mode)

+        write_word(ADDR_CTRL, (CTRL_MODE_VALUE + CTRL_INIT_VALUE));

+      else

+        write_word(ADDR_CTRL, CTRL_INIT_VALUE);

+

+      #(CLK_PERIOD);

+      wait_ready();

+      read_digest();

+

+      // We need to ignore the LSW in SHA224 mode.

+      if (mode == SHA224_MODE)

+        digest_data[31 : 0] = 32'h0;

+

+      if (digest_data == expected)

+        begin

+          $display("TC%01d: OK.", tc_ctr);

+        end

+      else

+        begin

+          $display("TC%01d: ERROR.", tc_ctr);

+          $display("TC%01d: Expected: 0x%064x", tc_ctr, expected);

+          $display("TC%01d: Got:      0x%064x", tc_ctr, digest_data);

+          error_ctr = error_ctr + 1;

+        end

+      $display("*** TC%01d - Single block test done.", tc_ctr);

+      tc_ctr = tc_ctr + 1;

+    end

+  endtask // single_block_test

+

+

+  //----------------------------------------------------------------

+  // double_block_test()

+  //

+  //

+  // Perform test of a double block digest. Note that we check

+  // the digests for both the first and final block.

+  //----------------------------------------------------------------

+  task double_block_test(input           mode,

+                         input [511 : 0] block0,

+                         input [255 : 0] expected0,

+                         input [511 : 0] block1,

+                         input [255 : 0] expected1

+                        );

+    begin

+      $display("*** TC%01d - Double block test started.", tc_ctr);

+

+      // First block

+      write_block(block0);

+

+      if (mode)

+        write_word(ADDR_CTRL, (CTRL_MODE_VALUE + CTRL_INIT_VALUE));

+      else

+        write_word(ADDR_CTRL, CTRL_INIT_VALUE);

+

+      #(CLK_PERIOD);

+      wait_ready();

+      read_digest();

+

+      // We need to ignore the LSW in SHA224 mode.

+      if (mode == SHA224_MODE)

+        digest_data[31 : 0] = 32'h0;

+

+      if (digest_data == expected0)

+        begin

+          $display("TC%01d first block: OK.", tc_ctr);

+        end

+      else

+        begin

+          $display("TC%01d: ERROR in first digest", tc_ctr);

+          $display("TC%01d: Expected: 0x%064x", tc_ctr, expected0);

+          $display("TC%01d: Got:      0x%064x", tc_ctr, digest_data);

+          error_ctr = error_ctr + 1;

+        end

+

+      // Final block

+      write_block(block1);

+

+      if (mode)

+        write_word(ADDR_CTRL, (CTRL_MODE_VALUE + CTRL_NEXT_VALUE));

+      else

+        write_word(ADDR_CTRL, CTRL_NEXT_VALUE);

+

+      #(CLK_PERIOD);

+      wait_ready();

+      read_digest();

+

+      // We need to ignore the LSW in SHA224 mode.

+      if (mode == SHA224_MODE)

+        digest_data[31 : 0] = 32'h0;

+

+      if (digest_data == expected1)

+        begin

+          $display("TC%01d final block: OK.", tc_ctr);

+        end

+      else

+        begin

+          $display("TC%01d: ERROR in final digest", tc_ctr);

+          $display("TC%01d: Expected: 0x%064x", tc_ctr, expected1);

+          $display("TC%01d: Got:      0x%064x", tc_ctr, digest_data);

+          error_ctr = error_ctr + 1;

+        end

+

+      $display("*** TC%01d - Double block test done.", tc_ctr);

+      tc_ctr = tc_ctr + 1;

+    end

+  endtask // double_block_test

+

+

+  //----------------------------------------------------------------

+  // sha224_tests()

+  //

+  // Run test cases for sha224.

+  // Test cases taken from:

+  // http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/SHA224.pdf

+  //----------------------------------------------------------------

+  task sha224_tests;

+    begin : sha224_tests_block

+      reg [511 : 0] tc0;

+      reg [255 : 0] res0;

+

+      reg [511 : 0] tc1_0;

+      reg [255 : 0] res1_0;

+      reg [511 : 0] tc1_1;

+      reg [255 : 0] res1_1;

+

+      $display("*** Testcases for sha224 functionality started.");

+

+      tc0 = 512'h61626380000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018;

+

+      res0 = 256'h23097D223405D8228642A477BDA255B32AADBCE4BDA0B3F7E36C9DA700000000;

+      single_block_test(SHA224_MODE, tc0, res0);

+

+      tc1_0 = 512'h6162636462636465636465666465666765666768666768696768696A68696A6B696A6B6C6A6B6C6D6B6C6D6E6C6D6E6F6D6E6F706E6F70718000000000000000;

+      res1_0 = 256'h8250e65dbcf62f8466659c3333e5e91a10c8b7b0953927691f1419c200000000;

+      tc1_1 = 512'h000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001C0;

+      res1_1 = 256'h75388b16512776cc5dba5da1fd890150b0c6455cb4f58b195252252500000000;

+      double_block_test(SHA224_MODE, tc1_0, res1_0, tc1_1, res1_1);

+

+      $display("*** Testcases for sha224 functionality completed.");

+    end

+  endtask // sha224_tests

+

+

+  //----------------------------------------------------------------

+  // sha256_tests()

+  //

+  // Run test cases for sha256.

+  // Test cases taken from:

+  // http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/SHA256.pdf

+  //----------------------------------------------------------------

+  task sha256_tests;

+    begin : sha256_tests_block

+      reg [511 : 0] tc0;

+      reg [255 : 0] res0;

+

+      reg [511 : 0] tc1_0;

+      reg [255 : 0] res1_0;

+      reg [511 : 0] tc1_1;

+      reg [255 : 0] res1_1;

+

+      $display("*** Testcases for sha256 functionality started.");

+

+      tc0 = 512'h61626380000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018;

+      res0 = 256'hBA7816BF8F01CFEA414140DE5DAE2223B00361A396177A9CB410FF61F20015AD;

+      single_block_test(SHA256_MODE, tc0, res0);

+

+      tc1_0 = 512'h6162636462636465636465666465666765666768666768696768696A68696A6B696A6B6C6A6B6C6D6B6C6D6E6C6D6E6F6D6E6F706E6F70718000000000000000;

+      res1_0 = 256'h85E655D6417A17953363376A624CDE5C76E09589CAC5F811CC4B32C1F20E533A;

+      tc1_1 = 512'h000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001C0;

+      res1_1 = 256'h248D6A61D20638B8E5C026930C3E6039A33CE45964FF2167F6ECEDD419DB06C1;

+      double_block_test(SHA256_MODE, tc1_0, res1_0, tc1_1, res1_1);

+

+      $display("*** Testcases for sha256 functionality completed.");

+    end

+  endtask // sha256_tests

+

+

+

+  //----------------------------------------------------------------

+  // issue_test()

+  //----------------------------------------------------------------

+  task issue_test;

+    reg [511 : 0] block0;

+    reg [511 : 0] block1;

+    reg [511 : 0] block2;

+    reg [511 : 0] block3;

+    reg [511 : 0] block4;

+    reg [511 : 0] block5;

+    reg [511 : 0] block6;

+    reg [511 : 0] block7;

+    reg [511 : 0] block8;

+    reg [255 : 0] expected;

+    begin : issue_test

+      block0 = 512'h6b900001_496e2074_68652061_72656120_6f662049_6f542028_496e7465_726e6574_206f6620_5468696e_6773292c_206d6f72_6520616e_64206d6f_7265626f_6f6d2c20;

+      block1 = 512'h69742068_61732062_65656e20_6120756e_69766572_73616c20_636f6e73_656e7375_73207468_61742064_61746120_69732074_69732061_206e6577_20746563_686e6f6c;

+      block2 = 512'h6f677920_74686174_20696e74_65677261_74657320_64656365_6e747261_6c697a61_74696f6e_2c496e20_74686520_61726561_206f6620_496f5420_28496e74_65726e65;

+      block3 = 512'h74206f66_20546869_6e677329_2c206d6f_72652061_6e64206d_6f726562_6f6f6d2c_20697420_68617320_6265656e_20612075_6e697665_7273616c_20636f6e_73656e73;

+      block4 = 512'h75732074_68617420_64617461_20697320_74697320_61206e65_77207465_63686e6f_6c6f6779_20746861_7420696e_74656772_61746573_20646563_656e7472_616c697a;

+      block5 = 512'h6174696f_6e2c496e_20746865_20617265_61206f66_20496f54_2028496e_7465726e_6574206f_66205468_696e6773_292c206d_6f726520_616e6420_6d6f7265_626f6f6d;

+      block6 = 512'h2c206974_20686173_20626565_6e206120_756e6976_65727361_6c20636f_6e73656e_73757320_74686174_20646174_61206973_20746973_2061206e_65772074_6563686e;

+      block7 = 512'h6f6c6f67_79207468_61742069_6e746567_72617465_73206465_63656e74_72616c69_7a617469_6f6e2c49_6e207468_65206172_6561206f_6620496f_54202849_6e746572;

+      block8 = 512'h6e657420_6f662054_68696e67_73292c20_6d6f7265_20616e64_206d6f72_65800000_00000000_00000000_00000000_00000000_00000000_00000000_00000000_000010e8;

+

+      expected = 256'h7758a30bbdfc9cd92b284b05e9be9ca3d269d3d149e7e82ab4a9ed5e81fbcf9d;

+

+      $display("Running test for 9 block issue.");

+      tc_ctr = tc_ctr + 1;

+      write_block(block0);

+      write_word(ADDR_CTRL, (CTRL_MODE_VALUE + CTRL_INIT_VALUE));

+      #(CLK_PERIOD);

+      wait_ready();

+

+      write_block(block1);

+      write_word(ADDR_CTRL, (CTRL_MODE_VALUE + CTRL_NEXT_VALUE));

+      #(CLK_PERIOD);

+      wait_ready();

+

+      write_block(block2);

+      write_word(ADDR_CTRL, (CTRL_MODE_VALUE + CTRL_NEXT_VALUE));

+      #(CLK_PERIOD);

+      wait_ready();

+

+      write_block(block3);

+      write_word(ADDR_CTRL, (CTRL_MODE_VALUE + CTRL_NEXT_VALUE));

+      #(CLK_PERIOD);

+      wait_ready();

+

+      write_block(block4);

+      write_word(ADDR_CTRL, (CTRL_MODE_VALUE + CTRL_NEXT_VALUE));

+      #(CLK_PERIOD);

+      wait_ready();

+

+      write_block(block5);

+      write_word(ADDR_CTRL, (CTRL_MODE_VALUE + CTRL_NEXT_VALUE));

+      #(CLK_PERIOD);

+      wait_ready();

+

+      write_block(block6);

+      write_word(ADDR_CTRL, (CTRL_MODE_VALUE + CTRL_NEXT_VALUE));

+      #(CLK_PERIOD);

+      wait_ready();

+

+      write_block(block7);

+      write_word(ADDR_CTRL, (CTRL_MODE_VALUE + CTRL_NEXT_VALUE));

+      #(CLK_PERIOD);

+      wait_ready();

+

+      write_block(block8);

+      write_word(ADDR_CTRL, (CTRL_MODE_VALUE + CTRL_NEXT_VALUE));

+      #(CLK_PERIOD);

+      wait_ready();

+

+      read_digest();

+      if (digest_data == expected)

+        begin

+          $display("Digest ok.");

+        end

+      else

+        begin

+          $display("ERROR in digest");

+          $display("Expected: 0x%064x", expected);

+          $display("Got:      0x%064x", digest_data);

+          error_ctr = error_ctr + 1;

+        end

+    end

+  endtask // issue_test

+

+

+  //----------------------------------------------------------------

+  // The main test functionality.

+  //----------------------------------------------------------------

+  initial

+    begin : main

+      $display("   -- Testbench for sha256 started --");

+

+      init_sim();

+      reset_dut();

+

+      check_name_version();

+      sha224_tests();

+      sha256_tests();

+      issue_test();

+

+      display_test_result();

+

+      $display("   -- Testbench for sha256 done. --");

+      $finish;

+    end // main

+endmodule // tb_sha256

+

+//======================================================================

+// EOF tb_sha256.v

+//======================================================================

diff --git a/Verilog_Code/tb_sha256.v.bak b/Verilog_Code/tb_sha256.v.bak
new file mode 100644
index 0000000..79765b3
--- /dev/null
+++ b/Verilog_Code/tb_sha256.v.bak
@@ -0,0 +1,718 @@
+//======================================================================

+//

+// tb_sha256.v

+// -----------

+// Testbench for the SHA-256 top level wrapper.

+//

+//

+// 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 tb_sha256();

+

+  //----------------------------------------------------------------

+  // Internal constant and parameter definitions.

+  //----------------------------------------------------------------

+  parameter DEBUG = 0;

+

+  parameter CLK_HALF_PERIOD = 2;

+  parameter CLK_PERIOD = 2 * CLK_HALF_PERIOD;

+

+  // The address map.

+  parameter ADDR_NAME0       = 8'h00;

+  parameter ADDR_NAME1       = 8'h01;

+  parameter ADDR_VERSION     = 8'h02;

+

+  parameter ADDR_CTRL        = 8'h08;

+  parameter CTRL_INIT_VALUE  = 8'h01;

+  parameter CTRL_NEXT_VALUE  = 8'h02;

+  parameter CTRL_MODE_VALUE  = 8'h04;

+

+  parameter ADDR_STATUS      = 8'h09;

+  parameter STATUS_READY_BIT = 0;

+  parameter STATUS_VALID_BIT = 1;

+

+  parameter ADDR_BLOCK0    = 8'h10;

+  parameter ADDR_BLOCK1    = 8'h11;

+  parameter ADDR_BLOCK2    = 8'h12;

+  parameter ADDR_BLOCK3    = 8'h13;

+  parameter ADDR_BLOCK4    = 8'h14;

+  parameter ADDR_BLOCK5    = 8'h15;

+  parameter ADDR_BLOCK6    = 8'h16;

+  parameter ADDR_BLOCK7    = 8'h17;

+  parameter ADDR_BLOCK8    = 8'h18;

+  parameter ADDR_BLOCK9    = 8'h19;

+  parameter ADDR_BLOCK10   = 8'h1a;

+  parameter ADDR_BLOCK11   = 8'h1b;

+  parameter ADDR_BLOCK12   = 8'h1c;

+  parameter ADDR_BLOCK13   = 8'h1d;

+  parameter ADDR_BLOCK14   = 8'h1e;

+  parameter ADDR_BLOCK15   = 8'h1f;

+

+  parameter ADDR_DIGEST0   = 8'h20;

+  parameter ADDR_DIGEST1   = 8'h21;

+  parameter ADDR_DIGEST2   = 8'h22;

+  parameter ADDR_DIGEST3   = 8'h23;

+  parameter ADDR_DIGEST4   = 8'h24;

+  parameter ADDR_DIGEST5   = 8'h25;

+  parameter ADDR_DIGEST6   = 8'h26;

+  parameter ADDR_DIGEST7   = 8'h27;

+

+  parameter SHA224_MODE    = 0;

+  parameter SHA256_MODE    = 1;

+

+

+  //----------------------------------------------------------------

+  // Register and Wire declarations.

+  //----------------------------------------------------------------

+  reg [31 : 0] cycle_ctr;

+  reg [31 : 0] error_ctr;

+  reg [31 : 0] tc_ctr;

+

+  reg           tb_clk;

+  reg           tb_reset_n;

+  reg           tb_cs;

+  reg           tb_we;

+  reg [7 : 0]   tb_address;

+  reg [31 : 0]  tb_write_data;

+  wire [31 : 0] tb_read_data;

+  wire          tb_error;

+

+  reg [31 : 0]  read_data;

+  reg [255 : 0] digest_data;

+

+

+  //----------------------------------------------------------------

+  // Device Under Test.

+  //----------------------------------------------------------------

+  sha256 dut(

+             .clk(tb_clk),

+             .reset_n(tb_reset_n),

+

+             .cs(tb_cs),

+             .we(tb_we),

+

+

+             .address(tb_address),

+             .write_data(tb_write_data),

+             .read_data(tb_read_data),

+             .error(tb_error)

+            );

+

+

+  //----------------------------------------------------------------

+  // clk_gen

+  //

+  // Clock generator process.

+  //----------------------------------------------------------------

+  always

+    begin : clk_gen

+      #CLK_HALF_PERIOD tb_clk = !tb_clk;

+    end // clk_gen

+

+

+  //----------------------------------------------------------------

+  // sys_monitor

+  //

+  // Generates a cycle counter and displays information about

+  // the dut as needed.

+  //----------------------------------------------------------------

+  always

+    begin : sys_monitor

+      #(2 * CLK_HALF_PERIOD);

+      cycle_ctr = cycle_ctr + 1;

+    end

+

+

+  //----------------------------------------------------------------

+  // dump_dut_state()

+  //

+  // Dump the state of the dump when needed.

+  //----------------------------------------------------------------

+  task dump_dut_state;

+    begin

+      $display("State of DUT");

+      $display("------------");

+      $display("Inputs and outputs:");

+      $display("cs = 0x%01x, we = 0x%01x",

+               dut.cs, dut.we);

+      $display("address = 0x%02x", dut.address);

+      $display("write_data = 0x%08x, read_data = 0x%08x",

+               dut.write_data, dut.read_data);

+      $display("tmp_read_data = 0x%08x", dut.tmp_read_data);

+      $display("");

+

+      $display("Control and status:");

+      $display("ctrl = 0x%02x, status = 0x%02x",

+               {dut.next_reg, dut.init_reg},

+               {dut.digest_valid_reg, dut.ready_reg});

+      $display("");

+

+      $display("Message block:");

+      $display("block0  = 0x%08x, block1  = 0x%08x, block2  = 0x%08x,  block3  = 0x%08x",

+               dut.block_reg[00], dut.block_reg[01], dut.block_reg[02], dut.block_reg[03]);

+//      $display("block4  = 0x%08x, block5  = 0x%08x, block6  = 0x%08x,  block7  = 0x%08x",

+//               dut.block_reg[04], dut.block_reg[05], dut.block_reg[06], dut.block_reg[07]);

+

+      $display("block8  = 0x%08x, block9  = 0x%08x, block10 = 0x%08x,  block11 = 0x%08x",

+               dut.block_reg[08], dut.block_reg[09], dut.block_reg[10], dut.block_reg[11]);

+      $display("block12 = 0x%08x, block13 = 0x%08x, block14 = 0x%08x,  block15 = 0x%08x",

+               dut.block_reg[12], dut.block_reg[13], dut.block_reg[14], dut.block_reg[15]);

+      $display("");

+

+      $display("Digest:");

+      $display("digest = 0x%064x", dut.digest_reg);

+      $display("");

+

+    end

+  endtask // dump_dut_state

+

+

+  //----------------------------------------------------------------

+  // reset_dut()

+  //

+  // Toggles reset to force the DUT into a well defined state.

+  //----------------------------------------------------------------

+  task reset_dut;

+    begin

+      $display("*** Toggle reset.");

+      tb_reset_n = 0;

+      #(4 * CLK_HALF_PERIOD);

+      tb_reset_n = 1;

+    end

+  endtask // reset_dut

+

+

+  //----------------------------------------------------------------

+  // init_sim()

+  //

+  // Initialize all counters and testbed functionality as well

+  // as setting the DUT inputs to defined values.

+  //----------------------------------------------------------------

+  task init_sim;

+    begin

+      cycle_ctr = 32'h0;

+      error_ctr = 32'h0;

+      tc_ctr = 32'h0;

+

+      tb_clk = 0;

+      tb_reset_n = 0;

+      tb_cs = 0;

+      tb_we = 0;

+      tb_address = 6'h0;

+      tb_write_data = 32'h0;

+    end

+  endtask // init_dut

+

+

+  //----------------------------------------------------------------

+  // display_test_result()

+  //

+  // Display the accumulated test results.

+  //----------------------------------------------------------------

+  task display_test_result;

+    begin

+      if (error_ctr == 0)

+        begin

+          $display("*** All %02d test cases completed successfully.", tc_ctr);

+        end

+      else

+        begin

+          $display("*** %02d test cases completed.", tc_ctr);

+          $display("*** %02d errors detected during testing.", error_ctr);

+        end

+    end

+  endtask // display_test_result

+

+

+  //----------------------------------------------------------------

+  // wait_ready()

+  //

+  // Wait for the ready flag in the dut to be set.

+  // (Actually we wait for either ready or valid to be set.)

+  //

+  // Note: It is the callers responsibility to call the function

+  // when the dut is actively processing and will in fact at some

+  // point set the flag.

+  //----------------------------------------------------------------

+  task wait_ready;

+    begin

+      read_data = 0;

+

+      while (read_data == 0)

+        begin

+          read_word(ADDR_STATUS);

+        end

+    end

+  endtask // wait_ready

+

+

+  //----------------------------------------------------------------

+  // write_word()

+  //

+  // Write the given word to the DUT using the DUT interface.

+  //----------------------------------------------------------------

+  task write_word(input [7 : 0]  address,

+                  input [31 : 0] word);

+    begin

+      if (DEBUG)

+        begin

+          $display("*** Writing 0x%08x to 0x%02x.", word, address);

+          $display("");

+        end

+

+      tb_address = address;

+      tb_write_data = word;

+      tb_cs = 1;

+      tb_we = 1;

+      #(CLK_PERIOD);

+      tb_cs = 0;

+      tb_we = 0;

+    end

+  endtask // write_word

+

+

+  //----------------------------------------------------------------

+  // write_block()

+  //

+  // Write the given block to the dut.

+  //----------------------------------------------------------------

+  task write_block(input [511 : 0] block);

+    begin

+      write_word(ADDR_BLOCK0,  block[511 : 480]);

+      write_word(ADDR_BLOCK1,  block[479 : 448]);

+      write_word(ADDR_BLOCK2,  block[447 : 416]);

+      write_word(ADDR_BLOCK3,  block[415 : 384]);

+      write_word(ADDR_BLOCK4,  block[383 : 352]);

+      write_word(ADDR_BLOCK5,  block[351 : 320]);

+      write_word(ADDR_BLOCK6,  block[319 : 288]);

+      write_word(ADDR_BLOCK7,  block[287 : 256]);

+      write_word(ADDR_BLOCK8,  block[255 : 224]);

+      write_word(ADDR_BLOCK9,  block[223 : 192]);

+      write_word(ADDR_BLOCK10, block[191 : 160]);

+      write_word(ADDR_BLOCK11, block[159 : 128]);

+      write_word(ADDR_BLOCK12, block[127 :  96]);

+      write_word(ADDR_BLOCK13, block[95  :  64]);

+      write_word(ADDR_BLOCK14, block[63  :  32]);

+      write_word(ADDR_BLOCK15, block[31  :   0]);

+    end

+  endtask // write_block

+

+

+  //----------------------------------------------------------------

+  // read_word()

+  //

+  // Read a data word from the given address in the DUT.

+  // the word read will be available in the global variable

+  // read_data.

+  //----------------------------------------------------------------

+  task read_word(input [7 : 0]  address);

+    begin

+      tb_address = address;

+      tb_cs = 1;

+      tb_we = 0;

+      #(CLK_PERIOD);

+      read_data = tb_read_data;

+      tb_cs = 0;

+

+      if (DEBUG)

+        begin

+          $display("*** Reading 0x%08x from 0x%02x.", read_data, address);

+          $display("");

+        end

+    end

+  endtask // read_word

+

+

+  //----------------------------------------------------------------

+  // check_name_version()

+  //

+  // Read the name and version from the DUT.

+  //----------------------------------------------------------------

+  task check_name_version;

+    reg [31 : 0] name0;

+    reg [31 : 0] name1;

+    reg [31 : 0] version;

+    begin

+

+      read_word(ADDR_NAME0);

+      name0 = read_data;

+      read_word(ADDR_NAME1);

+      name1 = read_data;

+      read_word(ADDR_VERSION);

+      version = read_data;

+

+      $display("DUT name: %c%c%c%c%c%c%c%c",

+               name0[31 : 24], name0[23 : 16], name0[15 : 8], name0[7 : 0],

+               name1[31 : 24], name1[23 : 16], name1[15 : 8], name1[7 : 0]);

+      $display("DUT version: %c%c%c%c",

+               version[31 : 24], version[23 : 16], version[15 : 8], version[7 : 0]);

+    end

+  endtask // check_name_version

+

+

+  //----------------------------------------------------------------

+  // read_digest()

+  //

+  // Read the digest in the dut. The resulting digest will be

+  // available in the global variable digest_data.

+  //----------------------------------------------------------------

+  task read_digest;

+    begin

+      read_word(ADDR_DIGEST0);

+      digest_data[255 : 224] = read_data;

+      read_word(ADDR_DIGEST1);

+      digest_data[223 : 192] = read_data;

+      read_word(ADDR_DIGEST2);

+      digest_data[191 : 160] = read_data;

+      read_word(ADDR_DIGEST3);

+      digest_data[159 : 128] = read_data;

+      read_word(ADDR_DIGEST4);

+      digest_data[127 :  96] = read_data;

+      read_word(ADDR_DIGEST5);

+      digest_data[95  :  64] = read_data;

+      read_word(ADDR_DIGEST6);

+      digest_data[63  :  32] = read_data;

+      read_word(ADDR_DIGEST7);

+      digest_data[31  :   0] = read_data;

+    end

+  endtask // read_digest

+

+

+  //----------------------------------------------------------------

+  // single_block_test()

+  //

+  //

+  // Perform test of a single block digest.

+  //----------------------------------------------------------------

+  task single_block_test(input           mode,

+                         input [511 : 0] block,

+                         input [255 : 0] expected);

+    begin

+      $display("*** TC%01d - Single block test started.", tc_ctr);

+

+      write_block(block);

+

+      if (mode)

+        write_word(ADDR_CTRL, (CTRL_MODE_VALUE + CTRL_INIT_VALUE));

+      else

+        write_word(ADDR_CTRL, CTRL_INIT_VALUE);

+

+      #(CLK_PERIOD);

+      wait_ready();

+      read_digest();

+

+      // We need to ignore the LSW in SHA224 mode.

+      if (mode == SHA224_MODE)

+        digest_data[31 : 0] = 32'h0;

+

+      if (digest_data == expected)

+        begin

+          $display("TC%01d: OK.", tc_ctr);

+        end

+      else

+        begin

+          $display("TC%01d: ERROR.", tc_ctr);

+          $display("TC%01d: Expected: 0x%064x", tc_ctr, expected);

+          $display("TC%01d: Got:      0x%064x", tc_ctr, digest_data);

+          error_ctr = error_ctr + 1;

+        end

+      $display("*** TC%01d - Single block test done.", tc_ctr);

+      tc_ctr = tc_ctr + 1;

+    end

+  endtask // single_block_test

+

+

+  //----------------------------------------------------------------

+  // double_block_test()

+  //

+  //

+  // Perform test of a double block digest. Note that we check

+  // the digests for both the first and final block.

+  //----------------------------------------------------------------

+  task double_block_test(input           mode,

+                         input [511 : 0] block0,

+                         input [255 : 0] expected0,

+                         input [511 : 0] block1,

+                         input [255 : 0] expected1

+                        );

+    begin

+      $display("*** TC%01d - Double block test started.", tc_ctr);

+

+      // First block

+      write_block(block0);

+

+      if (mode)

+        write_word(ADDR_CTRL, (CTRL_MODE_VALUE + CTRL_INIT_VALUE));

+      else

+        write_word(ADDR_CTRL, CTRL_INIT_VALUE);

+

+      #(CLK_PERIOD);

+      wait_ready();

+      read_digest();

+

+      // We need to ignore the LSW in SHA224 mode.

+      if (mode == SHA224_MODE)

+        digest_data[31 : 0] = 32'h0;

+

+      if (digest_data == expected0)

+        begin

+          $display("TC%01d first block: OK.", tc_ctr);

+        end

+      else

+        begin

+          $display("TC%01d: ERROR in first digest", tc_ctr);

+          $display("TC%01d: Expected: 0x%064x", tc_ctr, expected0);

+          $display("TC%01d: Got:      0x%064x", tc_ctr, digest_data);

+          error_ctr = error_ctr + 1;

+        end

+

+      // Final block

+      write_block(block1);

+

+      if (mode)

+        write_word(ADDR_CTRL, (CTRL_MODE_VALUE + CTRL_NEXT_VALUE));

+      else

+        write_word(ADDR_CTRL, CTRL_NEXT_VALUE);

+

+      #(CLK_PERIOD);

+      wait_ready();

+      read_digest();

+

+      // We need to ignore the LSW in SHA224 mode.

+      if (mode == SHA224_MODE)

+        digest_data[31 : 0] = 32'h0;

+

+      if (digest_data == expected1)

+        begin

+          $display("TC%01d final block: OK.", tc_ctr);

+        end

+      else

+        begin

+          $display("TC%01d: ERROR in final digest", tc_ctr);

+          $display("TC%01d: Expected: 0x%064x", tc_ctr, expected1);

+          $display("TC%01d: Got:      0x%064x", tc_ctr, digest_data);

+          error_ctr = error_ctr + 1;

+        end

+

+      $display("*** TC%01d - Double block test done.", tc_ctr);

+      tc_ctr = tc_ctr + 1;

+    end

+  endtask // double_block_test

+

+

+  //----------------------------------------------------------------

+  // sha224_tests()

+  //

+  // Run test cases for sha224.

+  // Test cases taken from:

+  // http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/SHA224.pdf

+  //----------------------------------------------------------------

+  task sha224_tests;

+    begin : sha224_tests_block

+      reg [511 : 0] tc0;

+      reg [255 : 0] res0;

+

+      reg [511 : 0] tc1_0;

+      reg [255 : 0] res1_0;

+      reg [511 : 0] tc1_1;

+      reg [255 : 0] res1_1;

+

+      $display("*** Testcases for sha224 functionality started.");

+

+      tc0 = 512'h61626380000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018;

+

+      res0 = 256'h23097D223405D8228642A477BDA255B32AADBCE4BDA0B3F7E36C9DA700000000;

+      single_block_test(SHA224_MODE, tc0, res0);

+

+      tc1_0 = 512'h6162636462636465636465666465666765666768666768696768696A68696A6B696A6B6C6A6B6C6D6B6C6D6E6C6D6E6F6D6E6F706E6F70718000000000000000;

+      res1_0 = 256'h8250e65dbcf62f8466659c3333e5e91a10c8b7b0953927691f1419c200000000;

+      tc1_1 = 512'h000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001C0;

+      res1_1 = 256'h75388b16512776cc5dba5da1fd890150b0c6455cb4f58b195252252500000000;

+      double_block_test(SHA224_MODE, tc1_0, res1_0, tc1_1, res1_1);

+

+      $display("*** Testcases for sha224 functionality completed.");

+    end

+  endtask // sha224_tests

+

+

+  //----------------------------------------------------------------

+  // sha256_tests()

+  //

+  // Run test cases for sha256.

+  // Test cases taken from:

+  // http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/SHA256.pdf

+  //----------------------------------------------------------------

+  task sha256_tests;

+    begin : sha256_tests_block

+      reg [511 : 0] tc0;

+      reg [255 : 0] res0;

+

+      reg [511 : 0] tc1_0;

+      reg [255 : 0] res1_0;

+      reg [511 : 0] tc1_1;

+      reg [255 : 0] res1_1;

+

+      $display("*** Testcases for sha256 functionality started.");

+

+      tc0 = 512'h61626380000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018;

+      res0 = 256'hBA7816BF8F01CFEA414140DE5DAE2223B00361A396177A9CB410FF61F20015AD;

+      single_block_test(SHA256_MODE, tc0, res0);

+

+      tc1_0 = 512'h6162636462636465636465666465666765666768666768696768696A68696A6B696A6B6C6A6B6C6D6B6C6D6E6C6D6E6F6D6E6F706E6F70718000000000000000;

+      res1_0 = 256'h85E655D6417A17953363376A624CDE5C76E09589CAC5F811CC4B32C1F20E533A;

+      tc1_1 = 512'h000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001C0;

+      res1_1 = 256'h248D6A61D20638B8E5C026930C3E6039A33CE45964FF2167F6ECEDD419DB06C1;

+      double_block_test(SHA256_MODE, tc1_0, res1_0, tc1_1, res1_1);

+

+      $display("*** Testcases for sha256 functionality completed.");

+    end

+  endtask // sha256_tests

+

+

+

+  //----------------------------------------------------------------

+  // issue_test()

+  //----------------------------------------------------------------

+  task issue_test

+    reg [511 : 0] block0;

+    reg [511 : 0] block1;

+    reg [511 : 0] block2;

+    reg [511 : 0] block3;

+    reg [511 : 0] block4;

+    reg [511 : 0] block5;

+    reg [511 : 0] block6;

+    reg [511 : 0] block7;

+    reg [511 : 0] block8;

+    reg [255 : 0] expected;

+    begin : issue_test;

+      block0 = 512'h6b900001_496e2074_68652061_72656120_6f662049_6f542028_496e7465_726e6574_206f6620_5468696e_6773292c_206d6f72_6520616e_64206d6f_7265626f_6f6d2c20;

+      block1 = 512'h69742068_61732062_65656e20_6120756e_69766572_73616c20_636f6e73_656e7375_73207468_61742064_61746120_69732074_69732061_206e6577_20746563_686e6f6c;

+      block2 = 512'h6f677920_74686174_20696e74_65677261_74657320_64656365_6e747261_6c697a61_74696f6e_2c496e20_74686520_61726561_206f6620_496f5420_28496e74_65726e65;

+      block3 = 512'h74206f66_20546869_6e677329_2c206d6f_72652061_6e64206d_6f726562_6f6f6d2c_20697420_68617320_6265656e_20612075_6e697665_7273616c_20636f6e_73656e73;

+      block4 = 512'h75732074_68617420_64617461_20697320_74697320_61206e65_77207465_63686e6f_6c6f6779_20746861_7420696e_74656772_61746573_20646563_656e7472_616c697a;

+      block5 = 512'h6174696f_6e2c496e_20746865_20617265_61206f66_20496f54_2028496e_7465726e_6574206f_66205468_696e6773_292c206d_6f726520_616e6420_6d6f7265_626f6f6d;

+      block6 = 512'h2c206974_20686173_20626565_6e206120_756e6976_65727361_6c20636f_6e73656e_73757320_74686174_20646174_61206973_20746973_2061206e_65772074_6563686e;

+      block7 = 512'h6f6c6f67_79207468_61742069_6e746567_72617465_73206465_63656e74_72616c69_7a617469_6f6e2c49_6e207468_65206172_6561206f_6620496f_54202849_6e746572;

+      block8 = 512'h6e657420_6f662054_68696e67_73292c20_6d6f7265_20616e64_206d6f72_65800000_00000000_00000000_00000000_00000000_00000000_00000000_00000000_000010e8;

+

+      expected = 256'h7758a30bbdfc9cd92b284b05e9be9ca3d269d3d149e7e82ab4a9ed5e81fbcf9d;

+

+      $display("Running test for 9 block issue.");

+      tc_ctr = tc_ctr + 1;

+      write_block(block0);

+      write_word(ADDR_CTRL, (CTRL_MODE_VALUE + CTRL_INIT_VALUE));

+      #(CLK_PERIOD);

+      wait_ready();

+

+      write_block(block1);

+      write_word(ADDR_CTRL, (CTRL_MODE_VALUE + CTRL_NEXT_VALUE));

+      #(CLK_PERIOD);

+      wait_ready();

+

+      write_block(block2);

+      write_word(ADDR_CTRL, (CTRL_MODE_VALUE + CTRL_NEXT_VALUE));

+      #(CLK_PERIOD);

+      wait_ready();

+

+      write_block(block3);

+      write_word(ADDR_CTRL, (CTRL_MODE_VALUE + CTRL_NEXT_VALUE));

+      #(CLK_PERIOD);

+      wait_ready();

+

+      write_block(block4);

+      write_word(ADDR_CTRL, (CTRL_MODE_VALUE + CTRL_NEXT_VALUE));

+      #(CLK_PERIOD);

+      wait_ready();

+

+      write_block(block5);

+      write_word(ADDR_CTRL, (CTRL_MODE_VALUE + CTRL_NEXT_VALUE));

+      #(CLK_PERIOD);

+      wait_ready();

+

+      write_block(block6);

+      write_word(ADDR_CTRL, (CTRL_MODE_VALUE + CTRL_NEXT_VALUE));

+      #(CLK_PERIOD);

+      wait_ready();

+

+      write_block(block7);

+      write_word(ADDR_CTRL, (CTRL_MODE_VALUE + CTRL_NEXT_VALUE));

+      #(CLK_PERIOD);

+      wait_ready();

+

+      write_block(block8);

+      write_word(ADDR_CTRL, (CTRL_MODE_VALUE + CTRL_NEXT_VALUE));

+      #(CLK_PERIOD);

+      wait_ready();

+

+      read_digest();

+      if (digest_data == expected)

+        begin

+          $display("Digest ok.");

+        end

+      else

+        begin

+          $display("ERROR in digest");

+          $display("Expected: 0x%064x", expected);

+          $display("Got:      0x%064x", digest_data);

+          error_ctr = error_ctr + 1;

+        end

+    end

+  endtask // issue_test

+

+

+  //----------------------------------------------------------------

+  // The main test functionality.

+  //----------------------------------------------------------------

+  initial

+    begin : main

+      $display("   -- Testbench for sha256 started --");

+

+      init_sim();

+      reset_dut();

+

+      check_name_version();

+      sha224_tests();

+      sha256_tests();

+      issue_test();

+

+      display_test_result();

+

+      $display("   -- Testbench for sha256 done. --");

+      $finish;

+    end // main

+endmodule // tb_sha256

+

+//======================================================================

+// EOF tb_sha256.v

+//======================================================================

diff --git a/Verilog_Code/tb_sha256_core.v b/Verilog_Code/tb_sha256_core.v
new file mode 100644
index 0000000..acf3867
--- /dev/null
+++ b/Verilog_Code/tb_sha256_core.v
@@ -0,0 +1,521 @@
+//======================================================================

+//

+// tb_sha256_core.v

+// ----------------

+// Testbench for the SHA-256 core.

+//

+//

+// 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 tb_sha256_core();

+

+  //----------------------------------------------------------------

+  // Internal constant and parameter definitions.

+  //----------------------------------------------------------------

+  parameter DEBUG = 0;

+

+  parameter CLK_HALF_PERIOD = 2;

+  parameter CLK_PERIOD = 2 * CLK_HALF_PERIOD;

+

+

+  //----------------------------------------------------------------

+  // Register and Wire declarations.

+  //----------------------------------------------------------------

+  reg [31 : 0] cycle_ctr;

+  reg [31 : 0] error_ctr;

+  reg [31 : 0] tc_ctr;

+

+  reg            tb_clk;

+  reg            tb_reset_n;

+  reg            tb_init;

+  reg            tb_next;

+  reg            tb_mode;

+  reg [511 : 0]  tb_block;

+  wire           tb_ready;

+  wire [255 : 0] tb_digest;

+  wire           tb_digest_valid;

+

+

+  //----------------------------------------------------------------

+  // Device Under Test.

+  //----------------------------------------------------------------

+  sha256_core dut(

+                  .clk(tb_clk),

+                  .reset_n(tb_reset_n),

+

+                  .init(tb_init),

+                  .next(tb_next),

+                  .mode(tb_mode),

+

+                  .block(tb_block),

+

+                  .ready(tb_ready),

+

+                  .digest(tb_digest),

+                  .digest_valid(tb_digest_valid)

+                 );

+

+

+  //----------------------------------------------------------------

+  // clk_gen

+  //

+  // Always running clock generator process.

+  //----------------------------------------------------------------

+  always

+    begin : clk_gen

+      #CLK_HALF_PERIOD;

+      tb_clk = !tb_clk;

+    end // clk_gen

+

+

+  //----------------------------------------------------------------

+  // sys_monitor()

+  //

+  // An always running process that creates a cycle counter and

+  // conditionally displays information about the DUT.

+  //----------------------------------------------------------------

+  always

+    begin : sys_monitor

+      cycle_ctr = cycle_ctr + 1;

+      #(2 * CLK_HALF_PERIOD);

+      if (DEBUG)

+        begin

+          dump_dut_state();

+        end

+    end

+

+

+  //----------------------------------------------------------------

+  // dump_dut_state()

+  //

+  // Dump the state of the dump when needed.

+  //----------------------------------------------------------------

+  task dump_dut_state;

+    begin

+      $display("State of DUT");

+      $display("------------");

+      $display("Inputs and outputs:");

+      $display("init   = 0x%01x, next  = 0x%01x",

+               dut.init, dut.next);

+      $display("block  = 0x%0128x", dut.block);

+

+      $display("ready  = 0x%01x, valid = 0x%01x",

+               dut.ready, dut.digest_valid);

+      $display("digest = 0x%064x", dut.digest);

+      $display("H0_reg = 0x%08x, H1_reg = 0x%08x, H2_reg = 0x%08x, H3_reg = 0x%08x",

+               dut.H0_reg, dut.H1_reg, dut.H2_reg, dut.H3_reg);

+      $display("H4_reg = 0x%08x, H5_reg = 0x%08x, H6_reg = 0x%08x, H7_reg = 0x%08x",

+               dut.H4_reg, dut.H5_reg, dut.H6_reg, dut.H7_reg);

+      $display("");

+

+      $display("Control signals and counter:");

+      $display("sha256_ctrl_reg = 0x%02x", dut.sha256_ctrl_reg);

+      $display("digest_init     = 0x%01x, digest_update = 0x%01x",

+               dut.digest_init, dut.digest_update);

+      $display("state_init      = 0x%01x, state_update  = 0x%01x",

+               dut.state_init, dut.state_update);

+      $display("first_block     = 0x%01x, ready_flag    = 0x%01x, w_init    = 0x%01x",

+               dut.first_block, dut.ready_flag, dut.w_init);

+      $display("t_ctr_inc       = 0x%01x, t_ctr_rst     = 0x%01x, t_ctr_reg = 0x%02x",

+               dut.t_ctr_inc, dut.t_ctr_rst, dut.t_ctr_reg);

+      $display("");

+

+      $display("State registers:");

+      $display("a_reg = 0x%08x, b_reg = 0x%08x, c_reg = 0x%08x, d_reg = 0x%08x",

+               dut.a_reg, dut.b_reg, dut.c_reg, dut.d_reg);

+      $display("e_reg = 0x%08x, f_reg = 0x%08x, g_reg = 0x%08x, h_reg = 0x%08x",

+               dut.e_reg, dut.f_reg, dut.g_reg, dut.h_reg);

+      $display("");

+      $display("a_new = 0x%08x, b_new = 0x%08x, c_new = 0x%08x, d_new = 0x%08x",

+               dut.a_new, dut.b_new, dut.c_new, dut.d_new);

+      $display("e_new = 0x%08x, f_new = 0x%08x, g_new = 0x%08x, h_new = 0x%08x",

+               dut.e_new, dut.f_new, dut.g_new, dut.h_new);

+      $display("");

+

+      $display("State update values:");

+      $display("w  = 0x%08x, k  = 0x%08x", dut.w_data, dut.k_data);

+      $display("t1 = 0x%08x, t2 = 0x%08x", dut.t1, dut.t2);

+      $display("");

+    end

+  endtask // dump_dut_state

+

+

+  //----------------------------------------------------------------

+  // reset_dut()

+  //

+  // Toggle reset to put the DUT into a well known state.

+  //----------------------------------------------------------------

+  task reset_dut;

+    begin

+      $display("*** Toggle reset.");

+      tb_reset_n = 0;

+      #(4 * CLK_HALF_PERIOD);

+      tb_reset_n = 1;

+    end

+  endtask // reset_dut

+

+

+  //----------------------------------------------------------------

+  // init_sim()

+  //

+  // Initialize all counters and testbed functionality as well

+  // as setting the DUT inputs to defined values.

+  //----------------------------------------------------------------

+  task init_sim;

+    begin

+      cycle_ctr = 0;

+      error_ctr = 0;

+      tc_ctr = 0;

+

+      tb_clk = 0;

+      tb_reset_n = 1;

+

+      tb_init = 0;

+      tb_next = 0;

+      tb_mode = 1;

+      tb_block = 512'h00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000;

+    end

+  endtask // init_dut

+

+

+  //----------------------------------------------------------------

+  // display_test_result()

+  //

+  // Display the accumulated test results.

+  //----------------------------------------------------------------

+  task display_test_result;

+    begin

+      if (error_ctr == 0)

+        begin

+          $display("*** All %02d test cases completed successfully", tc_ctr);

+        end

+      else

+        begin

+          $display("*** %02d test cases did not complete successfully.", error_ctr);

+        end

+    end

+  endtask // display_test_result

+

+

+  //----------------------------------------------------------------

+  // wait_ready()

+  //

+  // Wait for the ready flag in the dut to be set.

+  //

+  // Note: It is the callers responsibility to call the function

+  // when the dut is actively processing and will in fact at some

+  // point set the flag.

+  //----------------------------------------------------------------

+  task wait_ready;

+    begin

+      while (!tb_ready)

+        begin

+          #(CLK_PERIOD);

+        end

+    end

+  endtask // wait_ready

+

+

+  //----------------------------------------------------------------

+  // single_block_test()

+  //

+  // Run a test case spanning a single data block.

+  //----------------------------------------------------------------

+  task single_block_test(input [7 : 0]   tc_number,

+                         input [511 : 0] block,

+                         input [255 : 0] expected);

+   begin

+     $display("*** TC %0d single block test case started.", tc_number);

+     tc_ctr = tc_ctr + 1;

+

+     tb_block = block;

+     tb_init = 1;

+     #(CLK_PERIOD);

+     wait_ready();

+

+

+     if (tb_digest == expected)

+       begin

+         $display("*** TC %0d successful.", tc_number);

+         $display("");

+       end

+     else

+       begin

+         $display("*** ERROR: TC %0d NOT successful.", tc_number);

+         $display("Expected: 0x%064x", expected);

+         $display("Got:      0x%064x", tb_digest);

+         $display("");

+

+         error_ctr = error_ctr + 1;

+       end

+   end

+  endtask // single_block_test

+

+

+  //----------------------------------------------------------------

+  // double_block_test()

+  //

+  // Run a test case spanning two data blocks. We check both

+  // intermediate and final digest.

+  //----------------------------------------------------------------

+  task double_block_test(input [7 : 0]   tc_number,

+                         input [511 : 0] block1,

+                         input [255 : 0] expected1,

+                         input [511 : 0] block2,

+                         input [255 : 0] expected2);

+

+     reg [255 : 0] db_digest1;

+     reg [255 : 0] db_digest2;

+     reg           db_error;

+   begin

+     $display("*** TC %0d double block test case started.", tc_number);

+     db_error = 0;

+     tc_ctr = tc_ctr + 1;

+

+     $display("*** TC %0d first block started.", tc_number);

+     tb_block = block1;

+     tb_init = 1;

+     #(CLK_PERIOD);

+     tb_init = 0;

+     wait_ready();

+     db_digest1 = tb_digest;

+     $display("*** TC %0d first block done.", tc_number);

+

+     $display("*** TC %0d second block started.", tc_number);

+     tb_block = block2;

+     tb_next = 1;

+     #(CLK_PERIOD);

+     tb_next = 0;

+     wait_ready();

+     db_digest2 = tb_digest;

+     $display("*** TC %0d second block done.", tc_number);

+

+     if (DEBUG)

+       begin

+         $display("Generated digests:");

+         $display("Expected 1: 0x%064x", expected1);

+         $display("Got      1: 0x%064x", db_digest1);

+         $display("Expected 2: 0x%064x", expected2);

+         $display("Got      2: 0x%064x", db_digest2);

+         $display("");

+       end

+

+     if (db_digest1 == expected1)

+       begin

+         $display("*** TC %0d first block successful", tc_number);

+         $display("");

+       end

+     else

+       begin

+         $display("*** ERROR: TC %0d first block NOT successful", tc_number);

+         $display("Expected: 0x%064x", expected1);

+         $display("Got:      0x%064x", db_digest1);

+         $display("");

+         db_error = 1;

+       end

+

+     if (db_digest2 == expected2)

+       begin

+         $display("*** TC %0d second block successful", tc_number);

+         $display("");

+       end

+     else

+       begin

+         $display("*** ERROR: TC %0d second block NOT successful", tc_number);

+         $display("Expected: 0x%064x", expected2);

+         $display("Got:      0x%064x", db_digest2);

+         $display("");

+         db_error = 1;

+       end

+

+     if (db_error)

+       begin

+         error_ctr = error_ctr + 1;

+       end

+   end

+  endtask // double_block_test

+

+

+  //----------------------------------------------------------------

+  // issue_test()

+  //----------------------------------------------------------------

+  task issue_test;

+   

+    reg [511 : 0] block0;

+    reg [511 : 0] block1;

+    reg [511 : 0] block2;

+    reg [511 : 0] block3;

+    reg [511 : 0] block4;

+    reg [511 : 0] block5;

+    reg [511 : 0] block6;

+    reg [511 : 0] block7;

+    reg [511 : 0] block8;

+    reg [255 : 0] expected;

+    begin :issue_test

+      block0 = 512'h6b900001_496e2074_68652061_72656120_6f662049_6f542028_496e7465_726e6574_206f6620_5468696e_6773292c_206d6f72_6520616e_64206d6f_7265626f_6f6d2c20;

+      block1 = 512'h69742068_61732062_65656e20_6120756e_69766572_73616c20_636f6e73_656e7375_73207468_61742064_61746120_69732074_69732061_206e6577_20746563_686e6f6c;

+      block2 = 512'h6f677920_74686174_20696e74_65677261_74657320_64656365_6e747261_6c697a61_74696f6e_2c496e20_74686520_61726561_206f6620_496f5420_28496e74_65726e65;

+      block3 = 512'h74206f66_20546869_6e677329_2c206d6f_72652061_6e64206d_6f726562_6f6f6d2c_20697420_68617320_6265656e_20612075_6e697665_7273616c_20636f6e_73656e73;

+      block4 = 512'h75732074_68617420_64617461_20697320_74697320_61206e65_77207465_63686e6f_6c6f6779_20746861_7420696e_74656772_61746573_20646563_656e7472_616c697a;

+      block5 = 512'h6174696f_6e2c496e_20746865_20617265_61206f66_20496f54_2028496e_7465726e_6574206f_66205468_696e6773_292c206d_6f726520_616e6420_6d6f7265_626f6f6d;

+      block6 = 512'h2c206974_20686173_20626565_6e206120_756e6976_65727361_6c20636f_6e73656e_73757320_74686174_20646174_61206973_20746973_2061206e_65772074_6563686e;

+      block7 = 512'h6f6c6f67_79207468_61742069_6e746567_72617465_73206465_63656e74_72616c69_7a617469_6f6e2c49_6e207468_65206172_6561206f_6620496f_54202849_6e746572;

+      block8 = 512'h6e657420_6f662054_68696e67_73292c20_6d6f7265_20616e64_206d6f72_65800000_00000000_00000000_00000000_00000000_00000000_00000000_00000000_000010e8;

+

+      expected = 256'h7758a30bbdfc9cd92b284b05e9be9ca3d269d3d149e7e82ab4a9ed5e81fbcf9d;

+

+      $display("Running test for 9 block issue.");

+      tc_ctr = tc_ctr + 1;

+      tb_block = block0;

+      tb_init = 1;

+      #(CLK_PERIOD);

+      tb_init = 0;

+      wait_ready();

+

+      tb_block = block1;

+      tb_next = 1;

+      #(CLK_PERIOD);

+      tb_next = 0;

+      wait_ready();

+

+      tb_block = block2;

+      tb_next = 1;

+      #(CLK_PERIOD);

+      tb_next = 0;

+      wait_ready();

+

+      tb_block = block3;

+      tb_next = 1;

+      #(CLK_PERIOD);

+      tb_next = 0;

+      wait_ready();

+

+      tb_block = block4;

+      tb_next = 1;

+      #(CLK_PERIOD);

+      tb_next = 0;

+      wait_ready();

+

+      tb_block = block5;

+      tb_next = 1;

+      #(CLK_PERIOD);

+      tb_next = 0;

+      wait_ready();

+

+      tb_block = block6;

+      tb_next = 1;

+      #(CLK_PERIOD);

+      tb_next = 0;

+      wait_ready();

+

+      tb_block = block7;

+      tb_next = 1;

+      #(CLK_PERIOD);

+      tb_next = 0;

+      wait_ready();

+

+      tb_block = block8;

+      tb_next = 1;

+      #(CLK_PERIOD);

+      tb_next = 0;

+      wait_ready();

+

+      if (tb_digest == expected)

+        begin

+          $display("Digest ok.");

+        end

+      else

+        begin

+          error_ctr = error_ctr + 1;

+          $display("Error! Got:      0x%064x", tb_digest);

+          $display("Error! Expected: 0x%064x", expected);

+        end

+    end

+  endtask // issue_test

+

+

+  //----------------------------------------------------------------

+  // sha256_core_test

+  // Test cases taken from:

+  // http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/SHA256.pdf

+  //----------------------------------------------------------------

+  task sha256_core_test;

+    reg [511 : 0] tc1;

+    reg [255 : 0] res1;

+    reg [511 : 0] tc2_1;

+    reg [255 : 0] res2_1;

+    reg [511 : 0] tc2_2;

+    reg [255 : 0] res2_2;

+    begin : sha256_core_test

+      // TC1: Single block message: "abc".

+      tc1 = 512'h61626380000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018;

+      res1 = 256'hBA7816BF8F01CFEA414140DE5DAE2223B00361A396177A9CB410FF61F20015AD;

+      single_block_test(1, tc1, res1);

+

+      // TC2: Double block message.

+      // "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"

+      tc2_1 = 512'h6162636462636465636465666465666765666768666768696768696A68696A6B696A6B6C6A6B6C6D6B6C6D6E6C6D6E6F6D6E6F706E6F70718000000000000000;

+      res2_1 = 256'h85E655D6417A17953363376A624CDE5C76E09589CAC5F811CC4B32C1F20E533A;

+

+      tc2_2 = 512'h000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001C0;

+      res2_2 = 256'h248D6A61D20638B8E5C026930C3E6039A33CE45964FF2167F6ECEDD419DB06C1;

+      double_block_test(2, tc2_1, res2_1, tc2_2, res2_2);

+    end

+  endtask // sha256_core_test

+

+

+  //----------------------------------------------------------------

+  // main()

+  //----------------------------------------------------------------

+  initial

+    begin : main

+      $display("   -- Testbench for sha256 core started --");

+

+      init_sim();

+      dump_dut_state();

+      reset_dut();

+      dump_dut_state();

+

+      sha256_core_test();

+      issue_test();

+

+      display_test_result();

+      $display("*** Simulation done.");

+      $finish;

+    end // main

+endmodule // tb_sha256_core

+

+//======================================================================

+// EOF tb_sha256_core.v

+//======================================================================

diff --git a/Verilog_Code/tb_sha256_w_mem.v b/Verilog_Code/tb_sha256_w_mem.v
new file mode 100644
index 0000000..8c929c6
--- /dev/null
+++ b/Verilog_Code/tb_sha256_w_mem.v
@@ -0,0 +1,213 @@
+//======================================================================
+//
+// tb_sha256_w_mem.v
+// -----------------
+// Testbench for the SHA-256 W memory module.
+//
+//
+// 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 tb_sha256_w_mem();
+
+  //----------------------------------------------------------------
+  // Internal constant and parameter definitions.
+  //----------------------------------------------------------------
+  parameter DEBUG          = 1;
+  parameter DISPLAY_CYCLES = 0;
+
+  parameter CLK_HALF_PERIOD = 2;
+
+
+  //----------------------------------------------------------------
+  // Wires.
+  //----------------------------------------------------------------
+  reg            tb_clk;
+  reg            tb_reset_n;
+
+  reg           tb_init;
+  reg           tb_next;
+  reg [511 : 0] tb_block;
+  wire [31 : 0] tb_w;
+
+  reg [63 : 0] cycle_ctr;
+  reg [31 : 0] error_ctr;
+  reg [31 : 0] tc_ctr;
+
+
+  //----------------------------------------------------------------
+  // Device Under Test.
+  //----------------------------------------------------------------
+  sha256_w_mem dut(
+                   .clk(tb_clk),
+                   .reset_n(tb_reset_n),
+
+                   .block(tb_block),
+
+                   .init(tb_init),
+                   .next(tb_next),
+
+                   .w(tb_w)
+                  );
+
+
+  //----------------------------------------------------------------
+  // clk_gen
+  //
+  // Clock generator process.
+  //----------------------------------------------------------------
+  always
+    begin : clk_gen
+      #CLK_HALF_PERIOD tb_clk = !tb_clk;
+    end // clk_gen
+
+
+  //--------------------------------------------------------------------
+  // dut_monitor
+  //
+  // Monitor displaying information every cycle.
+  // Includes the cycle counter.
+  //--------------------------------------------------------------------
+  always @ (posedge tb_clk)
+    begin : dut_monitor
+      cycle_ctr = cycle_ctr + 1;
+
+      if (DISPLAY_CYCLES)
+        begin
+          $display("cycle = %016x:", cycle_ctr);
+        end
+
+      if (DEBUG)
+        begin
+          $display("dut w_ctr      = %02x:", dut.w_ctr_reg);
+          $display("dut w_tmp      = %02x:", dut.w_tmp);
+          dump_w_state();
+        end
+    end // dut_monitor
+
+
+  //----------------------------------------------------------------
+  // dump_w_state()
+  //
+  // Dump the current state of all W registers.
+  //----------------------------------------------------------------
+  task dump_w_state;
+    begin
+      $display("W state:");
+
+      $display("w0_reg  = %08x, w1_reg  = %08x, w2_reg  = %08x, w3_reg  = %08x",
+               dut.w_mem[00], dut.w_mem[01], dut.w_mem[02], dut.w_mem[03]);
+
+      $display("w4_reg  = %08x, w5_reg  = %08x, w6_reg  = %08x, w7_reg  = %08x",
+               dut.w_mem[04], dut.w_mem[05], dut.w_mem[06], dut.w_mem[07]);
+
+      $display("w8_reg  = %08x, w9_reg  = %08x, w10_reg = %08x, w11_reg = %08x",
+               dut.w_mem[08], dut.w_mem[09], dut.w_mem[10], dut.w_mem[11]);
+
+      $display("w12_reg = %08x, w13_reg = %08x, w14_reg = %08x, w15_reg = %08x",
+               dut.w_mem[12], dut.w_mem[13], dut.w_mem[14], dut.w_mem[15]);
+
+      $display("w_new = %08x", dut.w_new);
+      $display("");
+    end
+  endtask // dump_state
+
+
+  //----------------------------------------------------------------
+  // reset_dut
+  //----------------------------------------------------------------
+  task reset_dut;
+    begin
+      $display("*** Toggle reset.");
+      tb_reset_n = 0;
+      #(4 * CLK_HALF_PERIOD);
+      tb_reset_n = 1;
+    end
+  endtask // reset_dut
+
+
+  //----------------------------------------------------------------
+  // init_sim
+  //----------------------------------------------------------------
+  task init_sim;
+    begin
+      $display("*** Simulation init.");
+      tb_clk = 0;
+      tb_reset_n = 1;
+      cycle_ctr = 0;
+
+      tb_init = 0;
+      tb_block = 512'h0;
+    end
+  endtask // reset_dut
+
+
+  //----------------------------------------------------------------
+  // test_w_schedule()
+  //
+  // Test that W scheduling happens and work correctly.
+  // Note: Currently not a self checking test case.
+  //----------------------------------------------------------------
+  task test_w_schedule;
+    begin
+      $display("*** Test of W schedule processing. --");
+      tb_block = 512'h61626380000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018;
+      tb_init = 1;
+      #(4 * CLK_HALF_PERIOD);
+      tb_init = 0;
+      dump_w_state();
+
+      tb_next = 1;
+      #(150 * CLK_HALF_PERIOD);
+    end
+  endtask // test_w_schedule
+
+
+  //----------------------------------------------------------------
+  // The main test functionality.
+  //----------------------------------------------------------------
+  initial
+    begin : w_mem_test
+      $display("   -- Testbench for sha256 w memory started --");
+      init_sim();
+      reset_dut();
+      test_w_schedule();
+
+      $display("*** Simulation done.");
+      $finish;
+    end
+
+endmodule // w_mem_test
+
+//======================================================================
+// EOF tb_sha256_w_mem.v
+//======================================================================
diff --git a/Verilog_Code/tb_top.v b/Verilog_Code/tb_top.v
new file mode 100644
index 0000000..ab6e82f
--- /dev/null
+++ b/Verilog_Code/tb_top.v
@@ -0,0 +1,726 @@
+//======================================================================

+//

+// tb_top_tukka_proj.v

+// -----------

+// Testbench for the SHA-256 and clock mux top level wrapper.

+//

+//

+// 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 tb_top_tukka_proj();

+

+  //----------------------------------------------------------------

+  // Internal constant and parameter definitions.

+  //----------------------------------------------------------------

+  parameter DEBUG = 0;

+

+  parameter CLK_HALF_PERIOD1 = 2;

+  parameter CLK_HALF_PERIOD2 = 4;

+  parameter CLK_PERIOD1 = 2 * CLK_HALF_PERIOD1;

+  parameter CLK_PERIOD2 = 2 * CLK_HALF_PERIOD2;

+

+  // The address map.

+  parameter ADDR_NAME0       = 8'h00;

+  parameter ADDR_NAME1       = 8'h01;

+  parameter ADDR_VERSION     = 8'h02;

+

+  parameter ADDR_CTRL        = 8'h08;

+  parameter CTRL_INIT_VALUE  = 8'h01;

+  parameter CTRL_NEXT_VALUE  = 8'h02;

+  parameter CTRL_MODE_VALUE  = 8'h04;

+

+  parameter ADDR_STATUS      = 8'h09;

+  parameter STATUS_READY_BIT = 0;

+  parameter STATUS_VALID_BIT = 1;

+

+  parameter ADDR_BLOCK0    = 8'h10;

+  parameter ADDR_BLOCK1    = 8'h11;

+  parameter ADDR_BLOCK2    = 8'h12;

+  parameter ADDR_BLOCK3    = 8'h13;

+  parameter ADDR_BLOCK4    = 8'h14;

+  parameter ADDR_BLOCK5    = 8'h15;

+  parameter ADDR_BLOCK6    = 8'h16;

+  parameter ADDR_BLOCK7    = 8'h17;

+  parameter ADDR_BLOCK8    = 8'h18;

+  parameter ADDR_BLOCK9    = 8'h19;

+  parameter ADDR_BLOCK10   = 8'h1a;

+  parameter ADDR_BLOCK11   = 8'h1b;

+  parameter ADDR_BLOCK12   = 8'h1c;

+  parameter ADDR_BLOCK13   = 8'h1d;

+  parameter ADDR_BLOCK14   = 8'h1e;

+  parameter ADDR_BLOCK15   = 8'h1f;

+

+  parameter ADDR_DIGEST0   = 8'h20;

+  parameter ADDR_DIGEST1   = 8'h21;

+  parameter ADDR_DIGEST2   = 8'h22;

+  parameter ADDR_DIGEST3   = 8'h23;

+  parameter ADDR_DIGEST4   = 8'h24;

+  parameter ADDR_DIGEST5   = 8'h25;

+  parameter ADDR_DIGEST6   = 8'h26;

+  parameter ADDR_DIGEST7   = 8'h27;

+

+  parameter SHA224_MODE    = 0;

+  parameter SHA256_MODE    = 1;

+

+

+  //----------------------------------------------------------------

+  // Register and Wire declarations.

+  //----------------------------------------------------------------

+  reg [31 : 0] cycle_ctr;

+  reg [31 : 0] error_ctr;

+  reg [31 : 0] tc_ctr;

+  reg           tb_clk1,tb_clk2,tb_sel_clk2;

+  reg           tb_clk;

+  reg           tb_reset_n;

+  reg           tb_cs;

+  reg           tb_we;

+  reg [7 : 0]   tb_address;

+  reg [31 : 0]  tb_write_data;

+  wire [31 : 0] tb_read_data;

+  wire          tb_error;

+

+  reg [31 : 0]  read_data;

+  reg [255 : 0] digest_data;

+

+

+  //----------------------------------------------------------------

+  // Device Under Test.

+  //----------------------------------------------------------------

+ 

+top_tukka_proj dut(

+.clk1(tb_clk1),

+.clk2(tb_clk2),

+.reset_n(tb_reset_n),

+.sel_clk2(tb_sel_clk2),

+.cs(tb_cs),

+.we(tb_we),

+.address(tb_address),

+.write_data(tb_write_data),

+.read_data(tb_read_data),

+.error(tb_error)

+);

+

+

+  //----------------------------------------------------------------

+  // clk_gen

+  //

+  // Clock generator process.

+  //----------------------------------------------------------------

+  always

+    begin : clk_gen

+      #CLK_HALF_PERIOD1 tb_clk1 = !tb_clk1;

+      #CLK_HALF_PERIOD2 tb_clk2 = !tb_clk2;

+    end // clk_gen

+

+

+  //----------------------------------------------------------------

+  // sys_monitor

+  //

+  // Generates a cycle counter and displays information about

+  // the dut as needed.

+  //----------------------------------------------------------------

+  always

+    begin : sys_monitor

+      #(2 * CLK_HALF_PERIOD2);

+      cycle_ctr = cycle_ctr + 1;

+    end

+

+

+  //----------------------------------------------------------------

+  // dump_dut_state()

+  //

+  // Dump the state of the dump when needed.

+  //----------------------------------------------------------------

+ /* task dump_dut_state;

+    begin

+      $display("State of DUT");

+      $display("------------");

+      $display("Inputs and outputs:");

+      $display("cs = 0x%01x, we = 0x%01x",

+               dut.cs, dut.we);

+      $display("address = 0x%02x", dut.address);

+      $display("write_data = 0x%08x, read_data = 0x%08x",

+               dut.write_data, dut.read_data);

+      $display("tmp_read_data = 0x%08x", dut.tmp_read_data);

+      $display("");

+

+      $display("Control and status:");

+      $display("ctrl = 0x%02x, status = 0x%02x",

+               {dut.next_reg, dut.init_reg},

+               {dut.digest_valid_reg, dut.ready_reg});

+      $display("");

+

+      $display("Message block:");

+      $display("block0  = 0x%08x, block1  = 0x%08x, block2  = 0x%08x,  block3  = 0x%08x",

+               dut.block_reg[00], dut.block_reg[01], dut.block_reg[02], dut.block_reg[03]);

+//      $display("block4  = 0x%08x, block5  = 0x%08x, block6  = 0x%08x,  block7  = 0x%08x",

+//               dut.block_reg[04], dut.block_reg[05], dut.block_reg[06], dut.block_reg[07]);

+

+      $display("block8  = 0x%08x, block9  = 0x%08x, block10 = 0x%08x,  block11 = 0x%08x",

+               dut.block_reg[08], dut.block_reg[09], dut.block_reg[10], dut.block_reg[11]);

+      $display("block12 = 0x%08x, block13 = 0x%08x, block14 = 0x%08x,  block15 = 0x%08x",

+               dut.block_reg[12], dut.block_reg[13], dut.block_reg[14], dut.block_reg[15]);

+      $display("");

+

+      $display("Digest:");

+      $display("digest = 0x%064x", dut.digest_reg);

+      $display("");

+

+    end

+  endtask // dump_dut_state   */

+

+

+  //----------------------------------------------------------------

+  // reset_dut()

+  //

+  // Toggles reset to force the DUT into a well defined state.

+  //----------------------------------------------------------------

+  task reset_dut;

+    begin

+      $display("*** Toggle reset.");

+      tb_reset_n = 0;

+      #(4 * CLK_HALF_PERIOD1);

+      tb_reset_n = 1;

+    end

+  endtask // reset_dut

+

+

+  //----------------------------------------------------------------

+  // init_sim()

+  //

+  // Initialize all counters and testbed functionality as well

+  // as setting the DUT inputs to defined values.

+  //----------------------------------------------------------------

+  task init_sim;

+    begin

+      cycle_ctr = 32'h0;

+      error_ctr = 32'h0;

+      tc_ctr = 32'h0;

+      tb_sel_clk2=1'b0;

+      tb_clk1 = 0;

+      tb_clk2 = 0;

+      tb_reset_n = 0;

+      tb_cs = 0;

+      tb_we = 0;

+      tb_address = 6'h0;

+      tb_write_data = 32'h0;

+    end

+  endtask // init_dut

+

+

+  //----------------------------------------------------------------

+  // display_test_result()

+  //

+  // Display the accumulated test results.

+  //----------------------------------------------------------------

+  task display_test_result;

+    begin

+      if (error_ctr == 0)

+        begin

+          $display("*** All %02d test cases completed successfully.", tc_ctr);

+        end

+      else

+        begin

+          $display("*** %02d test cases completed.", tc_ctr);

+          $display("*** %02d errors detected during testing.", error_ctr);

+        end

+    end

+  endtask // display_test_result

+

+

+  //----------------------------------------------------------------

+  // wait_ready()

+  //

+  // Wait for the ready flag in the dut to be set.

+  // (Actually we wait for either ready or valid to be set.)

+  //

+  // Note: It is the callers responsibility to call the function

+  // when the dut is actively processing and will in fact at some

+  // point set the flag.

+  //----------------------------------------------------------------

+  task wait_ready;

+    begin

+      read_data = 0;

+

+      while (read_data == 0)

+        begin

+          read_word(ADDR_STATUS);

+        end

+    end

+  endtask // wait_ready

+

+

+  //----------------------------------------------------------------

+  // write_word()

+  //

+  // Write the given word to the DUT using the DUT interface.

+  //----------------------------------------------------------------

+  task write_word(input [7 : 0]  address,

+                  input [31 : 0] word);

+    begin

+      if (DEBUG)

+        begin

+          $display("*** Writing 0x%08x to 0x%02x.", word, address);

+          $display("");

+        end

+

+      tb_address = address;

+      tb_write_data = word;

+      tb_cs = 1;

+      tb_we = 1;

+      #(CLK_PERIOD2);

+      tb_cs = 0;

+      tb_we = 0;

+    end

+  endtask // write_word

+

+

+  //----------------------------------------------------------------

+  // write_block()

+  //

+  // Write the given block to the dut.

+  //----------------------------------------------------------------

+  task write_block(input [511 : 0] block);

+    begin

+      write_word(ADDR_BLOCK0,  block[511 : 480]);

+      write_word(ADDR_BLOCK1,  block[479 : 448]);

+      write_word(ADDR_BLOCK2,  block[447 : 416]);

+      write_word(ADDR_BLOCK3,  block[415 : 384]);

+      write_word(ADDR_BLOCK4,  block[383 : 352]);

+      write_word(ADDR_BLOCK5,  block[351 : 320]);

+      write_word(ADDR_BLOCK6,  block[319 : 288]);

+      write_word(ADDR_BLOCK7,  block[287 : 256]);

+      write_word(ADDR_BLOCK8,  block[255 : 224]);

+      write_word(ADDR_BLOCK9,  block[223 : 192]);

+      write_word(ADDR_BLOCK10, block[191 : 160]);

+      write_word(ADDR_BLOCK11, block[159 : 128]);

+      write_word(ADDR_BLOCK12, block[127 :  96]);

+      write_word(ADDR_BLOCK13, block[95  :  64]);

+      write_word(ADDR_BLOCK14, block[63  :  32]);

+      write_word(ADDR_BLOCK15, block[31  :   0]);

+    end

+  endtask // write_block

+

+

+  //----------------------------------------------------------------

+  // read_word()

+  //

+  // Read a data word from the given address in the DUT.

+  // the word read will be available in the global variable

+  // read_data.

+  //----------------------------------------------------------------

+  task read_word(input [7 : 0]  address);

+    begin

+      tb_address = address;

+      tb_cs = 1;

+      tb_we = 0;

+      #(CLK_PERIOD2);

+      read_data = tb_read_data;

+      tb_cs = 0;

+

+      if (DEBUG)

+        begin

+          $display("*** Reading 0x%08x from 0x%02x.", read_data, address);

+          $display("");

+        end

+    end

+  endtask // read_word

+

+

+  //----------------------------------------------------------------

+  // check_name_version()

+  //

+  // Read the name and version from the DUT.

+  //----------------------------------------------------------------

+  task check_name_version;

+    reg [31 : 0] name0;

+    reg [31 : 0] name1;

+    reg [31 : 0] version;

+    begin

+

+      read_word(ADDR_NAME0);

+      name0 = read_data;

+      read_word(ADDR_NAME1);

+      name1 = read_data;

+      read_word(ADDR_VERSION);

+      version = read_data;

+

+      $display("DUT name: %c%c%c%c%c%c%c%c",

+               name0[31 : 24], name0[23 : 16], name0[15 : 8], name0[7 : 0],

+               name1[31 : 24], name1[23 : 16], name1[15 : 8], name1[7 : 0]);

+      $display("DUT version: %c%c%c%c",

+               version[31 : 24], version[23 : 16], version[15 : 8], version[7 : 0]);

+    end

+  endtask // check_name_version

+

+

+  //----------------------------------------------------------------

+  // read_digest()

+  //

+  // Read the digest in the dut. The resulting digest will be

+  // available in the global variable digest_data.

+  //----------------------------------------------------------------

+  task read_digest;

+    begin

+      read_word(ADDR_DIGEST0);

+      digest_data[255 : 224] = read_data;

+      read_word(ADDR_DIGEST1);

+      digest_data[223 : 192] = read_data;

+      read_word(ADDR_DIGEST2);

+      digest_data[191 : 160] = read_data;

+      read_word(ADDR_DIGEST3);

+      digest_data[159 : 128] = read_data;

+      read_word(ADDR_DIGEST4);

+      digest_data[127 :  96] = read_data;

+      read_word(ADDR_DIGEST5);

+      digest_data[95  :  64] = read_data;

+      read_word(ADDR_DIGEST6);

+      digest_data[63  :  32] = read_data;

+      read_word(ADDR_DIGEST7);

+      digest_data[31  :   0] = read_data;

+    end

+  endtask // read_digest

+

+

+  //----------------------------------------------------------------

+  // single_block_test()

+  //

+  //

+  // Perform test of a single block digest.

+  //----------------------------------------------------------------

+  task single_block_test(input           mode,

+                         input [511 : 0] block,

+                         input [255 : 0] expected);

+    begin

+      $display("*** TC%01d - Single block test started.", tc_ctr);

+

+      write_block(block);

+

+      if (mode)

+        write_word(ADDR_CTRL, (CTRL_MODE_VALUE + CTRL_INIT_VALUE));

+      else

+        write_word(ADDR_CTRL, CTRL_INIT_VALUE);

+

+      #(CLK_PERIOD1);

+      wait_ready();

+      read_digest();

+

+      // We need to ignore the LSW in SHA224 mode.

+      if (mode == SHA224_MODE)

+        digest_data[31 : 0] = 32'h0;

+

+      if (digest_data == expected)

+        begin

+          $display("TC%01d: OK.", tc_ctr);

+        end

+      else

+        begin

+          $display("TC%01d: ERROR.", tc_ctr);

+          $display("TC%01d: Expected: 0x%064x", tc_ctr, expected);

+          $display("TC%01d: Got:      0x%064x", tc_ctr, digest_data);

+          error_ctr = error_ctr + 1;

+        end

+      $display("*** TC%01d - Single block test done.", tc_ctr);

+      tc_ctr = tc_ctr + 1;

+    end

+  endtask // single_block_test

+

+

+  //----------------------------------------------------------------

+  // double_block_test()

+  //

+  //

+  // Perform test of a double block digest. Note that we check

+  // the digests for both the first and final block.

+  //----------------------------------------------------------------

+  task double_block_test(input           mode,

+                         input [511 : 0] block0,

+                         input [255 : 0] expected0,

+                         input [511 : 0] block1,

+                         input [255 : 0] expected1

+                        );

+    begin

+      $display("*** TC%01d - Double block test started.", tc_ctr);

+

+      // First block

+      write_block(block0);

+

+      if (mode)

+        write_word(ADDR_CTRL, (CTRL_MODE_VALUE + CTRL_INIT_VALUE));

+      else

+        write_word(ADDR_CTRL, CTRL_INIT_VALUE);

+

+      #(CLK_PERIOD2);

+      wait_ready();

+      read_digest();

+

+      // We need to ignore the LSW in SHA224 mode.

+      if (mode == SHA224_MODE)

+        digest_data[31 : 0] = 32'h0;

+

+      if (digest_data == expected0)

+        begin

+          $display("TC%01d first block: OK.", tc_ctr);

+        end

+      else

+        begin

+          $display("TC%01d: ERROR in first digest", tc_ctr);

+          $display("TC%01d: Expected: 0x%064x", tc_ctr, expected0);

+          $display("TC%01d: Got:      0x%064x", tc_ctr, digest_data);

+          error_ctr = error_ctr + 1;

+        end

+

+      // Final block

+      write_block(block1);

+

+      if (mode)

+        write_word(ADDR_CTRL, (CTRL_MODE_VALUE + CTRL_NEXT_VALUE));

+      else

+        write_word(ADDR_CTRL, CTRL_NEXT_VALUE);

+

+      #(CLK_PERIOD2);

+      wait_ready();

+      read_digest();

+

+      // We need to ignore the LSW in SHA224 mode.

+      if (mode == SHA224_MODE)

+        digest_data[31 : 0] = 32'h0;

+

+      if (digest_data == expected1)

+        begin

+          $display("TC%01d final block: OK.", tc_ctr);

+        end

+      else

+        begin

+          $display("TC%01d: ERROR in final digest", tc_ctr);

+          $display("TC%01d: Expected: 0x%064x", tc_ctr, expected1);

+          $display("TC%01d: Got:      0x%064x", tc_ctr, digest_data);

+          error_ctr = error_ctr + 1;

+        end

+

+      $display("*** TC%01d - Double block test done.", tc_ctr);

+      tc_ctr = tc_ctr + 1;

+    end

+  endtask // double_block_test

+

+

+  //----------------------------------------------------------------

+  // sha224_tests()

+  //

+  // Run test cases for sha224.

+  // Test cases taken from:

+  // http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/SHA224.pdf

+  //----------------------------------------------------------------

+  task sha224_tests;

+    begin : sha224_tests_block

+      reg [511 : 0] tc0;

+      reg [255 : 0] res0;

+

+      reg [511 : 0] tc1_0;

+      reg [255 : 0] res1_0;

+      reg [511 : 0] tc1_1;

+      reg [255 : 0] res1_1;

+

+      $display("*** Testcases for sha224 functionality started.");

+

+      tc0 = 512'h61626380000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018;

+

+      res0 = 256'h23097D223405D8228642A477BDA255B32AADBCE4BDA0B3F7E36C9DA700000000;

+      single_block_test(SHA224_MODE, tc0, res0);

+

+      tc1_0 = 512'h6162636462636465636465666465666765666768666768696768696A68696A6B696A6B6C6A6B6C6D6B6C6D6E6C6D6E6F6D6E6F706E6F70718000000000000000;

+      res1_0 = 256'h8250e65dbcf62f8466659c3333e5e91a10c8b7b0953927691f1419c200000000;

+      tc1_1 = 512'h000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001C0;

+      res1_1 = 256'h75388b16512776cc5dba5da1fd890150b0c6455cb4f58b195252252500000000;

+      double_block_test(SHA224_MODE, tc1_0, res1_0, tc1_1, res1_1);

+

+      $display("*** Testcases for sha224 functionality completed.");

+    end

+  endtask // sha224_tests

+

+

+  //----------------------------------------------------------------

+  // sha256_tests()

+  //

+  // Run test cases for sha256.

+  // Test cases taken from:

+  // http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/SHA256.pdf

+  //----------------------------------------------------------------

+  task sha256_tests;

+    begin : sha256_tests_block

+      reg [511 : 0] tc0;

+      reg [255 : 0] res0;

+

+      reg [511 : 0] tc1_0;

+      reg [255 : 0] res1_0;

+      reg [511 : 0] tc1_1;

+      reg [255 : 0] res1_1;

+

+      $display("*** Testcases for sha256 functionality started.");

+

+      tc0 = 512'h61626380000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018;

+      res0 = 256'hBA7816BF8F01CFEA414140DE5DAE2223B00361A396177A9CB410FF61F20015AD;

+      single_block_test(SHA256_MODE, tc0, res0);

+

+      tc1_0 = 512'h6162636462636465636465666465666765666768666768696768696A68696A6B696A6B6C6A6B6C6D6B6C6D6E6C6D6E6F6D6E6F706E6F70718000000000000000;

+      res1_0 = 256'h85E655D6417A17953363376A624CDE5C76E09589CAC5F811CC4B32C1F20E533A;

+      tc1_1 = 512'h000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001C0;

+      res1_1 = 256'h248D6A61D20638B8E5C026930C3E6039A33CE45964FF2167F6ECEDD419DB06C1;

+      double_block_test(SHA256_MODE, tc1_0, res1_0, tc1_1, res1_1);

+

+      $display("*** Testcases for sha256 functionality completed.");

+    end

+  endtask // sha256_tests

+

+

+

+  //----------------------------------------------------------------

+  // issue_test()

+  //----------------------------------------------------------------

+  task issue_test;

+    reg [511 : 0] block0;

+    reg [511 : 0] block1;

+    reg [511 : 0] block2;

+    reg [511 : 0] block3;

+    reg [511 : 0] block4;

+    reg [511 : 0] block5;

+    reg [511 : 0] block6;

+    reg [511 : 0] block7;

+    reg [511 : 0] block8;

+    reg [255 : 0] expected;

+    begin : issue_test

+      block0 = 512'h6b900001_496e2074_68652061_72656120_6f662049_6f542028_496e7465_726e6574_206f6620_5468696e_6773292c_206d6f72_6520616e_64206d6f_7265626f_6f6d2c20;

+      block1 = 512'h69742068_61732062_65656e20_6120756e_69766572_73616c20_636f6e73_656e7375_73207468_61742064_61746120_69732074_69732061_206e6577_20746563_686e6f6c;

+      block2 = 512'h6f677920_74686174_20696e74_65677261_74657320_64656365_6e747261_6c697a61_74696f6e_2c496e20_74686520_61726561_206f6620_496f5420_28496e74_65726e65;

+      block3 = 512'h74206f66_20546869_6e677329_2c206d6f_72652061_6e64206d_6f726562_6f6f6d2c_20697420_68617320_6265656e_20612075_6e697665_7273616c_20636f6e_73656e73;

+      block4 = 512'h75732074_68617420_64617461_20697320_74697320_61206e65_77207465_63686e6f_6c6f6779_20746861_7420696e_74656772_61746573_20646563_656e7472_616c697a;

+      block5 = 512'h6174696f_6e2c496e_20746865_20617265_61206f66_20496f54_2028496e_7465726e_6574206f_66205468_696e6773_292c206d_6f726520_616e6420_6d6f7265_626f6f6d;

+      block6 = 512'h2c206974_20686173_20626565_6e206120_756e6976_65727361_6c20636f_6e73656e_73757320_74686174_20646174_61206973_20746973_2061206e_65772074_6563686e;

+      block7 = 512'h6f6c6f67_79207468_61742069_6e746567_72617465_73206465_63656e74_72616c69_7a617469_6f6e2c49_6e207468_65206172_6561206f_6620496f_54202849_6e746572;

+      block8 = 512'h6e657420_6f662054_68696e67_73292c20_6d6f7265_20616e64_206d6f72_65800000_00000000_00000000_00000000_00000000_00000000_00000000_00000000_000010e8;

+

+      expected = 256'h7758a30bbdfc9cd92b284b05e9be9ca3d269d3d149e7e82ab4a9ed5e81fbcf9d;

+

+      $display("Running test for 9 block issue.");

+      tc_ctr = tc_ctr + 1;

+      write_block(block0);

+      write_word(ADDR_CTRL, (CTRL_MODE_VALUE + CTRL_INIT_VALUE));

+      #(2*CLK_PERIOD2);

+      wait_ready();

+

+      write_block(block1);

+      write_word(ADDR_CTRL, (CTRL_MODE_VALUE + CTRL_NEXT_VALUE));

+      #(2*CLK_PERIOD2);

+      tb_sel_clk2=1'b1;

+      wait_ready();

+      

+      write_block(block2);

+      write_word(ADDR_CTRL, (CTRL_MODE_VALUE + CTRL_NEXT_VALUE));

+      #(2*CLK_PERIOD2);

+      wait_ready();

+

+      write_block(block3);

+      write_word(ADDR_CTRL, (CTRL_MODE_VALUE + CTRL_NEXT_VALUE));

+      #(2*CLK_PERIOD2);

+      wait_ready();

+

+      write_block(block4);

+      write_word(ADDR_CTRL, (CTRL_MODE_VALUE + CTRL_NEXT_VALUE));

+      #(2*CLK_PERIOD2);

+      tb_sel_clk2=1'b0;

+      wait_ready();

+

+      write_block(block5);

+      write_word(ADDR_CTRL, (CTRL_MODE_VALUE + CTRL_NEXT_VALUE));

+      #(2*CLK_PERIOD2);

+      wait_ready();

+

+      write_block(block6);

+      write_word(ADDR_CTRL, (CTRL_MODE_VALUE + CTRL_NEXT_VALUE));

+      #(2*CLK_PERIOD2);

+      tb_sel_clk2=1'b1;

+      wait_ready();

+

+      write_block(block7);

+      write_word(ADDR_CTRL, (CTRL_MODE_VALUE + CTRL_NEXT_VALUE));

+      #(2*CLK_PERIOD2);

+      tb_sel_clk2=1'b0;

+      wait_ready();

+

+      write_block(block8);

+      write_word(ADDR_CTRL, (CTRL_MODE_VALUE + CTRL_NEXT_VALUE));

+      #(2*CLK_PERIOD2);

+      wait_ready();

+

+      read_digest();

+      if (digest_data == expected)

+        begin

+          $display("Digest ok.");

+        end

+      else

+        begin

+          $display("ERROR in digest");

+          $display("Expected: 0x%064x", expected);

+          $display("Got:      0x%064x", digest_data);

+          error_ctr = error_ctr + 1;

+        end

+    end

+  endtask // issue_test

+

+

+  //----------------------------------------------------------------

+  // The main test functionality.

+  //----------------------------------------------------------------

+  initial

+    begin : main

+      $display("   -- Testbench for sha256 started --");

+

+      init_sim();

+      reset_dut();

+

+      check_name_version();

+      sha224_tests();

+      sha256_tests();

+      issue_test();

+

+      display_test_result();

+

+      $display("   -- Testbench for sha256 done. --");

+      $finish;

+    end // main

+endmodule // tb_sha256

+

+//======================================================================

+// EOF tb_sha256.v

+//======================================================================

diff --git a/Verilog_Code/top_tukka_proj.v b/Verilog_Code/top_tukka_proj.v
new file mode 100644
index 0000000..ba7fde4
--- /dev/null
+++ b/Verilog_Code/top_tukka_proj.v
@@ -0,0 +1,39 @@
+module top_tukka_proj (clk1,clk2,reset_n,sel_clk2,cs,we,address,write_data,read_data,error);

+

+input    clk1;      // Clock 1 supposed to be faster

+input    clk2;      // Clock 2  supposed to be slower

+input    reset_n;   // System reset

+input    sel_clk2;  // Select clock2 when high

+//for SHA

+// Control.

+input wire cs;

+input wire we;

+// Data ports.

+input wire  [7 : 0]  address;

+input wire  [31 : 0] write_data;

+output wire [31 : 0] read_data;

+output wire error;

+//output clock

+wire clk1or2;    // Selected clock

+

+//clock mux instintiated

+clock_mux clock_mux0(

+.clk1(clk1),     

+.clk2(clk2),     

+.reset_n(reset_n),  

+.sel_clk2(sel_clk2), 

+.clk1or2(clk1or2)   

+);

+//sha instintiated

+sha256 dut(

+.clk(clk1or2),

+.reset_n(reset_n),

+.cs(cs),

+.we(we),

+.address(address),

+.write_data(write_data),

+.read_data(read_data),

+.error(error)

+);

+

+endmodule