如何在VHDL中将端口指定为字节数组

时间:2014-03-04 00:36:21

标签: arrays aes vhdl bus

好的家伙,对不起,如果这是一个已被问过的问题,因为我对VHDL逻辑设计有足够的新意,不知道如何定义一个特定的概念。

我要做的是在VHDL中实现AES-256算法以供FPGA使用。

我有一个名为:

的端口
entity rijndael is port
(
input : in std_logic_vector(255 downto 0)
subkey: in std_logic_vector(255 downto 0)
output: out std_logic_vector(255 downto 0)
);
end rijndael;

如何在架构中为{1}} AES算法的input进程指定array的每个字节作为subBytes()个字节值段?

3 个答案:

答案 0 :(得分:2)

从标准中看,AES中的字节值被组织成列和行,您基本上需要和索引系统来标识数组子范围,这些子范围指定输入的哪些8位与哪个行和列相关联。

如果你需要循环(如在生成循环中,来到这个硬件上)你可以使用多维数组并从输入数组子范围中分配它们,其中你有行和列索引。你可以使输入数组成为一个8位的数组,紧跟FIPS-197:

Input, State and Output Byte relationship, 128 bit block

您会发现FIPS中使用的符号系统与Rijndael提交的不同,您最好在任何可能在某些时候提供帮助的人使用通用参考系统。 FIPS似乎意味着你应该使用大端数组,而你已经将输入声明为小端。

我将展示一个分析,阐述和模拟的设计规范。 (不能保证它是正确的,已经很晚了,我有点饿了。)

library ieee;
use ieee.std_logic_1164.all;

entity State is
    port (
        input:      in      std_logic_vector (0 to 255);
        output:     out     std_logic_vector (0 to 255)
    );

end entity;

architecture foo of State is

    subtype in0  is natural range   0 to   7;
    subtype in1  is natural range   8 to  15;
    subtype in2  is natural range  16 to  23;
    subtype in3  is natural range  24 to  31;
    subtype in4  is natural range  32 to  39;
    subtype in5  is natural range  40 to  47;
    subtype in6  is natural range  48 to  55;
    subtype in7  is natural range  56 to  63;
    subtype in8  is natural range  64 to  71;
    subtype in9  is natural range  72 to  79;
    subtype in10 is natural range  80 to  87;
    subtype in11 is natural range  88 to  95;
    subtype in12 is natural range  96 to 103;
    subtype in13 is natural range 104 to 111;
    subtype in14 is natural range 112 to 119;
    subtype in15 is natural range 120 to 127;
    subtype in16 is natural range 128 to 135;
    subtype in17 is natural range 136 to 143;
    subtype in18 is natural range 144 to 151;
    subtype in19 is natural range 152 to 159;
    subtype in20 is natural range 160 to 167;
    subtype in21 is natural range 168 to 175;
    subtype in22 is natural range 176 to 183;
    subtype in23 is natural range 184 to 191;
    subtype in24 is natural range 192 to 199;
    subtype in25 is natural range 200 to 207;
    subtype in26 is natural range 208 to 215;
    subtype in27 is natural range 216 to 223;
    subtype in28 is natural range 224 to 231;
    subtype in29 is natural range 232 to 239;
    subtype in30 is natural range 240 to 247;
    subtype in31 is natural range 248 to 255;

    type state_array is array   -- (row, col) of 8 bits
         (natural range 0 to 3, natural range 0 to 7)
                         of std_logic_vector(0 to 7); 

    signal S:   state_array;

begin 

    S <= state_array'( 
              ( input(in0),  input(in4),  input(in8),  input(in12),
                input(in16), input(in20), input(in24), input(in28) ),
              ( input(in1),  input(in5),  input(in9),  input(in13),
                input(in17), input(in21), input(in25), input(in29) ),
              ( input(in2),  input(in6),  input(in10), input(in14), 
                input(in18), input(in22), input(in26), input(in30) ),
              ( input(in3),  input(in7),  input(in11), input(in15),
                input(in19), input(in23), input(in27), input(in31) )
         );

    output <= S(0,0) & S(1,0) & S(2,0) & S(3,0) &  -- columns on side
              S(0,1) & S(1,1) & S(2,1) & S(3,1) &
              S(0,2) & S(1,2) & S(2,2) & S(3,2) &
              S(0,3) & S(1,3) & S(2,3) & S(3,3) &
              S(0,4) & S(1,4) & S(2,4) & S(3,4) &
              S(0,5) & S(1,5) & S(2,5) & S(3,5) &
              S(0,6) & S(1,6) & S(2,6) & S(3,6) &
              S(0,7) & S(1,7) & S(2,7) & S(3,7) ;

end architecture;

这为您提供了字节索引,因此您可以使用生成语句并根据状态(显示S)进行字节转换以进行转换。您当然可以直接省去输入切片的子类型声明和范围。

答案 1 :(得分:1)

以下是我在实施AES-128时的定义:

constant KEY_LENGTH: integer := 128;
constant BLOCK_LENGTH: integer := 128;

subtype key_type is std_logic_vector(KEY_LENGTH-1 downto 0);
type key_array_type is array (natural range<>) of key_type;
subtype word_type is std_logic_vector(31 downto 0);
subtype byte_type is std_logic_vector(7 downto 0);
type state_type is array (0 to 3, 0 to 3) of std_logic_vector(7 downto 0);
type state_array_type is array (natural range<>) of state_type;
type column_type is array (0 to 3) of std_logic_vector(7 downto 0);
type column_array_type is array (natural range<>) of column_type;

这是公共界面:

function encrypt(
    plain_text: std_logic_vector(BLOCK_LENGTH-1 downto 0);
    cypher_key: in key_type
) return std_logic_vector;

在这里你可以看到一些私人方法。请注意,主要处理方法接受一个对象'state_type'并返回另一个值,也是state_type:

function shift_rows(state_in: state_type) return state_type;
function mix_columns(state_in: state_type) return state_type;
function add_round_key(state: state_type; round_key: key_type) return state_type;
function mix_column(column_in: column_type) return column_type;
function expand_key(cypher_key: key_type) return column_array_type;
function round_key(expanded_key: column_array_type; round_number: integer) return key_type;

我发现声明一些函数可以转换为自定义类型和std_logic_vector是有用的:

function vector_from_state(state: state_type) return std_logic_vector;
function state_from_vector(vector: std_logic_vector(127 downto 0)) return state_type;
function vector_from_column(column: column_type) return std_logic_vector;
function state_from_columns(columns: column_array_type) return state_type;
function vector_from_columns(columns: column_array_type) return std_logic_vector;
function columns_from_state(state: state_type) return column_array_type;

如果有人发现它有用,我可以根据要求将整个代码上传到GitHub。

答案 2 :(得分:0)

一个字节是8位;所以,std_logic_vector(7 downto 0)是正确的。 std_logic_vectorstd_logic的数组 - 每个std_logic可以代表一个数字位。