//////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////
|
////
|
////
|
////
|
////
|
//// AES CORE BLOCK
|
//// AES CORE BLOCK
|
////
|
////
|
////
|
////
|
////
|
////
|
//// This file is part of the APB to I2C project
|
//// This file is part of the APB to I2C project
|
////
|
////
|
//// http://www.opencores.org/cores/apbi2c/
|
//// http://www.opencores.org/cores/apbi2c/
|
////
|
////
|
////
|
////
|
////
|
////
|
//// Description
|
//// Description
|
////
|
////
|
//// Implementation of APB IP core according to
|
//// Implementation of APB IP core according to
|
////
|
////
|
//// aes128_spec IP core specification document.
|
//// aes128_spec IP core specification document.
|
////
|
////
|
////
|
////
|
////
|
////
|
//// To Do: Things are right here but always all block can suffer changes
|
//// To Do: Things are right here but always all block can suffer changes
|
////
|
////
|
////
|
////
|
////
|
////
|
////
|
////
|
////
|
////
|
//// Author(s): - Felipe Fernandes Da Costa, fefe2560@gmail.com
|
//// Author(s): - Felipe Fernandes Da Costa, fefe2560@gmail.com
|
//// Julio Cesar
|
//// Julio Cesar
|
////
|
////
|
/////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////
|
////
|
////
|
////
|
////
|
//// Copyright (C) 2009 Authors and OPENCORES.ORG
|
//// Copyright (C) 2009 Authors and OPENCORES.ORG
|
////
|
////
|
////
|
////
|
////
|
////
|
//// This source file may be used and distributed without
|
//// This source file may be used and distributed without
|
////
|
////
|
//// restriction provided that this copyright statement is not
|
//// restriction provided that this copyright statement is not
|
////
|
////
|
//// removed from the file and that any derivative work contains
|
//// removed from the file and that any derivative work contains
|
//// the original copyright notice and the associated disclaimer.
|
//// the original copyright notice and the associated disclaimer.
|
////
|
////
|
////
|
////
|
//// This source file is free software; you can redistribute it
|
//// This source file is free software; you can redistribute it
|
////
|
////
|
//// and/or modify it under the terms of the GNU Lesser General
|
//// and/or modify it under the terms of the GNU Lesser General
|
////
|
////
|
//// Public License as published by the Free Software Foundation;
|
//// Public License as published by the Free Software Foundation;
|
//// either version 2.1 of the License, or (at your option) any
|
//// either version 2.1 of the License, or (at your option) any
|
////
|
////
|
//// later version.
|
//// later version.
|
////
|
////
|
////
|
////
|
////
|
////
|
//// This source is distributed in the hope that it will be
|
//// This source is distributed in the hope that it will be
|
////
|
////
|
//// useful, but WITHOUT ANY WARRANTY; without even the implied
|
//// useful, but WITHOUT ANY WARRANTY; without even the implied
|
////
|
////
|
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
////
|
////
|
//// PURPOSE. See the GNU Lesser General Public License for more
|
//// PURPOSE. See the GNU Lesser General Public License for more
|
//// details.
|
//// details.
|
////
|
////
|
////
|
////
|
////
|
////
|
//// You should have received a copy of the GNU Lesser General
|
//// You should have received a copy of the GNU Lesser General
|
////
|
////
|
//// Public License along with this source; if not, download it
|
//// Public License along with this source; if not, download it
|
////
|
////
|
//// from http://www.opencores.org/lgpl.shtml
|
//// from http://www.opencores.org/lgpl.shtml
|
////
|
////
|
////
|
////
|
///////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////
|
module datapath
|
module datapath
|
(
|
(
|
// OUTPUTS
|
// OUTPUTS
|
output [31:0] col_bus,
|
output [31:0] col_bus,
|
output [31:0] key_bus,
|
output [31:0] key_bus,
|
output [31:0] iv_bus,
|
output [31:0] iv_bus,
|
output end_aes,
|
output end_aes,
|
// INPUTS
|
// INPUTS
|
input [31:0] bus_in,
|
input [31:0] bus_in,
|
input [ 1:0] data_type,
|
input [ 1:0] data_type,
|
input [ 1:0] rk_sel,
|
input [ 1:0] rk_sel,
|
input [ 1:0] key_out_sel,
|
input [ 1:0] key_out_sel,
|
input [ 3:0] round,
|
input [ 3:0] round,
|
input [ 2:0] sbox_sel,
|
input [ 2:0] sbox_sel,
|
input [ 3:0] iv_en,
|
input [ 3:0] iv_en,
|
input [ 3:0] iv_sel_rd,
|
input [ 3:0] iv_sel_rd,
|
input [ 3:0] col_en_host,
|
input [ 3:0] col_en_host,
|
input [ 3:0] col_en_cnt_unit,
|
input [ 3:0] col_en_cnt_unit,
|
input [ 3:0] key_host_en,
|
input [ 3:0] key_host_en,
|
input [ 3:0] key_en,
|
input [ 3:0] key_en,
|
input [ 1:0] key_sel_rd,
|
input [ 1:0] key_sel_rd,
|
input [ 1:0] col_sel,
|
input [ 1:0] col_sel,
|
input [ 1:0] col_sel_host,
|
input [ 1:0] col_sel_host,
|
input end_comp,
|
input end_comp,
|
input key_sel,
|
input key_sel,
|
input key_init,
|
input key_init,
|
input bypass_rk,
|
input bypass_rk,
|
input bypass_key_en,
|
input bypass_key_en,
|
input first_block,
|
input first_block,
|
input last_round,
|
input last_round,
|
input iv_cnt_en,
|
input iv_cnt_en,
|
input iv_cnt_sel,
|
input iv_cnt_sel,
|
input enc_dec,
|
input enc_dec,
|
input mode_ctr,
|
input mode_ctr,
|
input mode_cbc,
|
input mode_cbc,
|
input key_gen,
|
input key_gen,
|
input key_derivation_en,
|
input key_derivation_en,
|
input rst_n,
|
input rst_n,
|
input clk
|
input clk
|
);
|
);
|
|
|
//`include "include/control_unit_params.vh"
|
//`include "include/control_unit_params.vh"
|
//=============================================================================
|
//=============================================================================
|
// SBOX SEL
|
// SBOX SEL
|
//=============================================================================
|
//=============================================================================
|
localparam COL_0 = 3'b000;
|
localparam COL_0 = 3'b000;
|
localparam COL_1 = 3'b001;
|
localparam COL_1 = 3'b001;
|
localparam COL_2 = 3'b010;
|
localparam COL_2 = 3'b010;
|
localparam COL_3 = 3'b011;
|
localparam COL_3 = 3'b011;
|
localparam G_FUNCTION = 3'b100;
|
localparam G_FUNCTION = 3'b100;
|
|
|
//=============================================================================
|
//=============================================================================
|
// RK_SEL
|
// RK_SEL
|
//=============================================================================
|
//=============================================================================
|
localparam COL = 2'b00;
|
localparam COL = 2'b00;
|
localparam MIXCOL_IN = 2'b01;
|
localparam MIXCOL_IN = 2'b01;
|
localparam MIXCOL_OUT = 2'b10;
|
localparam MIXCOL_OUT = 2'b10;
|
|
|
//=============================================================================
|
//=============================================================================
|
// KEY_OUT_SEL
|
// KEY_OUT_SEL
|
//=============================================================================
|
//=============================================================================
|
localparam KEY_0 = 2'b00;
|
localparam KEY_0 = 2'b00;
|
localparam KEY_1 = 2'b01;
|
localparam KEY_1 = 2'b01;
|
localparam KEY_2 = 2'b10;
|
localparam KEY_2 = 2'b10;
|
localparam KEY_3 = 2'b11;
|
localparam KEY_3 = 2'b11;
|
|
|
//=============================================================================
|
//=============================================================================
|
// COL_SEL
|
// COL_SEL
|
//=============================================================================
|
//=============================================================================
|
localparam SHIFT_ROWS = 2'b00;
|
localparam SHIFT_ROWS = 2'b00;
|
localparam ADD_RK_OUT = 2'b01;
|
localparam ADD_RK_OUT = 2'b01;
|
localparam INPUT = 2'b10;
|
localparam INPUT = 2'b10;
|
|
|
//=============================================================================
|
//=============================================================================
|
// KEY_SEL
|
// KEY_SEL
|
//=============================================================================
|
//=============================================================================
|
localparam KEY_HOST = 1'b0;
|
localparam KEY_HOST = 1'b0;
|
localparam KEY_OUT = 1'b1;
|
localparam KEY_OUT = 1'b1;
|
|
|
//=============================================================================
|
//=============================================================================
|
// KEY_EN
|
// KEY_EN
|
//=============================================================================
|
//=============================================================================
|
localparam KEY_DIS = 4'b0000;
|
localparam KEY_DIS = 4'b0000;
|
localparam EN_KEY_0 = 4'b0001;
|
localparam EN_KEY_0 = 4'b0001;
|
localparam EN_KEY_1 = 4'b0010;
|
localparam EN_KEY_1 = 4'b0010;
|
localparam EN_KEY_2 = 4'b0100;
|
localparam EN_KEY_2 = 4'b0100;
|
localparam EN_KEY_3 = 4'b1000;
|
localparam EN_KEY_3 = 4'b1000;
|
localparam KEY_ALL = 4'b1111;
|
localparam KEY_ALL = 4'b1111;
|
|
|
//=============================================================================
|
//=============================================================================
|
// COL_EN
|
// COL_EN
|
//=============================================================================
|
//=============================================================================
|
localparam COL_DIS = 4'b0000;
|
localparam COL_DIS = 4'b0000;
|
localparam EN_COL_0 = 4'b0001;
|
localparam EN_COL_0 = 4'b0001;
|
localparam EN_COL_1 = 4'b0010;
|
localparam EN_COL_1 = 4'b0010;
|
localparam EN_COL_2 = 4'b0100;
|
localparam EN_COL_2 = 4'b0100;
|
localparam EN_COL_3 = 4'b1000;
|
localparam EN_COL_3 = 4'b1000;
|
localparam COL_ALL = 4'b1111;
|
localparam COL_ALL = 4'b1111;
|
|
|
//=============================================================================
|
//=============================================================================
|
// IV_CNT_SEL
|
// IV_CNT_SEL
|
//=============================================================================
|
//=============================================================================
|
localparam IV_CNT = 1'b1;
|
localparam IV_CNT = 1'b1;
|
localparam IV_BUS = 1'b0;
|
localparam IV_BUS = 1'b0;
|
|
|
//=============================================================================
|
//=============================================================================
|
// ENABLES
|
// ENABLES
|
//=============================================================================
|
//=============================================================================
|
localparam ENABLE = 1'b1;
|
localparam ENABLE = 1'b1;
|
localparam DISABLE = 1'b0;
|
localparam DISABLE = 1'b0;
|
|
|
reg [31 : 0] col [0:3];
|
reg [31 : 0] col [0:3];
|
reg [31 : 0] key [0:3];
|
reg [31 : 0] key [0:3];
|
reg [31 : 0] key_host[0:3];
|
reg [31 : 0] key_host[0:3];
|
reg [31 : 0] bkp [0:3];
|
reg [31 : 0] bkp [0:3];
|
reg [31 : 0] bkp_1 [0:3];
|
reg [31 : 0] bkp_1 [0:3];
|
reg [31 : 0] iv [0:3];
|
reg [31 : 0] iv [0:3];
|
|
|
reg [127 : 0] col_in;
|
reg [127 : 0] col_in;
|
reg [ 31 : 0] data_in;
|
reg [ 31 : 0] data_in;
|
reg [ 31 : 0] add_rd_key_in;
|
reg [ 31 : 0] add_rd_key_in;
|
reg [ 31 : 0] sbox_input;
|
reg [ 31 : 0] sbox_input;
|
reg [ 31 : 0] key_mux_out;
|
reg [ 31 : 0] key_mux_out;
|
reg [ 31 : 0] iv_mux_out;
|
reg [ 31 : 0] iv_mux_out;
|
reg [ 31 : 0] bkp_mux_out;
|
reg [ 31 : 0] bkp_mux_out;
|
|
|
wire [127 : 0] key_in, key_out;
|
wire [127 : 0] key_in, key_out;
|
wire [127 : 0] sr_input;
|
wire [127 : 0] sr_input;
|
wire [127 : 0] sr_enc, sr_dec;
|
wire [127 : 0] sr_enc, sr_dec;
|
wire [ 31 : 0] add_rk_out;
|
wire [ 31 : 0] add_rk_out;
|
wire [ 31 : 0] sbox_out_enc;
|
wire [ 31 : 0] sbox_out_enc;
|
wire [ 31 : 0] sbox_out_dec;
|
wire [ 31 : 0] sbox_out_dec;
|
wire [ 31 : 0] g_in;
|
wire [ 31 : 0] g_in;
|
wire [ 31 : 0] mix_out_enc;
|
wire [ 31 : 0] mix_out_enc;
|
wire [ 31 : 0] mix_out_dec;
|
wire [ 31 : 0] mix_out_dec;
|
wire [ 31 : 0] add_rd;
|
wire [ 31 : 0] add_rd;
|
wire [ 31 : 0] bus_swap;
|
wire [ 31 : 0] bus_swap;
|
wire [ 31 : 0] iv_bkp_mux;
|
wire [ 31 : 0] iv_bkp_mux;
|
wire [ 31 : 0] xor_input_bkp_iv;
|
wire [ 31 : 0] xor_input_bkp_iv;
|
wire [ 31 : 0] sr_input_0;
|
wire [ 31 : 0] sr_input_0;
|
wire [ 31 : 0] sr_input_3;
|
wire [ 31 : 0] sr_input_3;
|
wire [ 3 : 0] key_en_sel;
|
wire [ 3 : 0] key_en_sel;
|
wire [ 3 : 0] bkp_en;
|
wire [ 3 : 0] bkp_en;
|
wire [ 3 : 0] col_en;
|
wire [ 3 : 0] col_en;
|
wire [ 1 : 0] key_mux_sel;
|
wire [ 1 : 0] key_mux_sel;
|
wire [ 1 : 0] rk_sel_mux;
|
wire [ 1 : 0] rk_sel_mux;
|
wire [ 1 : 0] col_sel_w_bypass;
|
wire [ 1 : 0] col_sel_w_bypass;
|
wire [ 3 : 0] col_en_w_bypass;
|
wire [ 3 : 0] col_en_w_bypass;
|
wire rk_out_sel;
|
wire rk_out_sel;
|
wire add_rk_sel;
|
wire add_rk_sel;
|
wire key_sel_mux;
|
wire key_sel_mux;
|
wire key1_mux_cnt;
|
wire key1_mux_cnt;
|
wire enc_dec_sbox;
|
wire enc_dec_sbox;
|
|
|
reg [31 : 0] sbox_pp2;
|
reg [31 : 0] sbox_pp2;
|
reg [ 3 : 0] col_en_cnt_unit_pp1;
|
reg [ 3 : 0] col_en_cnt_unit_pp1;
|
reg [ 3 : 0] col_en_cnt_unit_pp2;
|
reg [ 3 : 0] col_en_cnt_unit_pp2;
|
reg [ 3 : 0] key_en_pp1;
|
reg [ 3 : 0] key_en_pp1;
|
reg [ 3 : 0] round_pp1;
|
reg [ 3 : 0] round_pp1;
|
reg [ 1 : 0] col_sel_pp1;
|
reg [ 1 : 0] col_sel_pp1;
|
reg [ 1 : 0] col_sel_pp2;
|
reg [ 1 : 0] col_sel_pp2;
|
reg [ 1 : 0] key_out_sel_pp1;
|
reg [ 1 : 0] key_out_sel_pp1;
|
reg [ 1 : 0] key_out_sel_pp2;
|
reg [ 1 : 0] key_out_sel_pp2;
|
reg [ 1 : 0] rk_sel_pp1;
|
reg [ 1 : 0] rk_sel_pp1;
|
reg [ 1 : 0] rk_sel_pp2;
|
reg [ 1 : 0] rk_sel_pp2;
|
reg key_sel_pp1;
|
reg key_sel_pp1;
|
reg rk_out_sel_pp1, rk_out_sel_pp2;
|
reg rk_out_sel_pp1, rk_out_sel_pp2;
|
reg last_round_pp1, last_round_pp2;
|
reg last_round_pp1, last_round_pp2;
|
//reg end_aes_pp2,end_aes_pp1;//end_aes_pp2;
|
//reg end_aes_pp2,end_aes_pp1;//end_aes_pp2;
|
|
|
assign key_bus = key_mux_out;
|
assign key_bus = key_mux_out;
|
assign iv_bus = iv_mux_out;
|
assign iv_bus = iv_mux_out;
|
|
|
// Input Swap Unit
|
// Input Swap Unit
|
data_swap SWAP_IN
|
data_swap SWAP_IN
|
(
|
(
|
.data_swap( bus_swap ),
|
.data_swap( bus_swap ),
|
.data_in ( bus_in ),
|
.data_in ( bus_in ),
|
.swap_type( data_type )
|
.swap_type( data_type )
|
);
|
);
|
|
|
// Output Swap Unit
|
// Output Swap Unit
|
data_swap SWAP_OUT
|
data_swap SWAP_OUT
|
(
|
(
|
.data_swap( col_bus ),
|
.data_swap( col_bus ),
|
.data_in ( sbox_input ),
|
.data_in ( sbox_input ),
|
.swap_type( data_type )
|
.swap_type( data_type )
|
);
|
);
|
|
|
// IV and BKP Muxs
|
// IV and BKP Muxs
|
always@(iv_mux_out or bkp_mux_out or col_en or iv_sel_rd or iv[0] or iv[1] or iv[2] or iv[3] or bkp[0] or bkp[1] or bkp[2] or bkp[3])
|
always@(iv_mux_out or bkp_mux_out or col_en or iv_sel_rd or iv[0] or iv[1] or iv[2] or iv[3] or bkp[0] or bkp[1] or bkp[2] or bkp[3])
|
begin: IV_BKP_MUX
|
begin: IV_BKP_MUX
|
integer i;
|
integer i;
|
iv_mux_out = {32{1'b0}};
|
iv_mux_out = {32{1'b0}};
|
bkp_mux_out = {32{1'b0}};
|
bkp_mux_out = {32{1'b0}};
|
for(i = 0; i < 4; i = i + 1)
|
for(i = 0; i < 4; i = i + 1)
|
begin:IVBKP
|
begin:IVBKP
|
if(col_en[i] | iv_sel_rd[i])
|
if(col_en[i] | iv_sel_rd[i])
|
begin
|
begin
|
iv_mux_out = iv[i];
|
iv_mux_out = iv[i];
|
bkp_mux_out = bkp[i];
|
bkp_mux_out = bkp[i];
|
end
|
end
|
end
|
end
|
end
|
end
|
|
|
assign iv_bkp_mux = (first_block && !mode_ctr) ? iv_mux_out : bkp_mux_out;
|
assign iv_bkp_mux = (first_block && !mode_ctr) ? iv_mux_out : bkp_mux_out;
|
|
|
assign xor_input_bkp_iv = ((enc_dec && !mode_ctr) ? bus_swap : add_rk_out) ^ iv_bkp_mux;
|
assign xor_input_bkp_iv = ((enc_dec && !mode_ctr) ? bus_swap : add_rk_out) ^ iv_bkp_mux;
|
|
|
always @(*)
|
always @(*)
|
begin
|
begin
|
data_in = {32{1'b0}};
|
data_in = {32{1'b0}};
|
case(1'b1)
|
case(1'b1)
|
mode_cbc:
|
mode_cbc:
|
data_in = (enc_dec || last_round) ? xor_input_bkp_iv : bus_swap;
|
data_in = (enc_dec || last_round) ? xor_input_bkp_iv : bus_swap;
|
mode_ctr:
|
mode_ctr:
|
data_in = (last_round) ? xor_input_bkp_iv : iv_mux_out;
|
data_in = (last_round) ? xor_input_bkp_iv : iv_mux_out;
|
default:
|
default:
|
data_in = bus_swap;
|
data_in = bus_swap;
|
endcase
|
endcase
|
end
|
end
|
|
|
assign bkp_en = ( {4{ mode_cbc && last_round && enc_dec}} & col_en_cnt_unit_pp2) |
|
assign bkp_en = ( {4{ mode_cbc && last_round && enc_dec}} & col_en_cnt_unit_pp2) |
|
( {4{(mode_cbc && !enc_dec) || mode_ctr}} & col_en_host );
|
( {4{(mode_cbc && !enc_dec) || mode_ctr}} & col_en_host );
|
|
|
|
|
// IV and BKP Registers
|
// IV and BKP Registers
|
generate
|
generate
|
genvar l;
|
genvar l;
|
|
|
for(l = 0; l < 4;l=l+1)
|
for(l = 0; l < 4;l=l+1)
|
begin:IV_BKP_REGISTERS
|
begin:IV_BKP_REGISTERS
|
always @(posedge clk, negedge rst_n)
|
always @(posedge clk, negedge rst_n)
|
begin
|
begin
|
if(!rst_n)
|
if(!rst_n)
|
begin
|
begin
|
iv[l] <= {32{1'b0}};
|
iv[l] <= {32{1'b0}};
|
bkp[l] <= {32{1'b0}};
|
bkp[l] <= {32{1'b0}};
|
bkp_1[l] <= {32{1'b0}};
|
bkp_1[l] <= {32{1'b0}};
|
end
|
end
|
else
|
else
|
begin
|
begin
|
if(l == 3)
|
if(l == 3)
|
begin
|
begin
|
if(iv_en[l] || iv_cnt_en)
|
if(iv_en[l] || iv_cnt_en)
|
begin
|
begin
|
/*
|
|
if(mode_ctr)
|
|
iv[l] <= (iv_cnt_sel) ? iv[l] + 1'b1 : bus_in;
|
|
|
|
else
|
if(mode_ctr)
|
iv[l] <= (iv_cnt_sel) ? iv[l] : bus_in;
|
iv[l] <= (iv_cnt_sel) ? iv[l] + 1'b1 : bus_in;
|
*/
|
|
|
|
|
else
|
iv[l] <= (iv_cnt_sel) ? iv[l] : bus_in;
|
iv[l] <= (iv_cnt_sel) ? iv[l] : bus_in;
|
|
|
|
|
|
//iv[l] <= (iv_cnt_sel) ? iv[l] : bus_in;
|
end
|
end
|
end
|
end
|
else
|
else
|
begin
|
begin
|
if(iv_en[l])
|
if(iv_en[l])
|
iv[l] <= bus_in;
|
iv[l] <= bus_in;
|
end
|
end
|
|
|
if(bkp_en[l])
|
if(bkp_en[l])
|
//bkp[l] <= (mode_ctr) ? bus_swap : ((mode_cbc && enc_dec) ? col_in : bkp_1[l]);
|
//bkp[l] <= (mode_ctr) ? bus_swap : ((mode_cbc && enc_dec) ? col_in : bkp_1[l]);
|
bkp[l] <= (mode_ctr) ? bus_swap : ((mode_cbc && enc_dec)? col_in[32*(l + 1) - 1 : 32*l] : bkp_1[l]);
|
bkp[l] <= (mode_ctr) ? bus_swap : ((mode_cbc && enc_dec)? col_in[32*(l + 1) - 1 : 32*l] : bkp_1[l]);
|
|
|
if(bkp_en[l])
|
if(bkp_en[l])
|
bkp_1[l] <= col_in[32*(l + 1) - 1 : 32*l];
|
bkp_1[l] <= col_in[32*(l + 1) - 1 : 32*l];
|
end
|
end
|
end
|
end
|
|
|
end
|
end
|
endgenerate
|
endgenerate
|
|
|
assign col_sel_w_bypass = (bypass_rk) ? col_sel : col_sel_pp2;
|
assign col_sel_w_bypass = (bypass_rk) ? col_sel : col_sel_pp2;
|
|
|
// Columns Input Multiplexors
|
// Columns Input Multiplexors
|
always @(*)
|
always @(*)
|
begin
|
begin
|
col_in = {128{1'b0}};
|
col_in = {128{1'b0}};
|
case(col_sel_w_bypass)
|
case(col_sel_w_bypass)
|
SHIFT_ROWS:
|
SHIFT_ROWS:
|
col_in = (enc_dec) ? sr_enc : sr_dec;
|
col_in = (enc_dec) ? sr_enc : sr_dec;
|
ADD_RK_OUT:
|
ADD_RK_OUT:
|
col_in = {4{add_rk_out}};
|
col_in = {4{add_rk_out}};
|
INPUT:
|
INPUT:
|
col_in = {4{data_in}};
|
col_in = {4{data_in}};
|
endcase
|
endcase
|
end
|
end
|
|
|
assign col_en_w_bypass = (bypass_rk) ? col_en_cnt_unit : col_en_cnt_unit_pp2;
|
assign col_en_w_bypass = (bypass_rk) ? col_en_cnt_unit : col_en_cnt_unit_pp2;
|
assign col_en = col_en_host | col_en_w_bypass;
|
assign col_en = col_en_host | col_en_w_bypass;
|
|
|
// Columns Definition
|
// Columns Definition
|
generate
|
generate
|
genvar i;
|
genvar i;
|
for(i = 0; i < 4; i = i + 1)
|
for(i = 0; i < 4; i = i + 1)
|
begin:CD
|
begin:CD
|
always @(posedge clk, negedge rst_n)
|
always @(posedge clk, negedge rst_n)
|
begin
|
begin
|
if(!rst_n)
|
if(!rst_n)
|
col[3 - i] <= {32{1'b0}};
|
col[3 - i] <= {32{1'b0}};
|
else
|
else
|
if(col_en[3 - i])
|
if(col_en[3 - i])
|
col[3 - i] <= col_in[32*(i + 1) - 1 : 32*i];
|
col[3 - i] <= col_in[32*(i + 1) - 1 : 32*i];
|
end
|
end
|
end
|
end
|
endgenerate
|
endgenerate
|
|
|
// Shift Rows Operation
|
// Shift Rows Operation
|
assign sr_input_3 = (enc_dec) ? add_rk_out : col[3];
|
assign sr_input_3 = (enc_dec) ? add_rk_out : col[3];
|
assign sr_input_0 = (enc_dec) ? col[0] : add_rk_out;
|
assign sr_input_0 = (enc_dec) ? col[0] : add_rk_out;
|
assign sr_input = {sr_input_0, col[1], col[2], sr_input_3};
|
assign sr_input = {sr_input_0, col[1], col[2], sr_input_3};
|
|
|
shift_rows SHIFT_ROW
|
shift_rows SHIFT_ROW
|
(
|
(
|
.data_out_enc ( sr_enc ),
|
.data_out_enc ( sr_enc ),
|
.data_out_dec ( sr_dec ),
|
.data_out_dec ( sr_dec ),
|
.data_in ( sr_input )
|
.data_in ( sr_input )
|
);
|
);
|
|
|
//SBOX Input Multiplexor
|
//SBOX Input Multiplexor
|
always @(sbox_input or sbox_sel or col_sel_host or col[0] or col[1] or col[2] or col[3] or g_in)
|
always @(sbox_input or sbox_sel or col_sel_host or col[0] or col[1] or col[2] or col[3] or g_in)
|
begin
|
begin
|
sbox_input = {32{1'b0}};
|
sbox_input = {32{1'b0}};
|
case(sbox_sel | col_sel_host)
|
case(sbox_sel | col_sel_host)
|
COL_0:
|
COL_0:
|
sbox_input = col[0];
|
sbox_input = col[0];
|
COL_1:
|
COL_1:
|
sbox_input = col[1];
|
sbox_input = col[1];
|
COL_2:
|
COL_2:
|
sbox_input = col[2];
|
sbox_input = col[2];
|
COL_3:
|
COL_3:
|
sbox_input = col[3];
|
sbox_input = col[3];
|
G_FUNCTION:
|
G_FUNCTION:
|
sbox_input = g_in;
|
sbox_input = g_in;
|
endcase
|
endcase
|
end
|
end
|
|
|
// 32 bits SBOX
|
// 32 bits SBOX
|
assign enc_dec_sbox = enc_dec | key_gen;
|
assign enc_dec_sbox = enc_dec | key_gen;
|
sBox SBOX
|
sBox SBOX
|
(
|
(
|
.sbox_out_enc ( sbox_out_enc ),
|
.sbox_out_enc ( sbox_out_enc ),
|
.sbox_out_dec ( sbox_out_dec ),
|
.sbox_out_dec ( sbox_out_dec ),
|
.sbox_in ( sbox_input ),
|
.sbox_in ( sbox_input ),
|
.enc_dec ( enc_dec_sbox ),
|
.enc_dec ( enc_dec_sbox ),
|
.clk ( clk )
|
.clk ( clk )
|
);
|
);
|
|
|
// Second stage of pipeline
|
// Second stage of pipeline
|
always @(posedge clk)
|
always @(posedge clk)
|
begin
|
begin
|
sbox_pp2 <= (enc_dec || mode_ctr) ? sbox_out_enc : sbox_out_dec ^ key_mux_out;
|
sbox_pp2 <= (enc_dec || mode_ctr) ? sbox_out_enc : sbox_out_dec ^ key_mux_out;
|
end
|
end
|
|
|
assign key_en_sel = (bypass_key_en) ? key_en : key_en_pp1;
|
assign key_en_sel = (bypass_key_en) ? key_en : key_en_pp1;
|
assign key_sel_mux = (bypass_key_en) ? key_sel : key_sel_pp1;
|
assign key_sel_mux = (bypass_key_en) ? key_sel : key_sel_pp1;
|
|
|
// Key registers
|
// Key registers
|
generate
|
generate
|
genvar j;
|
genvar j;
|
for(j = 0; j < 4; j = j + 1)
|
for(j = 0; j < 4; j = j + 1)
|
begin:KR
|
begin:KR
|
always @(posedge clk, negedge rst_n)
|
always @(posedge clk, negedge rst_n)
|
begin
|
begin
|
if(!rst_n)
|
if(!rst_n)
|
begin
|
begin
|
key_host[3 - j] <= {32{1'b0}};
|
key_host[3 - j] <= {32{1'b0}};
|
key[3 - j] <= {32{1'b0}};
|
key[3 - j] <= {32{1'b0}};
|
end
|
end
|
else
|
else
|
begin
|
begin
|
if(key_host_en[3 - j] || key_derivation_en)
|
if(key_host_en[3 - j] || key_derivation_en)
|
key_host[3 - j] <= (key_derivation_en) ? key[3 - j] : bus_in;
|
key_host[3 - j] <= (key_derivation_en) ? key[3 - j] : bus_in;
|
|
|
if(key_en_sel[3 - j] || key_init || key_host_en[3 - j])
|
if(key_en_sel[3 - j] || key_init || key_host_en[3 - j])
|
key[3 - j] <= (key_sel_mux) ? key_out[32*(j + 1) - 1 : 32*j] : ( (key_host_en[3 - j]) ? bus_in : key_host[3 - j] );
|
key[3 - j] <= (key_sel_mux) ? key_out[32*(j + 1) - 1 : 32*j] : ( (key_host_en[3 - j]) ? bus_in : key_host[3 - j] );
|
end
|
end
|
end
|
end
|
end
|
end
|
endgenerate
|
endgenerate
|
|
|
assign key_in = {key[0], key[1], key[2], key[3]};
|
assign key_in = {key[0], key[1], key[2], key[3]};
|
|
|
assign key1_mux_cnt = bypass_key_en & enc_dec;
|
assign key1_mux_cnt = bypass_key_en & enc_dec;
|
|
|
key_expander KEY_EXPANDER
|
key_expander KEY_EXPANDER
|
(
|
(
|
.key_out ( key_out ),
|
.key_out ( key_out ),
|
.g_in ( g_in ),
|
.g_in ( g_in ),
|
.g_out ( sbox_out_enc ),
|
.g_out ( sbox_out_enc ),
|
.key_in ( key_in ),
|
.key_in ( key_in ),
|
.round ( round_pp1 ),
|
.round ( round_pp1 ),
|
.add_w_out ( key1_mux_cnt ),
|
.add_w_out ( key1_mux_cnt ),
|
.enc_dec ( enc_dec | key_gen)
|
.enc_dec ( enc_dec | key_gen)
|
);
|
);
|
|
|
assign key_mux_sel = (bypass_key_en) ? key_out_sel : ( (enc_dec | mode_ctr) ? key_out_sel_pp2 : key_out_sel_pp1 );
|
assign key_mux_sel = (bypass_key_en) ? key_out_sel : ( (enc_dec | mode_ctr) ? key_out_sel_pp2 : key_out_sel_pp1 );
|
|
|
// Key Expander Mux
|
// Key Expander Mux
|
always @(key_mux_out or key_mux_sel or key_sel_rd or key[0] or key[1] or key[2] or key[3])
|
always @(key_mux_out or key_mux_sel or key_sel_rd or key[0] or key[1] or key[2] or key[3])
|
begin
|
begin
|
key_mux_out = {32{1'b0}};
|
key_mux_out = {32{1'b0}};
|
case(key_mux_sel | key_sel_rd)
|
case(key_mux_sel | key_sel_rd)
|
KEY_0:
|
KEY_0:
|
key_mux_out = key[0];
|
key_mux_out = key[0];
|
KEY_1:
|
KEY_1:
|
key_mux_out = key[1];
|
key_mux_out = key[1];
|
KEY_2:
|
KEY_2:
|
key_mux_out = key[2];
|
key_mux_out = key[2];
|
KEY_3:
|
KEY_3:
|
key_mux_out = key[3];
|
key_mux_out = key[3];
|
endcase
|
endcase
|
end
|
end
|
|
|
mix_columns MIX_COL
|
mix_columns MIX_COL
|
(
|
(
|
.mix_out_enc ( mix_out_enc ),
|
.mix_out_enc ( mix_out_enc ),
|
.mix_out_dec ( mix_out_dec ),
|
.mix_out_dec ( mix_out_dec ),
|
.mix_in ( sbox_pp2 )
|
.mix_in ( sbox_pp2 )
|
);
|
);
|
|
|
assign rk_sel_mux = (bypass_rk) ? rk_sel : rk_sel_pp2;
|
assign rk_sel_mux = (bypass_rk) ? rk_sel : rk_sel_pp2;
|
|
|
always @(*)
|
always @(*)
|
begin
|
begin
|
add_rd_key_in = {32{1'b0}};
|
add_rd_key_in = {32{1'b0}};
|
case(rk_sel_mux)
|
case(rk_sel_mux)
|
COL:
|
COL:
|
add_rd_key_in = sbox_input;
|
add_rd_key_in = sbox_input;
|
MIXCOL_IN:
|
MIXCOL_IN:
|
add_rd_key_in = sbox_pp2;
|
add_rd_key_in = sbox_pp2;
|
MIXCOL_OUT:
|
MIXCOL_OUT:
|
add_rd_key_in = mix_out_enc;
|
add_rd_key_in = mix_out_enc;
|
endcase
|
endcase
|
end
|
end
|
|
|
// Add Round Key
|
// Add Round Key
|
assign add_rd = add_rd_key_in ^ key_mux_out;
|
assign add_rd = add_rd_key_in ^ key_mux_out;
|
|
|
assign rk_out_sel = (enc_dec | mode_ctr | bypass_rk);
|
assign rk_out_sel = (enc_dec | mode_ctr | bypass_rk);
|
|
|
assign add_rk_sel = (bypass_rk) ? rk_out_sel : rk_out_sel_pp2;
|
assign add_rk_sel = (bypass_rk) ? rk_out_sel : rk_out_sel_pp2;
|
|
|
assign add_rk_out = (add_rk_sel) ? add_rd : (last_round_pp2 ? sbox_pp2 : mix_out_dec);
|
assign add_rk_out = (add_rk_sel) ? add_rd : (last_round_pp2 ? sbox_pp2 : mix_out_dec);
|
|
|
assign end_aes = end_comp;
|
assign end_aes = end_comp;
|
|
|
// Pipeline Registers for Control Signals
|
// Pipeline Registers for Control Signals
|
always @(posedge clk, negedge rst_n)
|
always @(posedge clk, negedge rst_n)
|
begin
|
begin
|
if(!rst_n)
|
if(!rst_n)
|
begin
|
begin
|
//end_aes_pp1 <= DISABLE;
|
//end_aes_pp1 <= DISABLE;
|
//end_aes_pp2 <= DISABLE;
|
//end_aes_pp2 <= DISABLE;
|
|
|
col_sel_pp1 <= INPUT;
|
col_sel_pp1 <= INPUT;
|
col_sel_pp2 <= INPUT;
|
col_sel_pp2 <= INPUT;
|
|
|
col_en_cnt_unit_pp1 <= COL_DIS;
|
col_en_cnt_unit_pp1 <= COL_DIS;
|
col_en_cnt_unit_pp2 <= COL_DIS;
|
col_en_cnt_unit_pp2 <= COL_DIS;
|
|
|
key_sel_pp1 <= KEY_HOST;
|
key_sel_pp1 <= KEY_HOST;
|
key_en_pp1 <= KEY_DIS;
|
key_en_pp1 <= KEY_DIS;
|
|
|
round_pp1 <= 4'b0000;
|
round_pp1 <= 4'b0000;
|
|
|
key_out_sel_pp1 <= KEY_0;
|
key_out_sel_pp1 <= KEY_0;
|
key_out_sel_pp2 <= KEY_0;
|
key_out_sel_pp2 <= KEY_0;
|
|
|
rk_sel_pp1 <= COL;
|
rk_sel_pp1 <= COL;
|
rk_sel_pp2 <= COL;
|
rk_sel_pp2 <= COL;
|
|
|
rk_out_sel_pp1 <= 1'b1;
|
rk_out_sel_pp1 <= 1'b1;
|
rk_out_sel_pp2 <= 1'b1;
|
rk_out_sel_pp2 <= 1'b1;
|
|
|
last_round_pp1 <= 1'b1;
|
last_round_pp1 <= 1'b1;
|
last_round_pp2 <= 1'b0;
|
last_round_pp2 <= 1'b0;
|
end
|
end
|
else
|
else
|
begin
|
begin
|
col_sel_pp1 <= col_sel;
|
col_sel_pp1 <= col_sel;
|
col_sel_pp2 <= col_sel_pp1;
|
col_sel_pp2 <= col_sel_pp1;
|
|
|
if(!bypass_rk)
|
if(!bypass_rk)
|
begin
|
begin
|
col_en_cnt_unit_pp1 <= col_en_cnt_unit;
|
col_en_cnt_unit_pp1 <= col_en_cnt_unit;
|
col_en_cnt_unit_pp2 <= col_en_cnt_unit_pp1;
|
col_en_cnt_unit_pp2 <= col_en_cnt_unit_pp1;
|
end
|
end
|
|
|
key_sel_pp1 <= key_sel;
|
key_sel_pp1 <= key_sel;
|
|
|
if(!bypass_key_en)
|
if(!bypass_key_en)
|
key_en_pp1 <= key_en;
|
key_en_pp1 <= key_en;
|
|
|
round_pp1 <= round;
|
round_pp1 <= round;
|
|
|
key_out_sel_pp1 <= key_out_sel;
|
key_out_sel_pp1 <= key_out_sel;
|
key_out_sel_pp2 <= key_out_sel_pp1;
|
key_out_sel_pp2 <= key_out_sel_pp1;
|
|
|
rk_sel_pp1 <= rk_sel;
|
rk_sel_pp1 <= rk_sel;
|
rk_sel_pp2 <= rk_sel_pp1;
|
rk_sel_pp2 <= rk_sel_pp1;
|
|
|
rk_out_sel_pp1 <= rk_out_sel;
|
rk_out_sel_pp1 <= rk_out_sel;
|
rk_out_sel_pp2 <= rk_out_sel_pp1;
|
rk_out_sel_pp2 <= rk_out_sel_pp1;
|
|
|
last_round_pp1 <= last_round;
|
last_round_pp1 <= last_round;
|
last_round_pp2 <= last_round_pp1;
|
last_round_pp2 <= last_round_pp1;
|
|
|
//end_aes_pp1 <= end_comp;
|
//end_aes_pp1 <= end_comp;
|
//end_aes_pp2 <= end_aes_pp1;
|
//end_aes_pp2 <= end_aes_pp1;
|
end
|
end
|
end
|
end
|
endmodule
|
endmodule
|
|
|