diff options
author | Pavel V. Shatov (Meister) <meisterpaul1@yandex.ru> | 2017-12-05 22:26:31 +0300 |
---|---|---|
committer | Pavel V. Shatov (Meister) <meisterpaul1@yandex.ru> | 2017-12-05 22:29:26 +0300 |
commit | 267a42bc7463c5ff1f4115eabb083cc9cb035fbc (patch) | |
tree | d4dc0416c54bba1ebbf463efb6e11999401b0c68 | |
parent | 9ba428e606573d233b193c8afe0ecd875866e839 (diff) |
Added new testbench.
-rw-r--r-- | src/tb/tb_sha3.v | 761 | ||||
-rw-r--r-- | src/tb/tb_sha3_old.v | 256 |
2 files changed, 814 insertions, 203 deletions
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; i<output_words; i=i+1) begin
+
+ tb_addr = {1'b1, i[5:0]};
+ #(CLK_PERIOD);
+
+ // swap bytes in the read value
+ for (j=31; j>0; 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; i<output_words; i=i+1) begin
+
+ tb_addr = {1'b1, i[5:0]};
+ #(CLK_PERIOD);
+
+ // swap bytes in the read value
+ for (j=31; j>0; 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<block_words; i=i+1) begin
+
+
+ if (total_bits > 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; i<output_words; i=i+1) begin
+
+ tb_addr = {1'b1, i[5:0]};
+ #(CLK_PERIOD);
+
+ // swap bytes in the read value
+ for (j=31; j>0; 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 +//====================================================================== |