keysched.v 4.02 KB
// This confidential and propriety software may be used
// only as authorized by a licensing agreement from
// Ocean Logic Pty Ltd http://www.ocean-logic.com
// 
// In the event of publication, the following notice is
// applicable
// 
// (C) COPYRIGHT 2001 Ocean Logic Pty Ltd
// ALL RIGHTS RESERVED
//
// the entire notice must be reproduced on all
// authorized copies
// 
// File : keysched.vhd
// Author : Vincenzo Liguori
// Date : 01-03-02
// Version 1.0
// Abstract :
// This implements the AES key scheduler
// 
// Modification history :
// Date      by  Version  Change description
// -------------------------------------------------
// 01-03-02  VL   1.0     Original

module keysched(
rstn,
clk,
en,
rotsel,
sel,
kinit,
kin,
oldkey,
rcaddr,
key
);

// Inputs
input rstn, clk;
input en;
input rotsel, sel, kinit;
input[31:0] kin, oldkey;
input[4:0] rcaddr;
// Outputs 
output[31:0] key;

wire   rstn;
wire   clk;
wire   en;
wire   rotsel;
wire   sel;
wire   kinit;
wire  [31:0] kin;
wire  [31:0] oldkey;
wire  [4:0] rcaddr;
wire  [31:0] key;


// AES S-box
wire [31:0] sb;
wire [31:0] k;
reg [31:0] prevkey;
wire [31:0] nkey;
wire [31:0] rot;
reg [7:0] rc;

  sbox sbx0(
      // Inputs
    .rstn(rstn),
    .clk(clk),
    .en(en),
    .din(key[31:24] ),
    // Outputs 
    .s(sb[31:24] ));

  sbox sbx1(
      // Inputs
    .rstn(rstn),
    .clk(clk),
    .en(en),
    .din(key[23:16] ),
    // Outputs 
    .s(sb[23:16] ));

  sbox sbx2(
      // Inputs
    .rstn(rstn),
    .clk(clk),
    .en(en),
    .din(key[15:8] ),
    // Outputs 
    .s(sb[15:8] ));

  sbox sbx3(
      // Inputs
    .rstn(rstn),
    .clk(clk),
    .en(en),
    .din(key[7:0] ),
    // Outputs 
    .s(sb[7:0] ));

  always @(rcaddr) begin
    case(rcaddr)
    5'b 00000 : begin
      rc <= 8'b 00000001;
    end
    5'b 00001 : begin
      rc <= 8'b 00000010;
    end
    5'b 00010 : begin
      rc <= 8'b 00000100;
    end
    5'b 00011 : begin
      rc <= 8'b 00001000;
    end
    5'b 00100 : begin
      rc <= 8'b 00010000;
    end
    5'b 00101 : begin
      rc <= 8'b 00100000;
    end
    5'b 00110 : begin
      rc <= 8'b 01000000;
    end
    5'b 00111 : begin
      rc <= 8'b 10000000;
    end
    5'b 01000 : begin
      rc <= 8'b 00011011;
    end
    5'b 01001 : begin
      rc <= 8'b 00110110;
    end
    5'b 01010 : begin
      rc <= 8'b 01101100;
    end
    5'b 01011 : begin
      rc <= 8'b 11011000;
    end
    5'b 01100 : begin
      rc <= 8'b 10101011;
    end
    5'b 01101 : begin
      rc <= 8'b 01001101;
    end
    5'b 01110 : begin
      rc <= 8'b 10011010;
    end
    5'b 01111 : begin
      rc <= 8'b 00101111;
    end
    5'b 10000 : begin
      rc <= 8'b 01011110;
    end
    5'b 10001 : begin
      rc <= 8'b 10111100;
    end
    5'b 10010 : begin
      rc <= 8'b 01100011;
    end
    5'b 10011 : begin
      rc <= 8'b 11000110;
    end
    5'b 10100 : begin
      rc <= 8'b 10010111;
    end
    5'b 10101 : begin
      rc <= 8'b 00110101;
    end
    5'b 10110 : begin
      rc <= 8'b 01101010;
    end
    5'b 10111 : begin
      rc <= 8'b 11010100;
    end
    5'b 11000 : begin
      rc <= 8'b 10110011;
    end
    5'b 11001 : begin
      rc <= 8'b 01111101;
    end
    5'b 11010 : begin
      rc <= 8'b 11111010;
    end
    5'b 11011 : begin
      rc <= 8'b 11101111;
    end
    5'b 11100 : begin
      rc <= 8'b 11000101;
    end
    5'b 11101 : begin
      rc <= 8'b 10010001;
    end
    default : begin
      rc <= {8{1'b0}};
    end
    endcase
  end

  assign rot = rotsel == 1'b 1 ? {rc ^ sb[23:16] ,sb[15:0] ,sb[31:24] } : sb;
  assign k = sel == 1'b 1 ? rot : prevkey;
  assign nkey = oldkey ^ k;
  assign key = kinit == 1'b 1 ? kin : nkey;
  always @(posedge clk or negedge rstn) begin
    if(rstn == 1'b 0) begin
      prevkey <= {32{1'b0}};
    end else begin
      if(en == 1'b 1) begin
        prevkey <= nkey;
      end
    end
  end


endmodule