-- ============================================================================
--
-- Design unit      :   ecb_128_encryption_core_tb (vefification testbench for
--                      ECB-128 encryption core)
--
-- File Name        :   ecb_128_encryption_core_tb.vhd
--
-- Purpose          :   The testbench uses test vectors to stimulate the encryption
--                      core with given test data and verify output data and
--                      behaviour of the core
--
--
-- Depends on       :
--
--  - Package(s)    :   tech_iface, key_schedule_iface, engine_iface,
--                      ecb_mode_iface, ecb_core_iface
--
--  - Module(s)     :   ecb_128_encryption_core, sbox_loader
--
--
-- Dev. Platform    :   Xilinx ISE 8.1i SP3 / Win32 (W2k SP4)
--
--  - Simulator(s)  :   Modelsim XE III 6.0d
--
--  - Synthesis     :   Xilinx XST
--
--  - Place & Route :   Xilinx PAR
--
--
-- Errors           :   None known
--
--
-- Limitations      :   None known
--
--
-- Notes            :   Version for implementation using 32-bit datapath
--
--
-- Author(s)        :   A. Freund (af) <a.freund@dsi-it.de>
--                      Digitale Signalverabeitung & Informationstechnik GmbH,
--                      Bremen, Germany
--
--
-- ============================================================================
--
-- Revision List:
-- Version      Author(s)       Date        Changes
--
-- v0.00        af              2006-11-15  initial version
--
-- see SVN logs
--
-- ============================================================================
--
-- Naming conventions:
--
--  - coding style: record-signals for related purposes (Gaisler-style)
--  - active-low signals are indicated by appending "_n"
--  - constants are in UPPERCASE
--  - name parts are separated by "_"
--
-- ============================================================================


library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;

use std.textio.all;


use work.tech_iface.all;
use work.key_schedule_iface.all;
use work.engine_iface.all;
use work.ecb_mode_iface.all;
use work.ecb_core_iface.all;


entity ecb_128_encryption_core_tb is
end ecb_128_encryption_core_tb;


