From c6dbd00f22876863ce9aeb5c0c7c5e016ca71426 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joachim=20Stro=CC=88mbergson?= Date: Thu, 27 Nov 2014 15:49:22 +0100 Subject: Adding testbenchs. --- src/tb/tb_aes_encipher_block.v | 427 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 427 insertions(+) create mode 100644 src/tb/tb_aes_encipher_block.v (limited to 'src/tb/tb_aes_encipher_block.v') diff --git a/src/tb/tb_aes_encipher_block.v b/src/tb/tb_aes_encipher_block.v new file mode 100644 index 0000000..39d7c26 --- /dev/null +++ b/src/tb/tb_aes_encipher_block.v @@ -0,0 +1,427 @@ +//====================================================================== +// +// tb_aes_encipher_block.v +// ----------------------- +// Testbench for the AES encipher block module. +// +// +// Author: Joachim Strombergson +// Copyright (c) 2014, SUNET +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or +// without modification, are permitted provided that the following +// conditions are met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// 2. 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. +// +// 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 OWNER 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_aes_encipher_block(); + + //---------------------------------------------------------------- + // Internal constant and parameter definitions. + //---------------------------------------------------------------- + parameter DEBUG = 1; + parameter DUMP_WAIT = 0; + + parameter CLK_HALF_PERIOD = 1; + parameter CLK_PERIOD = 2 * CLK_HALF_PERIOD; + + parameter AES_128_BIT_KEY = 0; + parameter AES_256_BIT_KEY = 1; + + parameter AES_DECIPHER = 1'b0; + parameter AES_ENCIPHER = 1'b1; + + + //---------------------------------------------------------------- + // 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_next; + reg tb_keylen; + wire tb_ready; + wire [3 : 0] tb_round; + wire [127 : 0] tb_round_key; + + wire [31 : 0] tb_sboxw; + wire [31 : 0] tb_new_sboxw; + + reg [127 : 0] tb_block; + wire [127 : 0] tb_new_block; + + reg [127 : 0] key_mem [0 : 14]; + + + //---------------------------------------------------------------- + // Assignments. + //---------------------------------------------------------------- + assign tb_round_key = key_mem[tb_round]; + + + //---------------------------------------------------------------- + // Device Under Test. + //---------------------------------------------------------------- + // We need an sbox for the tests. + aes_sbox sbox( + .sboxw(tb_sboxw), + .new_sboxw(tb_new_sboxw) + ); + + + // The device under test. + aes_encipher_block dut( + .clk(tb_clk), + .reset_n(tb_reset_n), + + .next(tb_next), + + .keylen(tb_keylen), + .round(tb_round), + .round_key(tb_round_key), + + .sboxw(tb_sboxw), + .new_sboxw(tb_new_sboxw), + + .block(tb_block), + .new_block(tb_new_block), + .ready(tb_ready) + ); + + + //---------------------------------------------------------------- + // clk_gen + // + // Always running clock generator process. + //---------------------------------------------------------------- + always + begin : clk_gen + #CLK_HALF_PERIOD; + tb_clk = !tb_clk; + end // clk_gen + + + //---------------------------------------------------------------- + // sys_monitor() + // + // An always running process that creates a cycle counter and + // conditionally displays information about the DUT. + //---------------------------------------------------------------- + always + begin : sys_monitor + cycle_ctr = cycle_ctr + 1; + #(CLK_PERIOD); + if (DEBUG) + begin + dump_dut_state(); + end + end + + + //---------------------------------------------------------------- + // dump_dut_state() + // + // Dump the state of the dump when needed. + //---------------------------------------------------------------- + task dump_dut_state(); + begin + $display("State of DUT"); + $display("------------"); + $display("Interfaces"); + $display("ready = 0x%01x, next = 0x%01x, keylen = 0x%01x", + dut.ready, dut.next, dut.keylen); + $display("block = 0x%032x", dut.block); + $display("new_block = 0x%032x", dut.new_block); + $display(""); + + $display("Control states"); + $display("round = 0x%01x", dut.round); + $display("enc_ctrl = 0x%01x, update_type = 0x%01x, sword_ctr = 0x%01x, round_ctr = 0x%01x", + dut.enc_ctrl_reg, dut.update_type, dut.sword_ctr_reg, dut.round_ctr_reg); + $display(""); + + $display("Internal data values"); + $display("round_key = 0x%016x", dut.round_key); + $display("sboxw = 0x%08x, new_sboxw = 0x%08x", dut.sboxw, dut.new_sboxw); + $display("block_w0_reg = 0x%08x, block_w1_reg = 0x%08x, block_w2_reg = 0x%08x, block_w3_reg = 0x%08x", + dut.block_w0_reg, dut.block_w1_reg, dut.block_w2_reg, dut.block_w3_reg); + $display(""); + $display("old_block = 0x%08x", dut.round_logic.old_block); + $display("shiftrows_block = 0x%08x", dut.round_logic.shiftrows_block); + $display("mixcolumns_block = 0x%08x", dut.round_logic.mixcolumns_block); + $display("addkey_init_block = 0x%08x", dut.round_logic.addkey_init_block); + $display("addkey_main_block = 0x%08x", dut.round_logic.addkey_main_block); + $display("addkey_final_block = 0x%08x", dut.round_logic.addkey_final_block); + $display("block_w0_new = 0x%08x, block_w1_new = 0x%08x, block_w2_new = 0x%08x, block_w3_new = 0x%08x", + dut.block_new[127 : 096], dut.block_new[095 : 064], + dut.block_new[063 : 032], dut.block_new[031 : 000]); + $display(""); + end + endtask // dump_dut_state + + + //---------------------------------------------------------------- + // reset_dut() + // + // Toggle reset to put the DUT into a well known state. + //---------------------------------------------------------------- + task reset_dut(); + begin + $display("*** Toggle reset."); + tb_reset_n = 0; + #(2 * CLK_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 = 0; + error_ctr = 0; + tc_ctr = 0; + + tb_clk = 0; + tb_reset_n = 1; + + tb_next = 0; + tb_keylen = 0; + + tb_block = {4{32'h00000000}}; + end + endtask // init_sim + + + //---------------------------------------------------------------- + // 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 tests completed - %02d test cases did not complete successfully.", + tc_ctr, error_ctr); + end + end + endtask // display_test_result + + + //---------------------------------------------------------------- + // wait_ready() + // + // Wait for the ready flag in the dut 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 + while (!tb_ready) + begin + #(CLK_PERIOD); + if (DUMP_WAIT) + begin + dump_dut_state(); + end + end + end + endtask // wait_ready + + + //---------------------------------------------------------------- + // test_ecb_enc() + // + // Perform ECB mode encryption test. + //---------------------------------------------------------------- + task test_ecb_enc( + input key_length, + input [127 : 0] block, + input [127 : 0] expected); + begin + $display("*** TC %0d ECB mode test started.", tc_ctr); + + // Init the cipher with the given key and length. + tb_keylen = key_length; + + // Perform encipher operation on the block. + tb_block = block; + tb_next = 1; + #(2 * CLK_PERIOD); + tb_next = 0; + #(2 * CLK_PERIOD); + + wait_ready(); + + if (tb_new_block == expected) + begin + $display("*** TC %0d successful.", tc_ctr); + $display(""); + end + else + begin + $display("*** ERROR: TC %0d NOT successful.", tc_ctr); + $display("Expected: 0x%032x", expected); + $display("Got: 0x%032x", tb_new_block); + $display(""); + + error_ctr = error_ctr + 1; + end + tc_ctr = tc_ctr + 1; + end + endtask // ecb_mode_single_block_test + + + //---------------------------------------------------------------- + // tb_aes_encipher_block + // The main test functionality. + // + // Test cases taken from NIST SP 800-38A: + // http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf + //---------------------------------------------------------------- + initial + begin : tb_aes_encipher_block + reg [127 : 0] nist_plaintext0; + reg [127 : 0] nist_plaintext1; + reg [127 : 0] nist_plaintext2; + reg [127 : 0] nist_plaintext3; + + reg [127 : 0] nist_ecb_128_enc_expected0; + reg [127 : 0] nist_ecb_128_enc_expected1; + reg [127 : 0] nist_ecb_128_enc_expected2; + reg [127 : 0] nist_ecb_128_enc_expected3; + + reg [127 : 0] nist_ecb_256_enc_expected0; + reg [127 : 0] nist_ecb_256_enc_expected1; + reg [127 : 0] nist_ecb_256_enc_expected2; + reg [127 : 0] nist_ecb_256_enc_expected3; + + nist_plaintext0 = 128'h6bc1bee22e409f96e93d7e117393172a; + nist_plaintext1 = 128'hae2d8a571e03ac9c9eb76fac45af8e51; + nist_plaintext2 = 128'h30c81c46a35ce411e5fbc1191a0a52ef; + nist_plaintext3 = 128'hf69f2445df4f9b17ad2b417be66c3710; + + nist_ecb_128_enc_expected0 = 128'h3ad77bb40d7a3660a89ecaf32466ef97; + nist_ecb_128_enc_expected1 = 128'hf5d3d58503b9699de785895a96fdbaaf; + nist_ecb_128_enc_expected2 = 128'h43b1cd7f598ece23881b00e3ed030688; + nist_ecb_128_enc_expected3 = 128'h7b0c785e27e8ad3f8223207104725dd4; + + nist_ecb_256_enc_expected0 = 255'hf3eed1bdb5d2a03c064b5a7e3db181f8; + nist_ecb_256_enc_expected1 = 255'h591ccb10d410ed26dc5ba74a31362870; + nist_ecb_256_enc_expected2 = 255'hb6ed21b99ca6f4f9f153e7b1beafed1d; + nist_ecb_256_enc_expected3 = 255'h23304b7a39f9f3ff067d8d8f9e24ecc7; + + + $display(" -= Testbench for aes encipher block started =-"); + $display(" ============================================"); + $display(""); + + init_sim(); + dump_dut_state(); + reset_dut(); + dump_dut_state(); + + + // NIST 128 bit ECB tests. + key_mem[00] = 128'h2b7e151628aed2a6abf7158809cf4f3c; + key_mem[01] = 128'ha0fafe1788542cb123a339392a6c7605; + key_mem[02] = 128'hf2c295f27a96b9435935807a7359f67f; + key_mem[03] = 128'h3d80477d4716fe3e1e237e446d7a883b; + key_mem[04] = 128'hef44a541a8525b7fb671253bdb0bad00; + key_mem[05] = 128'hd4d1c6f87c839d87caf2b8bc11f915bc; + key_mem[06] = 128'h6d88a37a110b3efddbf98641ca0093fd; + key_mem[07] = 128'h4e54f70e5f5fc9f384a64fb24ea6dc4f; + key_mem[08] = 128'head27321b58dbad2312bf5607f8d292f; + key_mem[09] = 128'hac7766f319fadc2128d12941575c006e; + key_mem[10] = 128'hd014f9a8c9ee2589e13f0cc8b6630ca6; + key_mem[11] = 128'h00000000000000000000000000000000; + key_mem[12] = 128'h00000000000000000000000000000000; + key_mem[13] = 128'h00000000000000000000000000000000; + key_mem[14] = 128'h00000000000000000000000000000000; + + test_ecb_enc(AES_128_BIT_KEY, nist_plaintext0, nist_ecb_128_enc_expected0); + test_ecb_enc(AES_128_BIT_KEY, nist_plaintext1, nist_ecb_128_enc_expected1); + test_ecb_enc(AES_128_BIT_KEY, nist_plaintext2, nist_ecb_128_enc_expected2); + test_ecb_enc(AES_128_BIT_KEY, nist_plaintext3, nist_ecb_128_enc_expected3); + + + // NIST 256 bit ECB tests. + key_mem[00] = 128'h603deb1015ca71be2b73aef0857d7781; + key_mem[01] = 128'h1f352c073b6108d72d9810a30914dff4; + key_mem[02] = 128'h9ba354118e6925afa51a8b5f2067fcde; + key_mem[03] = 128'ha8b09c1a93d194cdbe49846eb75d5b9a; + key_mem[04] = 128'hd59aecb85bf3c917fee94248de8ebe96; + key_mem[05] = 128'hb5a9328a2678a647983122292f6c79b3; + key_mem[06] = 128'h812c81addadf48ba24360af2fab8b464; + key_mem[07] = 128'h98c5bfc9bebd198e268c3ba709e04214; + key_mem[08] = 128'h68007bacb2df331696e939e46c518d80; + key_mem[09] = 128'hc814e20476a9fb8a5025c02d59c58239; + key_mem[10] = 128'hde1369676ccc5a71fa2563959674ee15; + key_mem[11] = 128'h5886ca5d2e2f31d77e0af1fa27cf73c3; + key_mem[12] = 128'h749c47ab18501ddae2757e4f7401905a; + key_mem[13] = 128'hcafaaae3e4d59b349adf6acebd10190d; + key_mem[14] = 128'hfe4890d1e6188d0b046df344706c631e; + + test_ecb_enc(AES_256_BIT_KEY, nist_plaintext0, nist_ecb_256_enc_expected0); + test_ecb_enc(AES_256_BIT_KEY, nist_plaintext1, nist_ecb_256_enc_expected1); + test_ecb_enc(AES_256_BIT_KEY, nist_plaintext2, nist_ecb_256_enc_expected2); + test_ecb_enc(AES_256_BIT_KEY, nist_plaintext3, nist_ecb_256_enc_expected3); + + + display_test_result(); + $display(""); + $display("*** AES encipher block module simulation done. ***"); + $finish; + end // aes_core_test +endmodule // tb_aes_encipher_block + +//====================================================================== +// EOF tb_aes_encipher_block.v +//====================================================================== -- cgit v1.2.3