Line 1... |
Line 1... |
//////////////////////////////////////////////////////////////////////
|
//---------------------------------------------------------------------------------------
|
//// ////
|
//
|
//// AES top file ////
|
// AES core top module
|
//// ////
|
//
|
//// Description: ////
|
// Description:
|
//// AES top ////
|
// AES core top module with direct interface to key and data buses.
|
//// ////
|
//
|
//// To Do: ////
|
// To Do:
|
//// - done ////
|
// - done
|
//// ////
|
//
|
//// Author(s): ////
|
// Author(s):
|
//// - Luo Dongjun, dongjun_luo@hotmail.com ////
|
// - Luo Dongjun, dongjun_luo@hotmail.com
|
//// ////
|
//
|
//////////////////////////////////////////////////////////////////////
|
//---------------------------------------------------------------------------------------
|
|
|
// uncomment the following define to enable use of distributed RAM implementation
|
// uncomment the following define to enable use of distributed RAM implementation
|
// for XILINX FPGAs instead of block memory.
|
// for XILINX FPGAs instead of block memory.
|
|
// NOTE: when commenting the following define, core size is slightly smaller but maximum
|
|
// achievable clock frequency is also slightly lower.
|
`define XILINX 1
|
`define XILINX 1
|
|
|
module aes (
|
module aes (
|
clk,
|
clk, reset,
|
reset,
|
i_start, i_enable,
|
i_start,
|
i_ende, i_key,
|
i_enable,
|
i_key_mode, i_data,
|
i_ende,
|
i_data_valid, o_ready,
|
i_key,
|
o_data, o_data_valid,
|
i_key_mode,
|
|
i_data,
|
|
i_data_valid,
|
|
o_ready,
|
|
o_data,
|
|
o_data_valid,
|
|
o_key_ready
|
o_key_ready
|
);
|
);
|
|
|
input clk;
|
//---------------------------------------------------------------------------------------
|
input reset;
|
// module interfaces
|
input i_start;
|
input clk; // core global clock
|
input i_enable;
|
input reset; // core global async reset control
|
input [1:0] i_key_mode; // 0: 128; 1: 192; 2: 256
|
input i_start; // key expansion start pulse
|
|
input i_enable; // enable encryption / decryption core operation
|
|
input [1:0] i_key_mode; // key length: 0 => 128; 1 => 192; 2 => 256
|
input [255:0] i_key; // if key size is 128/192, upper bits are the inputs
|
input [255:0] i_key; // if key size is 128/192, upper bits are the inputs
|
input [127:0] i_data;
|
input [127:0] i_data; // plain/cipher text data input
|
input i_data_valid;
|
input i_data_valid; // data input valid
|
input i_ende; // 0: encryption; 1: decryption
|
input i_ende; // core mode of operation: 0 => encryption; 1 => decryption
|
output o_ready; // user shall not input data if IP is not ready
|
output o_ready; // indicates core is ready for new input data at the next clock cycle
|
output [127:0] o_data; // output data
|
output [127:0] o_data; // data output
|
output o_data_valid;
|
output o_data_valid; // data output valid
|
output o_key_ready; // key expansion procedure completes
|
output o_key_ready; // key expansion procedure done
|
|
|
|
//---------------------------------------------------------------------------------------
|
|
// module registers and signals
|
genvar i;
|
genvar i;
|
wire final_round;
|
wire final_round;
|
reg [3:0] max_round;
|
reg [3:0] max_round;
|
wire [127:0] en_sb_data,de_sb_data,sr_data,mc_data,imc_data,ark_data;
|
wire [127:0] en_sb_data,de_sb_data,sr_data,mc_data,imc_data,ark_data;
|
reg [127:0] sb_data,o_data,i_data_L;
|
reg [127:0] sb_data,o_data,i_data_L;
|
Line 62... |
Line 62... |
wire wr;
|
wire wr;
|
wire [4:0] wr_addr;
|
wire [4:0] wr_addr;
|
wire [63:0] wr_data;
|
wire [63:0] wr_data;
|
wire [127:0] imc_round_key,en_ark_data,de_ark_data,ark_data_final,ark_data_init;
|
wire [127:0] imc_round_key,en_ark_data,de_ark_data,ark_data_final,ark_data_init;
|
|
|
|
//---------------------------------------------------------------------------------------
|
|
// module implementation
|
assign final_round = sb_round_cnt3[3:0] == max_round[3:0];
|
assign final_round = sb_round_cnt3[3:0] == max_round[3:0];
|
//assign o_ready = ~sb_valid[1]; // if ready is asserted, user can input data for the same cycle
|
//assign o_ready = ~sb_valid[1]; // if ready is asserted, user can input data for the same cycle
|
assign o_ready = ~sb_valid[0]; // if ready is asserted, user can input data for the next cycle
|
assign o_ready = ~sb_valid[0]; // if ready is asserted, user can input data for the next cycle
|
|
|
// round count is Nr - 1
|
// round count is Nr - 1
|
Line 76... |
Line 78... |
2'b01: max_round[3:0] = 4'd12;
|
2'b01: max_round[3:0] = 4'd12;
|
default: max_round[3:0] = 4'd14;
|
default: max_round[3:0] = 4'd14;
|
endcase
|
endcase
|
end
|
end
|
|
|
/*****************************************************************************/
|
//---------------------------------------------------------------------------------------
|
// Sub Bytes
|
// Sub Bytes
|
//
|
//
|
//
|
//
|
generate
|
generate
|
for (i=0;i<16;i=i+1)
|
for (i=0;i<16;i=i+1)
|
Line 103... |
Line 105... |
sb_data[127:0] <= 128'b0;
|
sb_data[127:0] <= 128'b0;
|
else if (i_enable)
|
else if (i_enable)
|
sb_data[127:0] <= i_ende ? de_sb_data[127:0] : en_sb_data[127:0];
|
sb_data[127:0] <= i_ende ? de_sb_data[127:0] : en_sb_data[127:0];
|
end
|
end
|
|
|
/*****************************************************************************/
|
//---------------------------------------------------------------------------------------
|
// Shift Rows
|
// Shift Rows
|
//
|
//
|
//
|
//
|
wire [127:0] shrows, ishrows;
|
wire [127:0] shrows, ishrows;
|
|
|
shift_rows u_shrows (.si(sb_data[127:0]), .so(shrows));
|
shift_rows u_shrows (.si(sb_data[127:0]), .so(shrows));
|
inv_shift_rows u_ishrows (.si(sb_data[127:0]), .so(ishrows));
|
inv_shift_rows u_ishrows (.si(sb_data[127:0]), .so(ishrows));
|
|
|
assign sr_data[127:0] = i_ende ? ishrows : shrows;
|
assign sr_data[127:0] = i_ende ? ishrows : shrows;
|
|
|
/*****************************************************************************/
|
//---------------------------------------------------------------------------------------
|
// Mix Columns
|
// Mix Columns
|
//
|
//
|
//
|
//
|
mix_columns mxc_u (.in(sr_data), .out(mc_data));
|
mix_columns mxc_u (.in(sr_data), .out(mc_data));
|
|
|
Line 134... |
Line 136... |
i_data_valid_L <= i_data_valid;
|
i_data_valid_L <= i_data_valid;
|
i_data_L[127:0] <=i_data[127:0];
|
i_data_L[127:0] <=i_data[127:0];
|
end
|
end
|
end
|
end
|
|
|
/*****************************************************************************/
|
//---------------------------------------------------------------------------------------
|
// Inverse Mix Columns
|
// Inverse Mix Columns
|
//
|
//
|
//
|
//
|
inv_mix_columns imxc_u (.in(sr_data), .out(imc_data));
|
inv_mix_columns imxc_u (.in(sr_data), .out(imc_data));
|
|
|
/*****************************************************************************/
|
//---------------------------------------------------------------------------------------
|
// add round key for decryption
|
// add round key for decryption
|
//
|
//
|
inv_mix_columns imxk_u (.in(round_key), .out(imc_round_key));
|
inv_mix_columns imxk_u (.in(round_key), .out(imc_round_key));
|
|
|
assign ark_data_final[127:0] = sr_data[127:0] ^ round_key[127:0];
|
assign ark_data_final[127:0] = sr_data[127:0] ^ round_key[127:0];
|
Line 153... |
Line 155... |
assign de_ark_data[127:0] = imc_data[127:0] ^ imc_round_key[127:0];
|
assign de_ark_data[127:0] = imc_data[127:0] ^ imc_round_key[127:0];
|
assign ark_data[127:0] = i_data_valid_L ? ark_data_init[127:0] :
|
assign ark_data[127:0] = i_data_valid_L ? ark_data_init[127:0] :
|
(final_round ? ark_data_final[127:0] :
|
(final_round ? ark_data_final[127:0] :
|
(i_ende ? de_ark_data[127:0] : en_ark_data[127:0]));
|
(i_ende ? de_ark_data[127:0] : en_ark_data[127:0]));
|
|
|
/*****************************************************************************/
|
//---------------------------------------------------------------------------------------
|
// Data outputs after each round
|
// Data outputs after each round
|
//
|
//
|
always @ (posedge clk or posedge reset)
|
always @ (posedge clk or posedge reset)
|
begin
|
begin
|
if (reset)
|
if (reset)
|
o_data[127:0] <= 128'b0;
|
o_data[127:0] <= 128'b0;
|
else if (i_enable && (i_data_valid_L || sb_valid[2]))
|
else if (i_enable && (i_data_valid_L || sb_valid[2]))
|
o_data[127:0] <= ark_data[127:0];
|
o_data[127:0] <= ark_data[127:0];
|
end
|
end
|
|
|
/*****************************************************************************/
|
//---------------------------------------------------------------------------------------
|
// in sbox, we have 3 stages (sb_valid),
|
// in sbox, we have 3 stages (sb_valid),
|
// before the end of each round, we have another stage (round_valid)
|
// before the end of each round, we have another stage (round_valid)
|
//
|
//
|
always @ (posedge clk or posedge reset)
|
always @ (posedge clk or posedge reset)
|
begin
|
begin
|
Line 207... |
Line 209... |
if (sb_valid[0]) sb_round_cnt2[3:0] <= sb_round_cnt1[3:0];
|
if (sb_valid[0]) sb_round_cnt2[3:0] <= sb_round_cnt1[3:0];
|
if (sb_valid[1]) sb_round_cnt3[3:0] <= sb_round_cnt2[3:0];
|
if (sb_valid[1]) sb_round_cnt3[3:0] <= sb_round_cnt2[3:0];
|
end
|
end
|
end
|
end
|
|
|
/*****************************************************************************/
|
//---------------------------------------------------------------------------------------
|
// round key generation: the expansion keys are stored in 4 16*32 rams or
|
// round key generation: the expansion keys are stored in 4 16*32 rams or
|
// 2 16*64 rams or 1 16*128 rams
|
// 2 16*64 rams or 1 16*128 rams
|
//
|
//
|
//assign rd_addr[3:0] = i_ende ? (max_round[3:0] - sb_round_cnt2[3:0]) : sb_round_cnt2[3:0];
|
//assign rd_addr[3:0] = i_ende ? (max_round[3:0] - sb_round_cnt2[3:0]) : sb_round_cnt2[3:0];
|
|
|
Line 286... |
Line 288... |
.rd_addr(rd_addr[3:0]),
|
.rd_addr(rd_addr[3:0]),
|
.rd_data(rd_data1[63:0]),
|
.rd_data(rd_data1[63:0]),
|
.rd(sb_valid[1] | i_data_valid)
|
.rd(sb_valid[1] | i_data_valid)
|
);
|
);
|
`endif
|
`endif
|
/*****************************************************************************/
|
//---------------------------------------------------------------------------------------
|
// Key Expansion module
|
// Key Expansion module
|
//
|
//
|
//
|
//
|
key_exp u_key_exp (
|
key_exp u_key_exp (
|
.clk(clk),
|
.clk(clk),
|
Line 303... |
Line 305... |
.wr_data(wr_data[63:0]),
|
.wr_data(wr_data[63:0]),
|
.key_ready(o_key_ready)
|
.key_ready(o_key_ready)
|
);
|
);
|
|
|
endmodule
|
endmodule
|
/*****************************************************************************/
|
//---------------------------------------------------------------------------------------
|
|
|
No newline at end of file
|
No newline at end of file
|