diff options
-rw-r--r-- | src/rtl/sha256.v | 23 | ||||
-rw-r--r-- | src/rtl/sha256_core.v | 101 | ||||
-rw-r--r-- | src/tb/tb_sha256.v | 142 | ||||
-rw-r--r-- | src/tb/tb_sha256_core.v | 3 |
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; |