//======================================================================
//
// 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.
//
//======================================================================
//------------------------------------------------------------------
// Simulator directives.
//------------------------------------------------------------------
`timescale 1ns/100ps
//------------------------------------------------------------------
// Test module.
//------------------------------------------------------------------
module tb_sha256();
//----------------------------------------------------------------
// 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_cs;
reg tb_we;
reg [7 : 0] tb_address;
reg [31 : 0] tb_write_data;
wire [31 : 0] tb_read_data;
wire tb_error;
reg [31 : 0] read_data;
reg [255 : 0] digest_data;
//----------------------------------------------------------------
// Device Under Test.
//----------------------------------------------------------------
sha3 dut(
.clk(tb_clk),
.reset_n(tb_reset_n),
.cs(tb_cs),
.we(tb_we),
.address(tb_address),
.write_data(tb_write_data),
.read_data(tb_read_data),
.error(tb_error)
);
//----------------------------------------------------------------
// 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
//----------------------------------------------------------------
// 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'h00000000;
error_ctr = 32'h00000000;
tc_ctr = 32'h00000000;
tb_clk = 0;
tb_reset_n = 0;
tb_cs = 0;
tb_we = 0;
tb_address = 6'h00;
tb_write_data = 32'h00000000;
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
//----------------------------------------------------------------
// wait_ready()
//
// Wait for the ready flag in the dut to be set.
// (Actually we wait for either ready or valid to be set.)
//
// Note: It is the callers responsibility to call the function
// when the dut is actively processing and will in fact at some
// point set the flag.
//----------------------------------------------------------------
task wait_ready();
begin
read_data = 0;
while (read_data == 0)
begin
read_word(ADDR_STATUS);
end
end
endtask // wait_ready
//----------------------------------------------------------------
// single_block_test()
//
//
// Perform test of a single block digest.
//----------------------------------------------------------------
task single_block_test(input [511 : 0] block,
input [255 : 0] expected);
begin
$display("*** TC%01d - Single block test started.", tc_ctr);
$display("*** TC%01d - Single block test done.", tc_ctr);
tc_ctr = tc_ctr + 1;
end
endtask // single_block_test
//----------------------------------------------------------------
// double_block_test()
//
//
// 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,
input [255 : 0] expected0,
input [511 : 0] block1,
input [255 : 0] expected1
);
begin
$display("*** TC%01d - Double block test started.", tc_ctr);
$display("*** TC%01d - Double block test done.", tc_ctr);
tc_ctr = tc_ctr + 1;
end
endtask // double_block_test
//----------------------------------------------------------------
// sha3_test
// The main test functionality.
//----------------------------------------------------------------
initial
begin : sha3_test
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(" -- Testbench for sha3 started --");
init_sim();
reset_dut();
$display(" -- Testbench for sha3 done. --");
$finish;
end // sha3_test
endmodule // tb_sha3
//======================================================================
// EOF tb_sha3.v
//======================================================================