[Cryptech-Commits] [core/novena_eim] 01/01: try to nail down timing, with just the sha1 core and bunnie's registers

git at cryptech.is git at cryptech.is
Sat Dec 6 15:03:54 UTC 2014


This is an automated email from the git hooks/post-receive script.

paul at psgd.org pushed a commit to branch gothenburg_test
in repository core/novena_eim.

commit 0b64cf71eedca18cc7d8ccee4ac95a9eadb6c8b4
Author: Paul Selkirk <paul at psgd.org>
Date:   Sat Dec 6 10:03:25 2014 -0500

    try to nail down timing, with just the sha1 core and bunnie's registers
---
 build/.gitignore      |  41 +++++
 build/Makefile        |  21 +--
 build/novena_eim.bit  | Bin 1484504 -> 1484504 bytes
 src/rtl/novena_fpga.v | 266 ++++-----------------------
 src/rtl/sha1.v        | 382 ++++++++++++++++++++++++++++++++++++++
 src/rtl/sha1_core.v   | 501 ++++++++++++++++++++++++++++++++++++++++++++++++++
 6 files changed, 966 insertions(+), 245 deletions(-)

diff --git a/build/.gitignore b/build/.gitignore
new file mode 100644
index 0000000..1aaff66
--- /dev/null
+++ b/build/.gitignore
@@ -0,0 +1,41 @@
+GuidePresReport.tmp
+_xmsgs/
+netlist.lst
+novena_eim.bgn
+novena_eim.bld
+novena_eim.cfi
+novena_eim.drc
+novena_eim.map
+novena_eim.mcs
+novena_eim.mrp
+novena_eim.ncd
+novena_eim.ngc
+novena_eim.ngc_xst.xrpt
+novena_eim.ngd
+novena_eim.ngm
+novena_eim.pcf
+novena_eim.prj
+novena_eim.prm
+novena_eim.psr
+novena_eim.scr
+novena_eim.srp
+novena_eim_bitgen.xwbt
+novena_eim_ngdbuild.xrpt
+novena_eim_par.ncd
+novena_eim_par.pad
+novena_eim_par.par
+novena_eim_par.ptwx
+novena_eim_par.unroutes
+novena_eim_par.xpi
+novena_eim_par_pad.csv
+novena_eim_par_pad.txt
+novena_eim_summary.xml
+novena_eim_usage.xml
+novena_fpga.lso
+novena_fpga_map.xrpt
+novena_fpga_par.xrpt
+par_usage_statistics.html
+usage_statistics_webtalk.html
+webtalk.log
+xlnx_auto_0_xdb/
+xst/
diff --git a/build/Makefile b/build/Makefile
index 081333d..86f3563 100644
--- a/build/Makefile
+++ b/build/Makefile
@@ -3,23 +3,18 @@ vendor = xilinx
 family = spartan6
 part = xc6slx45csg324-3
 top_module = novena_fpga
-isedir = /opt/Xilinx/14.3/ISE_DS
+isedir = /opt/Xilinx/14.7/ISE_DS
 xil_env = . $(isedir)/settings64.sh
+#par_opts = -x -ol high
 
-vfiles = ../../sha1/src/rtl/sha1.v \
-	../../sha1/src/rtl/sha1_core.v \
+vfiles = \
+	../src/rtl/sha1.v \
+	../src/rtl/sha1_core.v \
 	../../sha1/src/rtl/sha1_w_mem.v \
-	../../sha256/src/rtl/sha256.v \
-	../../sha256/src/rtl/sha256_core.v \
-	../../sha256/src/rtl/sha256_k_constants.v \
-	../../sha256/src/rtl/sha256_w_mem.v \
-	../../sha512/src/rtl/sha512.v \
-	../../sha512/src/rtl/sha512_core.v \
-	../../sha512/src/rtl/sha512_h_constants.v \
-	../../sha512/src/rtl/sha512_k_constants.v \
-	../../sha512/src/rtl/sha512_w_mem.v \
+	../src/rtl/sha256.v \
+	../src/rtl/common/reg_ro.v \
+	../src/rtl/common/reg_wo.v \
 	../src/rtl/common/sync_reset.v \
-	../src/rtl/coretest_hashes.v \
 	../src/rtl/ip/bclk_dll/bclk_dll.v \
 	../src/rtl/ip/clk_dll/clk_dll.v \
 	../src/rtl/ip/dcm_delay/dcm_delay.v \
diff --git a/build/novena_eim.bit b/build/novena_eim.bit
index e9db564..2e3f1a9 100644
Binary files a/build/novena_eim.bit and b/build/novena_eim.bit differ
diff --git a/src/rtl/novena_fpga.v b/src/rtl/novena_fpga.v
old mode 100755
new mode 100644
index 27bc2f8..8506497
--- a/src/rtl/novena_fpga.v
+++ b/src/rtl/novena_fpga.v
@@ -1,3 +1,4 @@
+//`define BURST
 //////////////////////////////////////////////////////////////////////////////
 // Copyright (c) 2014, Andrew "bunnie" Huang
 //
