-- ============================================================================
--
-- Design unit      :   aux_funcs (auxiliary functions)
--
-- File Name        :   aux_funcs.vhd
--
-- Purpose          :   The package collects type declarations and auxiliary
--                      functions which are commonly used by encryption,
--                      decryption and key schedule
--
--
-- Depends on       :
--
--  - Package(s)    :   aes_definitions, aes_common, aes_column_ops,
--                      aes_row_ops
--
--  - Module(s)     :   -
--
--
-- 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            :   -
--
--
-- 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-14  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 work.aes_definitions.all;
use work.aes_common.all;
use work.aes_column_ops.all;
use work.aes_row_ops.all;


package aux_funcs is


	subtype slv256_t is std_logic_vector(255 downto 0);

	subtype slv32_t is std_logic_vector(31 downto 0);

	subtype slv3_t is std_logic_vector(2 downto 0);

	subtype slv4_t is std_logic_vector(3 downto 0);

	subtype slv5_t is std_logic_vector(4 downto 0);

	subtype slv13_t is std_logic_vector(12 downto 0);

	subtype slv19_t is std_logic_vector(18 downto 0);



	-- rotate left
	function rotl(val : std_logic_vector; pos : natural) return std_logic_vector;

	-- rotate right
	function rotr(val : std_logic_vector; pos : natural) return std_logic_vector;


	-- convert the row representation to 32-bit logic vector
	function row2slv(row : row_t) return slv32_t;


	-- convert 32-bit logic vector to row representation
	function slv2row(slv :  slv32_t) return row_t;


	-- convert the column representation to 32-bit logic vector
	function col2slv(col : column_t) return slv32_t;


	-- convert 32-bit logic vector to column representation
	function slv2col(slv :  slv32_t) return column_t;


end aux_funcs;


package body aux_funcs is


	-- rotate left
	function rotl(val : std_logic_vector; pos : natural) return std_logic_vector is
		variable v : std_logic_vector(val'high downto 0);
	begin
		v := val;
		return v(v'left - pos downto 0) & v(v'left downto v'left - pos + 1);
	end function;


	-- rotate right
	function rotr(val : std_logic_vector; pos : natural) return std_logic_vector is
		variable v : std_logic_vector(val'high downto 0);
	begin
		v := val;
		return v(pos - 1 downto 0) & v(v'left downto pos);
	end function;


	-- convert the row representation to 32-bit logic vector
	function row2slv(row : row_t) return slv32_t is
		variable v : slv32_t;
	begin
		v := row(0) & row(1) & row(2) & row(3);
		return v;
	end function;


	-- convert 32-bit logic vector to row representation
	function slv2row(slv :  slv32_t) return row_t is
		variable row :  row_t;
	begin
		for i in row'range loop
			row(i) := slv(31 - 8*i downto 31-8*i - 7);
		end loop;

		return row;
	end function;


	-- convert the column representation to 32-bit logic vector
	function col2slv(col : column_t) return slv32_t is
		variable v : slv32_t;
	begin
		v := col(0) & col(1) & col(2) & col(3);
		return v;
	end function;


	-- convert 32-bit logic vector to column representation
	function slv2col(slv :  slv32_t) return column_t is
		variable col :  column_t;
	begin
		for i in col'range loop
			col(i) := slv(31 - 8*i downto 31-8*i - 7);
		end loop;

		return col;
	end function;


end aux_funcs;
