Skip to content

Test Bench Code for AES

You can find the original work here.
Only comments were added to the original codes to make them more readable.

 

Testbench for the AES top level wrapper.

// tb_aes.v
// --------
// Testbench for the aes top level wrapper.

// Author: Joachim Strombergson
// Copyright (c) 2014, Secworks Sweden AB
// All rights reserved.
`default_nettype none

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_STATUS      = 8'h09;
  parameter STATUS_READY_BIT = 0;
  parameter STATUS_VALID_BIT = 1;

  parameter ADDR_CONFIG      = 8'h0a;

  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;


  //----------------------------------------------------------------
  // 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)
          );


  //----------------------------------------------------------------
  // 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.block_reg[0], dut.block_reg[1], dut.block_reg[2], dut.block_reg[3]);
      $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'h0;
      tb_write_data = 32'h0;
    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.
  // Test vectors copied from the follwing NIST documents.
  //
  // NIST SP 800-38A:
  // http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
  //
  // NIST FIPS-197, Appendix C:
  // https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.197.pdf
  //----------------------------------------------------------------
  task aes_test;
    reg [255 : 0] nist_aes128_key1;
    reg [255 : 0] nist_aes128_key2;
    reg [255 : 0] nist_aes256_key1;
    reg [255 : 0] nist_aes256_key2;

    reg [127 : 0] nist_plaintext0;
    reg [127 : 0] nist_plaintext1;
    reg [127 : 0] nist_plaintext2;
    reg [127 : 0] nist_plaintext3;
    reg [127 : 0] nist_plaintext4;

    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_128_enc_expected4;

    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;
    reg [127 : 0] nist_ecb_256_enc_expected4;

    begin
      nist_aes128_key1 = 256'h2b7e151628aed2a6abf7158809cf4f3c00000000000000000000000000000000;
      nist_aes128_key2 = 256'h000102030405060708090a0b0c0d0e0f00000000000000000000000000000000;
      nist_aes256_key1 = 256'h603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4;
      nist_aes256_key2 = 256'h000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f;

      nist_plaintext0 = 128'h6bc1bee22e409f96e93d7e117393172a;
      nist_plaintext1 = 128'hae2d8a571e03ac9c9eb76fac45af8e51;
      nist_plaintext2 = 128'h30c81c46a35ce411e5fbc1191a0a52ef;
      nist_plaintext3 = 128'hf69f2445df4f9b17ad2b417be66c3710;
      nist_plaintext4 = 128'h00112233445566778899aabbccddeeff;

      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_128_enc_expected4 = 128'h69c4e0d86a7b0430d8cdb78070b4c55a;

      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;
      nist_ecb_256_enc_expected4 = 128'h8ea2b7ca516745bfeafc49904b496089;


      $display("ECB 128 bit key tests");
      $display("---------------------");
      ecb_mode_single_block_test(8'h01, AES_ENCIPHER, nist_aes128_key1, AES_128_BIT_KEY,
                                 nist_plaintext0, nist_ecb_128_enc_expected0);

      ecb_mode_single_block_test(8'h02, AES_ENCIPHER, nist_aes128_key1, AES_128_BIT_KEY,
                                nist_plaintext1, nist_ecb_128_enc_expected1);

      ecb_mode_single_block_test(8'h03, AES_ENCIPHER, nist_aes128_key1, AES_128_BIT_KEY,
                                 nist_plaintext2, nist_ecb_128_enc_expected2);

      ecb_mode_single_block_test(8'h04, AES_ENCIPHER, nist_aes128_key1, AES_128_BIT_KEY,
                                 nist_plaintext3, nist_ecb_128_enc_expected3);


      ecb_mode_single_block_test(8'h05, AES_DECIPHER, nist_aes128_key1, AES_128_BIT_KEY,
                                 nist_ecb_128_enc_expected0, nist_plaintext0);

      ecb_mode_single_block_test(8'h06, AES_DECIPHER, nist_aes128_key1, AES_128_BIT_KEY,
                                 nist_ecb_128_enc_expected1, nist_plaintext1);

      ecb_mode_single_block_test(8'h07, AES_DECIPHER, nist_aes128_key1, AES_128_BIT_KEY,
                                 nist_ecb_128_enc_expected2, nist_plaintext2);

      ecb_mode_single_block_test(8'h08, AES_DECIPHER, nist_aes128_key1, AES_128_BIT_KEY,
                                 nist_ecb_128_enc_expected3, nist_plaintext3);


      ecb_mode_single_block_test(8'h09, AES_ENCIPHER, nist_aes128_key2, AES_128_BIT_KEY,
                                 nist_plaintext4, nist_ecb_128_enc_expected4);

      ecb_mode_single_block_test(8'h0a, AES_DECIPHER, nist_aes128_key2, AES_128_BIT_KEY,
                                 nist_ecb_128_enc_expected4, nist_plaintext4);


      $display("");
      $display("ECB 256 bit key tests");
      $display("---------------------");
      ecb_mode_single_block_test(8'h10, AES_ENCIPHER, nist_aes256_key1, AES_256_BIT_KEY,
                                 nist_plaintext0, nist_ecb_256_enc_expected0);

      ecb_mode_single_block_test(8'h11, AES_ENCIPHER, nist_aes256_key1, AES_256_BIT_KEY,
                                 nist_plaintext1, nist_ecb_256_enc_expected1);

      ecb_mode_single_block_test(8'h12, AES_ENCIPHER, nist_aes256_key1, AES_256_BIT_KEY,
                                 nist_plaintext2, nist_ecb_256_enc_expected2);

      ecb_mode_single_block_test(8'h13, AES_ENCIPHER, nist_aes256_key1, AES_256_BIT_KEY,
                                 nist_plaintext3, nist_ecb_256_enc_expected3);


      ecb_mode_single_block_test(8'h14, AES_DECIPHER, nist_aes256_key1, AES_256_BIT_KEY,
                                 nist_ecb_256_enc_expected0, nist_plaintext0);

      ecb_mode_single_block_test(8'h15, AES_DECIPHER, nist_aes256_key1, AES_256_BIT_KEY,
                                 nist_ecb_256_enc_expected1, nist_plaintext1);

      ecb_mode_single_block_test(8'h16, AES_DECIPHER, nist_aes256_key1, AES_256_BIT_KEY,
                                 nist_ecb_256_enc_expected2, nist_plaintext2);

      ecb_mode_single_block_test(8'h17, AES_DECIPHER, nist_aes256_key1, AES_256_BIT_KEY,
                                 nist_ecb_256_enc_expected3, nist_plaintext3);


      ecb_mode_single_block_test(8'h18, AES_ENCIPHER, nist_aes256_key2, AES_256_BIT_KEY,
                                 nist_plaintext4, nist_ecb_256_enc_expected4);

      ecb_mode_single_block_test(8'h19, AES_DECIPHER, nist_aes256_key2, AES_256_BIT_KEY,
                                 nist_ecb_256_enc_expected4, nist_plaintext4);
    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

Testbench for the AES block cipher core.
// tb_aes_core.v
// -------------
// Testbench for the AES block cipher core.
// Author: Joachim Strombergson
// Copyright (c) 2014, Secworks Sweden AB
// All rights reserved.
`default_nettype none

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 vectors copied from the follwing NIST documents.
  //
  // NIST SP 800-38A:
  // http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
  //
  // NIST FIPS-197, Appendix C:
  // https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.197.pdf
  //
  // 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_key1;
      reg [255 : 0] nist_aes128_key2;
      reg [255 : 0] nist_aes256_key1;
      reg [255 : 0] nist_aes256_key2;

      reg [127 : 0] nist_plaintext0;
      reg [127 : 0] nist_plaintext1;
      reg [127 : 0] nist_plaintext2;
      reg [127 : 0] nist_plaintext3;
      reg [127 : 0] nist_plaintext4;

      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_128_enc_expected4;

      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;
      reg [127 : 0] nist_ecb_256_enc_expected4;

      nist_aes128_key1 = 256'h2b7e151628aed2a6abf7158809cf4f3c00000000000000000000000000000000;
      nist_aes128_key2 = 256'h000102030405060708090a0b0c0d0e0f00000000000000000000000000000000;
      nist_aes256_key1 = 256'h603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4;
      nist_aes256_key2 = 256'h000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f;

      nist_plaintext0 = 128'h6bc1bee22e409f96e93d7e117393172a;
      nist_plaintext1 = 128'hae2d8a571e03ac9c9eb76fac45af8e51;
      nist_plaintext2 = 128'h30c81c46a35ce411e5fbc1191a0a52ef;
      nist_plaintext3 = 128'hf69f2445df4f9b17ad2b417be66c3710;
      nist_plaintext4 = 128'h00112233445566778899aabbccddeeff;

      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_128_enc_expected4 = 128'h69c4e0d86a7b0430d8cdb78070b4c55a;

      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;
      nist_ecb_256_enc_expected4 = 128'h8ea2b7ca516745bfeafc49904b496089;


      $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_key1, AES_128_BIT_KEY,
                                 nist_plaintext0, nist_ecb_128_enc_expected0);

      ecb_mode_single_block_test(8'h02, AES_ENCIPHER, nist_aes128_key1, AES_128_BIT_KEY,
                                 nist_plaintext1, nist_ecb_128_enc_expected1);

      ecb_mode_single_block_test(8'h03, AES_ENCIPHER, nist_aes128_key1, AES_128_BIT_KEY,
                                 nist_plaintext2, nist_ecb_128_enc_expected2);

      ecb_mode_single_block_test(8'h04, AES_ENCIPHER, nist_aes128_key1, AES_128_BIT_KEY,
                                 nist_plaintext3, nist_ecb_128_enc_expected3);


      ecb_mode_single_block_test(8'h05, AES_DECIPHER, nist_aes128_key1, AES_128_BIT_KEY,
                                 nist_ecb_128_enc_expected0, nist_plaintext0);

      ecb_mode_single_block_test(8'h06, AES_DECIPHER, nist_aes128_key1, AES_128_BIT_KEY,
                                 nist_ecb_128_enc_expected1, nist_plaintext1);

      ecb_mode_single_block_test(8'h07, AES_DECIPHER, nist_aes128_key1, AES_128_BIT_KEY,
                                 nist_ecb_128_enc_expected2, nist_plaintext2);

      ecb_mode_single_block_test(8'h08, AES_DECIPHER, nist_aes128_key1, AES_128_BIT_KEY,
                                 nist_ecb_128_enc_expected3, nist_plaintext3);


      ecb_mode_single_block_test(8'h09, AES_ENCIPHER, nist_aes128_key2, AES_128_BIT_KEY,
                                 nist_plaintext4, nist_ecb_128_enc_expected4);

      ecb_mode_single_block_test(8'h0a, AES_DECIPHER, nist_aes128_key2, AES_128_BIT_KEY,
                                 nist_ecb_128_enc_expected4, nist_plaintext4);


      $display("");
      $display("ECB 256 bit key tests");
      $display("---------------------");
      ecb_mode_single_block_test(8'h10, AES_ENCIPHER, nist_aes256_key1, AES_256_BIT_KEY,
                                 nist_plaintext0, nist_ecb_256_enc_expected0);

      ecb_mode_single_block_test(8'h11, AES_ENCIPHER, nist_aes256_key1, AES_256_BIT_KEY,
                                 nist_plaintext1, nist_ecb_256_enc_expected1);

      ecb_mode_single_block_test(8'h12, AES_ENCIPHER, nist_aes256_key1, AES_256_BIT_KEY,
                                 nist_plaintext2, nist_ecb_256_enc_expected2);

      ecb_mode_single_block_test(8'h13, AES_ENCIPHER, nist_aes256_key1, AES_256_BIT_KEY,
                                 nist_plaintext3, nist_ecb_256_enc_expected3);


      ecb_mode_single_block_test(8'h14, AES_DECIPHER, nist_aes256_key1, AES_256_BIT_KEY,
                                 nist_ecb_256_enc_expected0, nist_plaintext0);

      ecb_mode_single_block_test(8'h15, AES_DECIPHER, nist_aes256_key1, AES_256_BIT_KEY,
                                 nist_ecb_256_enc_expected1, nist_plaintext1);

      ecb_mode_single_block_test(8'h16, AES_DECIPHER, nist_aes256_key1, AES_256_BIT_KEY,
                                 nist_ecb_256_enc_expected2, nist_plaintext2);

      ecb_mode_single_block_test(8'h17, AES_DECIPHER, nist_aes256_key1, AES_256_BIT_KEY,
                                 nist_ecb_256_enc_expected3, nist_plaintext3);


      ecb_mode_single_block_test(8'h18, AES_ENCIPHER, nist_aes256_key2, AES_256_BIT_KEY,
                                 nist_plaintext4, nist_ecb_256_enc_expected4);

      ecb_mode_single_block_test(8'h19, AES_DECIPHER, nist_aes256_key2, AES_256_BIT_KEY,
                                 nist_ecb_256_enc_expected4, nist_plaintext4);

      display_test_result();
      $display("");
      $display("*** AES core simulation done. ***");
      $finish;
    end // aes_core_test
