[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