aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/rtl/sha256.v23
-rw-r--r--src/rtl/sha256_core.v101
-rw-r--r--src/tb/tb_sha256.v142
-rw-r--r--src/tb/tb_sha256_core.v3
4 files changed, 204 insertions, 65 deletions
diff --git a/src/rtl/sha256.v b/src/rtl/sha256.v
index 1f9e75e..17fcd84 100644
--- a/src/rtl/sha256.v
+++ b/src/rtl/sha256.v
@@ -64,6 +64,7 @@ module sha256(
localparam ADDR_CTRL = 8'h08;
localparam CTRL_INIT_BIT = 0;
localparam CTRL_NEXT_BIT = 1;
+ localparam CTRL_MODE_BIT = 2;
localparam ADDR_STATUS = 8'h09;
localparam STATUS_READY_BIT = 0;
@@ -97,7 +98,10 @@ module sha256(
localparam CORE_NAME0 = 32'h73686132; // "sha2"
localparam CORE_NAME1 = 32'h2d323536; // "-256"
- localparam CORE_VERSION = 32'h302e3831; // "0.81"
+ localparam CORE_VERSION = 32'h312e3830; // "1.80"
+
+ localparam MODE_SHA_224 = 1'h0;
+ localparam MODE_SHA_256 = 1'h1;
//----------------------------------------------------------------
@@ -113,6 +117,10 @@ module sha256(
reg next_we;
reg next_set;
+ reg mode_reg;
+ reg mode_new;
+ reg mode_we;
+
reg ready_reg;
reg [31 : 0] block0_reg;
@@ -201,6 +209,7 @@ module sha256(
.init(core_init),
.next(core_next),
+ .mode(mode_reg),
.block(core_block),
@@ -235,6 +244,7 @@ module sha256(
begin
init_reg <= 0;
next_reg <= 0;
+ mode_reg <= MODE_SHA_256;
ready_reg <= 0;
digest_reg <= 256'h0;
digest_valid_reg <= 0;
@@ -270,6 +280,9 @@ module sha256(
next_reg <= next_new;
end
+ if (mode_we)
+ mode_reg <= mode_new;
+
if (core_digest_valid)
begin
digest_reg <= core_digest;
@@ -405,6 +418,8 @@ module sha256(
begin : api_logic
init_set = 0;
next_set = 0;
+ mode_new = 0;
+ mode_we = 0;
block0_we = 0;
block1_we = 0;
block2_we = 0;
@@ -443,6 +458,8 @@ module sha256(
begin
init_set = write_data[CTRL_INIT_BIT];
next_set = write_data[CTRL_NEXT_BIT];
+ mode_new = write_data[CTRL_MODE_BIT];
+ mode_we = 1;
end
ADDR_BLOCK0:
@@ -538,10 +555,10 @@ module sha256(
tmp_read_data = CORE_VERSION;
ADDR_CTRL:
- tmp_read_data = {28'h0000000, 2'b00, next_reg, init_reg};
+ tmp_read_data = {29'h0, mode_reg, next_reg, init_reg};
ADDR_STATUS:
- tmp_read_data = {28'h0000000, 2'b00, digest_valid_reg, ready_reg};
+ tmp_read_data = {30'h0, digest_valid_reg, ready_reg};
ADDR_BLOCK0:
tmp_read_data = block0_reg;
diff --git a/src/rtl/sha256_core.v b/src/rtl/sha256_core.v
index 448dfe6..6553aab 100644
--- a/src/rtl/sha256_core.v
+++ b/src/rtl/sha256_core.v
@@ -44,6 +44,7 @@ module sha256_core(
input wire init,
input wire next,
+ input wire mode,
input wire [511 : 0] block,
@@ -68,20 +69,29 @@ module sha256_core(
//----------------------------------------------------------------
// Internal constant and parameter definitions.
//----------------------------------------------------------------
- parameter H0_0 = 32'h6a09e667;
- parameter H0_1 = 32'hbb67ae85;
- parameter H0_2 = 32'h3c6ef372;
- parameter H0_3 = 32'ha54ff53a;
- parameter H0_4 = 32'h510e527f;
- parameter H0_5 = 32'h9b05688c;
- parameter H0_6 = 32'h1f83d9ab;
- parameter H0_7 = 32'h5be0cd19;
-
- parameter SHA256_ROUNDS = 63;
-
- parameter CTRL_IDLE = 0;
- parameter CTRL_ROUNDS = 1;
- parameter CTRL_DONE = 2;
+ localparam SHA224_H0_0 = 32'hc1059ed8;
+ localparam SHA224_H0_1 = 32'h367cd507;
+ localparam SHA224_H0_2 = 32'h3070dd17;
+ localparam SHA224_H0_3 = 32'hf70e5939;
+ localparam SHA224_H0_4 = 32'hffc00b31;
+ localparam SHA224_H0_5 = 32'h68581511;
+ localparam SHA224_H0_6 = 32'h64f98fa7;
+ localparam SHA224_H0_7 = 32'hbefa4fa4;
+
+ localparam SHA256_H0_0 = 32'h6a09e667;
+ localparam SHA256_H0_1 = 32'hbb67ae85;
+ localparam SHA256_H0_2 = 32'h3c6ef372;
+ localparam SHA256_H0_3 = 32'ha54ff53a;
+ localparam SHA256_H0_4 = 32'h510e527f;
+ localparam SHA256_H0_5 = 32'h9b05688c;
+ localparam SHA256_H0_6 = 32'h1f83d9ab;
+ localparam SHA256_H0_7 = 32'h5be0cd19;
+
+ localparam SHA256_ROUNDS = 63;
+
+ localparam CTRL_IDLE = 0;
+ localparam CTRL_ROUNDS = 1;
+ localparam CTRL_DONE = 2;
//----------------------------------------------------------------
@@ -311,15 +321,29 @@ module sha256_core(
if (digest_init)
begin
- H0_new = H0_0;
- H1_new = H0_1;
- H2_new = H0_2;
- H3_new = H0_3;
- H4_new = H0_4;
- H5_new = H0_5;
- H6_new = H0_6;
- H7_new = H0_7;
H_we = 1;
+ if (mode)
+ begin
+ H0_new = SHA256_H0_0;
+ H1_new = SHA256_H0_1;
+ H2_new = SHA256_H0_2;
+ H3_new = SHA256_H0_3;
+ H4_new = SHA256_H0_4;
+ H5_new = SHA256_H0_5;
+ H6_new = SHA256_H0_6;
+ H7_new = SHA256_H0_7;
+ end
+ else
+ begin
+ H0_new = SHA224_H0_0;
+ H1_new = SHA224_H0_1;
+ H2_new = SHA224_H0_2;
+ H3_new = SHA224_H0_3;
+ H4_new = SHA224_H0_4;
+ H5_new = SHA224_H0_5;
+ H6_new = SHA224_H0_6;
+ H7_new = SHA224_H0_7;
+ end
end
if (digest_update)
@@ -397,17 +421,31 @@ module sha256_core(
if (state_init)
begin
+ a_h_we = 1;
if (first_block)
begin
- a_new = H0_0;
- b_new = H0_1;
- c_new = H0_2;
- d_new = H0_3;
- e_new = H0_4;
- f_new = H0_5;
- g_new = H0_6;
- h_new = H0_7;
- a_h_we = 1;
+ if (mode)
+ begin
+ a_new = SHA256_H0_0;
+ b_new = SHA256_H0_1;
+ c_new = SHA256_H0_2;
+ d_new = SHA256_H0_3;
+ e_new = SHA256_H0_4;
+ f_new = SHA256_H0_5;
+ g_new = SHA256_H0_6;
+ h_new = SHA256_H0_7;
+ end
+ else
+ begin
+ a_new = SHA224_H0_0;
+ b_new = SHA224_H0_1;
+ c_new = SHA224_H0_2;
+ d_new = SHA224_H0_3;
+ e_new = SHA224_H0_4;
+ f_new = SHA224_H0_5;
+ g_new = SHA224_H0_6;
+ h_new = SHA224_H0_7;
+ end
end
else
begin
@@ -419,7 +457,6 @@ module sha256_core(
f_new = H5_reg;
g_new = H6_reg;
h_new = H7_reg;
- a_h_we = 1;
end
end
diff --git a/src/tb/tb_sha256.v b/src/tb/tb_sha256.v
index d881dae..6377688 100644
--- a/src/tb/tb_sha256.v
+++ b/src/tb/tb_sha256.v
@@ -60,6 +60,7 @@ module tb_sha256();
parameter ADDR_NAME0 = 8'h00;
parameter ADDR_NAME1 = 8'h01;
parameter ADDR_VERSION = 8'h02;
+ parameter CTRL_MODE_VALUE = 8'h04;
parameter ADDR_CTRL = 8'h08;
parameter CTRL_INIT_VALUE = 8'h01;
@@ -95,6 +96,9 @@ module tb_sha256();
parameter ADDR_DIGEST6 = 8'h26;
parameter ADDR_DIGEST7 = 8'h27;
+ parameter SHA224_MODE = 0;
+ parameter SHA256_MODE = 1;
+
//----------------------------------------------------------------
// Register and Wire declarations.
@@ -435,17 +439,27 @@ module tb_sha256();
//
// Perform test of a single block digest.
//----------------------------------------------------------------
- task single_block_test(input [511 : 0] block,
+ task single_block_test(input mode,
+ input [511 : 0] block,
input [255 : 0] expected);
begin
$display("*** TC%01d - Single block test started.", tc_ctr);
write_block(block);
- write_word(ADDR_CTRL, CTRL_INIT_VALUE);
+
+ if (mode)
+ write_word(ADDR_CTRL, (CTRL_MODE_VALUE + CTRL_INIT_VALUE));
+ else
+ write_word(ADDR_CTRL, CTRL_INIT_VALUE);
+
#(CLK_PERIOD);
wait_ready();
read_digest();
+ // We need to ignore the LSW in SHA224 mode.
+ if (mode == SHA224_MODE)
+ digest_data[31 : 0] = 32'h0;
+
if (digest_data == expected)
begin
$display("TC%01d: OK.", tc_ctr);
@@ -470,7 +484,8 @@ module tb_sha256();
// Perform test of a double block digest. Note that we check
// the digests for both the first and final block.
//----------------------------------------------------------------
- task double_block_test(input [511 : 0] block0,
+ task double_block_test(input mode,
+ input [511 : 0] block0,
input [255 : 0] expected0,
input [511 : 0] block1,
input [255 : 0] expected1
@@ -480,11 +495,20 @@ module tb_sha256();
// First block
write_block(block0);
- write_word(ADDR_CTRL, CTRL_INIT_VALUE);
+
+ if (mode)
+ write_word(ADDR_CTRL, (CTRL_MODE_VALUE + CTRL_INIT_VALUE));
+ else
+ write_word(ADDR_CTRL, CTRL_INIT_VALUE);
+
#(CLK_PERIOD);
wait_ready();
read_digest();
+ // We need to ignore the LSW in SHA224 mode.
+ if (mode == SHA224_MODE)
+ digest_data[31 : 0] = 32'h0;
+
if (digest_data == expected0)
begin
$display("TC%01d first block: OK.", tc_ctr);
@@ -499,11 +523,20 @@ module tb_sha256();
// Final block
write_block(block1);
- write_word(ADDR_CTRL, CTRL_NEXT_VALUE);
+
+ if (mode)
+ write_word(ADDR_CTRL, (CTRL_MODE_VALUE + CTRL_NEXT_VALUE));
+ else
+ write_word(ADDR_CTRL, CTRL_NEXT_VALUE);
+
#(CLK_PERIOD);
wait_ready();
read_digest();
+ // We need to ignore the LSW in SHA224 mode.
+ if (mode == SHA224_MODE)
+ digest_data[31 : 0] = 32'h0;
+
if (digest_data == expected1)
begin
$display("TC%01d final block: OK.", tc_ctr);
@@ -525,15 +558,19 @@ module tb_sha256();
//----------------------------------------------------------------
// restore_state_test()
//
- //
// Perform test of a double block digest. Note that we check
// the digests for both the first and final block.
//----------------------------------------------------------------
- task restore_state_test(input [255 : 0] state,
- input [511 : 0] block,
- input [255 : 0] expected
- );
- begin
+ task restore_state_test;
+ begin : restore_state
+ reg [255 : 0] state;
+ reg [511 : 0] block;
+ reg [255 : 0] expected;
+
+ state = 256'h85E655D6417A17953363376A624CDE5C76E09589CAC5F811CC4B32C1F20E533A;
+ block = 512'h000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001C0;
+ expected = 256'h248D6A61D20638B8E5C026930C3E6039A33CE45964FF2167F6ECEDD419DB06C1;
+
$display("*** TC%01d - Restore state test started.", tc_ctr);
// Write state.
@@ -548,7 +585,7 @@ module tb_sha256();
// Process block.
write_block(block);
- write_word(ADDR_CTRL, CTRL_NEXT_VALUE);
+ write_word(ADDR_CTRL, (CTRL_MODE_VALUE + CTRL_NEXT_VALUE));
#(CLK_PERIOD);
wait_ready();
read_digest();
@@ -572,14 +609,14 @@ module tb_sha256();
//----------------------------------------------------------------
- // sha256_test
- // The main test functionality.
+ // sha224_tests()
//
+ // Run test cases for sha224.
// Test cases taken from:
- // http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/SHA256.pdf
+ // http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/SHA224.pdf
//----------------------------------------------------------------
- initial
- begin : sha256_test
+ task sha224_tests;
+ begin : sha224_tests_block
reg [511 : 0] tc0;
reg [255 : 0] res0;
@@ -588,35 +625,80 @@ module tb_sha256();
reg [511 : 0] tc1_1;
reg [255 : 0] res1_1;
- $display(" -- Testbench for sha256 started --");
+ $display("*** Testcases for sha224 functionality started.");
- init_sim();
- reset_dut();
- check_name_version();
+ tc0 = 512'h61626380000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018;
- // dump_dut_state();
- // write_word(ADDR_BLOCK0, 32'hdeadbeef);
- // dump_dut_state();
- // read_word(ADDR_BLOCK0);
- // dump_dut_state();
+ res0 = 256'h23097D223405D8228642A477BDA255B32AADBCE4BDA0B3F7E36C9DA700000000;
+ single_block_test(SHA224_MODE, tc0, res0);
+
+ tc1_0 = 512'h6162636462636465636465666465666765666768666768696768696A68696A6B696A6B6C6A6B6C6D6B6C6D6E6C6D6E6F6D6E6F706E6F70718000000000000000;
+ res1_0 = 256'h8250e65dbcf62f8466659c3333e5e91a10c8b7b0953927691f1419c200000000;
+ tc1_1 = 512'h000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001C0;
+ res1_1 = 256'h75388b16512776cc5dba5da1fd890150b0c6455cb4f58b195252252500000000;
+ double_block_test(SHA224_MODE, tc1_0, res1_0, tc1_1, res1_1);
+
+ $display("*** Testcases for sha224 functionality completed.");
+ end
+ endtask // sha224_tests
+
+
+ //----------------------------------------------------------------
+ // sha256_tests()
+ //
+ // Run test cases for sha256.
+ // Test cases taken from:
+ // http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/SHA256.pdf
+ //----------------------------------------------------------------
+ task sha256_tests;
+ begin : sha256_tests_block
+ reg [511 : 0] tc0;
+ reg [255 : 0] res0;
+
+ reg [511 : 0] tc1_0;
+ reg [255 : 0] res1_0;
+ reg [511 : 0] tc1_1;
+ reg [255 : 0] res1_1;
+
+ $display("*** Testcases for sha256 functionality started.");
tc0 = 512'h61626380000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018;
res0 = 256'hBA7816BF8F01CFEA414140DE5DAE2223B00361A396177A9CB410FF61F20015AD;
- single_block_test(tc0, res0);
+ single_block_test(SHA256_MODE, tc0, res0);
tc1_0 = 512'h6162636462636465636465666465666765666768666768696768696A68696A6B696A6B6C6A6B6C6D6B6C6D6E6C6D6E6F6D6E6F706E6F70718000000000000000;
res1_0 = 256'h85E655D6417A17953363376A624CDE5C76E09589CAC5F811CC4B32C1F20E533A;
tc1_1 = 512'h000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001C0;
res1_1 = 256'h248D6A61D20638B8E5C026930C3E6039A33CE45964FF2167F6ECEDD419DB06C1;
- double_block_test(tc1_0, res1_0, tc1_1, res1_1);
+ double_block_test(SHA256_MODE, tc1_0, res1_0, tc1_1, res1_1);
- restore_state_test(res1_0, tc1_1, res1_1);
+ $display("*** Testcases for sha256 functionality completed.");
+ end
+ endtask // sha256_tests
+
+
+ //----------------------------------------------------------------
+ // sha256_top_test
+ // The main test functionality.
+ //----------------------------------------------------------------
+ initial
+ begin : sha256_top_test
+ $display(" -- Testbench for sha256 started --");
+
+ init_sim();
+ reset_dut();
+
+ check_name_version();
+ sha224_tests();
+ sha256_tests();
+ restore_state_test();
display_test_result();
$display(" -- Testbench for sha256 done. --");
$finish;
- end // sha256_test
+ end // sha256_top_test
+
endmodule // tb_sha256
//======================================================================
diff --git a/src/tb/tb_sha256_core.v b/src/tb/tb_sha256_core.v
index 07e2334..981351c 100644
--- a/src/tb/tb_sha256_core.v
+++ b/src/tb/tb_sha256_core.v
@@ -68,6 +68,7 @@ module tb_sha256_core();
reg tb_reset_n;
reg tb_init;
reg tb_next;
+ reg tb_mode;
reg [511 : 0] tb_block;
reg [31 : 0] tb_state_wr_data;
reg tb_state0_we;
@@ -92,6 +93,7 @@ module tb_sha256_core();
.init(tb_init),
.next(tb_next),
+ .mode(tb_mode),
.block(tb_block),
@@ -244,6 +246,7 @@ module tb_sha256_core();
tb_init = 0;
tb_next = 0;
+ tb_mode = 1;
tb_block = 512'h0;
tb_state_wr_data = 32'h0;
tb_state0_we = 0;