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