ctrl.v 3.77 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 : ctrl.vhd
// Author : Vincenzo Liguori
// Date : 01-03-02
// Version 1.0
// Abstract :
// This implements the key expander controller
// 
// Modification history :
// Date      by  Version  Change description
// -------------------------------------------------
// 01-03-02  VL   1.0     Original

module ctrl(
clk,
rstn,
en,
go,
ksize,
rotsel,
sel,
kinit,
kaddr,
rcaddr,
addr,
first,
final,
key_last
);

// Inputs
input clk, rstn;
input en, go;
input[1:0] ksize;
// Outputs 
output rotsel, sel;
output kinit;
output[2:0] kaddr;
output[4:0] rcaddr;
output[5:0] addr;
output first, final, key_last;

wire   clk;
wire   rstn;
wire   en;
wire   go;
wire  [1:0] ksize;
wire   rotsel;
reg   sel;
reg   kinit;
reg  [2:0] kaddr;
reg  [4:0] rcaddr;
wire  [5:0] addr;
wire   first;
wire   final;
wire   key_last;


wire  finali;
wire  over;
wire  endround;
wire  k256;
reg [2:0] kc;
reg [3:0] maxround;
reg [3:0] round;
reg [1:0] raddr0;
wire  lastk;

  assign final = finali;
  assign key_last = over;
  assign addr = {round, ~raddr0};
  always @(ksize) begin
    case(ksize)
  // Key size selection
      2'b 00 : kc <= 3'b 011;
      2'b 01 : kc <= 3'b 101;
      default : kc <= 3'b 111;
    endcase
  end

  always @(ksize) begin
    // Select the number of rounds
    case(ksize)
    2'b 00 : begin
      maxround <= 4'b 1010;
    end
    2'b 01 : begin
      maxround <= 4'b 1100;
    end
    default : begin
      maxround <= 4'b 1110;
    end
    endcase
  end

  assign endround = raddr0 == 2'b 11 ? 1'b 1 : 1'b 0;
  assign finali = round == maxround ? 1'b 1 : 1'b 0;
  assign first = round == 4'b 0000 ? 1'b 1 : 1'b 0;
  assign over = endround & finali;
  assign lastk = kaddr == kc ? 1'b 1 : 1'b 0;
  always @(posedge clk or negedge rstn) begin
    if(rstn == 1'b 0) begin
      kaddr <= {3{1'b0}};
      kinit <= 1'b 0;
      round <= {4{1'b0}};
      rcaddr <= {5{1'b0}};
      raddr0 <= {2{1'b0}};
    end else begin
      if(en == 1'b 1) begin
        if(go == 1'b 0) begin
          kaddr <= {3{1'b0}};
          kinit <= 1'b 1;
          rcaddr <= {5{1'b1}};
          round <= {4{1'b0}};
          raddr0 <= {2{1'b0}};
        end
        else begin
          if(over == 1'b 1) begin
            kaddr <= {3{1'b0}};
            kinit <= 1'b 1;
          end
          else if(lastk == 1'b 1) begin
            kaddr <= {3{1'b0}};
            kinit <= 1'b 0;
          end
          else begin
            kaddr <= kaddr + 1'b 1;
          end
          if(lastk == 1'b 1) begin
            if(kinit == 1'b 1) begin
              rcaddr <= {5{1'b0}};
            end
            else begin
              rcaddr <= rcaddr + 1'b 1;
            end
          end
          if(endround == 1'b 1) begin
            raddr0 <= {2{1'b0}};
            if(finali == 1'b 1) begin
              round <= {4{1'b0}};
            end
            else begin
              round <= round + 1'b 1;
            end
          end
          else begin
            raddr0 <= raddr0 + 1'b 1;
          end
        end
      end
    end
  end

  assign rotsel = kaddr == 3'b 000 ? 1'b 1 : 1'b 0;
  assign k256 = ksize == 2'b 10 ? 1'b 1 : 1'b 0;
  always @(kaddr or k256) begin
    case(kaddr)
      3'b 000 : sel <= 1'b 1;
      3'b 100 : sel <= k256;
      default : sel <= 1'b 0;
    endcase
  end


endmodule