OpenCores
URL https://opencores.org/ocsvn/aes_highthroughput_lowarea/aes_highthroughput_lowarea/trunk

Subversion Repositories aes_highthroughput_lowarea

[/] [aes_highthroughput_lowarea/] [trunk/] [verilog/] [rtl/] [aes.v] - Diff between revs 7 and 8

Only display areas with differences | Details | Blame | View Log

Rev 7 Rev 8
//////////////////////////////////////////////////////////////////////
//---------------------------------------------------------------------------------------
////                                                              ////
// 
////  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;
reg            i_data_valid_L;
reg            i_data_valid_L;
reg            round_valid;
reg            round_valid;
reg   [2:0]    sb_valid;
reg   [2:0]    sb_valid;
reg            o_data_valid;
reg            o_data_valid;
reg   [3:0]    round_cnt,sb_round_cnt1,sb_round_cnt2,sb_round_cnt3;
reg   [3:0]    round_cnt,sb_round_cnt1,sb_round_cnt2,sb_round_cnt3;
wire  [127:0]  round_key;
wire  [127:0]  round_key;
wire  [63:0]   rd_data0,rd_data1;
wire  [63:0]   rd_data0,rd_data1;
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
always @ (*)
always @ (*)
begin
begin
   case (i_key_mode)
   case (i_key_mode)
      2'b00: max_round[3:0] = 4'd10;
      2'b00: max_round[3:0] = 4'd10;
      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)
begin : sbox_block
begin : sbox_block
   sbox u_sbox (
   sbox u_sbox (
      .clk(clk),
      .clk(clk),
      .reset(reset),
      .reset(reset),
      .enable(i_enable),
      .enable(i_enable),
      .ende(i_ende),
      .ende(i_ende),
      .din(o_data[i*8+7:i*8]),
      .din(o_data[i*8+7:i*8]),
      .en_dout(en_sb_data[i*8+7:i*8]),
      .en_dout(en_sb_data[i*8+7:i*8]),
      .de_dout(de_sb_data[i*8+7:i*8])
      .de_dout(de_sb_data[i*8+7:i*8])
   );
   );
end
end
endgenerate
endgenerate
 
 
always @ (posedge clk or posedge reset)
always @ (posedge clk or posedge reset)
begin
begin
   if (reset)
   if (reset)
      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));
 
 
always @ (posedge clk or posedge reset)
always @ (posedge clk or posedge reset)
begin
begin
   if (reset)
   if (reset)
   begin
   begin
      i_data_valid_L  <= 1'b0;
      i_data_valid_L  <= 1'b0;
      i_data_L[127:0] <= 128'b0;
      i_data_L[127:0] <= 128'b0;
   end
   end
   else
   else
   begin
   begin
      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];
assign ark_data_init[127:0] = i_data_L[127:0] ^ round_key[127:0];
assign ark_data_init[127:0] = i_data_L[127:0] ^ round_key[127:0];
assign en_ark_data[127:0] = mc_data[127:0] ^ round_key[127:0];
assign en_ark_data[127:0] = mc_data[127:0] ^ round_key[127:0];
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
   if (reset)
   if (reset)
   begin
   begin
      round_valid  <= 1'b0;
      round_valid  <= 1'b0;
      sb_valid[2:0] <= 3'b0;
      sb_valid[2:0] <= 3'b0;
      o_data_valid  <= 1'b0;
      o_data_valid  <= 1'b0;
   end
   end
   else if (i_enable)
   else if (i_enable)
   begin
   begin
      o_data_valid  <= sb_valid[2] && final_round;
      o_data_valid  <= sb_valid[2] && final_round;
      round_valid   <= (sb_valid[2] && !final_round) || i_data_valid_L;
      round_valid   <= (sb_valid[2] && !final_round) || i_data_valid_L;
      sb_valid[2:0] <= {sb_valid[1:0],round_valid};
      sb_valid[2:0] <= {sb_valid[1:0],round_valid};
   end
   end
end
end
 
 
always @ (posedge clk or posedge reset)
always @ (posedge clk or posedge reset)
begin
begin
   if (reset)                      round_cnt[3:0] <= 4'd0;
   if (reset)                      round_cnt[3:0] <= 4'd0;
   else if (i_data_valid_L) round_cnt[3:0] <= 4'd1;
   else if (i_data_valid_L) round_cnt[3:0] <= 4'd1;
   else if (i_enable && sb_valid[2])  round_cnt[3:0] <= sb_round_cnt3[3:0] + 1'b1;
   else if (i_enable && sb_valid[2])  round_cnt[3:0] <= sb_round_cnt3[3:0] + 1'b1;
end
end
 
 
always @ (posedge clk or posedge reset)
always @ (posedge clk or posedge reset)
begin
begin
   if (reset)
   if (reset)
   begin
   begin
      sb_round_cnt1[3:0] <= 4'd0;
      sb_round_cnt1[3:0] <= 4'd0;
      sb_round_cnt2[3:0] <= 4'd0;
      sb_round_cnt2[3:0] <= 4'd0;
      sb_round_cnt3[3:0] <= 4'd0;
      sb_round_cnt3[3:0] <= 4'd0;
   end
   end
   else if (i_enable)
   else if (i_enable)
   begin
   begin
      if (round_valid) sb_round_cnt1[3:0] <= round_cnt[3:0];
      if (round_valid) sb_round_cnt1[3:0] <= round_cnt[3:0];
      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];
 
 
assign round_key[127:0] = {rd_data0[63:0],rd_data1[63:0]};
assign round_key[127:0] = {rd_data0[63:0],rd_data1[63:0]};
 
 
`ifdef XILINX
`ifdef XILINX
reg [3:0] rd_addr;
reg [3:0] rd_addr;
 
 
always @ (posedge clk or posedge reset)
always @ (posedge clk or posedge reset)
begin
begin
        if (reset)
        if (reset)
                rd_addr <= 4'b0;
                rd_addr <= 4'b0;
        else if (sb_valid[1] | i_data_valid)
        else if (sb_valid[1] | i_data_valid)
        begin
        begin
                if (i_ende)
                if (i_ende)
                begin
                begin
                        if (i_data_valid)
                        if (i_data_valid)
                                rd_addr <= max_round[3:0];
                                rd_addr <= max_round[3:0];
                        else
                        else
                                rd_addr <= max_round[3:0] - sb_round_cnt2[3:0];
                                rd_addr <= max_round[3:0] - sb_round_cnt2[3:0];
                end
                end
                else
                else
                begin
                begin
                        if (i_data_valid)
                        if (i_data_valid)
                                rd_addr <= 4'b0;
                                rd_addr <= 4'b0;
                        else
                        else
                                rd_addr <= sb_round_cnt2[3:0];
                                rd_addr <= sb_round_cnt2[3:0];
                end
                end
        end
        end
end
end
 
 
xram_16x64 u_ram_0
xram_16x64 u_ram_0
(
(
        .clk(clk),
        .clk(clk),
        .wr(wr & ~wr_addr[0]),
        .wr(wr & ~wr_addr[0]),
        .wr_addr(wr_addr[4:1]),
        .wr_addr(wr_addr[4:1]),
        .wr_data(wr_data[63:0]),
        .wr_data(wr_data[63:0]),
        .rd_addr(rd_addr[3:0]),
        .rd_addr(rd_addr[3:0]),
        .rd_data(rd_data0[63:0])
        .rd_data(rd_data0[63:0])
);
);
xram_16x64 u_ram_1
xram_16x64 u_ram_1
(
(
        .clk(clk),
        .clk(clk),
        .wr(wr & wr_addr[0]),
        .wr(wr & wr_addr[0]),
        .wr_addr(wr_addr[4:1]),
        .wr_addr(wr_addr[4:1]),
        .wr_data(wr_data[63:0]),
        .wr_data(wr_data[63:0]),
        .rd_addr(rd_addr[3:0]),
        .rd_addr(rd_addr[3:0]),
        .rd_data(rd_data1[63:0])
        .rd_data(rd_data1[63:0])
);
);
`else
`else
wire [3:0] rd_addr;
wire [3:0] rd_addr;
 
 
assign rd_addr[3:0] = i_ende ? (i_data_valid ? max_round[3:0] : (max_round[3:0] - sb_round_cnt2[3:0])) :
assign rd_addr[3:0] = i_ende ? (i_data_valid ? max_round[3:0] : (max_round[3:0] - sb_round_cnt2[3:0])) :
                               (i_data_valid ? 4'b0 : sb_round_cnt2[3:0]);
                               (i_data_valid ? 4'b0 : sb_round_cnt2[3:0]);
 
 
ram_16x64 u_ram_0
ram_16x64 u_ram_0
(
(
        .clk(clk),
        .clk(clk),
        .wr(wr & ~wr_addr[0]),
        .wr(wr & ~wr_addr[0]),
        .wr_addr(wr_addr[4:1]),
        .wr_addr(wr_addr[4:1]),
        .wr_data(wr_data[63:0]),
        .wr_data(wr_data[63:0]),
        .rd_addr(rd_addr[3:0]),
        .rd_addr(rd_addr[3:0]),
        .rd_data(rd_data0[63:0]),
        .rd_data(rd_data0[63:0]),
        .rd(sb_valid[1] | i_data_valid)
        .rd(sb_valid[1] | i_data_valid)
);
);
ram_16x64 u_ram_1
ram_16x64 u_ram_1
(
(
        .clk(clk),
        .clk(clk),
        .wr(wr & wr_addr[0]),
        .wr(wr & wr_addr[0]),
        .wr_addr(wr_addr[4:1]),
        .wr_addr(wr_addr[4:1]),
        .wr_data(wr_data[63:0]),
        .wr_data(wr_data[63:0]),
        .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),
   .reset(reset),
   .reset(reset),
   .key_in(i_key[255:0]),
   .key_in(i_key[255:0]),
   .key_mode(i_key_mode[1:0]),
   .key_mode(i_key_mode[1:0]),
   .key_start(i_start),
   .key_start(i_start),
   .wr(wr),
   .wr(wr),
   .wr_addr(wr_addr[4:0]),
   .wr_addr(wr_addr[4:0]),
   .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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.