architecture stimuli of ecb_128_encryption_core_tb is


	-- put a message on stdout
	procedure puts(msg : string) is
		variable line_out_data : line;
	begin
		write(line_out_data, string'(msg));
		writeline(output, line_out_data);
	end procedure;


	component sbox_loader is
		port (
			rst		: 	in	std_logic;					-- reset
			clk		:	in	std_logic;					-- clock
			load_o	:	out	sbox_stage_load_in_type		-- see package tech_iface
		);
	end component;


	-- type definition for test vectors
	type test_vector_type_t is record
		cycles	:	integer;						-- number of clock cycles this test vector should be applied
		mode_i	:	ecb_mode_encryption_in_type;	-- stimulus for mode_i input (data to be encrypted etc.)
		key_i	:	key_schedule_128_in_type;		-- stimulus for key_i input (key to be expanded etc.)
		sep		:	character;
		mode_o	:	ecb_mode_encryption_out_type;	-- expected value for mode_o output (encrypted data etc.)
		key_o	:	key_schedule_128_out_type;		-- expected value for key_o output (key scheduling progress etc.)
	end record;


	constant KEY_ID1 : key_id_t := CONV_STD_LOGIC_VECTOR(0, key_id_t'length);

	constant KEY_ID2 : key_id_t := CONV_STD_LOGIC_VECTOR(1, key_id_t'length);



	type test_vectors_type_t is array(natural range <>) of test_vector_type_t;

	constant TEST_VECTORS : test_vectors_type_t := (

		-- (tv #1) idle
		(
			cycles		=>	1,
			mode_i		=>	(
								start		=>	'0',
								plain		=>	(others => '-'),
								key_id		=>	(others => '-')
							),
			key_i		=>	(
								load_key	=>	'0',
								key_id		=>	(others => '-'),
								key			=>	(others => '-')
							),
			sep			=>	'=',
			mode_o 		=>	(
								busy		=>	'0',
								valid		=>	'0',
								cipher		=>	(others => '-')
							),
			key_o 		=>	(busy => '0')
		),

--
-- load / expand key
--

		-- key = X"2b7e151628aed2a6abf7158809cf4f3c"
		-- (tv #2) load key (part #0)
		(
			cycles		=>	1,
			mode_i		=>	(
								start		=>	'0',
								plain		=>	(others => '-'),
								key_id		=>	(others => '-')
							),
			key_i		=>	(
								load_key	=>	'1',
								key_id		=>	KEY_ID1,
								key			=>	X"2b7e1516"
							),
			sep			=>	'=',
			mode_o 		=>	(
								busy		=>	'0',
								valid		=>	'0',
								cipher		=>	(others => '-')
							),
			key_o 		=>	(busy => '0')
		),

		-- (tv #3) load key (part #1)
		(
			cycles		=>	1,
			mode_i		=>	(
								start		=>	'0',
								plain		=>	(others => '-'),
								key_id		=>	(others => '-')
							),
			key_i		=>	(
								load_key	=>	'0',
								key_id		=>	(others => '-'),
								key			=>	X"28aed2a6"
							),
			sep			=>	'=',
			mode_o 		=>	(
								busy		=>	'0',
								valid		=>	'0',
								cipher		=>	(others => '-')
							),
			key_o 		=>	(busy => '1')
		),

		-- (tv #4) load key (part #2)
		(
			cycles		=>	1,
			mode_i		=>	(
								start		=>	'0',
								plain		=>	(others => '-'),
								key_id		=>	(others => '-')
							),
			key_i		=>	(
								load_key	=>	'0',
								key_id		=>	(others => '-'),
								key			=>	X"abf71588"
							),
			sep			=>	'=',
			mode_o 		=>	(
								busy		=>	'0',
								valid		=>	'0',
								cipher		=>	(others => '-')
							),
			key_o 		=>	(busy => '1')
		),

		-- (tv #5) load key (part #3)
		(
			cycles		=>	1,
			mode_i		=>	(
								start		=>	'0',
								plain		=>	(others => '-'),
								key_id		=>	(others => '-')
							),
			key_i		=>	(
								load_key	=>	'0',
								key_id		=>	(others => '-'),
								key			=>	X"09cf4f3c"
							),
			sep			=>	'=',
			mode_o 		=>	(
								busy		=>	'0',
								valid		=>	'0',
								cipher		=>	(others => '-')
							),
			key_o 		=>	(busy => '1')
		),

		-- (tv #6) wait while key is expanded
		(
			cycles		=>	41,
			mode_i		=>	(
								start		=>	'0',
								plain		=>	(others => '-'),
								key_id		=>	(others => '-')
							),
			key_i		=>	(
								load_key	=>	'0',
								key_id		=>	(others => '-'),
								key			=>	(others => '-')
							),
			sep			=>	'=',
			mode_o 		=>	(
								busy		=>	'0',
								valid		=>	'0',
								cipher		=>	(others => '-')
							),
			key_o 		=>	(busy => '1')
		),

--
-- encrypt data
--

		-- plaintext = X"3243f6a8885a308d313198a2e0370734"
		-- (tv #7) start encryption / load plaintext part 0
		(
			cycles			=>	1,
			mode_i		=>	(
								start		=>	'1',
								plain		=>	X"3243f6a8",
								key_id		=>	KEY_ID1
							),
			key_i		=>	(
								load_key	=>	'0',
								key_id		=>	(others => '-'),
								key			=>	(others => '-')
							),
			sep			=>	'=',
			mode_o 		=>	(
								busy		=>	'0',
								valid		=>	'0',
								cipher		=>	(others => '-')
							),
			key_o 		=>	(busy => '0')
		),


		-- (tv #8) load plaintext part 1
		(
			cycles			=>	1,
			mode_i		=>	(
								start		=>	'0',
								plain		=>	X"885a308d",
								key_id		=>	(others => '-')
							),
			key_i		=>	(
								load_key	=>	'0',
								key_id		=>	(others => '-'),
								key			=>	(others => '-')
							),
			sep			=>	'=',
			mode_o 		=>	(
								busy		=>	'1',
								valid		=>	'0',
								cipher		=>	(others => '-')
							),
			key_o 		=>	(busy => '0')
		),

		-- (tv #9) load plaintext part 2
		(
			cycles			=>	1,
			mode_i		=>	(
								start		=>	'0',
								plain		=>	X"313198a2",
								key_id		=>	(others => '-')
							),
			key_i		=>	(
								load_key	=>	'0',
								key_id		=>	(others => '-'),
								key			=>	(others => '-')
							),
			sep			=>	'=',
			mode_o 		=>	(
								busy		=>	'1',
								valid		=>	'0',
								cipher		=>	(others => '-')
							),
			key_o 		=>	(busy => '0')
		),


		-- (tv #10) load plaintext part 3
		(
			cycles			=>	1,
			mode_i		=>	(
								start		=>	'0',
								plain		=>	X"e0370734",
								key_id		=>	(others => '-')
							),
			key_i		=>	(
								load_key	=>	'0',
								key_id		=>	(others => '-'),
								key			=>	(others => '-')
							),
			sep			=>	'=',
			mode_o 		=>	(
								busy		=>	'1',
								valid		=>	'0',
								cipher		=>	(others => '-')
							),
			key_o 		=>	(busy => '0')
		),

		-- (tv #11) wait while busy
		(
			cycles			=>	47,
			mode_i		=>	(
								start		=>	'0',
								plain		=>	(others => '-'),
								key_id		=>	(others => '-')
							),
			key_i		=>	(
								load_key	=>	'0',
								key_id		=>	(others => '-'),
								key			=>	(others => '-')
							),
			sep			=>	'=',
			mode_o 		=>	(
								busy		=>	'1',
								valid		=>	'0',
								cipher		=>	(others => '-')
							),
			key_o 		=>	(busy => '0')
		),

--
-- verify ciphertext
--

		-- ciphertext = X"3925841d02dc09fbdc118597196a0b32"
		-- (tv #12) verify ciphertext part 0
		(
			cycles			=>	1,
			mode_i		=>	(
								start		=>	'0',
								plain		=>	(others => '-'),
								key_id		=>	(others => '-')
							),
			key_i		=>	(
								load_key	=>	'0',
								key_id		=>	(others => '-'),
								key			=>	(others => '-')
							),
			sep			=>	'=',
			mode_o 		=>	(
								busy		=>	'1',
								valid		=>	'1',
								cipher		=>	X"3925841d"
							),
			key_o 		=>	(busy => '0')
		),

		-- (tv #13) verify ciphertext part 1
		(
			cycles			=>	1,
			mode_i		=>	(
								start		=>	'0',
								plain		=>	(others => '-'),
								key_id		=>	(others => '-')
							),
			key_i		=>	(
								load_key	=>	'0',
								key_id		=>	(others => '-'),
								key			=>	(others => '-')
							),
			sep			=>	'=',
			mode_o 		=>	(
								busy		=>	'1',
								valid		=>	'1',
								cipher		=>	X"02dc09fb"
							),
			key_o 		=>	(busy => '0')
		),

		-- (tv #14) verify ciphertext part 2
		(
			cycles			=>	1,
			mode_i		=>	(
								start		=>	'0',
								plain		=>	(others => '-'),
								key_id		=>	(others => '-')
							),
			key_i		=>	(
								load_key	=>	'0',
								key_id		=>	(others => '-'),
								key			=>	(others => '-')
							),
			sep			=>	'=',
			mode_o 		=>	(
								busy		=>	'1',
								valid		=>	'1',
								cipher		=>	X"dc118597"
							),
			key_o 		=>	(busy => '0')
		),

		-- (tv #15) verify ciphertext part 3
		(
			cycles			=>	1,
			mode_i		=>	(
								start		=>	'0',
								plain		=>	(others => '-'),
								key_id		=>	(others => '-')
							),
			key_i		=>	(
								load_key	=>	'0',
								key_id		=>	(others => '-'),
								key			=>	(others => '-')
							),
			sep			=>	'=',
			mode_o 		=>	(
								busy		=>	'1',
								valid		=>	'1',
								cipher		=>	X"196a0b32"
							),
			key_o 		=>	(busy => '0')
		),

--
-- load / expand key
--

		-- key = X"000102030405060708090a0b0c0d0e0f"
		-- (tv #16) load key (part #0)
		(
			cycles		=>	1,
			mode_i		=>	(
								start		=>	'0',
								plain		=>	(others => '-'),
								key_id		=>	(others => '-')
							),
			key_i		=>	(
								load_key	=>	'1',
								key_id		=>	KEY_ID2,
								key			=>	X"00010203"
							),
			sep			=>	'=',
			mode_o 		=>	(
								busy		=>	'0',
								valid		=>	'0',
								cipher		=>	(others => '-')
							),
			key_o 		=>	(busy => '0')
		),

		-- (tv #17) load key (part #1)
		(
			cycles		=>	1,
			mode_i		=>	(
								start		=>	'0',
								plain		=>	(others => '-'),
								key_id		=>	(others => '-')
							),
			key_i		=>	(
								load_key	=>	'0',
								key_id		=>	(others => '-'),
								key			=>	X"04050607"
							),
			sep			=>	'=',
			mode_o 		=>	(
								busy		=>	'0',
								valid		=>	'0',
								cipher		=>	(others => '-')
							),
			key_o 		=>	(busy => '1')
		),

		-- (tv #18) load key (part #2)
		(
			cycles		=>	1,
			mode_i		=>	(
								start		=>	'0',
								plain		=>	(others => '-'),
								key_id		=>	(others => '-')
							),
			key_i		=>	(
								load_key	=>	'0',
								key_id		=>	(others => '-'),
								key			=>	X"08090a0b"
							),
			sep			=>	'=',
			mode_o 		=>	(
								busy		=>	'0',
								valid		=>	'0',
								cipher		=>	(others => '-')
							),
			key_o 		=>	(busy => '1')
		),

		-- (tv #19) load key (part #3)
		(
			cycles		=>	1,
			mode_i		=>	(
								start		=>	'0',
								plain		=>	(others => '-'),
								key_id		=>	(others => '-')
							),
			key_i		=>	(
								load_key	=>	'0',
								key_id		=>	(others => '-'),
								key			=>	X"0c0d0e0f"
							),
			sep			=>	'=',
			mode_o 		=>	(
								busy		=>	'0',
								valid		=>	'0',
								cipher		=>	(others => '-')
							),
			key_o 		=>	(busy => '1')
		),

		-- (tv #20) wait while key is expanded
		(
			cycles		=>	41,
			mode_i		=>	(
								start		=>	'0',
								plain		=>	(others => '-'),
								key_id		=>	(others => '-')
							),
			key_i		=>	(
								load_key	=>	'0',
								key_id		=>	(others => '-'),
								key			=>	(others => '-')
							),
			sep			=>	'=',
			mode_o 		=>	(
								busy		=>	'0',
								valid		=>	'0',
								cipher		=>	(others => '-')
							),
			key_o 		=>	(busy => '1')
		),

--
-- encrypt data
--

		-- plaintext = X"00112233445566778899aabbccddeeff"
		-- (tv #21) start encryption / load plaintext part 0
		(
			cycles			=>	1,
			mode_i		=>	(
								start		=>	'1',
								plain		=>	X"00112233",
								key_id		=>	KEY_ID2
							),
			key_i		=>	(
								load_key	=>	'0',
								key_id		=>	(others => '-'),
								key			=>	(others => '-')
							),
			sep			=>	'=',
			mode_o 		=>	(
								busy		=>	'0',
								valid		=>	'0',
								cipher		=>	(others => '-')
							),
			key_o 		=>	(busy => '0')
		),


		-- (tv #22) load plaintext part 1
		(
			cycles			=>	1,
			mode_i		=>	(
								start		=>	'0',
								plain		=>	X"44556677",
								key_id		=>	(others => '-')
							),
			key_i		=>	(
								load_key	=>	'0',
								key_id		=>	(others => '-'),
								key			=>	(others => '-')
							),
			sep			=>	'=',
			mode_o 		=>	(
								busy		=>	'1',
								valid		=>	'0',
								cipher		=>	(others => '-')
							),
			key_o 		=>	(busy => '0')
		),

		-- (tv #23) load plaintext part 2
		(
			cycles			=>	1,
			mode_i		=>	(
								start		=>	'0',
								plain		=>	X"8899aabb",
								key_id		=>	(others => '-')
							),
			key_i		=>	(
								load_key	=>	'0',
								key_id		=>	(others => '-'),
								key			=>	(others => '-')
							),
			sep			=>	'=',
			mode_o 		=>	(
								busy		=>	'1',
								valid		=>	'0',
								cipher		=>	(others => '-')
							),
			key_o 		=>	(busy => '0')
		),


		-- (tv #24) load plaintext part 3
		(
			cycles			=>	1,
			mode_i		=>	(
								start		=>	'0',
								plain		=>	X"ccddeeff",
								key_id		=>	(others => '-')
							),
			key_i		=>	(
								load_key	=>	'0',
								key_id		=>	(others => '-'),
								key			=>	(others => '-')
							),
			sep			=>	'=',
			mode_o 		=>	(
								busy		=>	'1',
								valid		=>	'0',
								cipher		=>	(others => '-')
							),
			key_o 		=>	(busy => '0')
		),

		-- (tv #25) wait while busy
		(
			cycles			=>	47,
			mode_i		=>	(
								start		=>	'0',
								plain		=>	(others => '-'),
								key_id		=>	(others => '-')
							),
			key_i		=>	(
								load_key	=>	'0',
								key_id		=>	(others => '-'),
								key			=>	(others => '-')
							),
			sep			=>	'=',
			mode_o 		=>	(
								busy		=>	'1',
								valid		=>	'0',
								cipher		=>	(others => '-')
							),
			key_o 		=>	(busy => '0')
		),

--
-- verify ciphertext
--

		-- ciphertext = X"69c4e0d86a7b0430d8cdb78070b4c55a"
		-- (tv #26) verify ciphertext part 0
		(
			cycles			=>	1,
			mode_i		=>	(
								start		=>	'0',
								plain		=>	(others => '-'),
								key_id		=>	(others => '-')
							),
			key_i		=>	(
								load_key	=>	'0',
								key_id		=>	(others => '-'),
								key			=>	(others => '-')
							),
			sep			=>	'=',
			mode_o 		=>	(
								busy		=>	'1',
								valid		=>	'1',
								cipher		=>	X"69c4e0d8"
							),
			key_o 		=>	(busy => '0')
		),

		-- (tv #27) verify ciphertext part 1
		(
			cycles			=>	1,
			mode_i		=>	(
								start		=>	'0',
								plain		=>	(others => '-'),
								key_id		=>	(others => '-')
							),
			key_i		=>	(
								load_key	=>	'0',
								key_id		=>	(others => '-'),
								key			=>	(others => '-')
							),
			sep			=>	'=',
			mode_o 		=>	(
								busy		=>	'1',
								valid		=>	'1',
								cipher		=>	X"6a7b0430"
							),
			key_o 		=>	(busy => '0')
		),

		-- (tv #28) verify ciphertext part 2
		(
			cycles			=>	1,
			mode_i		=>	(
								start		=>	'0',
								plain		=>	(others => '-'),
								key_id		=>	(others => '-')
							),
			key_i		=>	(
								load_key	=>	'0',
								key_id		=>	(others => '-'),
								key			=>	(others => '-')
							),
			sep			=>	'=',
			mode_o 		=>	(
								busy		=>	'1',
								valid		=>	'1',
								cipher		=>	X"d8cdb780"
							),
			key_o 		=>	(busy => '0')
		),

		-- (tv #29) verify ciphertext part 3
		(
			cycles			=>	1,
			mode_i		=>	(
								start		=>	'0',
								plain		=>	(others => '-'),
								key_id		=>	(others => '-')
							),
			key_i		=>	(
								load_key	=>	'0',
								key_id		=>	(others => '-'),
								key			=>	(others => '-')
							),
			sep			=>	'=',
			mode_o 		=>	(
								busy		=>	'1',
								valid		=>	'1',
								cipher		=>	X"70b4c55a"
							),
			key_o 		=>	(busy => '0')
		),

--
-- encrypt data
--

		-- key = X"2b7e151628aed2a6abf7158809cf4f3c"
		-- plaintext = X"3243f6a8885a308d313198a2e0370734"
		-- (tv #30) start encryption with prevoius key / load plaintext part 0
		(
			cycles			=>	1,
			mode_i		=>	(
								start		=>	'1',
								plain		=>	X"3243f6a8",
								key_id		=>	KEY_ID1
							),
			key_i		=>	(
								load_key	=>	'0',
								key_id		=>	(others => '-'),
								key			=>	(others => '-')
							),
			sep			=>	'=',
			mode_o 		=>	(
								busy		=>	'0',
								valid		=>	'0',
								cipher		=>	(others => '-')
							),
			key_o 		=>	(busy => '0')
		),


		-- (tv #31) load plaintext part 1
		(
			cycles			=>	1,
			mode_i		=>	(
								start		=>	'0',
								plain		=>	X"885a308d",
								key_id		=>	(others => '-')
							),
			key_i		=>	(
								load_key	=>	'0',
								key_id		=>	(others => '-'),
								key			=>	(others => '-')
							),
			sep			=>	'=',
			mode_o 		=>	(
								busy		=>	'1',
								valid		=>	'0',
								cipher		=>	(others => '-')
							),
			key_o 		=>	(busy => '0')
		),

		-- (tv #32) load plaintext part 2
		(
			cycles			=>	1,
			mode_i		=>	(
								start		=>	'0',
								plain		=>	X"313198a2",
								key_id		=>	(others => '-')
							),
			key_i		=>	(
								load_key	=>	'0',
								key_id		=>	(others => '-'),
								key			=>	(others => '-')
							),
			sep			=>	'=',
			mode_o 		=>	(
								busy		=>	'1',
								valid		=>	'0',
								cipher		=>	(others => '-')
							),
			key_o 		=>	(busy => '0')
		),


		-- (tv #33) load plaintext part 3
		(
			cycles			=>	1,
			mode_i		=>	(
								start		=>	'0',
								plain		=>	X"e0370734",
								key_id		=>	(others => '-')
							),
			key_i		=>	(
								load_key	=>	'0',
								key_id		=>	(others => '-'),
								key			=>	(others => '-')
							),
			sep			=>	'=',
			mode_o 		=>	(
								busy		=>	'1',
								valid		=>	'0',
								cipher		=>	(others => '-')
							),
			key_o 		=>	(busy => '0')
		),

		-- (tv #34) wait while busy
		(
			cycles			=>	47,
			mode_i		=>	(
								start		=>	'0',
								plain		=>	(others => '-'),
								key_id		=>	(others => '-')
							),
			key_i		=>	(
								load_key	=>	'0',
								key_id		=>	(others => '-'),
								key			=>	(others => '-')
							),
			sep			=>	'=',
			mode_o 		=>	(
								busy		=>	'1',
								valid		=>	'0',
								cipher		=>	(others => '-')
							),
			key_o 		=>	(busy => '0')
		),

--
-- verify ciphertext
--

		-- ciphertext = X"3925841d02dc09fbdc118597196a0b32"
		-- (tv #35) verify ciphertext part 0
		(
			cycles			=>	1,
			mode_i		=>	(
								start		=>	'0',
								plain		=>	(others => '-'),
								key_id		=>	(others => '-')
							),
			key_i		=>	(
								load_key	=>	'0',
								key_id		=>	(others => '-'),
								key			=>	(others => '-')
							),
			sep			=>	'=',
			mode_o 		=>	(
								busy		=>	'1',
								valid		=>	'1',
								cipher		=>	X"3925841d"
							),
			key_o 		=>	(busy => '0')
		),

		-- (tv #36) verify ciphertext part 1
		(
			cycles			=>	1,
			mode_i		=>	(
								start		=>	'0',
								plain		=>	(others => '-'),
								key_id		=>	(others => '-')
							),
			key_i		=>	(
								load_key	=>	'0',
								key_id		=>	(others => '-'),
								key			=>	(others => '-')
							),
			sep			=>	'=',
			mode_o 		=>	(
								busy		=>	'1',
								valid		=>	'1',
								cipher		=>	X"02dc09fb"
							),
			key_o 		=>	(busy => '0')
		),

		-- (tv #37) verify ciphertext part 2
		(
			cycles			=>	1,
			mode_i		=>	(
								start		=>	'0',
								plain		=>	(others => '-'),
								key_id		=>	(others => '-')
							),
			key_i		=>	(
								load_key	=>	'0',
								key_id		=>	(others => '-'),
								key			=>	(others => '-')
							),
			sep			=>	'=',
			mode_o 		=>	(
								busy		=>	'1',
								valid		=>	'1',
								cipher		=>	X"dc118597"
							),
			key_o 		=>	(busy => '0')
		),

		-- (tv #38) verify ciphertext part 3
		(
			cycles			=>	1,
			mode_i		=>	(
								start		=>	'0',
								plain		=>	(others => '-'),
								key_id		=>	(others => '-')
							),
			key_i		=>	(
								load_key	=>	'0',
								key_id		=>	(others => '-'),
								key			=>	(others => '-')
							),
			sep			=>	'=',
			mode_o 		=>	(
								busy		=>	'1',
								valid		=>	'1',
								cipher		=>	X"196a0b32"
							),
			key_o 		=>	(busy => '0')
		),

--
--
--

		-- (tv #39) idle
		(
			cycles			=>	1,
			mode_i		=>	(
								start		=>	'0',
								plain		=>	(others => '-'),
								key_id		=>	(others => '-')
							),
			key_i		=>	(
								load_key	=>	'0',
								key_id		=>	(others => '-'),
								key			=>	(others => '-')
							),
			sep			=>	'=',
			mode_o 		=>	(
								busy		=>	'0',
								valid		=>	'0',
								cipher		=>	(others => '-')
							),
			key_o 		=>	(busy => '0')
		)


	);


	signal rst		: 	std_logic;						-- reset
	signal clk		:	std_logic;						-- clock
	signal mode_i	:	ecb_mode_encryption_in_type;	-- see package ecb_mode_iface
	signal mode_o	:	ecb_mode_encryption_out_type;	-- see package ecb_mode_iface
	signal key_i	:	key_schedule_128_in_type;		-- see package key_schedule_iface
	signal key_o	:	key_schedule_128_out_type;		-- see package key_schedule_iface
	signal sbld_i	:	sbox_stage_load_in_type;		-- see package tech_iface


	constant CLK_PERIOD : time  := 20 ns;


begin


	uut: ecb_128_encryption_core
		port map (
			rst		=> 	rst,
			clk		=>	clk,
			mode_i	=>	mode_i,
			mode_o	=>	mode_o,
			key_i	=>	key_i,
			key_o	=>	key_o,
			sbld_i	=>	sbld_i
		);


	init: sbox_loader
		port map (
			rst		=>	rst,
			clk		=>	clk,
			load_o	=>	sbld_i
		);


	tb: process
	begin

		clk <= '0';
		rst <= '1';
		mode_i.start <= '0';
		key_i.load_key <= '0';

		-- Virtex GSR-signal is deactivated 100ns after "configuration"
		wait for 200 ns;


		-- some clock cycles for reset
		for i in 0 to 3 loop
			wait for CLK_PERIOD / 2;
			clk <= '1';
			wait for CLK_PERIOD / 2;
			clk <= '0';
		end loop;


		wait for CLK_PERIOD / 2;
		clk <= '1';
		wait for CLK_PERIOD / 4;


		-- separate normal output from the ugly stuff displayed at start-up
		puts("#");
		puts("#");
		puts("# *** Releasing reset ***");
		puts("#");
		puts("#");

		rst <= '0';


		puts("#");
		puts("#");
		puts("# *** Pre-loading S-boxes ***");
		puts("#");
		puts("#");

		while (sbld_i.done = '0') loop

			wait for CLK_PERIOD / 4;
			clk <= '0';
			wait for CLK_PERIOD / 2;
			clk <= '1';
			wait for CLK_PERIOD / 4;

		end loop;


		-- some more clock cycles
		for i in 0 to 3 loop
			wait for CLK_PERIOD / 4;
			clk <= '0';
			wait for CLK_PERIOD / 2;
			clk <= '1';
			wait for CLK_PERIOD / 4;
		end loop;


		puts("#");
		puts("#");
		puts("# *** Processing Test-Vectors ***");
		puts("#");
		puts("#");


		for i in TEST_VECTORS'range loop

			-- assign stimuli
			mode_i <= TEST_VECTORS(i).mode_i;
			key_i <= TEST_VECTORS(i).key_i;


			for j in 1 to TEST_VECTORS(i).cycles loop

				wait for CLK_PERIOD / 4;
				clk <= '0';
				wait for CLK_PERIOD / 4;


				-- verify results (still during the same clock cycle)

				assert (mode_o.busy = TEST_VECTORS(i).mode_o.busy)
					report "Test vector #" & Integer'image(i+1) & " failed on <mode_o.busy>!"
						severity failure;

				assert (mode_o.valid = TEST_VECTORS(i).mode_o.valid)
					report "Test vector #" & Integer'image(i+1) & " failed on <mode_o.valid>!"
						severity failure;

				if (mode_o.valid = '1')
					then
						assert (mode_o.cipher = TEST_VECTORS(i).mode_o.cipher)
							report "Test vector #" & Integer'image(i+1) & " failed on <mode_o.cipher>!"
								severity failure;
				end if;

				assert (key_o.busy = TEST_VECTORS(i).key_o.busy)
					report "Test vector #" & Integer'image(i+1) & " failed on <key_o.busy>!"
						severity failure;


				wait for CLK_PERIOD / 4;
				clk <= '1';
				wait for CLK_PERIOD / 4;

			end loop;

		end loop;



		puts("#");
		puts("#");
		puts("# *** All test vectors processed! ***");
		puts("#");
		puts("#");


		-- some more clock cycles
		for i in 0 to 10 loop
			wait for CLK_PERIOD / 4;
			clk <= '0';
			wait for CLK_PERIOD / 2;
			clk <= '1';
			wait for CLK_PERIOD / 4;
		end loop;


		puts("# *** End of test! ***");
		puts("#");
		puts("#");


		assert false
			report "Forced simulation halt"
				severity failure;

		wait;

	end process;


end stimuli;
