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: