aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoachim StroĢˆmbergson <joachim@secworks.se>2014-02-23 21:12:10 +0100
committerJoachim StroĢˆmbergson <joachim@secworks.se>2014-02-23 21:12:10 +0100
commit5e6b7c37996926722cd19038c1813b77cf1302c7 (patch)
tree2d41afe85d78eebdcdf8737e612a2bc1f26fa384
parente7763f95ceaee327c96a22ce958c6340ec61ee92 (diff)
Updated W memory module with new sliding window version. Updated README with more info.
-rw-r--r--README.md34
-rw-r--r--src/rtl/sha1_core.v10
-rw-r--r--src/rtl/sha1_w_mem.v218
-rw-r--r--src/tb/tb_sha1_w_mem.v92
4 files changed, 216 insertions, 138 deletions
diff --git a/README.md b/README.md
index 730ef3f..36f6d2e 100644
--- a/README.md
+++ b/README.md
@@ -11,21 +11,43 @@ https://github.com/secworks/sha1
## Implementation details ##
-### Altera Cyclone IV GX ###
-Implementation using Altera Quartus-II 13.1 with a EP4CGX22CF19C6 device
-as target.
-* 10718 LEs
-* 3575 Regs
-* 103 MHz
+### Altera Cyclone FPGAs ###
+Implementation results using Altera Quartus-II 13.1.
+
+***Altera Cyclone IV E***
+- EP4CE6F17C6
+- 2913 LEs
+- 1527 regs
+- 107 MHz
+
+***Altera Cyclone IV GX***
+- EP4CGX22CF19C6
+- 2814 LEs
+- 1527 regs
+- 105 MHz
+
+***Altera Cyclone V***
+- 5CGXFC7C7F23C8
+- 1124 ALMs
+- 1527 regs
+- 104 MHz
## TODO ##
* Extensive functional verification in real HW.
* Add Wishbone interface.
+* Add results for Xilinx and possibly some other FPGA device.
* Documentation
## Status ##
+***(2014-02-23):***
+
+New version of the W memory module that quite drastically improves
+resource utilization. And a bit better performance too. Also added some
+new results for other Altera devices.
+
+
***(2014-02-21):***
Moved the core to Cryptech.
diff --git a/src/rtl/sha1_core.v b/src/rtl/sha1_core.v
index be83b52..aae578c 100644
--- a/src/rtl/sha1_core.v
+++ b/src/rtl/sha1_core.v
@@ -120,6 +120,7 @@ module sha1_core(
reg first_block;
reg ready_flag;
reg w_init;
+ reg w_next;
wire w_ready;
wire [31 : 0] w;
@@ -131,10 +132,11 @@ module sha1_core(
.clk(clk),
.reset_n(reset_n),
- .init(w_init),
.block(block),
+
+ .init(w_init),
+ .next(w_next),
- .addr(round_ctr_reg),
.w(w)
);
@@ -365,6 +367,7 @@ module sha1_core(
first_block = 0;
ready_flag = 0;
w_init = 0;
+ w_next = 0;
round_ctr_inc = 0;
round_ctr_rst = 0;
digest_valid_new = 0;
@@ -407,7 +410,8 @@ module sha1_core(
begin
state_update = 1;
round_ctr_inc = 1;
-
+ w_next = 1;
+
if (round_ctr_reg == SHA1_ROUNDS)
begin
sha1_ctrl_new = CTRL_DONE;
diff --git a/src/rtl/sha1_w_mem.v b/src/rtl/sha1_w_mem.v
index 9aaa403..7b30683 100644
--- a/src/rtl/sha1_w_mem.v
+++ b/src/rtl/sha1_w_mem.v
@@ -2,8 +2,9 @@
//
// sha1_w_mem_reg.v
// -----------------
-// The SHA-1 W memory. This memory includes functionality to
-// expand the block into 80 words.
+// The SHA-1 W memory. This memory is based around a sliding window
+// of 16 32-bit registers that are used to create the w words
+// needed by the core during the 80 rounds.
//
//
// Author: Joachim Strombergson
@@ -40,10 +41,11 @@ module sha1_w_mem(
input wire clk,
input wire reset_n,
- input wire init,
input wire [511 : 0] block,
- input wire [6 : 0] addr,
+ input wire init,
+ input wire next,
+
output wire [31 : 0] w
);
@@ -60,15 +62,30 @@ module sha1_w_mem(
//----------------------------------------------------------------
// Registers including update variables and write enable.
//----------------------------------------------------------------
- reg [31 : 0] w_mem [0 : 79];
- reg [31 : 0] w_mem_new;
+ 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 [6 : 0] w_ctr_reg;
reg [6 : 0] w_ctr_new;
reg w_ctr_we;
reg w_ctr_inc;
- reg w_ctr_set;
+ reg w_ctr_rst;
reg sha1_w_mem_ctrl_reg;
reg sha1_w_mem_ctrl_new;
@@ -80,14 +97,13 @@ module sha1_w_mem(
//----------------------------------------------------------------
reg [31 : 0] w_tmp;
reg [31 : 0] w_new;
- reg [6 : 0] w_addr;
- reg w_update;
+ reg mem_update;
//----------------------------------------------------------------
// Concurrent connectivity for ports etc.
//----------------------------------------------------------------
- assign w = w_tmp;
+ assign w = w_tmp;
//----------------------------------------------------------------
@@ -101,34 +117,45 @@ module sha1_w_mem(
begin : reg_update
if (!reset_n)
begin
+ w_mem[00] <= 32'h00000000;
+ w_mem[01] <= 32'h00000000;
+ w_mem[02] <= 32'h00000000;
+ w_mem[03] <= 32'h00000000;
+ w_mem[04] <= 32'h00000000;
+ w_mem[05] <= 32'h00000000;
+ w_mem[06] <= 32'h00000000;
+ w_mem[07] <= 32'h00000000;
+ w_mem[08] <= 32'h00000000;
+ w_mem[09] <= 32'h00000000;
+ w_mem[10] <= 32'h00000000;
+ w_mem[11] <= 32'h00000000;
+ w_mem[12] <= 32'h00000000;
+ w_mem[13] <= 32'h00000000;
+ w_mem[14] <= 32'h00000000;
+ w_mem[15] <= 32'h00000000;
w_ctr_reg <= 7'b0000000;
sha1_w_mem_ctrl_reg <= CTRL_IDLE;
end
else
begin
- if (init)
- begin
- w_mem[00] <= block[511 : 480];
- w_mem[01] <= block[479 : 448];
- w_mem[02] <= block[447 : 416];
- w_mem[03] <= block[415 : 384];
- w_mem[04] <= block[383 : 352];
- w_mem[05] <= block[351 : 320];
- w_mem[06] <= block[319 : 288];
- w_mem[07] <= block[287 : 256];
- w_mem[08] <= block[255 : 224];
- w_mem[09] <= block[223 : 192];
- w_mem[10] <= block[191 : 160];
- w_mem[11] <= block[159 : 128];
- w_mem[12] <= block[127 : 96];
- w_mem[13] <= block[95 : 64];
- w_mem[14] <= block[63 : 32];
- w_mem[15] <= block[31 : 0];
- end
-
if (w_mem_we)
begin
- w_mem[w_addr] <= w_mem_new;
+ 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)
@@ -146,40 +173,105 @@ module sha1_w_mem(
//----------------------------------------------------------------
- // external_addr_mux
+ // select_w
//
- // Mux for the external read operation. This is where we exract
- // the W variable.
+ // W word selection logic. Returns either directly from the
+ // memory or the next w value calculated.
//----------------------------------------------------------------
always @*
- begin : external_addr_mux
- w_tmp = w_mem[addr];
- end // external_addr_mux
-
+ begin : w_schedule
+ if (w_ctr_reg < 16)
+ begin
+ w_tmp = w_mem[w_ctr_reg[3 : 0]];
+ end
+ else
+ begin
+ w_tmp = w_new;
+ end
+ end // w_schedule
+
//----------------------------------------------------------------
- // w_schedule
+ // w_mem_update_logic
//
- // W word expansion logic.
+ // Update logic for the W memory. This is where the scheduling
+ // based on a sliding window is implemented.
//----------------------------------------------------------------
always @*
- begin : w_schedule
- reg [31 : 0] w_new_tmp;
+ begin : w_mem_update_logic
+ reg [31 : 0] w_0;
+ reg [31 : 0] w_2;
+ reg [31 : 0] w_8;
+ reg [31 : 0] w_13;
+ reg [31 : 0] w_16;
+
+ w_mem00_new = 32'h00000000;
+ w_mem01_new = 32'h00000000;
+ w_mem02_new = 32'h00000000;
+ w_mem03_new = 32'h00000000;
+ w_mem04_new = 32'h00000000;
+ w_mem05_new = 32'h00000000;
+ w_mem06_new = 32'h00000000;
+ w_mem07_new = 32'h00000000;
+ w_mem08_new = 32'h00000000;
+ w_mem09_new = 32'h00000000;
+ w_mem10_new = 32'h00000000;
+ w_mem11_new = 32'h00000000;
+ w_mem12_new = 32'h00000000;
+ w_mem13_new = 32'h00000000;
+ w_mem14_new = 32'h00000000;
+ w_mem15_new = 32'h00000000;
+ w_mem_we = 0;
+
+ w_0 = w_mem[0];
+ w_2 = w_mem[2];
+ w_8 = w_mem[8];
+ w_13 = w_mem[13];
+ w_16 = w_13 ^ w_8 ^ w_2 ^ w_0;
+ w_new = {w_16[30 : 0], w_16[31]};
- w_mem_we = 0;
- w_new_tmp = 32'h00000000;
- w_mem_new = 32'h00000000;
- w_addr = 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 (w_update)
+ else if (w_ctr_reg > 15)
begin
- w_new_tmp = w_mem[(w_ctr_reg - 3)] ^ w_mem[(w_ctr_reg - 8)] ^
- w_mem[(w_ctr_reg - 14)] ^ w_mem[(w_ctr_reg - 16)];
- w_mem_new = {w_new_tmp[30 : 0], w_new_tmp[31]};
- w_addr = w_ctr_reg;
- w_mem_we = 1;
+ 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_schedule
+ end // w_mem_update_logic
//----------------------------------------------------------------
@@ -193,9 +285,9 @@ module sha1_w_mem(
w_ctr_new = 0;
w_ctr_we = 0;
- if (w_ctr_set)
+ if (w_ctr_rst)
begin
- w_ctr_new = 6'h10;
+ w_ctr_new = 6'h00;
w_ctr_we = 1;
end
@@ -214,10 +306,8 @@ module sha1_w_mem(
//----------------------------------------------------------------
always @*
begin : sha1_w_mem_fsm
- w_ctr_set = 0;
- w_ctr_inc = 0;
- w_update = 0;
-
+ w_ctr_rst = 0;
+ w_ctr_inc = 0;
sha1_w_mem_ctrl_new = CTRL_IDLE;
sha1_w_mem_ctrl_we = 0;
@@ -226,7 +316,7 @@ module sha1_w_mem(
begin
if (init)
begin
- w_ctr_set = 1;
+ w_ctr_rst = 1;
sha1_w_mem_ctrl_new = CTRL_UPDATE;
sha1_w_mem_ctrl_we = 1;
end
@@ -234,9 +324,11 @@ module sha1_w_mem(
CTRL_UPDATE:
begin
- w_update = 1;
- w_ctr_inc = 1;
-
+ if (next)
+ begin
+ w_ctr_inc = 1;
+ end
+
if (w_ctr_reg == SHA1_ROUNDS)
begin
sha1_w_mem_ctrl_new = CTRL_IDLE;
diff --git a/src/tb/tb_sha1_w_mem.v b/src/tb/tb_sha1_w_mem.v
index 233e409..9ad16da 100644
--- a/src/tb/tb_sha1_w_mem.v
+++ b/src/tb/tb_sha1_w_mem.v
@@ -3,7 +3,6 @@
// Tb_sha1_w_mem.v
// ---------------
// Testbench for the SHA-1 W memory module.
-// This testbench is currently not self testing.
//
//
// Author: Joachim Strombergson
@@ -64,8 +63,8 @@ module tb_sha1_w_mem();
reg tb_clk;
reg tb_reset_n;
reg tb_init;
+ reg tb_next;
reg [511 : 0] tb_block;
- reg [6 : 0] tb_addr;
wire [31 : 0] tb_w;
reg [63 : 0] cycle_ctr;
@@ -80,10 +79,11 @@ module tb_sha1_w_mem();
.clk(tb_clk),
.reset_n(tb_reset_n),
- .init(tb_init),
.block(tb_block),
+
+ .init(tb_init),
+ .next(tb_next),
- .addr(tb_addr),
.w(tb_w)
);
@@ -113,13 +113,10 @@ module tb_sha1_w_mem();
begin
$display("cycle = %016x:", cycle_ctr);
end
-
+
if (DEBUG)
begin
- $display("addr: 0x%02x:", dut.addr);
- $display("addr4: 0x%02x:", dut.addr[3 : 0]);
- $display("w_mem_new: 0x%08x:", dut.w_mem_new);
- $display("w_mem_we: 0x%x:", dut.w_mem_we);
+ dump_w_state();
end
end // dut_monitor
@@ -132,7 +129,14 @@ module tb_sha1_w_mem();
task dump_w_state();
begin
$display("W state:");
+
+ $display("ctrl_reg = %01x, w_ctr_reg = %02x, mem_update = %01x, init = %01x, next = %01x",
+ dut.sha1_w_mem_ctrl_reg, dut.w_ctr_reg, dut.mem_update,
+ dut.init, dut.next);
+
+ $display("w_tmp = %08x, w_new = %08x", dut.w_tmp, dut.w_new);
+
$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]);
@@ -145,54 +149,6 @@ module tb_sha1_w_mem();
$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("w16_reg = %08x, w17_reg = %08x, w18_reg = %08x, w19_reg = %08x",
- dut.w_mem[16], dut.w_mem[17], dut.w_mem[18], dut.w_mem[19]);
-
- $display("w20_reg = %08x, w21_reg = %08x, w22_reg = %08x, w23_reg = %08x",
- dut.w_mem[20], dut.w_mem[21], dut.w_mem[22], dut.w_mem[23]);
-
- $display("w24_reg = %08x, w25_reg = %08x, w26_reg = %08x, w27_reg = %08x",
- dut.w_mem[24], dut.w_mem[25], dut.w_mem[26], dut.w_mem[27]);
-
- $display("w28_reg = %08x, w29_reg = %08x, w30_reg = %08x, w31_reg = %08x",
- dut.w_mem[28], dut.w_mem[29], dut.w_mem[30], dut.w_mem[31]);
-
- $display("w32_reg = %08x, w33_reg = %08x, w34_reg = %08x, w35_reg = %08x",
- dut.w_mem[32], dut.w_mem[33], dut.w_mem[34], dut.w_mem[35]);
-
- $display("w36_reg = %08x, w37_reg = %08x, w38_reg = %08x, w39_reg = %08x",
- dut.w_mem[36], dut.w_mem[37], dut.w_mem[38], dut.w_mem[39]);
-
- $display("w40_reg = %08x, w41_reg = %08x, w42_reg = %08x, w43_reg = %08x",
- dut.w_mem[40], dut.w_mem[41], dut.w_mem[42], dut.w_mem[43]);
-
- $display("w44_reg = %08x, w45_reg = %08x, w46_reg = %08x, w47_reg = %08x",
- dut.w_mem[44], dut.w_mem[45], dut.w_mem[46], dut.w_mem[47]);
-
- $display("w48_reg = %08x, w49_reg = %08x, w50_reg = %08x, w51_reg = %08x",
- dut.w_mem[48], dut.w_mem[49], dut.w_mem[50], dut.w_mem[51]);
-
- $display("w52_reg = %08x, w53_reg = %08x, w54_reg = %08x, w55_reg = %08x",
- dut.w_mem[52], dut.w_mem[53], dut.w_mem[54], dut.w_mem[55]);
-
- $display("w56_reg = %08x, w57_reg = %08x, w58_reg = %08x, w59_reg = %08x",
- dut.w_mem[56], dut.w_mem[57], dut.w_mem[58], dut.w_mem[59]);
-
- $display("w60_reg = %08x, w61_reg = %08x, w62_reg = %08x, w63_reg = %08x",
- dut.w_mem[60], dut.w_mem[61], dut.w_mem[62], dut.w_mem[63]);
-
- $display("w64_reg = %08x, w65_reg = %08x, w66_reg = %08x, w67_reg = %08x",
- dut.w_mem[64], dut.w_mem[65], dut.w_mem[66], dut.w_mem[67]);
-
- $display("w68_reg = %08x, w69_reg = %08x, w70_reg = %08x, w71_reg = %08x",
- dut.w_mem[68], dut.w_mem[69], dut.w_mem[70], dut.w_mem[71]);
-
- $display("w72_reg = %08x, w73_reg = %08x, w74_reg = %08x, w75_reg = %08x",
- dut.w_mem[72], dut.w_mem[73], dut.w_mem[74], dut.w_mem[75]);
-
- $display("w76_reg = %08x, w77_reg = %08x, w78_reg = %08x, w79_reg = %08x",
- dut.w_mem[76], dut.w_mem[77], dut.w_mem[78], dut.w_mem[79]);
-
$display("");
end
endtask // dump_state
@@ -217,13 +173,12 @@ module tb_sha1_w_mem();
task init_sim();
begin
$display("*** Simulation init.");
- tb_clk = 0;
+ tb_clk = 0;
tb_reset_n = 1;
- cycle_ctr = 0;
-
- tb_init = 0;
- tb_block = 512'h00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000;
- tb_addr = 0;
+ cycle_ctr = 0;
+ tb_init = 0;
+ tb_next = 0;
+ tb_block = 512'h00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000;
end
endtask // reset_dut
@@ -272,8 +227,9 @@ module tb_sha1_w_mem();
#(4 * CLK_HALF_PERIOD);
tb_init = 0;
+ tb_next = 1;
#(200 * CLK_HALF_PERIOD);
-
+
dump_w_state();
end
endtask // test_w_schedule
@@ -290,10 +246,14 @@ module tb_sha1_w_mem();
begin
$display("*** Test of W read operations. --");
i = 0;
+ tb_init = 1;
+ #(2 * CLK_HALF_PERIOD);
+ tb_init = 0;
+
while (i < 80)
begin
- tb_addr = i;
- $display("API: w%02x, internal w%02x = 0x%02x", tb_addr, dut.addr, dut.w_tmp);
+ tb_next = i;
+ $display("API: w%02x = 0x%02x", i, dut.w_tmp);
i = i + 1;
#(2 * CLK_HALF_PERIOD);
end