-- ============================================================================
--
-- Design unit      :   cbc_128_encryption_core (CBC-mode encryption core with
--                      128-bit key schedule)
--
-- File Name        :   cbc_128_encryption_core.vhd
--
-- Purpose          :   The module instantiates all necessary modules (S-box
--                      stages, encryption, CBC-mode, key schedule, subkey
--                      memory etc.) to provide an CBC-mode encryption core
--
--
-- Depends on       :
--
--  - Package(s)    :   tech_iface, key_schedule_iface, engine_iface,
--                      cbc_mode_iface, cbc_core_iface
--
--  - Module(s)     :   cbc_mode_encryption, encryption_engine, tech_sbox_stage,
--                      tech_subkey_memory, key_schedule_128
--
--
-- 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              2007-01-31  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 work.tech_iface.all;
use work.key_schedule_iface.all;
use work.engine_iface.all;
use work.cbc_mode_iface.all;
use work.cbc_core_iface.all;


entity cbc_128_encryption_core is
	port (
		rst		: 	in	std_logic;						-- reset
		clk		:	in	std_logic;						-- clock
		mode_i	:	in	cbc_mode_encryption_in_type;	-- see package cbc_mode_iface
		mode_o	:	out	cbc_mode_encryption_out_type;	-- see package cbc_mode_iface
		key_i	:	in	key_schedule_128_in_type;		-- see package key_schedule_iface
		key_o	:	out	key_schedule_128_out_type;		-- see package key_schedule_iface
		sbld_i	:	in	sbox_stage_load_in_type			-- see package tech_iface
	);
end cbc_128_encryption_core;


architecture behavioural of cbc_128_encryption_core is


	signal enc_i		:	encryption_engine_in_type;	-- input to the encryption engine
	signal enc_o		:	encryption_engine_out_type;	-- output of the encryption engine

	signal sbox_enc_i	:	sbox_stage_in_type;			-- input to the S-box stage
	signal sbox_enc_o	:	sbox_stage_out_type;		-- output of the S-box stage

	signal sbox_ks_i	:	sbox_stage_in_type;			-- input to the S-box stage (key schedule)
	signal sbox_ks_o	:	sbox_stage_out_type;		-- output of the S-box stage (key schedule)

	signal skm_enc_i	:	subkey_memory_ed_in_type;	-- encryption-side subkey memory access (subkey selection)
	signal skm_enc_o	:	subkey_memory_ed_out_type;	-- encryption-side subkey memory access (selected subkey)

	signal skm_ks_enc_i	:	subkey_memory_ks_in_type;	-- subkey storage by key schedule


begin


	-- AES CBC-mode encryption
	cbc_mode: cbc_mode_encryption
		port map (
			rst		=>	rst,
			clk		=>	clk,
			mode_i	=>	mode_i,
			mode_o	=>	mode_o,
			enc_i	=>	enc_o,
			enc_o	=>	enc_i
		);


	-- AES encryption engine
	enc_eng: encryption_engine
		port map (
			rst		=>	rst,
			clk		=>	clk,
			enc_i	=>	enc_i,
			enc_o	=>	enc_o,
			skm_i	=>	skm_enc_o,
			skm_o	=>	skm_enc_i,
			sbox_i	=>	sbox_enc_o,
			sbox_o	=>	sbox_enc_i
		);


	-- S-Box stage for encryption engine
	sbox_enc: tech_sbox_stage
		port map (
			rst		=> 	rst,
			clk		=>	clk,
			data_i	=>	sbox_enc_i,
			data_o	=>	sbox_enc_o,
			load_i	=>	sbld_i
		);


	-- subkey memory for encryption engine
	skm_enc: tech_subkey_memory
		port map (
			clk			=>	clk,
			key_sched_i	=>	skm_ks_enc_i,
			enc_dec_i	=>	skm_enc_i,
			enc_dec_o	=>	skm_enc_o
		);


	-- 128-bit key schedule
	key_sched:  key_schedule_128
		port map (
			rst			=> 	rst,
			clk			=>	clk,
			key_i		=>	key_i,
			key_o		=>	key_o,
			sbox_i		=>	sbox_ks_o,
			sbox_o		=>	sbox_ks_i,
			skm_enc_o	=>	skm_ks_enc_i,
			skm_dec_o	=>	open
		);


	-- S-Box stage for key schedule
	sbox_ks: tech_sbox_stage
		port map (
			rst		=> 	rst,
			clk		=>	clk,
			data_i	=>	sbox_ks_i,
			data_o	=>	sbox_ks_o,
			load_i	=>	sbld_i
		);


end behavioural;