@@ -29,54 +30,6 @@ module novena_fpga(
 		   input wire EIM_RW,
 		   inout wire [15:0] EIM_DA,
 
-`ifdef UNDEFINED
-		   ////// expansion connector side mapping
-		   // CPU->DUT mappings bank A
-		   output wire F_LVDS_P15,
-		   output wire F_LVDS_N15,
-		   output wire F_LVDS_P0,
-		   output wire F_LVDS_N0,
-		   output wire F_LVDS_CK1_P,
-		   output wire F_LVDS_CK1_N,
-		   output wire F_DX14,
-		   output wire F_LVDS_P4,
-		   // CPU->DUT mappings bank B
-		   output wire F_LVDS_P11,
-		   output wire F_LVDS_N11,
-		   output wire F_DX1,
-		   output wire F_LVDS_NC,
-		   output wire F_LVDS_PC,
-		   output wire F_DX17,
-		   output wire F_LVDS_NB,
-		   output wire F_LVDS_PB,
-
-		   output wire F_LVDS_P7, // OE_N control for CPU->DUT bank A mappings
-		   output wire F_LVDS_N7, // OE_N control for CPU->DUT bank B mappings
-
-		   // DUT->CPU mappings
-		   input wire F_DX18,
-		   input wire F_LVDS_CK0_N,
-		   input wire F_LVDS_CK0_P,
-		   input wire F_LVDS_P9,
-		   input wire F_DX0,
-		   input wire F_DX3,
-		   input wire F_DX2,
-		   input wire F_DX11,
-
-		   /// board control
-		   output wire F_DX15,    // output voltage select, 1 = Low V, 0 = 5V
-		   input wire F_LVDS_NA,  // OC flag
-
-		   /// ADC
-		   output wire F_DX13, // CS
-		   output wire F_DX7,  // SCLK
-		   output wire F_DX6,  // DIN
-		   input wire F_DX12,  // DOUT
-		   
-		   input wire I2C3_SCL,
-		   inout wire I2C3_SDA,
-`endif // UNDEFINED
-
 		   //// clocks n stuff
 		   input wire CLK2_N, // free-runs at 50 MHz
 		   input wire CLK2_P,
@@ -97,95 +50,8 @@ module novena_fpga(
    wire 		      bclk_early;
    wire 		      bclk_i, bclk_o;
    wire 		      clk25;
+   wire 		      slowclk;
 
-`ifdef UNDEFINED   
-   ////////////
-   // This code section is specific to the GPBB
-   //
-   // The rest of the code is generic to creating EIM/I2C interfaces in the FPGA
-   ////////////
-   wire [7:0] 		      cpu_to_dutA; // this set of wires connected to EIM registers below
-   wire [7:0] 		      cpu_to_dutB;
-   wire 		      drive_dutA_N;
-   wire 		      drive_dutB_N;
-   wire [7:0] 		      dut_to_cpu;
-   wire [15:0] 		      gpbb_ctl;
-   wire [15:0] 		      gpbb_stat;
-
-   /// the following is a set of board/pin-name to logical mappings
-   // CPU->DUT mappings bank A
-   assign F_LVDS_P15 = cpu_to_dutA[0];
-   assign F_LVDS_N15 = cpu_to_dutA[1];
-   assign F_LVDS_P0 =  cpu_to_dutA[2];
-   assign F_LVDS_N0 =  cpu_to_dutA[3];
-   assign F_LVDS_CK1_P =  cpu_to_dutA[4];
-   assign F_LVDS_CK1_N =  cpu_to_dutA[5];
-   assign F_DX14 =  cpu_to_dutA[6];
-   assign F_LVDS_P4 =  cpu_to_dutA[7];
-   // CPU->DUT mappings bank B
-   assign F_LVDS_P11 = cpu_to_dutB[0];   // LED 0
-   assign F_LVDS_N11 = cpu_to_dutB[1];   // LED 1
-   assign F_DX1 = cpu_to_dutB[2];        // LED 2
-   assign F_LVDS_NC = cpu_to_dutB[3];    // LED 3
-   assign F_LVDS_PC = cpu_to_dutB[4];
-   assign F_DX17 = cpu_to_dutB[5];
-   assign F_LVDS_NB = cpu_to_dutB[6];
-   assign F_LVDS_PB = cpu_to_dutB[7];
-
-   assign F_LVDS_P7 = drive_dutA_N; // OE_N control for CPU->DUT mappings
-   assign F_LVDS_N7 = drive_dutB_N; // OE_N control for CPU->DUT mappings
-   
-   assign drive_dutA_N = !gpbb_ctl[0]; // invert so drive is true from programming model
-   assign drive_dutB_N = !gpbb_ctl[1]; // invert so drive is true from programming model
-
-   assign F_DX15 = !gpbb_ctl[15];  // bit 15 selects output voltage
-   // invert so from software, default 0 = low voltage; 1 = drive 5V
-      
-   // DUT->CPU mappings
-   assign dut_to_cpu[0] = F_DX18;
-   assign dut_to_cpu[1] = F_LVDS_CK0_N;
-   assign dut_to_cpu[2] = F_LVDS_CK0_P;
-   assign dut_to_cpu[3] = F_LVDS_P9;
-   assign dut_to_cpu[4] = F_DX0;
-   assign dut_to_cpu[5] = F_DX3;
-   assign dut_to_cpu[6] = F_DX2;
-   assign dut_to_cpu[7] = F_DX11;
-   
-
-   assign gpbb_stat[15:0] = {15'b0, F_LVDS_NA};  // tie unused lines to 0
-   // bit 0 is overcurrent flag
-    
-   /////////////
-   // right, so fwiw, we map the ADC to the I2C bus.
-   // you can also map this to EIM by making registers that
-   // map to ADC wires, but this is an instructive example of
-   // how to use I2C-to-FPGA mappings with something reasonably generic.
-   // the I2C interface block is called i2c_slave and is near the bottom of this file
-   
-   /// ADC
-   wire       adc_go;
-   wire [2:0] adc_chan;
-   
-   wire [9:0] adc_in;
-   wire       adc_valid;
-   wire       slowclk;
-   
-   adc10cs022 adc10cs022 (
-			  .DIG_ADC_CS(F_DX13),
-			  .DIG_ADC_IN(F_DX6),
-			  .DIG_ADC_OUT(F_DX12),
-			  .DIG_ADC_SCLK(F_DX7),
-
-			  .adc_in(adc_in),
-			  .adc_chan(adc_chan),
-			  .adc_valid(adc_valid),
-			  .adc_go(adc_go),
-			  
-			  .clk_3p2MHz(slowclk),
-			  .reset(reset)
-			  );
-`endif // UNDEFINED
-   
    //////////////////////////////
    ///// The following code is used to create the EIM interface to the CPU
    /////
@@ -265,7 +131,7 @@ module novena_fpga(
    end
 
    /// retime and mux between cs0 and cs1 banks on the output
-`ifdef UNDEFINED
+`ifdef BURST
    wire [15:0]               ro_d_b;
    reg [15:0] 		     ro_d_b_r;
    always @(posedge bclk_i) begin
@@ -280,7 +146,7 @@ module novena_fpga(
    always @(posedge bclk_dll) begin
       ro_d_r <= ro_d;
       eim_rdcs[1:0] <= EIM_CS[1:0];
-`ifdef UNDEFINED
+`ifdef BURST
       eim_dout_pipe <= (eim_rdcs[1:0] == 2'b10) ? ro_d_r : ro_d_b_r;
 `else
       eim_dout_pipe <= (eim_rdcs[1:0] == 2'b10) ? ro_d_r : 16'b0;
@@ -293,7 +159,6 @@ module novena_fpga(
    
    wire [15:0] ro_d;
 
-`ifdef UNDEFINED
    wire [15:0] r40000wo;
    wire [15:0] r40002wo;
 
@@ -307,14 +172,6 @@ module novena_fpga(
 			 .reg_d( r40002wo[15:0] ) );
 
 
-   reg_wo reg_wo_40010 ( .clk(bclk_dll), .bus_a(bus_addr_r), .my_a(19'h40010),
-			 .bus_d(din_r), .we(!cs0_r && !rw_r), .re(!cs0_r && rw_r), .rbk_d(ro_d), 
-			 .reg_d( {cpu_to_dutB[7:0], cpu_to_dutA[7:0]} ) );
-
-   reg_wo reg_wo_40012 ( .clk(bclk_dll), .bus_a(bus_addr_r), .my_a(19'h40012),
-			 .bus_d(din_r), .we(!cs0_r && !rw_r), .re(!cs0_r && rw_r), .rbk_d(ro_d), 
-			 .reg_d( gpbb_ctl[15:0] ) );
-   
    //////// read-only registers
    // loopback readback
    reg_ro reg_ro_41000 ( .clk(bclk_dll), .bus_a(bus_addr_r), .my_a(19'h41000),
@@ -325,42 +182,6 @@ module novena_fpga(
 			 .bus_d(ro_d), .re(!cs0_r && rw_r),
 			 .reg_d( r40002wo[15:0] ) );
 
-   reg_ro reg_ro_41010 ( .clk(bclk_dll), .bus_a(bus_addr_r), .my_a(19'h41010),
-			 .bus_d(ro_d), .re(!cs0_r && rw_r),
-			 .reg_d( {8'b0,dut_to_cpu[7:0]} ) );
-
-   reg_ro reg_ro_41012 ( .clk(bclk_dll), .bus_a(bus_addr_r), .my_a(19'h41012),
-			 .bus_d(ro_d), .re(!cs0_r && rw_r),
-			 .reg_d( gpbb_stat[15:0] ) );
-
-   
-   ///////////////////////
-   // CS1 bank registers: minimum size here is 64-bit, tuned for synchronous burst access only
-   ///////////////////////
-
-   wire [63:0] 	     rC04_0000wo;
-   wire [63:0] 	     rC04_0008wo;
-   
-   ///////// write registers
-   // loopback test
-   reg_wo_4burst reg_wo_4b_C04_0000( .clk(bclk_i), .bus_ad(eim_din), .my_a(19'h4_0000), 
-				     .bus_a(EIM_A[18:16]), .adv(!EIM_LBA), .rw(EIM_RW), .cs(!EIM_CS[1]), 
-				     .reg_d( rC04_0000wo[63:0] ), .rbk_d(ro_d_b) );
-
-   reg_wo_4burst reg_wo_4b_C04_0008( .clk(bclk_i), .bus_ad(eim_din), .my_a(19'h4_0008),
-				     .bus_a(EIM_A[18:16]), .adv(!EIM_LBA), .rw(EIM_RW), .cs(!EIM_CS[1]),
-				     .reg_d( rC04_0008wo[63:0] ), .rbk_d(ro_d_b) );
-
-   ///////// read registers
-   // loopback test
-   reg_ro_4burst reg_ro_4b_C04_1000( .clk(bclk_i), .bus_ad(eim_din), .my_a(19'h4_1000),
-				     .bus_a(EIM_A[18:16]), .adv(!EIM_LBA), .rw(EIM_RW), .cs(!EIM_CS[1]),
-				     .reg_d( rC04_0000wo[63:0] ), .rbk_d(ro_d_b) );
-
-   reg_ro_4burst reg_ro_4b_C04_1008( .clk(bclk_i), .bus_ad(eim_din), .my_a(19'h4_1008),
-				     .bus_a(EIM_A[18:16]), .adv(!EIM_LBA), .rw(EIM_RW), .cs(!EIM_CS[1]),
-				     .reg_d( rC04_0008wo[63:0] ), .rbk_d(ro_d_b) );
-
    // FPGA minor version code
    reg_ro reg_ro_41FFC ( .clk(bclk_dll), .bus_a(bus_addr_r), .my_a(19'h41FFC),
 			 .bus_d(ro_d), .re(!cs0_r && rw_r),
@@ -372,41 +193,6 @@ module novena_fpga(
 			 .reg_d( 16'h000B ) ); // 000B is for GPBB release
 
    ////////////////////////////////////
-   ///// I2C register set -- for those who don't want to use EIM
-   ////////////////////////////////////
-   wire [7:0] 	      reg_0_test;
-   wire       SDA_pd;
-   wire       SDA_int;
-   
-   IOBUF #(.DRIVE(8), .SLEW("SLOW")) IOBUF_sda (.IO(I2C3_SDA), .I(1'b0), .T(!SDA_pd), .O(SDA_int));
-   i2c_slave i2c_slave(
-		       .SCL(I2C3_SCL),
-		       .SDA(SDA_int),
-		       .SDA_pd(SDA_pd),
-		       .clk(clk25), // nominally 26 MHz, this is close enough
-		       .glbl_reset(reset),
-		       .i2c_device_addr(8'h3C),
-
-		       // outputs from I2C block (CPU->FPGA) 0-3F
-		       .reg_0(reg_0_test),
-
-		       .reg_2({adc_go,adc_chan[2:0]}),
-		       // bit 2-0:  ADC channel
-		       // bit 3:    initiate conversion
-
-		       // inputs to I2C block (FPGA->CPU) 40-7F
-		       .reg_40(adc_in[7:0]),
-		       .reg_41({6'b0,adc_in[9:8]}),
-
-		       .reg_42({7'b0, adc_valid}),
-
-		       // ID / version code
-		       // minor / major
-		       .reg_fc(8'h00), .reg_fd(8'h01), .reg_fe(8'h00), .reg_ff(8'h0B)
-		       );
-`endif // UNDEFINED
-      
-   ////////////////////////////////////
    ///// MASTER RESET
    ////////////////////////////////////
    // synced to a 3.2MHz clock
@@ -423,7 +209,7 @@ module novena_fpga(
    bclk_dll bclk_dll_mod( .clk133in(bclk_int_in), .clk133(bclk_dll),
 			  .RESET(reset), .LOCKED(bclk_locked));
 
-   wire 	      o_reset, o_locked;
+   wire 	      o_reset, o_locked, i_locked;
    wire 	      i_fbk_out, i_fbk_in;
    wire 	      o_fbk_out, o_fbk_in;
    
@@ -550,18 +336,34 @@ module novena_fpga(
    //////////////
    // coretest hash cores
    //////////////
-   coretest_hashes core(
-			//.clk(bclk_dll),
-			//.clk(clk50),
-			.clk(clk25),
-			.reset_n(1'b1),
-
-			.cs(!cs0_r && !adv_r),
-			.we(!rw_r),
-
-			.address(bus_addr_r),
-			.write_data(din_r),
-			.read_data(ro_d)
-			);
+   sha1 sha1(
+	     .clk(bclk_dll),
+	     .reset_n(!reset),
+	     .cs(!cs0_r && !adv_r),
+	     .we(!rw_r),
+	     .address(bus_addr_r),
+	     .write_data(din_r),
+	     .read_data(ro_d)
+	     );
+`ifdef UNDEFINED
+   sha256 sha256(
+		 .clk(bclk_dll),
+		 .reset_n(!reset),
+		 .cs(!cs0_r && !adv_r),
+		 .we(!rw_r),
+		 .address(bus_addr_r),
+		 .write_data(din_r),
+		 .read_data(ro_d)
+		 );
+   sha512 sha512(
+		 .clk(bclk_dll),
+		 .reset_n(!reset),
+		 .cs(!cs0_r && !adv_r),
+		 .we(!rw_r),
+		 .address(bus_addr_r),
+		 .write_data(din_r),
+		 .read_data(ro_d)
+		 );
+`endif
 
 endmodule
diff --git a/src/rtl/sha1.v b/src/rtl/sha1.v
new file mode 100644
index 0000000..920bee2
--- /dev/null
+++ b/src/rtl/sha1.v
@@ -0,0 +1,382 @@
+`define DEBUG
+//======================================================================
+//
+// sha1.v
+// ------
+// Top level wrapper for the SHA-1 hash function providing
+// a simple write()/read() interface with 16 bit data access.
+//
+//
+// Author: Paul Selkirk
+// Copyright (c) 2014, NORDUnet A/S All rights reserved.
+// 
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// - Redistributions of source code must retain the above copyright notice,
+//   this list of conditions and the following disclaimer.
+//
+// - 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.
+//
+// - Neither the name of the NORDUnet nor the names of its contributors may
+//   be used to endorse or promote products derived from this software
+//   without specific prior written permission.
+//
+// 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
+// HOLDER 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.
+//
+//======================================================================
+
+module sha1(
+            // Clock and reset.
+            input wire 	       clk,
+            input wire 	       reset_n,
+
+            // Control.
+            input wire 	       cs,
+            input wire 	       we,
+
+            // Data ports.
+            input wire [18:0]  address,
+            input wire [15:0]  write_data,
+            output wire [15:0] read_data
+            );
+
+   //----------------------------------------------------------------
+   // Internal constant and parameter definitions.
+   //----------------------------------------------------------------
+   parameter ADDR_NAME0       = 19'h42000;
+   parameter ADDR_NAME1       = 19'h42004;
+   parameter ADDR_VERSION     = 19'h42008;
+   parameter ADDR_CTRL        = 19'h42020;
+   parameter ADDR_STATUS      = 19'h42024;
+   parameter ADDR_BLOCK       = 19'h42040;
+   parameter ADDR_DIGEST      = 19'h42080;
+`ifdef DEBUG
+   parameter ADDR_ROUND_DEBUG = 19'h420FC;
+   parameter ADDR_STATE_DEBUG = 19'h42100;
+`endif
+
+   parameter CTRL_INIT_BIT    = 0;
+   parameter CTRL_NEXT_BIT    = 1;
+   parameter STATUS_READY_BIT = 0;
+   parameter STATUS_VALID_BIT = 1;
+
+   parameter CORE_NAME0       = 32'h73686131; // "sha1"
+   parameter CORE_NAME1       = 32'h20202020; // "    "
+   parameter CORE_VERSION     = 32'h302e3530; // "0.50"
+
+   parameter BLOCK_BITS       = 512;
+   parameter DIGEST_BITS      = 160;
+
+   //----------------------------------------------------------------
+   // Registers.
+   //----------------------------------------------------------------
+   reg                         init_reg;
+   reg                         next_reg;
+   reg [DIGEST_BITS - 1 : 0]   digest_reg;
+
+   //----------------------------------------------------------------
+   // Wires.
+   //----------------------------------------------------------------
+   wire                        core_init;
+   wire                        core_next;
+   wire                        core_ready;
+   wire [BLOCK_BITS - 1 : 0]   core_block;
+   wire [DIGEST_BITS - 1 : 0]  core_digest;
+   wire                        core_digest_valid;
+
+   wire [31:0]                 core_name0   = CORE_NAME0;
+   wire [31:0]                 core_name1   = CORE_NAME1;
+   wire [31:0]                 core_version = CORE_VERSION;
+   wire [31:0]                 core_ctrl;
+   wire [31:0]                 core_status;
+
+`ifdef DEBUG
+   wire [32:0] 		       core_round_debug;
+   wire [7:0] 		       round_debug_reg = core_round_debug[7:0];
+   wire [DIGEST_BITS - 1 : 0]  core_state_debug;
+`endif   
+   
+   
+   //----------------------------------------------------------------
+   // Concurrent connectivity for ports etc.
+   //----------------------------------------------------------------
+   assign core_init  = init_reg;
+   assign core_next  = next_reg;
+   assign core_ctrl   = { 30'b0, next_reg, init_reg };
+   assign core_status = { 30'b0, core_digest_valid, core_ready };
+
+   //----------------------------------------------------------------
+   // core instantiation.
+   //----------------------------------------------------------------
+   reg 			       clk66;
+   always @(posedge clk)
+      begin
+	 clk66 <= ~clk66;
+      end
+
+   reg 			       clk33;
+   always @(posedge clk66)
+      begin
+	 clk33 <= ~clk33;
+      end
+
+   sha1_core core(
+                  .clk(clk33),
+                  .reset_n(reset_n),
+
+                  .init(core_init),
+                  .next(core_next),
+
+                  .block(core_block),
+
+                  .ready(core_ready),
+
+                  .digest(core_digest),
+                  .digest_valid(core_digest_valid)
+`ifdef DEBUG
+		  ,
+		  .round_debug(round_debug_reg),
+		  .state_debug(core_state_debug)
+`endif
+                  );
+
+   //----------------------------------------------------------------
+   // latch in digest when ready
+   //----------------------------------------------------------------
+   always @(posedge clk)
+      begin
+         if (core_digest_valid)
+           digest_reg <= core_digest;
+      end
+
+   //----------------------------------------------------------------
+   // strobe init/next signals on write
+   //----------------------------------------------------------------
+   always @(posedge clk)
+      begin
+         init_reg <= 0;
+         next_reg <= 0;
+
+         if ((address == ADDR_CTRL + 2) && cs && we)
+           begin
+              init_reg <= write_data[CTRL_INIT_BIT];
+              next_reg <= write_data[CTRL_NEXT_BIT];
+           end
+      end
+
+   //----------------------------------------------------------------
+   // storage registers for mapping memory to core interface
+   //----------------------------------------------------------------
+   reg_ro reg_name0_0 ( .clk(clk), .bus_a(address), .my_a(ADDR_NAME0),
+                         .bus_d(read_data), .re(cs && !we),
+                         .reg_d(core_name0[31:16]) );
+   reg_ro reg_name0_2 ( .clk(clk), .bus_a(address), .my_a(ADDR_NAME0 + 12'd2),
+                         .bus_d(read_data), .re(cs && !we),
+                         .reg_d(core_name0[15:0]) );
+   reg_ro reg_name1_0 ( .clk(clk), .bus_a(address), .my_a(ADDR_NAME1),
+                         .bus_d(read_data), .re(cs && !we),
+                         .reg_d(core_name1[31:16]) );
+   reg_ro reg_name1_2 ( .clk(clk), .bus_a(address), .my_a(ADDR_NAME1 + 12'd2),
+                         .bus_d(read_data), .re(cs && !we),
+                         .reg_d(core_name1[15:0]) );
+   reg_ro reg_version_0 ( .clk(clk), .bus_a(address), .my_a(ADDR_VERSION),
+                         .bus_d(read_data), .re(cs && !we),
+                        .reg_d(core_version[31:16]) );
+   reg_ro reg_version_2 ( .clk(clk), .bus_a(address), .my_a(ADDR_VERSION + 12'd2),
+                         .bus_d(read_data), .re(cs && !we),
+                         .reg_d(core_version[15:0]) );
+   reg_ro reg_ctrl_0 ( .clk(clk), .bus_a(address), .my_a(ADDR_CTRL),
+                         .bus_d(read_data), .re(cs && !we),
+                         .reg_d(core_ctrl[31:16]) );
+   reg_ro reg_ctrl_2 ( .clk(clk), .bus_a(address), .my_a(ADDR_CTRL + 12'd2),
+                         .bus_d(read_data), .re(cs && !we),
+                         .reg_d(core_ctrl[15:0]) );
+   reg_ro reg_status_0 ( .clk(clk), .bus_a(address), .my_a(ADDR_STATUS),
+                         .bus_d(read_data), .re(cs && !we),
+                         .reg_d(core_status[31:16]) );
+   reg_ro reg_status_2 ( .clk(clk), .bus_a(address), .my_a(ADDR_STATUS + 12'd2),
+                         .bus_d(read_data), .re(cs && !we),
+                         .reg_d(core_status[15:0]) );
+
+   reg_wo reg_block_0 ( .clk(clk), .bus_a(address), .my_a(ADDR_BLOCK),
+                         .bus_d(write_data), .we(cs && we), .re(cs && !we),
+                         .reg_d(core_block[511:496]), .rbk_d(read_data) );
+   reg_wo reg_block_2 ( .clk(clk), .bus_a(address), .my_a(ADDR_BLOCK + 12'd2),
+                         .bus_d(write_data), .we(cs && we), .re(cs && !we),
+                         .reg_d(core_block[495:480]), .rbk_d(read_data) );
+   reg_wo reg_block_4 ( .clk(clk), .bus_a(address), .my_a(ADDR_BLOCK + 12'd4),
+                         .bus_d(write_data), .we(cs && we), .re(cs && !we),
+                         .reg_d(core_block[479:464]), .rbk_d(read_data) );
+   reg_wo reg_block_6 ( .clk(clk), .bus_a(address), .my_a(ADDR_BLOCK + 12'd6),
+                         .bus_d(write_data), .we(cs && we), .re(cs && !we),
+                         .reg_d(core_block[463:448]), .rbk_d(read_data) );
+   reg_wo reg_block_8 ( .clk(clk), .bus_a(address), .my_a(ADDR_BLOCK + 12'd8),
+                         .bus_d(write_data), .we(cs && we), .re(cs && !we),
+                         .reg_d(core_block[447:432]), .rbk_d(read_data) );
+   reg_wo reg_block_10 ( .clk(clk), .bus_a(address), .my_a(ADDR_BLOCK + 12'd10),
+                         .bus_d(write_data), .we(cs && we), .re(cs && !we),
+                         .reg_d(core_block[431:416]), .rbk_d(read_data) );
+   reg_wo reg_block_12 ( .clk(clk), .bus_a(address), .my_a(ADDR_BLOCK + 12'd12),
+                         .bus_d(write_data), .we(cs && we), .re(cs && !we),
+                         .reg_d(core_block[415:400]), .rbk_d(read_data) );
+   reg_wo reg_block_14 ( .clk(clk), .bus_a(address), .my_a(ADDR_BLOCK + 12'd14),
+                         .bus_d(write_data), .we(cs && we), .re(cs && !we),
+                         .reg_d(core_block[399:384]), .rbk_d(read_data) );
+   reg_wo reg_block_16 ( .clk(clk), .bus_a(address), .my_a(ADDR_BLOCK + 12'd16),
+                         .bus_d(write_data), .we(cs && we), .re(cs && !we),
+                         .reg_d(core_block[383:368]), .rbk_d(read_data) );
+   reg_wo reg_block_18 ( .clk(clk), .bus_a(address), .my_a(ADDR_BLOCK + 12'd18),
+                         .bus_d(write_data), .we(cs && we), .re(cs && !we),
+                         .reg_d(core_block[367:352]), .rbk_d(read_data) );
+   reg_wo reg_block_20 ( .clk(clk), .bus_a(address), .my_a(ADDR_BLOCK + 12'd20),
+                         .bus_d(write_data), .we(cs && we), .re(cs && !we),
+                         .reg_d(core_block[351:336]), .rbk_d(read_data) );
+   reg_wo reg_block_22 ( .clk(clk), .bus_a(address), .my_a(ADDR_BLOCK + 12'd22),
+                         .bus_d(write_data), .we(cs && we), .re(cs && !we),
+                         .reg_d(core_block[335:320]), .rbk_d(read_data) );
+   reg_wo reg_block_24 ( .clk(clk), .bus_a(address), .my_a(ADDR_BLOCK + 12'd24),
+                         .bus_d(write_data), .we(cs && we), .re(cs && !we),
+                         .reg_d(core_block[319:304]), .rbk_d(read_data) );
+   reg_wo reg_block_26 ( .clk(clk), .bus_a(address), .my_a(ADDR_BLOCK + 12'd26),
+                         .bus_d(write_data), .we(cs && we), .re(cs && !we),
+                         .reg_d(core_block[303:288]), .rbk_d(read_data) );
+   reg_wo reg_block_28 ( .clk(clk), .bus_a(address), .my_a(ADDR_BLOCK + 12'd28),
+                         .bus_d(write_data), .we(cs && we), .re(cs && !we),
+                         .reg_d(core_block[287:272]), .rbk_d(read_data) );
+   reg_wo reg_block_30 ( .clk(clk), .bus_a(address), .my_a(ADDR_BLOCK + 12'd30),
+                         .bus_d(write_data), .we(cs && we), .re(cs && !we),
+                         .reg_d(core_block[271:256]), .rbk_d(read_data) );
+   reg_wo reg_block_32 ( .clk(clk), .bus_a(address), .my_a(ADDR_BLOCK + 12'd32),
+                         .bus_d(write_data), .we(cs && we), .re(cs && !we),
+                         .reg_d(core_block[255:240]), .rbk_d(read_data) );
+   reg_wo reg_block_34 ( .clk(clk), .bus_a(address), .my_a(ADDR_BLOCK + 12'd34),
+                         .bus_d(write_data), .we(cs && we), .re(cs && !we),
+                         .reg_d(core_block[239:224]), .rbk_d(read_data) );
+   reg_wo reg_block_36 ( .clk(clk), .bus_a(address), .my_a(ADDR_BLOCK + 12'd36),
+                         .bus_d(write_data), .we(cs && we), .re(cs && !we),
+                         .reg_d(core_block[223:208]), .rbk_d(read_data) );
+   reg_wo reg_block_38 ( .clk(clk), .bus_a(address), .my_a(ADDR_BLOCK + 12'd38),
+                         .bus_d(write_data), .we(cs && we), .re(cs && !we),
+                         .reg_d(core_block[207:192]), .rbk_d(read_data) );
+   reg_wo reg_block_40 ( .clk(clk), .bus_a(address), .my_a(ADDR_BLOCK + 12'd40),
+                         .bus_d(write_data), .we(cs && we), .re(cs && !we),
+                         .reg_d(core_block[191:176]), .rbk_d(read_data) );
+   reg_wo reg_block_42 ( .clk(clk), .bus_a(address), .my_a(ADDR_BLOCK + 12'd42),
+                         .bus_d(write_data), .we(cs && we), .re(cs && !we),
+                         .reg_d(core_block[175:160]), .rbk_d(read_data) );
+   reg_wo reg_block_44 ( .clk(clk), .bus_a(address), .my_a(ADDR_BLOCK + 12'd44),
+                         .bus_d(write_data), .we(cs && we), .re(cs && !we),
+                         .reg_d(core_block[159:144]), .rbk_d(read_data) );
+   reg_wo reg_block_46 ( .clk(clk), .bus_a(address), .my_a(ADDR_BLOCK + 12'd46),
+                         .bus_d(write_data), .we(cs && we), .re(cs && !we),
+                         .reg_d(core_block[143:128]), .rbk_d(read_data) );
+   reg_wo reg_block_48 ( .clk(clk), .bus_a(address), .my_a(ADDR_BLOCK + 12'd48),
+                         .bus_d(write_data), .we(cs && we), .re(cs && !we),
+                         .reg_d(core_block[127:112]), .rbk_d(read_data) );
+   reg_wo reg_block_50 ( .clk(clk), .bus_a(address), .my_a(ADDR_BLOCK + 12'd50),
+                         .bus_d(write_data), .we(cs && we), .re(cs && !we),
+                         .reg_d(core_block[111:96]), .rbk_d(read_data) );
+   reg_wo reg_block_52 ( .clk(clk), .bus_a(address), .my_a(ADDR_BLOCK + 12'd52),
+                         .bus_d(write_data), .we(cs && we), .re(cs && !we),
+                         .reg_d(core_block[95:80]), .rbk_d(read_data) );
+   reg_wo reg_block_54 ( .clk(clk), .bus_a(address), .my_a(ADDR_BLOCK + 12'd54),
+                         .bus_d(write_data), .we(cs && we), .re(cs && !we),
+                         .reg_d(core_block[79:64]), .rbk_d(read_data) );
+   reg_wo reg_block_56 ( .clk(clk), .bus_a(address), .my_a(ADDR_BLOCK + 12'd56),
+                         .bus_d(write_data), .we(cs && we), .re(cs && !we),
+                         .reg_d(core_block[63:48]), .rbk_d(read_data) );
+   reg_wo reg_block_58 ( .clk(clk), .bus_a(address), .my_a(ADDR_BLOCK + 12'd58),
+                         .bus_d(write_data), .we(cs && we), .re(cs && !we),
+                         .reg_d(core_block[47:32]), .rbk_d(read_data) );
+   reg_wo reg_block_60 ( .clk(clk), .bus_a(address), .my_a(ADDR_BLOCK + 12'd60),
+                         .bus_d(write_data), .we(cs && we), .re(cs && !we),
+                         .reg_d(core_block[31:16]), .rbk_d(read_data) );
+   reg_wo reg_block_62 ( .clk(clk), .bus_a(address), .my_a(ADDR_BLOCK + 12'd62),
+                         .bus_d(write_data), .we(cs && we), .re(cs && !we),
+                         .reg_d(core_block[15:0]), .rbk_d(read_data) );
+
+   reg_ro reg_digest_0 ( .clk(clk), .bus_a(address), .my_a(ADDR_DIGEST),
+                         .bus_d(read_data), .re(cs && !we),
+                         .reg_d(digest_reg[159:144]) );
+   reg_ro reg_digest_2 ( .clk(clk), .bus_a(address), .my_a(ADDR_DIGEST + 12'd2),
+                         .bus_d(read_data), .re(cs && !we),
+                         .reg_d(digest_reg[143:128]) );
+   reg_ro reg_digest_4 ( .clk(clk), .bus_a(address), .my_a(ADDR_DIGEST + 12'd4),
+                         .bus_d(read_data), .re(cs && !we),
+                         .reg_d(digest_reg[127:112]) );
+   reg_ro reg_digest_6 ( .clk(clk), .bus_a(address), .my_a(ADDR_DIGEST + 12'd6),
+                         .bus_d(read_data), .re(cs && !we),
+                         .reg_d(digest_reg[111:96]) );
+   reg_ro reg_digest_8 ( .clk(clk), .bus_a(address), .my_a(ADDR_DIGEST + 12'd8),
+                         .bus_d(read_data), .re(cs && !we),
+                         .reg_d(digest_reg[95:80]) );
+   reg_ro reg_digest_10 ( .clk(clk), .bus_a(address), .my_a(ADDR_DIGEST + 12'd10),
+                         .bus_d(read_data), .re(cs && !we),
+                         .reg_d(digest_reg[79:64]) );
+   reg_ro reg_digest_12 ( .clk(clk), .bus_a(address), .my_a(ADDR_DIGEST + 12'd12),
+                         .bus_d(read_data), .re(cs && !we),
+                         .reg_d(digest_reg[63:48]) );
+   reg_ro reg_digest_14 ( .clk(clk), .bus_a(address), .my_a(ADDR_DIGEST + 12'd14),
+                         .bus_d(read_data), .re(cs && !we),
+                         .reg_d(digest_reg[47:32]) );
+   reg_ro reg_digest_16 ( .clk(clk), .bus_a(address), .my_a(ADDR_DIGEST + 12'd16),
+                         .bus_d(read_data), .re(cs && !we),
+                         .reg_d(digest_reg[31:16]) );
+   reg_ro reg_digest_18 ( .clk(clk), .bus_a(address), .my_a(ADDR_DIGEST + 12'd18),
+                         .bus_d(read_data), .re(cs && !we),
+                         .reg_d(digest_reg[15:0]) );
+
+`ifdef DEBUG
+   reg_wo reg_round_debug_0 ( .clk(clk), .bus_a(address), .my_a(ADDR_ROUND_DEBUG),
+                         .bus_d(write_data), .we(cs && we), .re(cs && !we),
+                         .reg_d(core_round_debug[31:16]), .rbk_d(read_data) );
+   reg_wo reg_round_debug_2 ( .clk(clk), .bus_a(address), .my_a(ADDR_ROUND_DEBUG + 12'd2),
+                         .bus_d(write_data), .we(cs && we), .re(cs && !we),
+                         .reg_d(core_round_debug[15:0]), .rbk_d(read_data) );
+
+   reg_ro reg_state_debug_0 ( .clk(clk), .bus_a(address), .my_a(ADDR_STATE_DEBUG),
+                         .bus_d(read_data), .re(cs && !we),
+                         .reg_d(core_state_debug[159:144]) );
+   reg_ro reg_state_debug_2 ( .clk(clk), .bus_a(address), .my_a(ADDR_STATE_DEBUG + 12'd2),
+                         .bus_d(read_data), .re(cs && !we),
+                         .reg_d(core_state_debug[143:128]) );
+   reg_ro reg_state_debug_4 ( .clk(clk), .bus_a(address), .my_a(ADDR_STATE_DEBUG + 12'd4),
+                         .bus_d(read_data), .re(cs && !we),
+                         .reg_d(core_state_debug[127:112]) );
+   reg_ro reg_state_debug_6 ( .clk(clk), .bus_a(address), .my_a(ADDR_STATE_DEBUG + 12'd6),
+                         .bus_d(read_data), .re(cs && !we),
+                         .reg_d(core_state_debug[111:96]) );
+   reg_ro reg_state_debug_8 ( .clk(clk), .bus_a(address), .my_a(ADDR_STATE_DEBUG + 12'd8),
+                         .bus_d(read_data), .re(cs && !we),
+                         .reg_d(core_state_debug[95:80]) );
+   reg_ro reg_state_debug_10 ( .clk(clk), .bus_a(address), .my_a(ADDR_STATE_DEBUG + 12'd10),
+                         .bus_d(read_data), .re(cs && !we),
+                         .reg_d(core_state_debug[79:64]) );
+   reg_ro reg_state_debug_12 ( .clk(clk), .bus_a(address), .my_a(ADDR_STATE_DEBUG + 12'd12),
+                         .bus_d(read_data), .re(cs && !we),
+                         .reg_d(core_state_debug[63:48]) );
+   reg_ro reg_state_debug_14 ( .clk(clk), .bus_a(address), .my_a(ADDR_STATE_DEBUG + 12'd14),
+                         .bus_d(read_data), .re(cs && !we),
+                         .reg_d(core_state_debug[47:32]) );
+   reg_ro reg_state_debug_16 ( .clk(clk), .bus_a(address), .my_a(ADDR_STATE_DEBUG + 12'd16),
+                         .bus_d(read_data), .re(cs && !we),
+                         .reg_d(core_state_debug[31:16]) );
+   reg_ro reg_state_debug_18 ( .clk(clk), .bus_a(address), .my_a(ADDR_STATE_DEBUG + 12'd18),
+                         .bus_d(read_data), .re(cs && !we),
+                         .reg_d(core_state_debug[15:0]) );
+`endif
+
+endmodule // sha1
diff --git a/src/rtl/sha1_core.v b/src/rtl/sha1_core.v
new file mode 100644
index 0000000..8dc633f
--- /dev/null
+++ b/src/rtl/sha1_core.v
@@ -0,0 +1,501 @@
+`define DEBUG
+`define ALT_WINIT
+//======================================================================
+//
+// sha1_core.v
+// -----------
+// Verilog 2001 implementation of the SHA-1 hash function.
+// This is the internal core with wide interfaces.
+//
+//
+// Author: Joachim Strombergson
+// Copyright (c) 2014 SUNET
+//
+// 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.
+//
+//======================================================================
+
+module sha1_core(
+                 input wire 	       clk,
+                 input wire 	       reset_n,
+
+                 input wire 	       init,
+                 input wire 	       next,
+
+                 input wire [511 : 0]  block,
+
+                 output wire 	       ready,
+
+                 output wire [159 : 0] digest,
+                 output wire 	       digest_valid
+`ifdef DEBUG
+		 ,
+		 input wire [7:0]      round_debug,
+                 output reg [159 : 0]  state_debug
+`endif
+                );
+
+
+  //----------------------------------------------------------------
+  // Internal constant and parameter definitions.
+  //----------------------------------------------------------------
+  parameter H0_0 = 32'h67452301;
+  parameter H0_1 = 32'hefcdab89;
+  parameter H0_2 = 32'h98badcfe;
+  parameter H0_3 = 32'h10325476;
+  parameter H0_4 = 32'hc3d2e1f0;
+
+  parameter SHA1_ROUNDS = 79;
+
+  parameter CTRL_IDLE   = 0;
+  parameter CTRL_ROUNDS = 1;
+  parameter CTRL_DIGEST = 2;
+  parameter CTRL_DONE   = 3;
+
+
+  //----------------------------------------------------------------
+  // 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          a_e_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          H_we;
+
+  reg [6 : 0] round_ctr_reg;
+  reg [6 : 0] round_ctr_new;
+  reg         round_ctr_we;
+  reg         round_ctr_inc;
+  reg         round_ctr_rst;
+
+  reg digest_valid_reg;
+  reg digest_valid_new;
+  reg digest_valid_we;
+
+  reg [1 : 0] sha1_ctrl_reg;
+  reg [1 : 0] sha1_ctrl_new;
+  reg         sha1_ctrl_we;
+
+
+  //----------------------------------------------------------------
+  // Wires.
+  //----------------------------------------------------------------
+  reg           digest_init;
+  reg           digest_update;
+  reg           state_init;
+  reg           state_update;
+  reg           first_block;
+  reg           ready_flag;
+`ifdef ALT_WINIT
+   reg [31:0] 	w [0:79];
+   always @ (posedge clk or negedge reset_n)
+     begin : w_init
+	reg [6:0]  i;
+	reg [31:0] w_tmp;
+	if (!reset_n)
+          begin
+	     for (i = 0; i < 80; i = i + 1)
+	       begin
+		  w[i] = 32'h0000;
+	       end
+	  end
+	else if (state_init)
+	  begin
+	     for (i = 0; i < 16; i = i + 1)
+	       begin
+		  w[i] = block[(511 - i*32)-:32];
+	       end
+	     for (i = 16; i < 80; i = i + 1)
+	       begin
+		  w_tmp = w[i-3] ^ w[i-8] ^ w[i-14] ^ w[i-16];
+		  w[i] = {w_tmp[30:0], w_tmp[31]};
+	       end
+	  end
+     end
+`else
+  reg           w_init;
+  reg           w_next;
+  wire [31 : 0] w;
+
+
+  //----------------------------------------------------------------
+  // Module instantiantions.
+  //----------------------------------------------------------------
+  sha1_w_mem w_mem_inst(
+                        .clk(clk),
+                        .reset_n(reset_n),
+
+                        .block(block),
+
+                        .init(w_init),
+                        .next(w_next),
+
+                        .w(w)
+                       );
+`endif
+
+
+  //----------------------------------------------------------------
+  // Concurrent connectivity for ports etc.
+  //----------------------------------------------------------------
+  assign ready        = ready_flag;
+  assign digest       = {H0_reg, H1_reg, H2_reg, H3_reg, H4_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.
+  //----------------------------------------------------------------
+  always @ (posedge clk or negedge reset_n)
+    begin : reg_update
+      if (!reset_n)
+        begin
+          a_reg            <= 32'h00000000;
+          b_reg            <= 32'h00000000;
+          c_reg            <= 32'h00000000;
+          d_reg            <= 32'h00000000;
+          e_reg            <= 32'h00000000;
+          H0_reg           <= 32'h00000000;
+          H1_reg           <= 32'h00000000;
+          H2_reg           <= 32'h00000000;
+          H3_reg           <= 32'h00000000;
+          H4_reg           <= 32'h00000000;
+          digest_valid_reg <= 0;
+          round_ctr_reg    <= 7'b0000000;
+          sha1_ctrl_reg    <= CTRL_IDLE;
+`ifdef DEBUG
+	   state_debug <= 160'b0;
+`endif
+        end
+      else
+        begin
+`ifdef DEBUG
+	   if (round_ctr_reg == round_debug)
+	     state_debug <= {a_reg, b_reg, c_reg, d_reg, e_reg};
+`endif
+          if (a_e_we)
+            begin
+              a_reg <= a_new;
+              b_reg <= b_new;
+              c_reg <= c_new;
+              d_reg <= d_new;
+              e_reg <= e_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;
+            end
+
+          if (round_ctr_we)
+            begin
+              round_ctr_reg <= round_ctr_new;
+            end
+
+          if (digest_valid_we)
+            begin
+              digest_valid_reg <= digest_valid_new;
+            end
+
+          if (sha1_ctrl_we)
+            begin
+              sha1_ctrl_reg <= sha1_ctrl_new;
+            end
+        end
+    end // reg_update
+
+
+  //----------------------------------------------------------------
+  // digest_logic
+  //
+  // The logic needed to init as well as update the digest.
+  //----------------------------------------------------------------
+  always @*
+    begin : digest_logic
+      H0_new = 32'h00000000;
+      H1_new = 32'h00000000;
+      H2_new = 32'h00000000;
+      H3_new = 32'h00000000;
+      H4_new = 32'h00000000;
+      H_we = 0;
+
+      if (digest_init)
+        begin
+          H0_new = H0_0;
+          H1_new = H0_1;
+          H2_new = H0_2;
+          H3_new = H0_3;
+          H4_new = H0_4;
+          H_we = 1;
+        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;
+          H_we = 1;
+        end
+    end // digest_logic
+
+
+  //----------------------------------------------------------------
+  // state_logic
+  //
+  // The logic needed to init as well as update the state during
+  // round processing.
+  //----------------------------------------------------------------
+  always @*
+    begin : state_logic
+      reg [31 : 0] a5;
+      reg [31 : 0] f;
+      reg [31 : 0] k;
+      reg [31 : 0] t;
+
+      a5     = 32'h00000000;
+      f      = 32'h00000000;
+      k      = 32'h00000000;
+      t      = 32'h00000000;
+      a_new  = 32'h00000000;
+      b_new  = 32'h00000000;
+      c_new  = 32'h00000000;
+      d_new  = 32'h00000000;
+      e_new  = 32'h00000000;
+      a_e_we = 0;
+
+      if (state_init)
+        begin
+          if (first_block)
+            begin
+              a_new  = H0_0;
+              b_new  = H0_1;
+              c_new  = H0_2;
+              d_new  = H0_3;
+              e_new  = H0_4;
+              a_e_we = 1;
+            end
+          else
+            begin
+              a_new  = H0_reg;
+              b_new  = H1_reg;
+              c_new  = H2_reg;
+              d_new  = H3_reg;
+              e_new  = H4_reg;
+              a_e_we = 1;
+            end
+        end
+
+      if (state_update)
+        begin
+          if (round_ctr_reg <= 19)
+            begin
+              k = 32'h5a827999;
+              f =  ((b_reg & c_reg) ^ (~b_reg & d_reg));
+            end
+          else if ((round_ctr_reg >= 20) && (round_ctr_reg <= 39))
+            begin
+              k = 32'h6ed9eba1;
+              f = b_reg ^ c_reg ^ d_reg;
+            end
+          else if ((round_ctr_reg >= 40) && (round_ctr_reg <= 59))
+            begin
+              k = 32'h8f1bbcdc;
+              f = ((b_reg | c_reg) ^ (b_reg | d_reg) ^ (c_reg | d_reg));
+            end
+          else if (round_ctr_reg >= 60)
+            begin
+              k = 32'hca62c1d6;
+              f = b_reg ^ c_reg ^ d_reg;
+            end
+
+          a5 = {a_reg[26 : 0], a_reg[31 : 27]};
+`ifdef ALT_WINIT
+          t = a5 + e_reg + f + k + w[round_ctr_reg];
+`else
+          t = a5 + e_reg + f + k + w;
+`endif
+
+          a_new  = t;
+          b_new  = a_reg;
+          c_new  = {b_reg[1 : 0], b_reg[31 : 2]};
+          d_new  = c_reg;
+          e_new  = d_reg;
+          a_e_we = 1;
+        end
+    end // state_logic
+
+
+  //----------------------------------------------------------------
+  // round_ctr
+  //
+  // Update logic for the round counter, a monotonically
+  // increasing counter with reset.
+  //----------------------------------------------------------------
+  always @*
+    begin : round_ctr
+      round_ctr_new = 0;
+      round_ctr_we  = 0;
+
+      if (round_ctr_rst)
+        begin
+          round_ctr_new = 0;
+          round_ctr_we  = 1;
+        end
+
+      if (round_ctr_inc)
+        begin
+          round_ctr_new = round_ctr_reg + 1'b1;
+          round_ctr_we  = 1;
+        end
+    end // round_ctr
+
+
+  //----------------------------------------------------------------
+  // sha1_ctrl_fsm
+  // Logic for the state machine controlling the core behaviour.
+  //----------------------------------------------------------------
+  always @*
+    begin : sha1_ctrl_fsm
+      digest_init      = 0;
+      digest_update    = 0;
+      state_init       = 0;
+      state_update     = 0;
+      first_block      = 0;
+      ready_flag       = 0;
+`ifdef ALT_WINIT
+`else
+      w_init           = 0;
+      w_next           = 0;
+`endif
+      round_ctr_inc    = 0;
+      round_ctr_rst    = 0;
+      digest_valid_new = 0;
+      digest_valid_we  = 0;
+      sha1_ctrl_new    = CTRL_IDLE;
+      sha1_ctrl_we     = 0;
+
+      case (sha1_ctrl_reg)
+        CTRL_IDLE:
+          begin
+            ready_flag = 1;
+
+            if (init)
+              begin
+                digest_init      = 1;
+`ifdef ALT_WINIT
+`else
+                w_init           = 1;
+`endif
+                state_init       = 1;
+                first_block      = 1;
+                round_ctr_rst    = 1;
+                digest_valid_new = 0;
+                digest_valid_we  = 1;
+                sha1_ctrl_new    = CTRL_ROUNDS;
+                sha1_ctrl_we     = 1;
+              end
+
+            if (next)
+              begin
+`ifdef ALT_WINIT
+`else
+                w_init           = 1;
+`endif
+                state_init       = 1;
+                round_ctr_rst    = 1;
+                digest_valid_new = 0;
+                digest_valid_we  = 1;
+                sha1_ctrl_new    = CTRL_ROUNDS;
+                sha1_ctrl_we     = 1;
+              end
+          end
+
+
+        CTRL_ROUNDS:
+          begin
+            state_update  = 1;
+            round_ctr_inc = 1;
+`ifdef ALT_WINIT
+`else
+            w_next        = 1;
+`endif
+
+            if (round_ctr_reg == SHA1_ROUNDS)
+              begin
+                sha1_ctrl_new = CTRL_DIGEST;
+                sha1_ctrl_we  = 1;
+              end
+          end
+
+        CTRL_DIGEST:
+          begin
+            digest_update = 1;
+            sha1_ctrl_new = CTRL_DONE;
+            sha1_ctrl_we  = 1;
+	  end
+
+        CTRL_DONE:
+          begin
+            digest_valid_new = 1;
+            digest_valid_we  = 1;
+            sha1_ctrl_new    = CTRL_IDLE;
+            sha1_ctrl_we     = 1;
+          end
+      endcase // case (sha1_ctrl_reg)
+    end // sha1_ctrl_fsm
+
+endmodule // sha1_core
+
+//======================================================================
+// EOF sha1_core.v
+//======================================================================



More information about the Commits mailing list