aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/tb/tb_aes.v553
-rw-r--r--src/tb/tb_aes_core.v469
-rw-r--r--src/tb/tb_aes_decipher_block.v411
-rw-r--r--src/tb/tb_aes_encipher_block.v427
-rw-r--r--src/tb/tb_aes_key_mem.v655
5 files changed, 2515 insertions, 0 deletions
diff --git a/src/tb/tb_aes.v b/src/tb/tb_aes.v
new file mode 100644
index 0000000..4413ded
--- /dev/null
+++ b/src/tb/tb_aes.v
@@ -0,0 +1,553 @@
+//======================================================================
+//
+// tb_aes.v
+// --------
+// Testbench for the aes top level wrapper.
+//
+//
+// 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();
+
+ //----------------------------------------------------------------
+ // Internal constant and parameter definitions.
+ //----------------------------------------------------------------
+ parameter DEBUG = 0;
+
+ parameter CLK_HALF_PERIOD = 1;
+ parameter CLK_PERIOD = 2 * CLK_HALF_PERIOD;
+
+ // The DUT address map.
+ parameter ADDR_NAME0 = 8'h00;
+ parameter ADDR_NAME1 = 8'h01;
+ parameter ADDR_VERSION = 8'h02;
+
+ parameter ADDR_CTRL = 8'h08;
+ parameter CTRL_INIT_BIT = 0;
+ parameter CTRL_NEXT_BIT = 1;
+ parameter CTRL_ENCDEC_BIT = 2;
+ parameter CTRL_KEYLEN_BIT = 3;
+
+ parameter ADDR_CONFIG = 8'h09;
+
+ parameter ADDR_STATUS = 8'h0a;
+ parameter STATUS_READY_BIT = 0;
+ parameter STATUS_VALID_BIT = 1;
+
+ parameter ADDR_KEY0 = 8'h10;
+ parameter ADDR_KEY1 = 8'h11;
+ parameter ADDR_KEY2 = 8'h12;
+ parameter ADDR_KEY3 = 8'h13;
+ parameter ADDR_KEY4 = 8'h14;
+ parameter ADDR_KEY5 = 8'h15;
+ parameter ADDR_KEY6 = 8'h16;
+ parameter ADDR_KEY7 = 8'h17;
+
+ parameter ADDR_BLOCK0 = 8'h20;
+ parameter ADDR_BLOCK1 = 8'h21;
+ parameter ADDR_BLOCK2 = 8'h22;
+ parameter ADDR_BLOCK3 = 8'h23;
+
+ parameter ADDR_RESULT0 = 8'h30;
+ parameter ADDR_RESULT1 = 8'h31;
+ parameter ADDR_RESULT2 = 8'h32;
+ parameter ADDR_RESULT3 = 8'h33;
+
+ 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 [31 : 0] read_data;
+ reg [127 : 0] result_data;
+
+ 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;
+
+
+ //----------------------------------------------------------------
+ // Device Under Test.
+ //----------------------------------------------------------------
+ aes 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)
+ );
+
+
+ //----------------------------------------------------------------
+ // Concurrent assignments.
+ //----------------------------------------------------------------
+
+
+ //----------------------------------------------------------------
+ // 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("cycle: 0x%016x", cycle_ctr);
+ $display("State of DUT");
+ $display("------------");
+ $display("ctrl_reg: init = 0x%01x, next = 0x%01x", dut.init_reg, dut.next_reg);
+ $display("config_reg: encdec = 0x%01x, length = 0x%01x ", dut.encdec_reg, dut.keylen_reg);
+ $display("");
+
+ $display("block: 0x%08x, 0x%08x, 0x%08x, 0x%08x",
+ dut.block0_reg, dut.block1_reg, dut.block2_reg, dut.block3_reg);
+ $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;
+ $display("");
+ end
+ endtask // reset_dut
+
+
+ //----------------------------------------------------------------
+ // display_test_results()
+ //
+ // Display the accumulated test results.
+ //----------------------------------------------------------------
+ task display_test_results();
+ 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_results
+
+
+ //----------------------------------------------------------------
+ // 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_cs = 0;
+ tb_we = 0;
+ tb_address = 8'h00;
+ tb_write_data = 32'h00000000;
+ end
+ endtask // init_sim
+
+
+ //----------------------------------------------------------------
+ // write_word()
+ //
+ // Write the given word to the DUT using the DUT interface.
+ //----------------------------------------------------------------
+ task write_word(input [11 : 0] address,
+ input [31 : 0] word);
+ begin
+ if (DEBUG)
+ begin
+ $display("*** Writing 0x%08x to 0x%02x.", word, address);
+ $display("");
+ end
+
+ tb_address = address;
+ tb_write_data = word;
+ tb_cs = 1;
+ tb_we = 1;
+ #(2 * CLK_PERIOD);
+ tb_cs = 0;
+ tb_we = 0;
+ end
+ endtask // write_word
+
+
+ //----------------------------------------------------------------
+ // write_block()
+ //
+ // Write the given block to the dut.
+ //----------------------------------------------------------------
+ task write_block(input [127 : 0] block);
+ begin
+ write_word(ADDR_BLOCK0, block[127 : 96]);
+ write_word(ADDR_BLOCK1, block[95 : 64]);
+ write_word(ADDR_BLOCK2, block[63 : 32]);
+ write_word(ADDR_BLOCK3, block[31 : 0]);
+ end
+ endtask // write_block
+
+
+ //----------------------------------------------------------------
+ // read_word()
+ //
+ // Read a data word from the given address in the DUT.
+ // the word read will be available in the global variable
+ // read_data.
+ //----------------------------------------------------------------
+ task read_word(input [11 : 0] address);
+ begin
+ tb_address = address;
+ tb_cs = 1;
+ tb_we = 0;
+ #(CLK_PERIOD);
+ read_data = tb_read_data;
+ tb_cs = 0;
+
+ if (DEBUG)
+ begin
+ $display("*** Reading 0x%08x from 0x%02x.", read_data, address);
+ $display("");
+ end
+ end
+ endtask // read_word
+
+
+ //----------------------------------------------------------------
+ // read_result()
+ //
+ // Read the result block in the dut.
+ //----------------------------------------------------------------
+ task read_result();
+ begin
+ read_word(ADDR_RESULT0);
+ result_data[127 : 096] = read_data;
+ read_word(ADDR_RESULT1);
+ result_data[095 : 064] = read_data;
+ read_word(ADDR_RESULT2);
+ result_data[063 : 032] = read_data;
+ read_word(ADDR_RESULT3);
+ result_data[031 : 000] = read_data;
+ end
+ endtask // read_result
+
+
+ //----------------------------------------------------------------
+ // init_key()
+ //
+ // init the key in the dut by writing the given key and
+ // key length and then trigger init processing.
+ //----------------------------------------------------------------
+ task init_key(input [255 : 0] key, input key_length);
+ begin
+ if (DEBUG)
+ begin
+ $display("key length: 0x%01x", key_length);
+ $display("Initializing key expansion for key: 0x%016x", key);
+ end
+
+ write_word(ADDR_KEY0, key[255 : 224]);
+ write_word(ADDR_KEY1, key[223 : 192]);
+ write_word(ADDR_KEY2, key[191 : 160]);
+ write_word(ADDR_KEY3, key[159 : 128]);
+ write_word(ADDR_KEY4, key[127 : 96]);
+ write_word(ADDR_KEY5, key[95 : 64]);
+ write_word(ADDR_KEY6, key[63 : 32]);
+ write_word(ADDR_KEY7, key[31 : 0]);
+
+ if (key_length)
+ begin
+ write_word(ADDR_CONFIG, 8'h02);
+ end
+ else
+ begin
+ write_word(ADDR_CONFIG, 8'h00);
+ end
+
+ write_word(ADDR_CTRL, 8'h01);
+
+ #(100 * CLK_PERIOD);
+ end
+ endtask // init_key
+
+
+ //----------------------------------------------------------------
+ // ecb_mode_single_block_test()
+ //
+ // Perform ECB mode encryption or decryption single block test.
+ //----------------------------------------------------------------
+ task ecb_mode_single_block_test(input [7 : 0] tc_number,
+ input encdec,
+ input [255 : 0] key,
+ input key_length,
+ input [127 : 0] block,
+ input [127 : 0] expected);
+ begin
+ $display("*** TC %0d ECB mode test started.", tc_number);
+ tc_ctr = tc_ctr + 1;
+
+ init_key(key, key_length);
+ write_block(block);
+ dump_dut_state();
+
+ write_word(ADDR_CONFIG, (8'h00 + (key_length << 1)+ encdec));
+ write_word(ADDR_CTRL, 8'h02);
+
+ #(100 * CLK_PERIOD);
+
+ read_result();
+
+ if (result_data == expected)
+ begin
+ $display("*** TC %0d successful.", tc_number);
+ $display("");
+ end
+ else
+ begin
+ $display("*** ERROR: TC %0d NOT successful.", tc_number);
+ $display("Expected: 0x%032x", expected);
+ $display("Got: 0x%032x", result_data);
+ $display("");
+
+ error_ctr = error_ctr + 1;
+ end
+ end
+ endtask // ecb_mode_single_block_test
+
+
+ //----------------------------------------------------------------
+ // aes_test()
+ //
+ // Main test task will perform complete NIST test of AES.
+ //----------------------------------------------------------------
+ task aes_test();
+ reg [255 : 0] nist_aes128_key;
+ reg [255 : 0] nist_aes256_key;
+
+ 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;
+
+ begin
+ nist_aes128_key = 256'h2b7e151628aed2a6abf7158809cf4f3c00000000000000000000000000000000;
+ nist_aes256_key = 256'h603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4;
+
+ 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 = 128'hf3eed1bdb5d2a03c064b5a7e3db181f8;
+ nist_ecb_256_enc_expected1 = 128'h591ccb10d410ed26dc5ba74a31362870;
+ nist_ecb_256_enc_expected2 = 128'hb6ed21b99ca6f4f9f153e7b1beafed1d;
+ nist_ecb_256_enc_expected3 = 128'h23304b7a39f9f3ff067d8d8f9e24ecc7;
+
+
+ $display("ECB 128 bit key tests");
+ $display("---------------------");
+ ecb_mode_single_block_test(8'h01, AES_ENCIPHER, nist_aes128_key, AES_128_BIT_KEY,
+ nist_plaintext0, nist_ecb_128_enc_expected0);
+
+ ecb_mode_single_block_test(8'h02, AES_ENCIPHER, nist_aes128_key, AES_128_BIT_KEY,
+ nist_plaintext1, nist_ecb_128_enc_expected1);
+
+ ecb_mode_single_block_test(8'h03, AES_ENCIPHER, nist_aes128_key, AES_128_BIT_KEY,
+ nist_plaintext2, nist_ecb_128_enc_expected2);
+
+ ecb_mode_single_block_test(8'h04, AES_ENCIPHER, nist_aes128_key, AES_128_BIT_KEY,
+ nist_plaintext3, nist_ecb_128_enc_expected3);
+
+
+ ecb_mode_single_block_test(8'h05, AES_DECIPHER, nist_aes128_key, AES_128_BIT_KEY,
+ nist_ecb_128_enc_expected0, nist_plaintext0);
+
+ ecb_mode_single_block_test(8'h06, AES_DECIPHER, nist_aes128_key, AES_128_BIT_KEY,
+ nist_ecb_128_enc_expected1, nist_plaintext1);
+
+ ecb_mode_single_block_test(8'h07, AES_DECIPHER, nist_aes128_key, AES_128_BIT_KEY,
+ nist_ecb_128_enc_expected2, nist_plaintext2);
+
+ ecb_mode_single_block_test(8'h08, AES_DECIPHER, nist_aes128_key, AES_128_BIT_KEY,
+ nist_ecb_128_enc_expected3, nist_plaintext3);
+
+
+ $display("");
+ $display("ECB 256 bit key tests");
+ $display("---------------------");
+ ecb_mode_single_block_test(8'h10, AES_ENCIPHER, nist_aes256_key, AES_256_BIT_KEY,
+ nist_plaintext0, nist_ecb_256_enc_expected0);
+
+ ecb_mode_single_block_test(8'h11, AES_ENCIPHER, nist_aes256_key, AES_256_BIT_KEY,
+ nist_plaintext1, nist_ecb_256_enc_expected1);
+
+ ecb_mode_single_block_test(8'h12, AES_ENCIPHER, nist_aes256_key, AES_256_BIT_KEY,
+ nist_plaintext2, nist_ecb_256_enc_expected2);
+
+ ecb_mode_single_block_test(8'h13, AES_ENCIPHER, nist_aes256_key, AES_256_BIT_KEY,
+ nist_plaintext3, nist_ecb_256_enc_expected3);
+
+
+ ecb_mode_single_block_test(8'h14, AES_DECIPHER, nist_aes256_key, AES_256_BIT_KEY,
+ nist_ecb_256_enc_expected0, nist_plaintext0);
+
+ ecb_mode_single_block_test(8'h15, AES_DECIPHER, nist_aes256_key, AES_256_BIT_KEY,
+ nist_ecb_256_enc_expected1, nist_plaintext1);
+
+ ecb_mode_single_block_test(8'h16, AES_DECIPHER, nist_aes256_key, AES_256_BIT_KEY,
+ nist_ecb_256_enc_expected2, nist_plaintext2);
+
+ ecb_mode_single_block_test(8'h17, AES_DECIPHER, nist_aes256_key, AES_256_BIT_KEY,
+ nist_ecb_256_enc_expected3, nist_plaintext3);
+ end
+ endtask // aes_test
+
+
+ //----------------------------------------------------------------
+ // main
+ //
+ // The main test functionality.
+ //----------------------------------------------------------------
+ initial
+ begin : main
+
+ $display(" -= Testbench for AES started =-");
+ $display(" ==============================");
+ $display("");
+
+ init_sim();
+ dump_dut_state();
+ reset_dut();
+ dump_dut_state();
+
+ aes_test();
+
+ display_test_results();
+
+ $display("");
+ $display("*** AES simulation done. ***");
+ $finish;
+ end // main
+endmodule // tb_aes
+
+//======================================================================
+// EOF tb_aes.v
+//======================================================================
diff --git a/src/tb/tb_aes_core.v b/src/tb/tb_aes_core.v
new file mode 100644
index 0000000..426e817
--- /dev/null
+++ b/src/tb/tb_aes_core.v
@@ -0,0 +1,469 @@
+//======================================================================
+//
+// tb_aes_core.v
+// -------------
+// Testbench for the AES block cipher core.
+//
+//
+// 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_core();
+
+ //----------------------------------------------------------------
+ // Internal constant and parameter definitions.
+ //----------------------------------------------------------------
+ parameter DEBUG = 0;
+ 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_encdec;
+ reg tb_init;
+ reg tb_next;
+ wire tb_ready;
+ reg [255 : 0] tb_key;
+ reg tb_keylen;
+ reg [127 : 0] tb_block;
+ wire [127 : 0] tb_result;
+ wire tb_result_valid;
+
+
+ //----------------------------------------------------------------
+ // Device Under Test.
+ //----------------------------------------------------------------
+ aes_core dut(
+ .clk(tb_clk),
+ .reset_n(tb_reset_n),
+
+ .encdec(tb_encdec),
+ .init(tb_init),
+ .next(tb_next),
+ .ready(tb_ready),
+
+ .key(tb_key),
+ .keylen(tb_keylen),
+
+ .block(tb_block),
+ .result(tb_result)
+ );
+
+
+ //----------------------------------------------------------------
+ // 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("Inputs and outputs:");
+ $display("encdec = 0x%01x, init = 0x%01x, next = 0x%01x",
+ dut.encdec, dut.init, dut.next);
+ $display("keylen = 0x%01x, key = 0x%032x ", dut.keylen, dut.key);
+ $display("block = 0x%032x", dut.block);
+ $display("");
+ $display("ready = 0x%01x", dut.ready);
+ $display("result_valid = 0x%01x, result = 0x%032x",
+ dut.result_valid, dut.result);
+ $display("");
+ $display("Encipher state::");
+ $display("enc_ctrl = 0x%01x, round_ctr = 0x%01x",
+ dut.enc_block.enc_ctrl_reg, dut.enc_block.round_ctr_reg);
+ $display("");
+ end
+ endtask // dump_dut_state
+
+
+ //----------------------------------------------------------------
+ // dump_keys()
+ //
+ // Dump the keys in the key memory of the dut.
+ //----------------------------------------------------------------
+ task dump_keys();
+ begin
+ $display("State of key memory in DUT:");
+ $display("key[00] = 0x%016x", dut.keymem.key_mem[00]);
+ $display("key[01] = 0x%016x", dut.keymem.key_mem[01]);
+ $display("key[02] = 0x%016x", dut.keymem.key_mem[02]);
+ $display("key[03] = 0x%016x", dut.keymem.key_mem[03]);
+ $display("key[04] = 0x%016x", dut.keymem.key_mem[04]);
+ $display("key[05] = 0x%016x", dut.keymem.key_mem[05]);
+ $display("key[06] = 0x%016x", dut.keymem.key_mem[06]);
+ $display("key[07] = 0x%016x", dut.keymem.key_mem[07]);
+ $display("key[08] = 0x%016x", dut.keymem.key_mem[08]);
+ $display("key[09] = 0x%016x", dut.keymem.key_mem[09]);
+ $display("key[10] = 0x%016x", dut.keymem.key_mem[10]);
+ $display("key[11] = 0x%016x", dut.keymem.key_mem[11]);
+ $display("key[12] = 0x%016x", dut.keymem.key_mem[12]);
+ $display("key[13] = 0x%016x", dut.keymem.key_mem[13]);
+ $display("key[14] = 0x%016x", dut.keymem.key_mem[14]);
+ $display("");
+ end
+ endtask // dump_keys
+
+
+ //----------------------------------------------------------------
+ // 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_encdec = 0;
+ tb_init = 0;
+ tb_next = 0;
+ tb_key = {8{32'h00000000}};
+ 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
+
+
+ //----------------------------------------------------------------
+ // wait_valid()
+ //
+ // Wait for the result_valid flag in the dut to be set.
+ //
+ // Note: It is the callers responsibility to call the function
+ // when the dut is actively processing a block and will in fact
+ // at some point set the flag.
+ //----------------------------------------------------------------
+ task wait_valid();
+ begin
+ while (!tb_result_valid)
+ begin
+ #(CLK_PERIOD);
+ end
+ end
+ endtask // wait_valid
+
+
+ //----------------------------------------------------------------
+ // ecb_mode_single_block_test()
+ //
+ // Perform ECB mode encryption or decryption single block test.
+ //----------------------------------------------------------------
+ task ecb_mode_single_block_test(input [7 : 0] tc_number,
+ input encdec,
+ input [255 : 0] key,
+ input key_length,
+ input [127 : 0] block,
+ input [127 : 0] expected);
+ begin
+ $display("*** TC %0d ECB mode test started.", tc_number);
+ tc_ctr = tc_ctr + 1;
+
+ // Init the cipher with the given key and length.
+ tb_key = key;
+ tb_keylen = key_length;
+ tb_init = 1;
+ #(2 * CLK_PERIOD);
+ tb_init = 0;
+ wait_ready();
+
+ $display("Key expansion done");
+ $display("");
+
+ dump_keys();
+
+
+ // Perform encipher och decipher operation on the block.
+ tb_encdec = encdec;
+ tb_block = block;
+ tb_next = 1;
+ #(2 * CLK_PERIOD);
+ tb_next = 0;
+ wait_ready();
+
+ if (tb_result == expected)
+ begin
+ $display("*** TC %0d successful.", tc_number);
+ $display("");
+ end
+ else
+ begin
+ $display("*** ERROR: TC %0d NOT successful.", tc_number);
+ $display("Expected: 0x%032x", expected);
+ $display("Got: 0x%032x", tb_result);
+ $display("");
+
+ error_ctr = error_ctr + 1;
+ end
+ end
+ endtask // ecb_mode_single_block_test
+
+
+ //----------------------------------------------------------------
+ // aes_core_test
+ // 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 : aes_core_test
+ reg [255 : 0] nist_aes128_key;
+ reg [255 : 0] nist_aes256_key;
+
+ 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_aes128_key = 256'h2b7e151628aed2a6abf7158809cf4f3c00000000000000000000000000000000;
+ nist_aes256_key = 256'h603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4;
+
+ 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 = 128'hf3eed1bdb5d2a03c064b5a7e3db181f8;
+ nist_ecb_256_enc_expected1 = 128'h591ccb10d410ed26dc5ba74a31362870;
+ nist_ecb_256_enc_expected2 = 128'hb6ed21b99ca6f4f9f153e7b1beafed1d;
+ nist_ecb_256_enc_expected3 = 128'h23304b7a39f9f3ff067d8d8f9e24ecc7;
+
+
+ $display(" -= Testbench for aes core started =-");
+ $display(" ================================");
+ $display("");
+
+ init_sim();
+ dump_dut_state();
+ reset_dut();
+ dump_dut_state();
+
+
+ $display("ECB 128 bit key tests");
+ $display("---------------------");
+ ecb_mode_single_block_test(8'h01, AES_ENCIPHER, nist_aes128_key, AES_128_BIT_KEY,
+ nist_plaintext0, nist_ecb_128_enc_expected0);
+
+ ecb_mode_single_block_test(8'h02, AES_ENCIPHER, nist_aes128_key, AES_128_BIT_KEY,
+ nist_plaintext1, nist_ecb_128_enc_expected1);
+
+ ecb_mode_single_block_test(8'h03, AES_ENCIPHER, nist_aes128_key, AES_128_BIT_KEY,
+ nist_plaintext2, nist_ecb_128_enc_expected2);
+
+ ecb_mode_single_block_test(8'h04, AES_ENCIPHER, nist_aes128_key, AES_128_BIT_KEY,
+ nist_plaintext3, nist_ecb_128_enc_expected3);
+
+
+ ecb_mode_single_block_test(8'h05, AES_DECIPHER, nist_aes128_key, AES_128_BIT_KEY,
+ nist_ecb_128_enc_expected0, nist_plaintext0);
+
+ ecb_mode_single_block_test(8'h06, AES_DECIPHER, nist_aes128_key, AES_128_BIT_KEY,
+ nist_ecb_128_enc_expected1, nist_plaintext1);
+
+ ecb_mode_single_block_test(8'h07, AES_DECIPHER, nist_aes128_key, AES_128_BIT_KEY,
+ nist_ecb_128_enc_expected2, nist_plaintext2);
+
+ ecb_mode_single_block_test(8'h08, AES_DECIPHER, nist_aes128_key, AES_128_BIT_KEY,
+ nist_ecb_128_enc_expected3, nist_plaintext3);
+
+
+ $display("");
+ $display("ECB 256 bit key tests");
+ $display("---------------------");
+ ecb_mode_single_block_test(8'h10, AES_ENCIPHER, nist_aes256_key, AES_256_BIT_KEY,
+ nist_plaintext0, nist_ecb_256_enc_expected0);
+
+ ecb_mode_single_block_test(8'h11, AES_ENCIPHER, nist_aes256_key, AES_256_BIT_KEY,
+ nist_plaintext1, nist_ecb_256_enc_expected1);
+
+ ecb_mode_single_block_test(8'h12, AES_ENCIPHER, nist_aes256_key, AES_256_BIT_KEY,
+ nist_plaintext2, nist_ecb_256_enc_expected2);
+
+ ecb_mode_single_block_test(8'h13, AES_ENCIPHER, nist_aes256_key, AES_256_BIT_KEY,
+ nist_plaintext3, nist_ecb_256_enc_expected3);
+
+
+ ecb_mode_single_block_test(8'h14, AES_DECIPHER, nist_aes256_key, AES_256_BIT_KEY,
+ nist_ecb_256_enc_expected0, nist_plaintext0);
+
+ ecb_mode_single_block_test(8'h15, AES_DECIPHER, nist_aes256_key, AES_256_BIT_KEY,
+ nist_ecb_256_enc_expected1, nist_plaintext1);
+
+ ecb_mode_single_block_test(8'h16, AES_DECIPHER, nist_aes256_key, AES_256_BIT_KEY,
+ nist_ecb_256_enc_expected2, nist_plaintext2);
+
+ ecb_mode_single_block_test(8'h17, AES_DECIPHER, nist_aes256_key, AES_256_BIT_KEY,
+ nist_ecb_256_enc_expected3, nist_plaintext3);
+
+
+ display_test_result();
+ $display("");
+ $display("*** AES core simulation done. ***");
+ $finish;
+ end // aes_core_test
+endmodule // tb_aes_core
+
+//======================================================================
+// EOF tb_aes_core.v
+//======================================================================
diff --git a/src/tb/tb_aes_decipher_block.v b/src/tb/tb_aes_decipher_block.v
new file mode 100644
index 0000000..5a89102
--- /dev/null
+++ b/src/tb/tb_aes_decipher_block.v
@@ -0,0 +1,411 @@
+//======================================================================
+//
+// tb_aes_decipher_block.v
+// -----------------------
+// Testbench for the AES decipher 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_decipher_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;
+
+ 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.
+ //----------------------------------------------------------------
+ aes_decipher_block dut(
+ .clk(tb_clk),
+ .reset_n(tb_reset_n),
+
+ .next(tb_next),
+
+ .keylen(tb_keylen),
+ .round(tb_round),
+ .round_key(tb_round_key),
+
+ .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("dec_ctrl = 0x%01x, update_type = 0x%01x, sword_ctr = 0x%01x, round_ctr = 0x%01x",
+ dut.dec_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.tmp_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("inv_shiftrows_block = 0x%08x", dut.round_logic.inv_shiftrows_block);
+ $display("inv_mixcolumns_block = 0x%08x", dut.round_logic.inv_mixcolumns_block);
+ $display("addkey_block = 0x%08x", dut.round_logic.addkey_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_de()
+ //
+ // Perform ECB mode encryption test.
+ //----------------------------------------------------------------
+ task test_ecb_dec(
+ 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 decipher 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_decipher_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_decipher_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_dec_ciphertext0;
+ reg [127 : 0] nist_ecb_128_dec_ciphertext1;
+ reg [127 : 0] nist_ecb_128_dec_ciphertext2;
+ reg [127 : 0] nist_ecb_128_dec_ciphertext3;
+
+ reg [127 : 0] nist_ecb_256_dec_ciphertext0;
+ reg [127 : 0] nist_ecb_256_dec_ciphertext1;
+ reg [127 : 0] nist_ecb_256_dec_ciphertext2;
+ reg [127 : 0] nist_ecb_256_dec_ciphertext3;
+
+ nist_plaintext0 = 128'h6bc1bee22e409f96e93d7e117393172a;
+ nist_plaintext1 = 128'hae2d8a571e03ac9c9eb76fac45af8e51;
+ nist_plaintext2 = 128'h30c81c46a35ce411e5fbc1191a0a52ef;
+ nist_plaintext3 = 128'hf69f2445df4f9b17ad2b417be66c3710;
+
+ nist_ecb_128_dec_ciphertext0 = 128'h3ad77bb40d7a3660a89ecaf32466ef97;
+ nist_ecb_128_dec_ciphertext1 = 128'hf5d3d58503b9699de785895a96fdbaaf;
+ nist_ecb_128_dec_ciphertext2 = 128'h43b1cd7f598ece23881b00e3ed030688;
+ nist_ecb_128_dec_ciphertext3 = 128'h7b0c785e27e8ad3f8223207104725dd4;
+
+ nist_ecb_256_dec_ciphertext0 = 255'hf3eed1bdb5d2a03c064b5a7e3db181f8;
+ nist_ecb_256_dec_ciphertext1 = 255'h591ccb10d410ed26dc5ba74a31362870;
+ nist_ecb_256_dec_ciphertext2 = 255'hb6ed21b99ca6f4f9f153e7b1beafed1d;
+ nist_ecb_256_dec_ciphertext3 = 255'h23304b7a39f9f3ff067d8d8f9e24ecc7;
+
+
+ $display(" -= Testbench for aes decipher 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_dec(AES_128_BIT_KEY, nist_ecb_128_dec_ciphertext0, nist_plaintext0);
+ test_ecb_dec(AES_128_BIT_KEY, nist_ecb_128_dec_ciphertext1, nist_plaintext1);
+ test_ecb_dec(AES_128_BIT_KEY, nist_ecb_128_dec_ciphertext2, nist_plaintext2);
+ test_ecb_dec(AES_128_BIT_KEY, nist_ecb_128_dec_ciphertext3, nist_plaintext3);
+
+
+ // 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_dec(AES_256_BIT_KEY, nist_ecb_256_dec_ciphertext0, nist_plaintext0);
+ test_ecb_dec(AES_256_BIT_KEY, nist_ecb_256_dec_ciphertext1, nist_plaintext1);
+ test_ecb_dec(AES_256_BIT_KEY, nist_ecb_256_dec_ciphertext2, nist_plaintext2);
+ test_ecb_dec(AES_256_BIT_KEY, nist_ecb_256_dec_ciphertext3, nist_plaintext3);
+
+
+ display_test_result();
+ $display("");
+ $display("*** AES decipher block module simulation done. ***");
+ $finish;
+ end // aes_core_test
+endmodule // tb_aes_decipher_block
+
+//======================================================================
+// EOF tb_aes_decipher_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
+//======================================================================
diff --git a/src/tb/tb_aes_key_mem.v b/src/tb/tb_aes_key_mem.v
new file mode 100644
index 0000000..748ae3f
--- /dev/null
+++ b/src/tb/tb_aes_key_mem.v
@@ -0,0 +1,655 @@
+//======================================================================
+//
+// tb_aes_key_mem.v
+// ----------------
+// Testbench for the AES key memory 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_key_mem();
+
+ //----------------------------------------------------------------
+ // Internal constant and parameter definitions.
+ //----------------------------------------------------------------
+ parameter DEBUG = 1;
+ parameter SHOW_SBOX = 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_128_NUM_ROUNDS = 10;
+ parameter AES_192_NUM_ROUNDS = 12;
+ parameter AES_256_NUM_ROUNDS = 14;
+
+ 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 [255 : 0] tb_key;
+ reg tb_keylen;
+ reg tb_init;
+ reg [3 : 0] tb_round;
+ wire [127 : 0] tb_round_key;
+ wire tb_ready;
+
+ wire [31 : 0] tb_sboxw;
+ wire [31 : 0] tb_new_sboxw;
+
+
+ //----------------------------------------------------------------
+ // Device Under Test.
+ //----------------------------------------------------------------
+ aes_key_mem dut(
+ .clk(tb_clk),
+ .reset_n(tb_reset_n),
+
+ .key(tb_key),
+ .keylen(tb_keylen),
+ .init(tb_init),
+
+ .round(tb_round),
+ .round_key(tb_round_key),
+ .ready(tb_ready),
+
+ .sboxw(tb_sboxw),
+ .new_sboxw(tb_new_sboxw)
+ );
+
+ // The DUT requirees Sboxes.
+ aes_sbox sbox(.sboxw(tb_sboxw), .new_sboxw(tb_new_sboxw));
+
+
+ //----------------------------------------------------------------
+ // 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("Inputs and outputs:");
+ $display("key = 0x%032x", dut.key);
+ $display("keylen = 0x%01x, init = 0x%01x, ready = 0x%01x",
+ dut.keylen, dut.init, dut.ready);
+ $display("round = 0x%02x", dut.round);
+ $display("round_key = 0x%016x", dut.round_key);
+ $display("");
+
+ $display("Internal states:");
+ $display("key_mem_ctrl = 0x%01x, round_key_update = 0x%01x, round_ctr_reg = 0x%01x, rcon_reg = 0x%01x",
+ dut.key_mem_ctrl_reg, dut.round_key_update, dut.round_ctr_reg, dut.rcon_reg);
+
+ $display("prev_key0_reg = 0x%016x, prev_key0_new = 0x%016x, prev_key0_we = 0x%01x",
+ dut.prev_key0_reg, dut.prev_key0_new, dut.prev_key0_we);
+ $display("prev_key1_reg = 0x%016x, prev_key1_new = 0x%016x, prev_key1_we = 0x%01x",
+ dut.prev_key1_reg, dut.prev_key1_new, dut.prev_key1_we);
+
+ $display("w0 = 0x%04x, w1 = 0x%04x, w2 = 0x%04x, w3 = 0x%04x",
+ dut.round_key_gen.w0, dut.round_key_gen.w1,
+ dut.round_key_gen.w2, dut.round_key_gen.w3);
+ $display("w4 = 0x%04x, w5 = 0x%04x, w6 = 0x%04x, w7 = 0x%04x",
+ dut.round_key_gen.w4, dut.round_key_gen.w5,
+ dut.round_key_gen.w6, dut.round_key_gen.w7);
+ $display("sboxw = 0x%04x, new_sboxw = 0x%04x, rconw = 0x%04x",
+ dut.sboxw, dut.new_sboxw, dut.round_key_gen.rconw);
+ $display("tw = 0x%04x, trw = 0x%04x", dut.round_key_gen.tw, dut.round_key_gen.trw);
+ $display("key_mem_new = 0x%016x, key_mem_we = 0x%01x",
+ dut.key_mem_new, dut.key_mem_we);
+ $display("");
+
+ if (SHOW_SBOX)
+ begin
+ $display("Sbox functionality:");
+ $display("sboxw = 0x%08x", sbox.sboxw);
+ $display("tmp_new_sbox0 = 0x%02x, tmp_new_sbox1 = 0x%02x, tmp_new_sbox2 = 0x%02x, tmp_new_sbox3",
+ sbox.tmp_new_sbox0, sbox.tmp_new_sbox1, sbox.tmp_new_sbox2, sbox.tmp_new_sbox3);
+ $display("new_sboxw = 0x%08x", sbox.new_sboxw);
+ $display("");
+ end
+ 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_key = {8{32'h00000000}};
+ tb_keylen = 0;
+ tb_init = 0;
+ tb_round = 4'h0;
+ end
+ endtask // init_sim
+
+
+ //----------------------------------------------------------------
+ // 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);
+ end
+ end
+ endtask // wait_ready
+
+
+ //----------------------------------------------------------------
+ // check_key()
+ //
+ // Check a given key in the dut key memory against a given
+ // expected key.
+ //----------------------------------------------------------------
+ task check_key(input [3 : 0] key_nr, input [127 : 0] expected);
+ begin
+ tb_round = key_nr;
+ #(CLK_PERIOD);
+ if (tb_round_key == expected)
+ begin
+ $display("** key 0x%01x matched expected round key.", key_nr);
+ $display("** Got: 0x%016x **", tb_round_key);
+ end
+ else
+ begin
+ $display("** Error: key 0x%01x did not match expected round key. **", key_nr);
+ $display("** Expected: 0x%016x **", expected);
+ $display("** Got: 0x%016x **", tb_round_key);
+ error_ctr = error_ctr + 1;
+ end
+ $display("");
+ end
+ endtask // check_key
+
+
+ //----------------------------------------------------------------
+ // test_key_128()
+ //
+ // Test 128 bit keys. Due to array problems, the result check
+ // is fairly ugly.
+ //----------------------------------------------------------------
+ task test_key_128(input [255 : 0] key,
+ input [127 : 0] expected00,
+ input [127 : 0] expected01,
+ input [127 : 0] expected02,
+ input [127 : 0] expected03,
+ input [127 : 0] expected04,
+ input [127 : 0] expected05,
+ input [127 : 0] expected06,
+ input [127 : 0] expected07,
+ input [127 : 0] expected08,
+ input [127 : 0] expected09,
+ input [127 : 0] expected10
+ );
+ begin
+ $display("** Testing with 128-bit key 0x%16x", key[255 : 128]);
+ $display("");
+
+ tb_key = key;
+ tb_keylen = AES_128_BIT_KEY;
+ tb_init = 1;
+ #(2 * CLK_PERIOD);
+ tb_init = 0;
+ wait_ready();
+
+ check_key(4'h0, expected00);
+ check_key(4'h1, expected01);
+ check_key(4'h2, expected02);
+ check_key(4'h3, expected03);
+ check_key(4'h4, expected04);
+ check_key(4'h5, expected05);
+ check_key(4'h6, expected06);
+ check_key(4'h7, expected07);
+ check_key(4'h8, expected08);
+ check_key(4'h9, expected09);
+ check_key(4'ha, expected10);
+
+ tc_ctr = tc_ctr + 1;
+ end
+ endtask // test_key_128
+
+
+ //----------------------------------------------------------------
+ // test_key_256()
+ //
+ // Test 256 bit keys. Due to array problems, the result check
+ // is fairly ugly.
+ //----------------------------------------------------------------
+ task test_key_256(input [255 : 0] key,
+ input [127 : 0] expected00,
+ input [127 : 0] expected01,
+ input [127 : 0] expected02,
+ input [127 : 0] expected03,
+ input [127 : 0] expected04,
+ input [127 : 0] expected05,
+ input [127 : 0] expected06,
+ input [127 : 0] expected07,
+ input [127 : 0] expected08,
+ input [127 : 0] expected09,
+ input [127 : 0] expected10,
+ input [127 : 0] expected11,
+ input [127 : 0] expected12,
+ input [127 : 0] expected13,
+ input [127 : 0] expected14
+ );
+ begin
+ $display("** Testing with 256-bit key 0x%32x", key[255 : 000]);
+ $display("");
+
+ tb_key = key;
+ tb_keylen = AES_256_BIT_KEY;
+ tb_init = 1;
+ #(2 * CLK_PERIOD);
+ tb_init = 0;
+
+ wait_ready();
+
+ check_key(4'h0, expected00);
+ check_key(4'h1, expected01);
+ check_key(4'h2, expected02);
+ check_key(4'h3, expected03);
+ check_key(4'h4, expected04);
+ check_key(4'h5, expected05);
+ check_key(4'h6, expected06);
+ check_key(4'h7, expected07);
+ check_key(4'h8, expected08);
+ check_key(4'h9, expected09);
+ check_key(4'ha, expected10);
+ check_key(4'hb, expected11);
+ check_key(4'hc, expected12);
+ check_key(4'hd, expected13);
+ check_key(4'he, expected14);
+
+ tc_ctr = tc_ctr + 1;
+ end
+ endtask // test_key_256
+
+
+ //----------------------------------------------------------------
+ // 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
+
+
+ //----------------------------------------------------------------
+ // aes_key_mem_test
+ // The main test functionality.
+ //----------------------------------------------------------------
+ initial
+ begin : aes_key_mem_test
+ reg [255 : 0] key128_0;
+ reg [255 : 0] key128_1;
+ reg [255 : 0] key128_2;
+ reg [255 : 0] key128_3;
+ reg [255 : 0] nist_key128;
+ reg [255 : 0] key256_0;
+ reg [255 : 0] key256_1;
+ reg [255 : 0] key256_2;
+ reg [255 : 0] nist_key256;
+
+ reg [127 : 0] expected_00;
+ reg [127 : 0] expected_01;
+ reg [127 : 0] expected_02;
+ reg [127 : 0] expected_03;
+ reg [127 : 0] expected_04;
+ reg [127 : 0] expected_05;
+ reg [127 : 0] expected_06;
+ reg [127 : 0] expected_07;
+ reg [127 : 0] expected_08;
+ reg [127 : 0] expected_09;
+ reg [127 : 0] expected_10;
+ reg [127 : 0] expected_11;
+ reg [127 : 0] expected_12;
+ reg [127 : 0] expected_13;
+ reg [127 : 0] expected_14;
+
+ $display(" -= Testbench for aes key mem started =-");
+ $display(" =====================================");
+ $display("");
+
+ init_sim();
+ dump_dut_state();
+ reset_dut();
+
+ $display("State after reset:");
+ dump_dut_state();
+ $display("");
+
+ #(100 *CLK_PERIOD);
+
+ // AES-128 test case 1 key and expected values.
+ key128_0 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ expected_00 = 128'h00000000000000000000000000000000;
+ expected_01 = 128'h62636363626363636263636362636363;
+ expected_02 = 128'h9b9898c9f9fbfbaa9b9898c9f9fbfbaa;
+ expected_03 = 128'h90973450696ccffaf2f457330b0fac99;
+ expected_04 = 128'hee06da7b876a1581759e42b27e91ee2b;
+ expected_05 = 128'h7f2e2b88f8443e098dda7cbbf34b9290;
+ expected_06 = 128'hec614b851425758c99ff09376ab49ba7;
+ expected_07 = 128'h217517873550620bacaf6b3cc61bf09b;
+ expected_08 = 128'h0ef903333ba9613897060a04511dfa9f;
+ expected_09 = 128'hb1d4d8e28a7db9da1d7bb3de4c664941;
+ expected_10 = 128'hb4ef5bcb3e92e21123e951cf6f8f188e;
+
+ test_key_128(key128_0,
+ expected_00, expected_01, expected_02, expected_03,
+ expected_04, expected_05, expected_06, expected_07,
+ expected_08, expected_09, expected_10);
+
+
+ // AES-128 test case 2 key and expected values.
+ key128_1 = 256'hffffffffffffffffffffffffffffffff00000000000000000000000000000000;
+ expected_00 = 128'hffffffffffffffffffffffffffffffff;
+ expected_01 = 128'he8e9e9e917161616e8e9e9e917161616;
+ expected_02 = 128'hadaeae19bab8b80f525151e6454747f0;
+ expected_03 = 128'h090e2277b3b69a78e1e7cb9ea4a08c6e;
+ expected_04 = 128'he16abd3e52dc2746b33becd8179b60b6;
+ expected_05 = 128'he5baf3ceb766d488045d385013c658e6;
+ expected_06 = 128'h71d07db3c6b6a93bc2eb916bd12dc98d;
+ expected_07 = 128'he90d208d2fbb89b6ed5018dd3c7dd150;
+ expected_08 = 128'h96337366b988fad054d8e20d68a5335d;
+ expected_09 = 128'h8bf03f233278c5f366a027fe0e0514a3;
+ expected_10 = 128'hd60a3588e472f07b82d2d7858cd7c326;
+
+ test_key_128(key128_1,
+ expected_00, expected_01, expected_02, expected_03,
+ expected_04, expected_05, expected_06, expected_07,
+ expected_08, expected_09, expected_10);
+
+
+ // AES-128 test case 3 key and expected values.
+ key128_2 = 256'h000102030405060708090a0b0c0d0e0f00000000000000000000000000000000;
+ expected_00 = 128'h000102030405060708090a0b0c0d0e0f;
+ expected_01 = 128'hd6aa74fdd2af72fadaa678f1d6ab76fe;
+ expected_02 = 128'hb692cf0b643dbdf1be9bc5006830b3fe;
+ expected_03 = 128'hb6ff744ed2c2c9bf6c590cbf0469bf41;
+ expected_04 = 128'h47f7f7bc95353e03f96c32bcfd058dfd;
+ expected_05 = 128'h3caaa3e8a99f9deb50f3af57adf622aa;
+ expected_06 = 128'h5e390f7df7a69296a7553dc10aa31f6b;
+ expected_07 = 128'h14f9701ae35fe28c440adf4d4ea9c026;
+ expected_08 = 128'h47438735a41c65b9e016baf4aebf7ad2;
+ expected_09 = 128'h549932d1f08557681093ed9cbe2c974e;
+ expected_10 = 128'h13111d7fe3944a17f307a78b4d2b30c5;
+
+ test_key_128(key128_2,
+ expected_00, expected_01, expected_02, expected_03,
+ expected_04, expected_05, expected_06, expected_07,
+ expected_08, expected_09, expected_10);
+
+
+ // AES-128 test case 4 key and expected values.
+ key128_3 = 256'h6920e299a5202a6d656e636869746f2a00000000000000000000000000000000;
+ expected_00 = 128'h6920e299a5202a6d656e636869746f2a;
+ expected_01 = 128'hfa8807605fa82d0d3ac64e6553b2214f;
+ expected_02 = 128'hcf75838d90ddae80aa1be0e5f9a9c1aa;
+ expected_03 = 128'h180d2f1488d0819422cb6171db62a0db;
+ expected_04 = 128'hbaed96ad323d173910f67648cb94d693;
+ expected_05 = 128'h881b4ab2ba265d8baad02bc36144fd50;
+ expected_06 = 128'hb34f195d096944d6a3b96f15c2fd9245;
+ expected_07 = 128'ha7007778ae6933ae0dd05cbbcf2dcefe;
+ expected_08 = 128'hff8bccf251e2ff5c5c32a3e7931f6d19;
+ expected_09 = 128'h24b7182e7555e77229674495ba78298c;
+ expected_10 = 128'hae127cdadb479ba8f220df3d4858f6b1;
+
+ test_key_128(key128_3,
+ expected_00, expected_01, expected_02, expected_03,
+ expected_04, expected_05, expected_06, expected_07,
+ expected_08, expected_09, expected_10);
+
+
+ // NIST AES-128 test case.
+ nist_key128 = 256'h2b7e151628aed2a6abf7158809cf4f3c00000000000000000000000000000000;
+ expected_00 = 128'h2b7e151628aed2a6abf7158809cf4f3c;
+ expected_01 = 128'ha0fafe1788542cb123a339392a6c7605;
+ expected_02 = 128'hf2c295f27a96b9435935807a7359f67f;
+ expected_03 = 128'h3d80477d4716fe3e1e237e446d7a883b;
+ expected_04 = 128'hef44a541a8525b7fb671253bdb0bad00;
+ expected_05 = 128'hd4d1c6f87c839d87caf2b8bc11f915bc;
+ expected_06 = 128'h6d88a37a110b3efddbf98641ca0093fd;
+ expected_07 = 128'h4e54f70e5f5fc9f384a64fb24ea6dc4f;
+ expected_08 = 128'head27321b58dbad2312bf5607f8d292f;
+ expected_09 = 128'hac7766f319fadc2128d12941575c006e;
+ expected_10 = 128'hd014f9a8c9ee2589e13f0cc8b6630ca6;
+
+ $display("Testing the NIST AES-128 key.");
+ test_key_128(nist_key128,
+ expected_00, expected_01, expected_02, expected_03,
+ expected_04, expected_05, expected_06, expected_07,
+ expected_08, expected_09, expected_10);
+
+
+ // AES-256 test case 1 key and expected values.
+ key256_0 = 256'h000000000000000000000000000000000000000000000000000000000000000;
+ expected_00 = 128'h00000000000000000000000000000000;
+ expected_01 = 128'h00000000000000000000000000000000;
+ expected_02 = 128'h62636363626363636263636362636363;
+ expected_03 = 128'haafbfbfbaafbfbfbaafbfbfbaafbfbfb;
+ expected_04 = 128'h6f6c6ccf0d0f0fac6f6c6ccf0d0f0fac;
+ expected_05 = 128'h7d8d8d6ad77676917d8d8d6ad7767691;
+ expected_06 = 128'h5354edc15e5be26d31378ea23c38810e;
+ expected_07 = 128'h968a81c141fcf7503c717a3aeb070cab;
+ expected_08 = 128'h9eaa8f28c0f16d45f1c6e3e7cdfe62e9;
+ expected_09 = 128'h2b312bdf6acddc8f56bca6b5bdbbaa1e;
+ expected_10 = 128'h6406fd52a4f79017553173f098cf1119;
+ expected_11 = 128'h6dbba90b0776758451cad331ec71792f;
+ expected_12 = 128'he7b0e89c4347788b16760b7b8eb91a62;
+ expected_13 = 128'h74ed0ba1739b7e252251ad14ce20d43b;
+ expected_14 = 128'h10f80a1753bf729c45c979e7cb706385;
+
+ test_key_256(key256_0,
+ expected_00, expected_01, expected_02, expected_03,
+ expected_04, expected_05, expected_06, expected_07,
+ expected_08, expected_09, expected_10, expected_11,
+ expected_12, expected_13, expected_14);
+
+
+ // AES-256 test case 2 key and expected values.
+ key256_1 = 256'hffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff;
+ expected_00 = 128'hffffffffffffffffffffffffffffffff;
+ expected_01 = 128'hffffffffffffffffffffffffffffffff;
+ expected_02 = 128'he8e9e9e917161616e8e9e9e917161616;
+ expected_03 = 128'h0fb8b8b8f04747470fb8b8b8f0474747;
+ expected_04 = 128'h4a4949655d5f5f73b5b6b69aa2a0a08c;
+ expected_05 = 128'h355858dcc51f1f9bcaa7a7233ae0e064;
+ expected_06 = 128'hafa80ae5f2f755964741e30ce5e14380;
+ expected_07 = 128'heca0421129bf5d8ae318faa9d9f81acd;
+ expected_08 = 128'he60ab7d014fde24653bc014ab65d42ca;
+ expected_09 = 128'ha2ec6e658b5333ef684bc946b1b3d38b;
+ expected_10 = 128'h9b6c8a188f91685edc2d69146a702bde;
+ expected_11 = 128'ha0bd9f782beeac9743a565d1f216b65a;
+ expected_12 = 128'hfc22349173b35ccfaf9e35dbc5ee1e05;
+ expected_13 = 128'h0695ed132d7b41846ede24559cc8920f;
+ expected_14 = 128'h546d424f27de1e8088402b5b4dae355e;
+
+ test_key_256(key256_1,
+ expected_00, expected_01, expected_02, expected_03,
+ expected_04, expected_05, expected_06, expected_07,
+ expected_08, expected_09, expected_10, expected_11,
+ expected_12, expected_13, expected_14);
+
+
+ // AES-256 test case 3 key and expected values.
+ key256_2 = 256'h000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f;
+ expected_00 = 128'h000102030405060708090a0b0c0d0e0f;
+ expected_01 = 128'h101112131415161718191a1b1c1d1e1f;
+ expected_02 = 128'ha573c29fa176c498a97fce93a572c09c;
+ expected_03 = 128'h1651a8cd0244beda1a5da4c10640bade;
+ expected_04 = 128'hae87dff00ff11b68a68ed5fb03fc1567;
+ expected_05 = 128'h6de1f1486fa54f9275f8eb5373b8518d;
+ expected_06 = 128'hc656827fc9a799176f294cec6cd5598b;
+ expected_07 = 128'h3de23a75524775e727bf9eb45407cf39;
+ expected_08 = 128'h0bdc905fc27b0948ad5245a4c1871c2f;
+ expected_09 = 128'h45f5a66017b2d387300d4d33640a820a;
+ expected_10 = 128'h7ccff71cbeb4fe5413e6bbf0d261a7df;
+ expected_11 = 128'hf01afafee7a82979d7a5644ab3afe640;
+ expected_12 = 128'h2541fe719bf500258813bbd55a721c0a;
+ expected_13 = 128'h4e5a6699a9f24fe07e572baacdf8cdea;
+ expected_14 = 128'h24fc79ccbf0979e9371ac23c6d68de36;
+
+ test_key_256(key256_2,
+ expected_00, expected_01, expected_02, expected_03,
+ expected_04, expected_05, expected_06, expected_07,
+ expected_08, expected_09, expected_10, expected_11,
+ expected_12, expected_13, expected_14);
+
+
+ nist_key256 = 256'h603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4;
+ expected_00 = 128'h603deb1015ca71be2b73aef0857d7781;
+ expected_01 = 128'h1f352c073b6108d72d9810a30914dff4;
+ expected_02 = 128'h9ba354118e6925afa51a8b5f2067fcde;
+ expected_03 = 128'ha8b09c1a93d194cdbe49846eb75d5b9a;
+ expected_04 = 128'hd59aecb85bf3c917fee94248de8ebe96;
+ expected_05 = 128'hb5a9328a2678a647983122292f6c79b3;
+ expected_06 = 128'h812c81addadf48ba24360af2fab8b464;
+ expected_07 = 128'h98c5bfc9bebd198e268c3ba709e04214;
+ expected_08 = 128'h68007bacb2df331696e939e46c518d80;
+ expected_09 = 128'hc814e20476a9fb8a5025c02d59c58239;
+ expected_10 = 128'hde1369676ccc5a71fa2563959674ee15;
+ expected_11 = 128'h5886ca5d2e2f31d77e0af1fa27cf73c3;
+ expected_12 = 128'h749c47ab18501ddae2757e4f7401905a;
+ expected_13 = 128'hcafaaae3e4d59b349adf6acebd10190d;
+ expected_14 = 128'hfe4890d1e6188d0b046df344706c631e;
+
+ test_key_256(nist_key256,
+ expected_00, expected_01, expected_02, expected_03,
+ expected_04, expected_05, expected_06, expected_07,
+ expected_08, expected_09, expected_10, expected_11,
+ expected_12, expected_13, expected_14);
+
+
+ display_test_result();
+ $display("");
+ $display("*** AES core simulation done. ***");
+ $finish;
+ end // aes_key_mem_test
+endmodule // tb_aes_key_mem
+
+//======================================================================
+// EOF tb_aes_key_mem.v
+//======================================================================