endmodule // tb_aes_core

Testbench for the AES encipher block module.
// tb_aes_encipher_block.v
// -----------------------
// Testbench for the AES encipher block module.
// Test cases from NIST SP 800-38A:
// http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
// Author: Joachim Strombergson
// Copyright (c) 2014, Secworks Sweden AB
// All rights reserved.
`default_nettype none

module tb_aes_encipher_block();

  //----------------------------------------------------------------
  // 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_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;
      $display("");
    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
     tc_ctr = tc_ctr + 1;

     $display("--- ECB mode test started.");

     // 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("--- Testcase successful.");
         $display("--- Got: 0x%032x", tb_new_block);
       end
     else
       begin
         $display("--- ERROR: Testcase NOT successful.");
         $display("--- Expected: 0x%032x", expected);
         $display("--- Got:      0x%032x", tb_new_block);
         error_ctr = error_ctr + 1;
       end
     $display("--- ECB mode test completed.");
   end
  endtask // ecb_mode_single_block_test


  //----------------------------------------------------------------
  // load_nist128_key
  //----------------------------------------------------------------
  task load_nist128_key;
    begin : load_nist128_key
      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;
    end
  endtask // load_nist128_key


  //----------------------------------------------------------------
  // load_nist256_key
  //----------------------------------------------------------------
  task load_nist256_key;
    begin : load_nist256_key
      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;
    end
  endtask // load_nist256_key


  //----------------------------------------------------------------
  // test_nist_enc_128_1
  //----------------------------------------------------------------
  task test_nist_enc_128_1;
    begin : nist_enc_128_1
      reg [127 : 0] plaintext;
      reg [127 : 0] ciphertext;

      plaintext  = 128'h6bc1bee22e409f96e93d7e117393172a;
      ciphertext = 128'h3ad77bb40d7a3660a89ecaf32466ef97;

      $display("--- test_nist_enc_128_1: Started.");

      test_ecb_enc(AES_128_BIT_KEY, plaintext, ciphertext);
      $display("--- test_nist_enc_128_1: Completed.");
      $display("");
    end
  endtask // test_nist_enc_128_1


  //----------------------------------------------------------------
  // test_nist_enc_128_2
  //----------------------------------------------------------------
  task test_nist_enc_128_2;
    begin : nist_enc_128_2
      reg [127 : 0] plaintext;
      reg [127 : 0] ciphertext;

      plaintext  = 128'hae2d8a571e03ac9c9eb76fac45af8e51;
      ciphertext = 128'hf5d3d58503b9699de785895a96fdbaaf;

      $display("--- test_nist_enc_128_2: Started.");

      test_ecb_enc(AES_128_BIT_KEY, plaintext, ciphertext);
      $display("--- test_nist_enc_128_2: Completed.");
      $display("");
    end
  endtask // test_nist_enc_128_2


  //----------------------------------------------------------------
  // test_nist_enc_128_3
  //----------------------------------------------------------------
  task test_nist_enc_128_3;
    begin : nist_enc_128_3
      reg [127 : 0] plaintext;
      reg [127 : 0] ciphertext;

      plaintext  = 128'h30c81c46a35ce411e5fbc1191a0a52ef;
      ciphertext = 128'h43b1cd7f598ece23881b00e3ed030688;

      $display("--- test_nist_enc_128_3: Started.");

      test_ecb_enc(AES_128_BIT_KEY, plaintext, ciphertext);
      $display("--- test_nist_enc_128_3: Completed.");
      $display("");
    end
  endtask // test_nist_enc_128_3


  //----------------------------------------------------------------
  // test_nist_enc_128_4
  //----------------------------------------------------------------
  task test_nist_enc_128_4;
    begin : nist_enc_128_4
      reg [127 : 0] plaintext;
      reg [127 : 0] ciphertext;

      plaintext  = 128'hf69f2445df4f9b17ad2b417be66c3710;
      ciphertext = 128'h7b0c785e27e8ad3f8223207104725dd4;

      $display("--- test_nist_enc_128_4: Started.");

      test_ecb_enc(AES_128_BIT_KEY, plaintext, ciphertext);
      $display("--- test_nist_enc_128_4: Completed.");
      $display("");
    end
  endtask // test_nist_enc_128_4


  //----------------------------------------------------------------
  // test_nist_enc_256_1
  //----------------------------------------------------------------
  task test_nist_enc_256_1;
    begin : nist_enc_256_1
      reg [127 : 0] plaintext;
      reg [127 : 0] ciphertext;

      plaintext  = 128'h6bc1bee22e409f96e93d7e117393172a;
      ciphertext = 128'hf3eed1bdb5d2a03c064b5a7e3db181f8;

      $display("--- test_nist_enc_256_1: Started.");

      test_ecb_enc(AES_256_BIT_KEY, plaintext, ciphertext);
      $display("--- test_nist_enc_256_1: Completed.");
      $display("");
    end
  endtask // test_nist_enc_256_1


  //----------------------------------------------------------------
  // test_nist_enc_256_2
  //----------------------------------------------------------------
  task test_nist_enc_256_2;
    begin : nist_enc_256_2
      reg [127 : 0] plaintext;
      reg [127 : 0] ciphertext;

      plaintext  = 128'hae2d8a571e03ac9c9eb76fac45af8e51;
      ciphertext = 128'h591ccb10d410ed26dc5ba74a31362870;

      $display("--- test_nist_enc_256_2: Started.");

      test_ecb_enc(AES_256_BIT_KEY, plaintext, ciphertext);
      $display("--- test_nist_enc_256_2: Completed.");
      $display("");
    end
  endtask // test_nist_enc_256_2


  //----------------------------------------------------------------
  // test_nist_enc_256_3
  //----------------------------------------------------------------
  task test_nist_enc_256_3;
    begin : nist_enc_256_3
      reg [127 : 0] plaintext;
      reg [127 : 0] ciphertext;

      plaintext  = 128'h30c81c46a35ce411e5fbc1191a0a52ef;
      ciphertext = 128'hb6ed21b99ca6f4f9f153e7b1beafed1d;

      $display("--- test_nist_enc_256_3: Started.");

      test_ecb_enc(AES_256_BIT_KEY, plaintext, ciphertext);
      $display("--- test_nist_enc_256_3: Completed.");
      $display("");
    end
  endtask // test_nist_enc_256_3


  //----------------------------------------------------------------
  // test_nist_enc_256_4
  //----------------------------------------------------------------
  task test_nist_enc_256_4;
    begin : nist_enc_256_4
      reg [127 : 0] plaintext;
      reg [127 : 0] ciphertext;

      plaintext  = 128'hf69f2445df4f9b17ad2b417be66c3710;
      ciphertext = 128'h23304b7a39f9f3ff067d8d8f9e24ecc7;

      $display("--- test_nist_enc_256_4: Started.");

      test_ecb_enc(AES_256_BIT_KEY, plaintext, ciphertext);
      $display("--- test_nist_enc_256_4: Completed.");
      $display("");
    end
  endtask // test_nist_enc_256_4


  //----------------------------------------------------------------
  // tb_aes_encipher_block
  // The main test functionality.
  //----------------------------------------------------------------
  initial
    begin : tb_aes_encipher_block
      $display("   -= Testbench for aes encipher block started =-");
      $display("     ============================================");
      $display("");

      init_sim();
      reset_dut();

      load_nist128_key();
      test_nist_enc_128_1();
      test_nist_enc_128_2();
      test_nist_enc_128_3();
      test_nist_enc_128_4();

      load_nist256_key();
      test_nist_enc_256_1();
      test_nist_enc_256_2();
      test_nist_enc_256_3();
      test_nist_enc_256_4();

      display_test_result();
      $display("");
      $display("   -= Testbench for aes encipher block completed =-");
      $display("     ============================================");
      $finish;
    end // tb_aes_encipher_block
endmodule // tb_aes_encipher_block

Testbench for the AES key memory module.
// tb_aes_key_mem.v
// ----------------
// Testbench for the AES key memory module.
// Author: Joachim Strombergson
// Copyright (c) 2014, Secworks Sweden AB
// All rights reserved.
`default_nettype none

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_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