From 267a42bc7463c5ff1f4115eabb083cc9cb035fbc Mon Sep 17 00:00:00 2001 From: "Pavel V. Shatov (Meister)" Date: Tue, 5 Dec 2017 22:26:31 +0300 Subject: Added new testbench. --- src/tb/tb_sha3.v | 761 +++++++++++++++++++++++++++++++++++++-------------- src/tb/tb_sha3_old.v | 256 +++++++++++++++++ 2 files changed, 814 insertions(+), 203 deletions(-) create mode 100644 src/tb/tb_sha3_old.v diff --git a/src/tb/tb_sha3.v b/src/tb/tb_sha3.v index b7e29d6..28d06a3 100644 --- a/src/tb/tb_sha3.v +++ b/src/tb/tb_sha3.v @@ -1,12 +1,11 @@ //====================================================================== // // tb_sha3.v -// ----------- +// ----------------------------- // Testbench for the SHA-3 core. // -// -// Author: Joachim Strombergson, Pernd Paysan -// Copyright (c) 2015, NORDUnet A/S +// Authors: Pavel Shatov, Joachim Strombergson, Pernd Paysan +// Copyright (c) 2015, 2017 NORDUnet A/S // All rights reserved. // // Redistribution and use in source and binary forms, with or without @@ -38,217 +37,573 @@ //====================================================================== module tb_sha3(); - - //---------------------------------------------------------------- - // Internal constant and parameter definitions. - //---------------------------------------------------------------- - parameter DEBUG = 0; - - parameter CLK_HALF_PERIOD = 2; - parameter CLK_PERIOD = 2 * CLK_HALF_PERIOD; - - - //---------------------------------------------------------------- - // Register and Wire declarations. - //---------------------------------------------------------------- - reg [31 : 0] cycle_ctr; - reg [31 : 0] error_ctr; - reg [31 : 0] tc_ctr; - - reg tb_clk; - reg tb_reset_n; - reg tb_we; - reg [7 : 0] tb_address; - reg [31 : 0] tb_write_data; - wire [31 : 0] tb_read_data; - wire tb_ready; - + + + //---------------------------------------------------------------- + // Hashes of empty messages + //---------------------------------------------------------------- + localparam [511:0] SHA3_224_EMPTY_MSG = + { 224'h6b4e03423667dbb73b6e15454f0eb1abd4597f9a1b078e3f5b5a6bc7, + {512-224{1'bX}}}; + + localparam [511:0] SHA3_256_EMPTY_MSG = + { 256'ha7ffc6f8bf1ed76651c14756a061d662f580ff4de43b49fa82d80a4b80f8434a, + {512-256{1'bX}}}; + + localparam [511:0] SHA3_384_EMPTY_MSG = + { 384'h0c63a75b845e4f7d01107d852e4c2485c51a50aaaa94fc61995e71bbee983a2ac3713831264adb47fb6bd1e058d5f004, + {512-384{1'bX}}}; + + localparam [511:0] SHA3_512_EMPTY_MSG = + { 512'ha69f73cca23a9ac5c8b567dc185a756e97c982164fe25859e0d1dcc1475c80a615b2123af1f5f94c11e3e9402c3ac558f500199d95b6d3e301758586281dcd26}; + + /* + * The "short" message is the "abc" string (0x616263): + * + * https://www.di-mgt.com.au/sha_testvectors.html + * + */ + localparam [511:0] SHA3_224_SHORT_MSG = + { 224'he642824c3f8cf24ad09234ee7d3c766fc9a3a5168d0c94ad73b46fdf, + {512-224{1'bX}}}; + + localparam [511:0] SHA3_256_SHORT_MSG = + { 256'h3a985da74fe225b2045c172d6bd390bd855f086e3e9d525b46bfe24511431532, + {512-256{1'bX}}}; + + localparam [511:0] SHA3_384_SHORT_MSG = + { 384'hec01498288516fc926459f58e2c6ad8df9b473cb0fc08c2596da7cf0e49be4b298d88cea927ac7f539f1edf228376d25, + {512-384{1'bX}}}; + + localparam [511:0] SHA3_512_SHORT_MSG = + { 512'hb751850b1a57168a5693cd924b6b096e08f621827444f70d884f5d0240d2712e10e116e9192af3c91a7ec57647e3934057340b4cf408d5a56592f8274eec53f0}; + + /* + * The "long" message is the 1600-bit string 0xA3...A3 taken from: + * https://csrc.nist.gov/Projects/Cryptographic-Standards-and-Guidelines/example-values + * + */ + + localparam [511:0] SHA3_224_LONG_MSG = + { 224'h9376816ABA503F72F96CE7EB65AC095DEEE3BE4BF9BBC2A1CB7E11E0, + {512-224{1'bX}}}; + + localparam [511:0] SHA3_256_LONG_MSG = + { 256'h79F38ADEC5C20307A98EF76E8324AFBFD46CFD81B22E3973C65FA1BD9DE31787, + {512-256{1'bX}}}; + + localparam [511:0] SHA3_384_LONG_MSG = + { 384'h1881DE2CA7E41EF95DC4732B8F5F002B189CC1E42B74168ED1732649CE1DBCDD76197A31FD55EE989F2D7050DD473E8F, + {512-384{1'bX}}}; + + localparam [511:0] SHA3_512_LONG_MSG = + { 512'hE76DFAD22084A8B1467FCF2FFA58361BEC7628EDF5F3FDC0E4805DC48CAEECA81B7C13C30ADF52A3659584739A2DF46BE589C51CA1A4A8416DF6545A1CE8BA00}; + + /* + * Sponge Parameters + * + */ + `define SHA3_224_BLOCK_BITS 1152 + `define SHA3_256_BLOCK_BITS 1088 + `define SHA3_384_BLOCK_BITS 832 + `define SHA3_512_BLOCK_BITS 576 + + `define SHA3_224_OUTPUT_BITS 224 + `define SHA3_256_OUTPUT_BITS 256 + `define SHA3_384_OUTPUT_BITS 384 + `define SHA3_512_OUTPUT_BITS 512 + + + //---------------------------------------------------------------- + // Internal constant and parameter definitions. + //---------------------------------------------------------------- + parameter CLK_HALF_PERIOD = 2; + parameter CLK_PERIOD = 2 * CLK_HALF_PERIOD; + + + //---------------------------------------------------------------- + // Register and Wire declarations. + //---------------------------------------------------------------- + reg tb_clk; + reg tb_rst_n; + reg tb_we; + reg [ 6:0] tb_addr; + reg [31:0] tb_wr_data; + reg tb_dut_init; + reg tb_dut_next; + wire [31:0] tb_rd_data; + wire tb_rdy; + + integer i, j; + integer num_err; + integer total_bits; + integer block_words, output_words; + + reg [511:0] hash_shreg; // output + reg [31: 0] hash_word; // current output word + + reg mismatch; // error flag + //---------------------------------------------------------------- // Device Under Test. //---------------------------------------------------------------- - sha3 dut( - .clk(tb_clk), - .nreset(tb_reset_n), - .w(tb_we), - .addr(tb_address[6 : 0]), - .din(tb_write_data), - .dout(tb_read_data), - .ready(tb_ready) - ); - - - //---------------------------------------------------------------- - // clk_gen - // - // Clock generator process. - //---------------------------------------------------------------- - always - begin : clk_gen - #CLK_HALF_PERIOD tb_clk = !tb_clk; - end // clk_gen - - - //---------------------------------------------------------------- - // sys_monitor - // - // Generates a cycle counter and displays information about - // the dut as needed. - //---------------------------------------------------------------- - always - begin : sys_monitor - #(2 * CLK_HALF_PERIOD); - cycle_ctr = cycle_ctr + 1; - end - - - //---------------------------------------------------------------- - // dump_state() - // - // Dump the internal state of the DUT. - //---------------------------------------------------------------- - task dump_state; - begin - $display("State of the DUT"); - $display("----------------"); - $display("st[00] = 0x%016x, st[01] = 0x%016x", dut.st[00], dut.st[01]); - $display("st[02] = 0x%016x, st[03] = 0x%016x", dut.st[02], dut.st[03]); - $display("st[04] = 0x%016x, st[05] = 0x%016x", dut.st[04], dut.st[05]); - $display("st[06] = 0x%016x, st[07] = 0x%016x", dut.st[06], dut.st[07]); - $display("st[08] = 0x%016x, st[09] = 0x%016x", dut.st[08], dut.st[09]); - $display("st[10] = 0x%016x, st[11] = 0x%016x", dut.st[10], dut.st[11]); - $display("st[12] = 0x%016x, st[13] = 0x%016x", dut.st[12], dut.st[13]); - $display("st[14] = 0x%016x, st[15] = 0x%016x", dut.st[14], dut.st[15]); - $display("st[16] = 0x%016x, st[17] = 0x%016x", dut.st[16], dut.st[17]); - $display("st[18] = 0x%016x, st[19] = 0x%016x", dut.st[18], dut.st[19]); - $display("st[20] = 0x%016x, st[21] = 0x%016x", dut.st[20], dut.st[21]); - $display("st[22] = 0x%016x, st[23] = 0x%016x", dut.st[22], dut.st[23]); - $display("st[24] = 0x%016x", dut.st[24]); - $display(""); - - $display("stn[00] = 0x%016x, stn[01] = 0x%016x", dut.stn[00], dut.stn[01]); - $display("stn[02] = 0x%016x, stn[03] = 0x%016x", dut.stn[02], dut.stn[03]); - $display("stn[04] = 0x%016x, stn[05] = 0x%016x", dut.stn[04], dut.stn[05]); - $display("stn[06] = 0x%016x, stn[07] = 0x%016x", dut.stn[06], dut.stn[07]); - $display("stn[08] = 0x%016x, stn[09] = 0x%016x", dut.stn[08], dut.stn[09]); - $display("stn[10] = 0x%016x, stn[11] = 0x%016x", dut.stn[10], dut.stn[11]); - $display("stn[12] = 0x%016x, stn[13] = 0x%016x", dut.stn[12], dut.stn[13]); - $display("stn[14] = 0x%016x, stn[15] = 0x%016x", dut.stn[14], dut.stn[15]); - $display("stn[16] = 0x%016x, stn[17] = 0x%016x", dut.stn[16], dut.stn[17]); - $display("stn[18] = 0x%016x, stn[19] = 0x%016x", dut.stn[18], dut.stn[19]); - $display("stn[20] = 0x%016x, stn[21] = 0x%016x", dut.stn[20], dut.stn[21]); - $display("stn[22] = 0x%016x, stn[23] = 0x%016x", dut.stn[22], dut.stn[23]); - $display("stn[24] = 0x%016x", dut.stn[24]); - $display(""); - - $display("bc[00] = 0x%016x, bc[01] = 0x%016x", dut.bc[00], dut.bc[01]); - $display("bc[02] = 0x%016x, bc[03] = 0x%016x", dut.bc[02], dut.bc[03]); - $display("bc[04] = 0x%016x", dut.stn[04]); - $display(""); - - $display("t = 0x%016x", dut.t); - $display(""); - - $display("round = 0x%04x, roundlimit = 0x%04x", dut.round, dut.roundlimit); - $display(""); - end - endtask // dump_state - - - //---------------------------------------------------------------- - // reset_dut() - // - // Toggles reset to force the DUT into a well defined state. - //---------------------------------------------------------------- - task reset_dut; - begin - $display("*** Toggle reset."); - tb_reset_n = 0; - #(4 * CLK_HALF_PERIOD); - tb_reset_n = 1; - end - endtask // reset_dut - - - //---------------------------------------------------------------- - // init_sim() - // - // Initialize all counters and testbed functionality as well - // as setting the DUT inputs to defined values. - //---------------------------------------------------------------- - task init_sim; - begin - cycle_ctr = 32'h0; - - tb_clk = 0; - tb_reset_n = 0; - tb_we = 0; - tb_address = 6'h0; - tb_write_data = 32'h0; - end - endtask // init_dut - - - //---------------------------------------------------------------- - // display_test_result() - // - // Display the accumulated test results. - //---------------------------------------------------------------- - task display_test_result; - begin - if (error_ctr == 0) - begin - $display("*** All %02d test cases completed successfully.", tc_ctr); - end - else - begin - $display("*** %02d test cases completed.", tc_ctr); - $display("*** %02d errors detected during testing.", error_ctr); - end - end - endtask // display_test_result - - - //---------------------------------------------------------------- - // simple_test() - // - // A first simple test that verifies what happens with an all - // zero data input. - //---------------------------------------------------------------- - task simple_test; - reg [7 : 0] i; - begin - dump_state(); - - for (i = 0 ; i < 64 ; i = i + 1) - begin - tb_write_data = {i, i, i, i}; - tb_address = i[6 : 0]; - tb_we = 1; - #(CLK_PERIOD); - tb_we = 0; - end - - dump_state(); - end - endtask // simple_test - + sha3 dut + ( + .clk (tb_clk), + .nreset (tb_rst_n), + .w (tb_we), + .addr (tb_addr), + .din (tb_wr_data), + .dout (tb_rd_data), + .init (tb_dut_init), + .next (tb_dut_next), + .ready (tb_rdy) + ); + + + //---------------------------------------------------------------- + // clk_gen + // + // Clock generator process. + //---------------------------------------------------------------- + always + begin : clk_gen + #CLK_HALF_PERIOD tb_clk = ~tb_clk; + end // clk_gen + + + //---------------------------------------------------------------- + // reset_dut() + // + // Toggles reset to force the DUT into a well defined state. + //---------------------------------------------------------------- + task reset_dut; + begin + $display("*** Toggling reset..."); + tb_rst_n = 0; + #(4 * CLK_HALF_PERIOD); + tb_rst_n = 1; + end + endtask // reset_dut() + + + //---------------------------------------------------------------- + // init_sim() + // + // Initialize all counters and testbed functionality as well + // as setting the DUT inputs to defined values. + //---------------------------------------------------------------- + task init_sim; + begin + tb_clk = 0; + tb_rst_n = 0; + tb_we = 0; + tb_addr = 7'd0; + tb_wr_data = 32'h0; + tb_dut_init = 0; + tb_dut_next = 0; + end + endtask // init_sim() + + + //---------------------------------------------------------------- + // test_empty_message() + // + // The first pritimive test that verifies what happens with an + // empty input message. + //---------------------------------------------------------------- + task test_empty_message; + + input [511:0] correct_hash; // known-good hash + input integer block_size; // block length (bits) + input integer output_size; // output length (bits) + + begin + + $display("*** Testing %0d-bit hash (%0d-bit block)...", output_size, block_size); + + // number of words in block and output + block_words = block_size >> 5; // block_words = block_length / 32 + output_words = output_size >> 5; // output_words = output_length / 32 + + // wait for some time + #(4*CLK_PERIOD); + + /* + * Note, that we must wipe entire block buffer, because + * it may contain leftovers from previous calculations! + * We wipe the registers and apply padding at the same time. + * + */ + + for (i=0; i<50; i=i+1) begin + case (i) + 0: tb_wr_data = 32'h00000006; // ...0001 | 10 + block_words-1: tb_wr_data = 32'h80000000; // 1000... + default: tb_wr_data = 32'h00000000; + endcase + tb_addr = {1'b0, i[5:0]}; // increment address + tb_we = 1; // enable writing + #(CLK_PERIOD); + end + + tb_addr = 'bX; + tb_we = 0; + + /* run one absord-squeeze cycle */ + sha3_sponge_pump_init(); + + // reset error counter + mismatch = 0; + + // save the expected result + hash_shreg = correct_hash; + + // now read and compare + for (i=0; i0; j=j-8) + hash_word[j-:8] = tb_rd_data[31-j+:8]; + + $display(" *** hash_word[%0d]: reference = %08x, calculated = %08x", + i, hash_shreg[511-:32], hash_word); + + // compare + if (hash_shreg[511-:32] !== hash_word) begin + mismatch = 1; + num_err = num_err + 1; + end + + hash_shreg = {hash_shreg[511-32:0], {32{1'bX}}}; + end + + if (mismatch) $display(" *** Test failed."); + else $display(" *** Test passed."); + + end + + endtask // test_empty_message + + + //---------------------------------------------------------------- + // test_short_message() + // + // The second simple test that verifies what happens with an + // input message, that fits into just one block. + //---------------------------------------------------------------- + task test_short_message; + + input [511:0] correct_hash; // known-good hash + input integer block_size; // block length (bits) + input integer output_size; // output length (bits) + + begin + + $display("*** Testing %0d-bit hash (%0d-bit block)...", output_size, block_size); + + // number of words in block and output + block_words = block_size >> 5; // block_words = block_length / 32 + output_words = output_size >> 5; // output_words = output_length / 32 + + // wait for some time + #(4*CLK_PERIOD); + + /* + * Note, that we must wipe entire internal state, because + * it may contain leftovers from previous calculations! + * We wipe the internal state, fill in the message (0x616263) + * and apply padding all at once. + * + */ + + for (i=0; i<50; i=i+1) begin + case (i) + 0: tb_wr_data = 32'h06636261; // ...0001 | 10 | 'cba' + block_words-1: tb_wr_data = 32'h80000000; // 1000... + default: tb_wr_data = 32'h00000000; + endcase + tb_addr = {1'b0, i[5:0]}; // increment address + tb_we = 1; // enable writing + #(CLK_PERIOD); + end + + tb_addr = 'bX; + tb_we = 0; + + /* run one absord-squeeze cycle */ + sha3_sponge_pump_init(); + + // reset error counter + mismatch = 0; + + // save the expected result + hash_shreg = correct_hash; + + // now read and compare + for (i=0; i0; j=j-8) + hash_word[j-:8] = tb_rd_data[31-j+:8]; + + $display(" *** hash_word[%0d]: reference = %08x, calculated = %08x", + i, hash_shreg[511-:32], hash_word); + + // compare + if (hash_shreg[511-:32] !== hash_word) begin + mismatch = 1; + num_err = num_err + 1; + end + + hash_shreg = {hash_shreg[511-32:0], {32{1'bX}}}; + end + + if (mismatch) $display(" *** Test failed."); + else $display(" *** Test passed."); + + end + + endtask // test_short_message + + + //---------------------------------------------------------------- + // test_long_message() + // + // The second not so pritimive test, that verifies what happens + // when an input message spans more than one block. + //---------------------------------------------------------------- + task test_long_message; + + input [511:0] correct_hash; + input integer block_size; + input integer output_size; + + begin + + $display("*** Testing %0d-bit hash (%0d-bit block)...", output_size, block_size); + + // number of words in block and output + block_words = block_size >> 5; // block_words = block_length / 32 + output_words = output_size >> 5; // output_words = output_length / 32 + + // wait for some time + #(4*CLK_PERIOD); + + /* start filling the first block */ + total_bits = 1600; + + /* + * note, that we must wipe entire internal state, because + * it may contain leftovers from previous calculations! + */ + + for (i=0; i<50; i=i+1) begin + tb_wr_data = (i < block_words) ? 32'hA3A3A3A3 : 32'h00000000; + tb_addr = {1'b0, i[5:0]}; + tb_we = 1; + #(CLK_PERIOD); + if (i < block_words) + total_bits = total_bits - 32; + end + + tb_addr = 'bX; + tb_we = 0; + + /* run one absord-squeeze cycle */ + sha3_sponge_pump_init(); + + // process remaining bits + while (total_bits > -64) begin + + /* + * note, that there's no need to fill entire bank now, + * because x ^ 0 == x + */ + + for (i=0; i 0) begin + // message + tb_wr_data = 32'hA3A3A3A3; + tb_addr = {1'b0, i[5:0]}; + tb_we = 1; + #(CLK_PERIOD); + total_bits = total_bits - 32; + end else if (total_bits == 0) begin + // padding + tb_wr_data = 32'h00000006; + tb_addr = {1'b0, i[5:0]}; + tb_we = 1; + #(CLK_PERIOD); + total_bits = total_bits - 32; + end else if (i == (block_words-1)) begin + // more padding + tb_wr_data = 32'h80000000; + tb_addr = {1'b0, i[5:0]}; + tb_we = 1; + #(CLK_PERIOD); + total_bits = total_bits - 32; + end else begin + // intermediate bytes + tb_wr_data = 32'h00000000; + tb_addr = {1'b0, i[5:0]}; + tb_we = 1; + #(CLK_PERIOD); + end + + end + + tb_addr = 'bX; + tb_we = 0; + + /* run one absord-squeeze cycle */ + sha3_sponge_pump_next(); + + end + + // reset error counter + mismatch = 0; + + // save the expected result + hash_shreg = correct_hash; + + // now read and compare + for (i=0; i0; j=j-8) + hash_word[j-:8] = tb_rd_data[31-j+:8]; + + $display(" *** hash_word[%0d]: reference = %08x, calculated = %08x", + i, hash_shreg[511-:32], hash_word); + + // compare + if (hash_shreg[511-:32] !== hash_word) begin + mismatch = 1; + num_err = num_err + 1; + end + + hash_shreg = {hash_shreg[511-32:0], {32{1'bX}}}; + end + + if (mismatch) $display(" *** Test failed."); + else $display(" *** Test passed."); + + end + + endtask // test_long_message + + + //---------------------------------------------------------------- + // sha3_sponge_pump_init; + // + // Make the "sponge" absord input data and then wait for output + // data to be "squeezed out". + //---------------------------------------------------------------- + task sha3_sponge_pump_init; + + begin : sha3_sponge_pump_init_task + + reg poll_rdy; // flag to keep waiting while the DUT is busy + + // start operation + tb_dut_init = 1; + #(CLK_PERIOD); + tb_dut_init = 0; + + // poll ready output until the operation is finished + poll_rdy = 1; + while (poll_rdy) begin + #(CLK_PERIOD); + poll_rdy = !tb_rdy; + end + + end + + endtask // sha3_sponge_pump + + + //---------------------------------------------------------------- + // sha3_sponge_pump_next; + // + // Make the "sponge" absord input data and then wait for output + // data to be "squeezed out". + //---------------------------------------------------------------- + task sha3_sponge_pump_next; + + begin : sha3_sponge_pump_next_task + + reg poll_rdy; // flag to keep waiting while the DUT is busy + + // start operation + tb_dut_next = 1; + #(CLK_PERIOD); + tb_dut_next = 0; + + // poll ready output until the operation is finished + poll_rdy = 1; + while (poll_rdy) begin + #(CLK_PERIOD); + poll_rdy = !tb_rdy; + end + + end + + endtask // sha3_sponge_pump + //---------------------------------------------------------------- // sha3_test // The main test functionality. //---------------------------------------------------------------- - initial + initial + begin : sha3_test - $display(" -- Testbench for sha3 started --"); + $display("*** Testbench for sha3.v started."); + + num_err = 0; init_sim(); - reset_dut(); - simple_test(); - - $display(" -- Testbench for sha3 done. --"); - $finish; - end // sha3_test + reset_dut(); + + test_empty_message(SHA3_224_EMPTY_MSG, `SHA3_224_BLOCK_BITS, `SHA3_224_OUTPUT_BITS); + test_empty_message(SHA3_256_EMPTY_MSG, `SHA3_256_BLOCK_BITS, `SHA3_256_OUTPUT_BITS); + test_empty_message(SHA3_384_EMPTY_MSG, `SHA3_384_BLOCK_BITS, `SHA3_384_OUTPUT_BITS); + test_empty_message(SHA3_512_EMPTY_MSG, `SHA3_512_BLOCK_BITS, `SHA3_512_OUTPUT_BITS); + + test_short_message(SHA3_224_SHORT_MSG, `SHA3_224_BLOCK_BITS, `SHA3_224_OUTPUT_BITS); + test_short_message(SHA3_256_SHORT_MSG, `SHA3_256_BLOCK_BITS, `SHA3_256_OUTPUT_BITS); + test_short_message(SHA3_384_SHORT_MSG, `SHA3_384_BLOCK_BITS, `SHA3_384_OUTPUT_BITS); + test_short_message(SHA3_512_SHORT_MSG, `SHA3_512_BLOCK_BITS, `SHA3_512_OUTPUT_BITS); + + test_long_message(SHA3_224_LONG_MSG, `SHA3_224_BLOCK_BITS, `SHA3_224_OUTPUT_BITS); + test_long_message(SHA3_256_LONG_MSG, `SHA3_256_BLOCK_BITS, `SHA3_256_OUTPUT_BITS); + test_long_message(SHA3_384_LONG_MSG, `SHA3_384_BLOCK_BITS, `SHA3_384_OUTPUT_BITS); + test_long_message(SHA3_512_LONG_MSG, `SHA3_512_BLOCK_BITS, `SHA3_512_OUTPUT_BITS); + + $display("*** Testbench for sha3.v done."); + + if (num_err == 0) + $display(" *** All tests passed."); + else + $display(" *** %0d tests not passed.", num_err); + + $finish; + + end // sha3_test + endmodule // tb_sha3 //====================================================================== diff --git a/src/tb/tb_sha3_old.v b/src/tb/tb_sha3_old.v new file mode 100644 index 0000000..b7e29d6 --- /dev/null +++ b/src/tb/tb_sha3_old.v @@ -0,0 +1,256 @@ +//====================================================================== +// +// tb_sha3.v +// ----------- +// Testbench for the SHA-3 core. +// +// +// Author: Joachim Strombergson, Pernd Paysan +// Copyright (c) 2015, 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 tb_sha3(); + + //---------------------------------------------------------------- + // Internal constant and parameter definitions. + //---------------------------------------------------------------- + parameter DEBUG = 0; + + parameter CLK_HALF_PERIOD = 2; + parameter CLK_PERIOD = 2 * CLK_HALF_PERIOD; + + + //---------------------------------------------------------------- + // Register and Wire declarations. + //---------------------------------------------------------------- + reg [31 : 0] cycle_ctr; + reg [31 : 0] error_ctr; + reg [31 : 0] tc_ctr; + + reg tb_clk; + reg tb_reset_n; + reg tb_we; + reg [7 : 0] tb_address; + reg [31 : 0] tb_write_data; + wire [31 : 0] tb_read_data; + wire tb_ready; + + + //---------------------------------------------------------------- + // Device Under Test. + //---------------------------------------------------------------- + sha3 dut( + .clk(tb_clk), + .nreset(tb_reset_n), + .w(tb_we), + .addr(tb_address[6 : 0]), + .din(tb_write_data), + .dout(tb_read_data), + .ready(tb_ready) + ); + + + //---------------------------------------------------------------- + // clk_gen + // + // Clock generator process. + //---------------------------------------------------------------- + always + begin : clk_gen + #CLK_HALF_PERIOD tb_clk = !tb_clk; + end // clk_gen + + + //---------------------------------------------------------------- + // sys_monitor + // + // Generates a cycle counter and displays information about + // the dut as needed. + //---------------------------------------------------------------- + always + begin : sys_monitor + #(2 * CLK_HALF_PERIOD); + cycle_ctr = cycle_ctr + 1; + end + + + //---------------------------------------------------------------- + // dump_state() + // + // Dump the internal state of the DUT. + //---------------------------------------------------------------- + task dump_state; + begin + $display("State of the DUT"); + $display("----------------"); + $display("st[00] = 0x%016x, st[01] = 0x%016x", dut.st[00], dut.st[01]); + $display("st[02] = 0x%016x, st[03] = 0x%016x", dut.st[02], dut.st[03]); + $display("st[04] = 0x%016x, st[05] = 0x%016x", dut.st[04], dut.st[05]); + $display("st[06] = 0x%016x, st[07] = 0x%016x", dut.st[06], dut.st[07]); + $display("st[08] = 0x%016x, st[09] = 0x%016x", dut.st[08], dut.st[09]); + $display("st[10] = 0x%016x, st[11] = 0x%016x", dut.st[10], dut.st[11]); + $display("st[12] = 0x%016x, st[13] = 0x%016x", dut.st[12], dut.st[13]); + $display("st[14] = 0x%016x, st[15] = 0x%016x", dut.st[14], dut.st[15]); + $display("st[16] = 0x%016x, st[17] = 0x%016x", dut.st[16], dut.st[17]); + $display("st[18] = 0x%016x, st[19] = 0x%016x", dut.st[18], dut.st[19]); + $display("st[20] = 0x%016x, st[21] = 0x%016x", dut.st[20], dut.st[21]); + $display("st[22] = 0x%016x, st[23] = 0x%016x", dut.st[22], dut.st[23]); + $display("st[24] = 0x%016x", dut.st[24]); + $display(""); + + $display("stn[00] = 0x%016x, stn[01] = 0x%016x", dut.stn[00], dut.stn[01]); + $display("stn[02] = 0x%016x, stn[03] = 0x%016x", dut.stn[02], dut.stn[03]); + $display("stn[04] = 0x%016x, stn[05] = 0x%016x", dut.stn[04], dut.stn[05]); + $display("stn[06] = 0x%016x, stn[07] = 0x%016x", dut.stn[06], dut.stn[07]); + $display("stn[08] = 0x%016x, stn[09] = 0x%016x", dut.stn[08], dut.stn[09]); + $display("stn[10] = 0x%016x, stn[11] = 0x%016x", dut.stn[10], dut.stn[11]); + $display("stn[12] = 0x%016x, stn[13] = 0x%016x", dut.stn[12], dut.stn[13]); + $display("stn[14] = 0x%016x, stn[15] = 0x%016x", dut.stn[14], dut.stn[15]); + $display("stn[16] = 0x%016x, stn[17] = 0x%016x", dut.stn[16], dut.stn[17]); + $display("stn[18] = 0x%016x, stn[19] = 0x%016x", dut.stn[18], dut.stn[19]); + $display("stn[20] = 0x%016x, stn[21] = 0x%016x", dut.stn[20], dut.stn[21]); + $display("stn[22] = 0x%016x, stn[23] = 0x%016x", dut.stn[22], dut.stn[23]); + $display("stn[24] = 0x%016x", dut.stn[24]); + $display(""); + + $display("bc[00] = 0x%016x, bc[01] = 0x%016x", dut.bc[00], dut.bc[01]); + $display("bc[02] = 0x%016x, bc[03] = 0x%016x", dut.bc[02], dut.bc[03]); + $display("bc[04] = 0x%016x", dut.stn[04]); + $display(""); + + $display("t = 0x%016x", dut.t); + $display(""); + + $display("round = 0x%04x, roundlimit = 0x%04x", dut.round, dut.roundlimit); + $display(""); + end + endtask // dump_state + + + //---------------------------------------------------------------- + // reset_dut() + // + // Toggles reset to force the DUT into a well defined state. + //---------------------------------------------------------------- + task reset_dut; + begin + $display("*** Toggle reset."); + tb_reset_n = 0; + #(4 * CLK_HALF_PERIOD); + tb_reset_n = 1; + end + endtask // reset_dut + + + //---------------------------------------------------------------- + // init_sim() + // + // Initialize all counters and testbed functionality as well + // as setting the DUT inputs to defined values. + //---------------------------------------------------------------- + task init_sim; + begin + cycle_ctr = 32'h0; + + tb_clk = 0; + tb_reset_n = 0; + tb_we = 0; + tb_address = 6'h0; + tb_write_data = 32'h0; + end + endtask // init_dut + + + //---------------------------------------------------------------- + // display_test_result() + // + // Display the accumulated test results. + //---------------------------------------------------------------- + task display_test_result; + begin + if (error_ctr == 0) + begin + $display("*** All %02d test cases completed successfully.", tc_ctr); + end + else + begin + $display("*** %02d test cases completed.", tc_ctr); + $display("*** %02d errors detected during testing.", error_ctr); + end + end + endtask // display_test_result + + + //---------------------------------------------------------------- + // simple_test() + // + // A first simple test that verifies what happens with an all + // zero data input. + //---------------------------------------------------------------- + task simple_test; + reg [7 : 0] i; + begin + dump_state(); + + for (i = 0 ; i < 64 ; i = i + 1) + begin + tb_write_data = {i, i, i, i}; + tb_address = i[6 : 0]; + tb_we = 1; + #(CLK_PERIOD); + tb_we = 0; + end + + dump_state(); + end + endtask // simple_test + + + //---------------------------------------------------------------- + // sha3_test + // The main test functionality. + //---------------------------------------------------------------- + initial + begin : sha3_test + $display(" -- Testbench for sha3 started --"); + + init_sim(); + reset_dut(); + simple_test(); + + $display(" -- Testbench for sha3 done. --"); + $finish; + end // sha3_test +endmodule // tb_sha3 + +//====================================================================== +// EOF tb_sha3.v +//====================================================================== -- cgit v1.2.3