hw/ip/aes/rtl/aes_control.sv Cov: 100%

   1: // Copyright lowRISC contributors.
   2: // Licensed under the Apache License, Version 2.0, see LICENSE for details.
   3: // SPDX-License-Identifier: Apache-2.0
   4: //
   5: // AES control
   6: 
   7: module aes_control (
   8:   input  logic                    clk_i,
   9:   input  logic                    rst_ni,
  10: 
  11:   // Main control inputs
  12:   input  aes_pkg::mode_e          mode_i,
  13:   input  aes_pkg::key_len_e       key_len_i,
  14:   input  logic                    manual_start_trigger_i,
  15:   input  logic                    force_data_overwrite_i,
  16:   input  logic                    start_i,
  17:   input  logic                    key_clear_i,
  18:   input  logic                    data_in_clear_i,
  19:   input  logic                    data_out_clear_i,
  20: 
  21:   // I/O register read/write enables
  22:   input  logic [3:0]              data_in_qe_i,
  23:   input  logic [7:0]              key_init_qe_i,
  24:   input  logic [3:0]              data_out_re_i,
  25: 
  26:   // Control outputs cipher data path
  27:   output aes_pkg::state_sel_e     state_sel_o,
  28:   output logic                    state_we_o,
  29:   output aes_pkg::add_rk_sel_e    add_rk_sel_o,
  30: 
  31:   // Control outputs key expand data path
  32:   output aes_pkg::mode_e          key_expand_mode_o,
  33:   output aes_pkg::key_init_sel_e  key_init_sel_o,
  34:   output logic [7:0]              key_init_we_o,
  35:   output aes_pkg::key_full_sel_e  key_full_sel_o,
  36:   output logic                    key_full_we_o,
  37:   output aes_pkg::key_dec_sel_e   key_dec_sel_o,
  38:   output logic                    key_dec_we_o,
  39:   output logic                    key_expand_step_o,
  40:   output logic                    key_expand_clear_o,
  41:   output logic [3:0]              key_expand_round_o,
  42:   output aes_pkg::key_words_sel_e key_words_sel_o,
  43:   output aes_pkg::round_key_sel_e round_key_sel_o,
  44: 
  45:   // Key/data registers
  46:   output logic                    data_in_we_o,
  47:   output logic                    data_out_we_o,
  48: 
  49:   // Trigger register
  50:   output logic                    start_o,
  51:   output logic                    start_we_o,
  52:   output logic                    key_clear_o,
  53:   output logic                    key_clear_we_o,
  54:   output logic                    data_in_clear_o,
  55:   output logic                    data_in_clear_we_o,
  56:   output logic                    data_out_clear_o,
  57:   output logic                    data_out_clear_we_o,
  58: 
  59:   // Status register
  60:   output logic                    output_valid_o,
  61:   output logic                    output_valid_we_o,
  62:   output logic                    input_ready_o,
  63:   output logic                    input_ready_we_o,
  64:   output logic                    idle_o,
  65:   output logic                    idle_we_o,
  66:   output logic                    stall_o,
  67:   output logic                    stall_we_o
  68: );
  69: 
  70:   import aes_pkg::*;
  71: 
  72:   // Types
  73:   typedef enum logic [2:0] {
  74:     IDLE, INIT, ROUND, FINISH, CLEAR
  75:   } aes_ctrl_e;
  76: 
  77:   aes_ctrl_e aes_ctrl_ns, aes_ctrl_cs;
  78: 
  79:   // Signals
  80:   logic [3:0] data_in_new_d, data_in_new_q;
  81:   logic       data_in_new;
  82:   logic       data_in_load;
  83: 
  84:   logic       key_init_clear;
  85:   logic [7:0] key_init_new_d, key_init_new_q;
  86:   logic       key_init_new;
  87:   logic       dec_key_gen;
  88: 
  89:   logic [3:0] data_out_read_d, data_out_read_q;
  90:   logic       data_out_read;
  91:   logic       output_valid_q;
  92: 
  93:   logic [3:0] round_d, round_q;
  94:   logic [3:0] num_rounds_d, num_rounds_q;
  95:   logic [3:0] num_rounds_regular;
  96:   logic       dec_key_gen_d, dec_key_gen_q;
  97: 
  98:   logic       start, finish;
  99: 
 100:   // If not set to manually start, we start once we have valid data available.
 101:   assign start = manual_start_trigger_i ? start_i : data_in_new;
 102: 
 103:   // If not set to overwrite data, we wait for previous output data to be read.
 104:   assign finish = force_data_overwrite_i ? 1'b1 : ~output_valid_q;
 105: 
 106:   // FSM
 107:   always_comb begin : aes_ctrl_fsm
 108: 
 109:     // Cipher data path
 110:     state_sel_o  = STATE_ROUND;
 111:     state_we_o   = 1'b0;
 112:     add_rk_sel_o = ADD_RK_ROUND;
 113: 
 114:     // Key expand data path
 115:     key_init_sel_o     = KEY_INIT_INPUT;
 116:     key_init_we_o      = 8'h00;
 117:     key_full_sel_o     = KEY_FULL_ROUND;
 118:     key_full_we_o      = 1'b0;
 119:     key_dec_sel_o      = KEY_DEC_EXPAND;
 120:     key_dec_we_o       = 1'b0;
 121:     key_expand_step_o  = 1'b0;
 122:     key_expand_clear_o = 1'b0;
 123:     key_words_sel_o    = KEY_WORDS_ZERO;
 124:     round_key_sel_o    = ROUND_KEY_DIRECT;
 125: 
 126:     // Trigger register control
 127:     start_we_o          = 1'b0;
 128:     key_clear_we_o      = 1'b0;
 129:     data_in_clear_we_o  = 1'b0;
 130:     data_out_clear_we_o = 1'b0;
 131: 
 132:     // Status register
 133:     idle_o     = 1'b0;
 134:     idle_we_o  = 1'b0;
 135:     stall_o    = 1'b0;
 136:     stall_we_o = 1'b0;
 137: 
 138:     // Key, data I/O register control
 139:     dec_key_gen   = 1'b0;
 140:     data_in_load  = 1'b0;
 141:     data_in_we_o  = 1'b0;
 142:     data_out_we_o = 1'b0;
 143: 
 144:     // FSM
 145:     aes_ctrl_ns   = aes_ctrl_cs;
 146:     round_d       = round_q;
 147:     num_rounds_d  = num_rounds_q;
 148:     dec_key_gen_d = dec_key_gen_q;
 149: 
 150:     unique case (aes_ctrl_cs)
 151: 
 152:       IDLE: begin
 153:         idle_o        = 1'b1;
 154:         idle_we_o     = 1'b1;
 155:         stall_o       = 1'b0;
 156:         stall_we_o    = 1'b1;
 157: 
 158:         dec_key_gen_d = 1'b0;
 159: 
 160:         if (start) begin
 161:           // We got a new initial key, but want to do decryption.
 162:           // We first must get the start key for decryption.
 163:           dec_key_gen_d = key_init_new & (mode_i == AES_DEC);
 164: 
 165:           // Load input data to state
 166:           state_sel_o = dec_key_gen_d ? STATE_CLEAR : STATE_INIT;
 167:           state_we_o  = 1'b1;
 168: 
 169:           // Init key expand
 170:           key_expand_clear_o = 1'b1;
 171: 
 172:           // Load full key
 173:           key_full_sel_o = dec_key_gen_d ? KEY_FULL_ENC_INIT :
 174:                      (mode_i == AES_ENC) ? KEY_FULL_ENC_INIT :
 175:                                            KEY_FULL_DEC_INIT;
 176:           key_full_we_o  = 1'b1;
 177: 
 178:           // Load num_rounds, round
 179:           round_d      = '0;
 180:           num_rounds_d = (key_len_i == AES_128) ? 4'd10 :
 181:                          (key_len_i == AES_192) ? 4'd12 :
 182:                                                   4'd14;
 183: 
 184:           idle_o      = 1'b0;
 185:           idle_we_o   = 1'b1;
 186:           start_we_o  = 1'b1;
 187: 
 188:           aes_ctrl_ns = INIT;
 189:         end else if (key_clear_i || data_in_clear_i || data_out_clear_i) begin
 190:           idle_o      = 1'b0;
 191:           idle_we_o   = 1'b1;
 192: 
 193:           aes_ctrl_ns = CLEAR;
 194:         end
 195: 
 196:         key_init_we_o = idle_o ? key_init_qe_i : 8'h00;
 197:       end
 198: 
 199:       INIT: begin
 200:         // Initial round: just add key to state
 201:         state_we_o   = ~dec_key_gen_q;
 202:         add_rk_sel_o = ADD_RK_INIT;
 203: 
 204:         // Select key words for initial add_round_key
 205:         key_words_sel_o = dec_key_gen_q                 ? KEY_WORDS_ZERO :
 206:             (key_len_i == AES_128)                      ? KEY_WORDS_0123 :
 207:             (key_len_i == AES_192 && mode_i == AES_ENC) ? KEY_WORDS_0123 :
 208:             (key_len_i == AES_192 && mode_i == AES_DEC) ? KEY_WORDS_2345 :
 209:             (key_len_i == AES_256 && mode_i == AES_ENC) ? KEY_WORDS_0123 :
 210:             (key_len_i == AES_256 && mode_i == AES_DEC) ? KEY_WORDS_4567 : KEY_WORDS_ZERO;
 211: 
 212:         // Make key expand advance - AES-256 has two round keys available right from beginning
 213:         if (key_len_i != AES_256) begin
 214:           key_expand_step_o = 1'b1;
 215:           key_full_we_o     = 1'b1;
 216:         end
 217: 
 218:         // Clear data_in_new, key_init_new
 219:         data_in_load = ~dec_key_gen_q;
 220:         dec_key_gen  =  dec_key_gen_q;
 221: 
 222:         aes_ctrl_ns = ROUND;
 223:       end
 224: 
 225:       ROUND: begin
 226:         // Normal rounds
 227:         state_we_o = ~dec_key_gen_q;
 228: 
 229:         // Select key words for add_round_key
 230:         key_words_sel_o = dec_key_gen_q                 ? KEY_WORDS_ZERO :
 231:             (key_len_i == AES_128)                      ? KEY_WORDS_0123 :
 232:             (key_len_i == AES_192 && mode_i == AES_ENC) ? KEY_WORDS_2345 :
 233:             (key_len_i == AES_192 && mode_i == AES_DEC) ? KEY_WORDS_0123 :
 234:             (key_len_i == AES_256 && mode_i == AES_ENC) ? KEY_WORDS_4567 :
 235:             (key_len_i == AES_256 && mode_i == AES_DEC) ? KEY_WORDS_0123 : KEY_WORDS_ZERO;
 236: 
 237:         // Make key expand advance
 238:         key_expand_step_o = 1'b1;
 239:         key_full_we_o     = 1'b1;
 240: 
 241:         // Select round key: direct or mixed (equivalent inverse cipher)
 242:         round_key_sel_o = (mode_i == AES_ENC) ? ROUND_KEY_DIRECT : ROUND_KEY_MIXED;
 243: 
 244:         // Update round
 245:         round_d = round_q+1;
 246: 
 247:         // Are we doing the last regular round?
 248:         if (round_q == num_rounds_regular) begin
 249:           if (dec_key_gen_q) begin
 250:             // Write decryption key and finish
 251:             key_dec_we_o  = 1'b1;
 252:             dec_key_gen_d = 1'b0;
 253:             aes_ctrl_ns   = IDLE;
 254:           end else begin
 255:             aes_ctrl_ns   = FINISH;
 256:           end
 257:         end
 258:       end
 259: 
 260:       FINISH: begin
 261:         // Final round
 262: 
 263:         // Select key words for add_round_key
 264:         key_words_sel_o = dec_key_gen_q                 ? KEY_WORDS_ZERO :
 265:             (key_len_i == AES_128)                      ? KEY_WORDS_0123 :
 266:             (key_len_i == AES_192 && mode_i == AES_ENC) ? KEY_WORDS_2345 :
 267:             (key_len_i == AES_192 && mode_i == AES_DEC) ? KEY_WORDS_0123 :
 268:             (key_len_i == AES_256 && mode_i == AES_ENC) ? KEY_WORDS_4567 :
 269:             (key_len_i == AES_256 && mode_i == AES_DEC) ? KEY_WORDS_0123 : KEY_WORDS_ZERO;
 270: 
 271:         // Skip mix_columns
 272:         add_rk_sel_o = ADD_RK_FINAL;
 273: 
 274:         // Write ouput register and clear internal state
 275:         if (!finish) begin
 276:           stall_o       = 1'b1;
 277:           stall_we_o    = 1'b1;
 278:         end else begin
 279:           stall_o       = 1'b0;
 280:           stall_we_o    = 1'b1;
 281:           data_out_we_o = 1'b1;
 282:           aes_ctrl_ns   = IDLE;
 283:           state_we_o    = 1'b1;
 284:           state_sel_o   = STATE_CLEAR;
 285:         end
 286:       end
 287: 
 288:       CLEAR: begin
 289:         if (key_clear_i) begin
 290:           key_init_sel_o = KEY_INIT_CLEAR;
 291:           key_init_we_o  = 8'hFF;
 292:           key_full_sel_o = KEY_FULL_CLEAR;
 293:           key_full_we_o  = 1'b1;
 294:           key_dec_sel_o  = KEY_DEC_CLEAR;
 295:           key_dec_we_o   = 1'b1;
 296:           key_clear_we_o = 1'b1;
 297:         end
 298:         if (data_in_clear_i) begin
 299:           data_in_we_o       = 1'b1;
 300:           data_in_clear_we_o = 1'b1;
 301:         end
 302:         if (data_out_clear_i) begin
 303:           add_rk_sel_o        = ADD_RK_INIT;
 304:           key_words_sel_o     = KEY_WORDS_ZERO;
 305:           round_key_sel_o     = ROUND_KEY_DIRECT;
 306:           data_out_we_o       = 1'b1;
 307:           data_out_clear_we_o = 1'b1;
 308:         end
 309: 
 310:         aes_ctrl_ns = IDLE;
 311:       end
 312: 
 313:       default: aes_ctrl_ns = IDLE;
 314:     endcase
 315:   end
 316: 
 317:   always_ff @(posedge clk_i or negedge rst_ni) begin : reg_fsm
 318:     if (!rst_ni) begin
 319:       aes_ctrl_cs   <= IDLE;
 320:       round_q       <= '0;
 321:       num_rounds_q  <= '0;
 322:       dec_key_gen_q <= 1'b0;
 323:     end else begin
 324:       aes_ctrl_cs   <= aes_ctrl_ns;
 325:       round_q       <= round_d;
 326:       num_rounds_q  <= num_rounds_d;
 327:       dec_key_gen_q <= dec_key_gen_d;
 328:     end
 329:   end
 330: 
 331:   // Use separate signal for number of regular rounds
 332:   assign num_rounds_regular = num_rounds_q - 4'd2;
 333: 
 334:   // Detect new key, new input, output read
 335:   // Edge detectors are cleared by the FSM
 336:   assign key_init_clear = (key_init_sel_o == KEY_INIT_CLEAR) & (&key_init_we_o);
 337:   assign key_init_new_d = (dec_key_gen | key_init_clear) ? '0 : (key_init_new_q | key_init_qe_i);
 338:   assign key_init_new   = &key_init_new_d;
 339: 
 340:   assign data_in_new_d = (data_in_load | data_in_we_o) ? '0 : (data_in_new_q | data_in_qe_i);
 341:   assign data_in_new   = &data_in_new_d;
 342: 
 343:   assign data_out_read_d = data_out_we_o ? '0 : data_out_read_q | data_out_re_i;
 344:   assign data_out_read   = &data_out_read_d;
 345: 
 346:   always_ff @(posedge clk_i or negedge rst_ni) begin : reg_edge_detection
 347:     if (!rst_ni) begin
 348:       key_init_new_q  <= '0;
 349:       data_in_new_q   <= '0;
 350:       data_out_read_q <= '0;
 351:     end else begin
 352:       key_init_new_q  <= key_init_new_d;
 353:       data_in_new_q   <= data_in_new_d;
 354:       data_out_read_q <= data_out_read_d;
 355:     end
 356:   end
 357: 
 358:   // Clear once all output regs have been read, or when output is cleared
 359:   assign output_valid_o    = data_out_we_o & ~data_out_clear_we_o;
 360:   assign output_valid_we_o = data_out_we_o | data_out_read | data_out_clear_we_o;
 361: 
 362:   always_ff @(posedge clk_i or negedge rst_ni) begin : reg_output_valid
 363:     if (!rst_ni) begin
 364:       output_valid_q <= '0;
 365:     end else if (output_valid_we_o) begin
 366:       output_valid_q <= output_valid_o;
 367:     end
 368:   end
 369: 
 370:   // Clear once all input regs have been written, or when input clear is requested
 371:   assign input_ready_o     = ~data_in_new;
 372:   assign input_ready_we_o  =  data_in_new | data_in_load | data_in_we_o;
 373: 
 374:   assign key_expand_mode_o  = (dec_key_gen_d || dec_key_gen_q) ? AES_ENC : mode_i;
 375:   assign key_expand_round_o = round_d;
 376: 
 377:   // Trigger register, the control only ever clears these
 378:   assign start_o             = 1'b0;
 379:   assign key_clear_o         = 1'b0;
 380:   assign data_in_clear_o     = 1'b0;
 381:   assign data_out_clear_o    = 1'b0;
 382: 
 383:   // Selectors must be known/valid
 384:   `ASSERT_KNOWN(AesModeKnown, mode_i, clk_i, !rst_ni)
 385:   `ASSERT(AesKeyLenValid, key_len_i inside {
 386:       AES_128,
 387:       AES_192,
 388:       AES_256
 389:       }, clk_i, !rst_ni)
 390:   `ASSERT(AesControlStateValid, aes_ctrl_cs inside {
 391:       IDLE,
 392:       INIT,
 393:       ROUND,
 394:       FINISH,
 395:       CLEAR
 396:       }, clk_i, !rst_ni)
 397: 
 398: endmodule
 399: