-
Notifications
You must be signed in to change notification settings - Fork 803
/
Copy pathaes_cipher_control.sv
485 lines (430 loc) · 21.9 KB
/
aes_cipher_control.sv
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
// Copyright lowRISC contributors (OpenTitan project).
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
//
// AES cipher core control
//
// This module controls the AES cipher core including the key expand module.
`include "prim_assert.sv"
module aes_cipher_control import aes_pkg::*;
#(
parameter bit CiphOpFwdOnly = 0,
parameter bit SecMasking = 0,
parameter sbox_impl_e SecSBoxImpl = SBoxImplDom
) (
input logic clk_i,
input logic rst_ni,
// Input handshake signals
input sp2v_e in_valid_i,
output sp2v_e in_ready_o,
// Output handshake signals
output sp2v_e out_valid_o,
input sp2v_e out_ready_i,
// Control and sync signals
input logic cfg_valid_i,
input ciph_op_e op_i,
input key_len_e key_len_i,
input sp2v_e crypt_i,
output sp2v_e crypt_o,
input sp2v_e dec_key_gen_i,
output sp2v_e dec_key_gen_o,
input logic prng_reseed_i,
output logic prng_reseed_o,
input logic key_clear_i,
output logic key_clear_o,
input logic data_out_clear_i,
output logic data_out_clear_o,
input logic mux_sel_err_i,
input logic sp_enc_err_i,
input logic op_err_i,
input logic alert_fatal_i,
output logic alert_o,
// Control signals for masking PRNG
output logic prng_update_o,
output logic prng_reseed_req_o,
input logic prng_reseed_ack_i,
// Control and sync signals for cipher data path
output state_sel_e state_sel_o,
output sp2v_e state_we_o,
output sp2v_e sub_bytes_en_o,
input sp2v_e sub_bytes_out_req_i,
output sp2v_e sub_bytes_out_ack_o,
output add_rk_sel_e add_rk_sel_o,
// Control and sync signals for key expand data path
output ciph_op_e key_expand_op_o,
output key_full_sel_e key_full_sel_o,
output sp2v_e key_full_we_o,
output key_dec_sel_e key_dec_sel_o,
output sp2v_e key_dec_we_o,
output sp2v_e key_expand_en_o,
input sp2v_e key_expand_out_req_i,
output sp2v_e key_expand_out_ack_o,
output logic key_expand_clear_o,
output logic [3:0] key_expand_round_o,
output key_words_sel_e key_words_sel_o,
output round_key_sel_e round_key_sel_o
);
// Signals
logic [3:0] rnd_ctr;
sp2v_e crypt_d, crypt_q;
sp2v_e dec_key_gen_d, dec_key_gen_q;
logic prng_reseed_d, prng_reseed_q;
logic key_clear_d, key_clear_q;
logic data_out_clear_d, data_out_clear_q;
sp2v_e sub_bytes_out_req;
sp2v_e key_expand_out_req;
sp2v_e in_valid;
sp2v_e out_ready;
sp2v_e crypt;
sp2v_e dec_key_gen;
logic mux_sel_err;
logic mr_err;
logic sp_enc_err;
logic rnd_ctr_err;
// Sparsified FSM signals. These are needed for connecting the individual bits of the Sp2V
// signals to the single-rail FSMs.
logic [Sp2VWidth-1:0] sp_in_valid;
logic [Sp2VWidth-1:0] sp_in_ready;
logic [Sp2VWidth-1:0] sp_out_valid;
logic [Sp2VWidth-1:0] sp_out_ready;
logic [Sp2VWidth-1:0] sp_crypt;
logic [Sp2VWidth-1:0] sp_dec_key_gen;
logic [Sp2VWidth-1:0] sp_state_we;
logic [Sp2VWidth-1:0] sp_sub_bytes_en;
logic [Sp2VWidth-1:0] sp_sub_bytes_out_req;
logic [Sp2VWidth-1:0] sp_sub_bytes_out_ack;
logic [Sp2VWidth-1:0] sp_key_full_we;
logic [Sp2VWidth-1:0] sp_key_dec_we;
logic [Sp2VWidth-1:0] sp_key_expand_en;
logic [Sp2VWidth-1:0] sp_key_expand_out_req;
logic [Sp2VWidth-1:0] sp_key_expand_out_ack;
logic [Sp2VWidth-1:0] sp_crypt_d;
logic [Sp2VWidth-1:0] sp_crypt_q;
logic [Sp2VWidth-1:0] sp_dec_key_gen_d;
logic [Sp2VWidth-1:0] sp_dec_key_gen_q;
// Multi-rail signals. These are outputs of the single-rail FSMs and need combining.
logic [Sp2VWidth-1:0] mr_alert;
logic [Sp2VWidth-1:0] mr_prng_update;
logic [Sp2VWidth-1:0] mr_prng_reseed_req;
logic [Sp2VWidth-1:0] mr_key_expand_clear;
logic [Sp2VWidth-1:0] mr_prng_reseed_d;
logic [Sp2VWidth-1:0] mr_key_clear_d;
logic [Sp2VWidth-1:0] mr_data_out_clear_d;
state_sel_e [Sp2VWidth-1:0] mr_state_sel;
add_rk_sel_e [Sp2VWidth-1:0] mr_add_rk_sel;
key_full_sel_e [Sp2VWidth-1:0] mr_key_full_sel;
key_dec_sel_e [Sp2VWidth-1:0] mr_key_dec_sel;
key_words_sel_e [Sp2VWidth-1:0] mr_key_words_sel;
round_key_sel_e [Sp2VWidth-1:0] mr_round_key_sel;
logic [Sp2VWidth-1:0][3:0] mr_rnd_ctr;
/////////
// FSM //
/////////
// Convert sp2v_e signals to sparsified inputs.
assign sp_in_valid = {in_valid};
assign sp_out_ready = {out_ready};
assign sp_crypt = {crypt};
assign sp_dec_key_gen = {dec_key_gen};
assign sp_sub_bytes_out_req = {sub_bytes_out_req};
assign sp_key_expand_out_req = {key_expand_out_req};
assign sp_crypt_q = {crypt_q};
assign sp_dec_key_gen_q = {dec_key_gen_q};
// SEC_CM: CIPHER.FSM.REDUN
// SEC_CM: CIPHER.CTR.REDUN
// For every bit in the Sp2V signals, one separate rail is instantiated. The inputs and outputs
// of every rail are buffered to prevent aggressive synthesis optimizations.
for (genvar i = 0; i < Sp2VWidth; i++) begin : gen_fsm
if (SP2V_LOGIC_HIGH[i] == 1'b1) begin : gen_fsm_p
aes_cipher_control_fsm_p #(
.SecMasking ( SecMasking ),
.SecSBoxImpl ( SecSBoxImpl )
) u_aes_cipher_control_fsm_i (
.clk_i ( clk_i ),
.rst_ni ( rst_ni ),
.in_valid_i ( sp_in_valid[i] ), // Sparsified
.in_ready_o ( sp_in_ready[i] ), // Sparsified
.out_valid_o ( sp_out_valid[i] ), // Sparsified
.out_ready_i ( sp_out_ready[i] ), // Sparsified
.cfg_valid_i ( cfg_valid_i ),
.op_i ( op_i ),
.key_len_i ( key_len_i ),
.crypt_i ( sp_crypt[i] ), // Sparsified
.dec_key_gen_i ( sp_dec_key_gen[i] ), // Sparsified
.prng_reseed_i ( prng_reseed_i ),
.key_clear_i ( key_clear_i ),
.data_out_clear_i ( data_out_clear_i ),
.mux_sel_err_i ( mux_sel_err ),
.sp_enc_err_i ( sp_enc_err ),
.rnd_ctr_err_i ( rnd_ctr_err ),
.op_err_i ( op_err_i ),
.alert_fatal_i ( alert_fatal_i ),
.alert_o ( mr_alert[i] ), // OR-combine
.prng_update_o ( mr_prng_update[i] ), // OR-combine
.prng_reseed_req_o ( mr_prng_reseed_req[i] ), // OR-combine
.prng_reseed_ack_i ( prng_reseed_ack_i ),
.state_sel_o ( mr_state_sel[i] ), // OR-combine
.state_we_o ( sp_state_we[i] ), // Sparsified
.sub_bytes_en_o ( sp_sub_bytes_en[i] ), // Sparsified
.sub_bytes_out_req_i ( sp_sub_bytes_out_req[i] ), // Sparsified
.sub_bytes_out_ack_o ( sp_sub_bytes_out_ack[i] ), // Sparsified
.add_rk_sel_o ( mr_add_rk_sel[i] ), // OR-combine
.key_full_sel_o ( mr_key_full_sel[i] ), // OR-combine
.key_full_we_o ( sp_key_full_we[i] ), // Sparsified
.key_dec_sel_o ( mr_key_dec_sel[i] ), // OR-combine
.key_dec_we_o ( sp_key_dec_we[i] ), // Sparsified
.key_expand_en_o ( sp_key_expand_en[i] ), // Sparsified
.key_expand_out_req_i ( sp_key_expand_out_req[i] ), // Sparsified
.key_expand_out_ack_o ( sp_key_expand_out_ack[i] ), // Sparsified
.key_expand_clear_o ( mr_key_expand_clear[i] ), // OR-combine
.rnd_ctr_o ( mr_rnd_ctr[i] ), // OR-combine
.key_words_sel_o ( mr_key_words_sel[i] ), // OR-combine
.round_key_sel_o ( mr_round_key_sel[i] ), // OR-combine
.crypt_q_i ( sp_crypt_q[i] ), // Sparsified
.crypt_d_o ( sp_crypt_d[i] ), // Sparsified
.dec_key_gen_q_i ( sp_dec_key_gen_q[i] ), // Sparsified
.dec_key_gen_d_o ( sp_dec_key_gen_d[i] ), // Sparsified
.prng_reseed_q_i ( prng_reseed_q ),
.prng_reseed_d_o ( mr_prng_reseed_d[i] ), // AND-combine
.key_clear_q_i ( key_clear_q ),
.key_clear_d_o ( mr_key_clear_d[i] ), // AND-combine
.data_out_clear_q_i ( data_out_clear_q ),
.data_out_clear_d_o ( mr_data_out_clear_d[i] ) // AND-combine
);
end else begin : gen_fsm_n
aes_cipher_control_fsm_n #(
.SecMasking ( SecMasking ),
.SecSBoxImpl ( SecSBoxImpl )
) u_aes_cipher_control_fsm_i (
.clk_i ( clk_i ),
.rst_ni ( rst_ni ),
.in_valid_ni ( sp_in_valid[i] ), // Sparsified
.in_ready_no ( sp_in_ready[i] ), // Sparsified
.out_valid_no ( sp_out_valid[i] ), // Sparsified
.out_ready_ni ( sp_out_ready[i] ), // Sparsified
.cfg_valid_i ( cfg_valid_i ),
.op_i ( op_i ),
.key_len_i ( key_len_i ),
.crypt_ni ( sp_crypt[i] ), // Sparsified
.dec_key_gen_ni ( sp_dec_key_gen[i] ), // Sparsified
.prng_reseed_i ( prng_reseed_i ),
.key_clear_i ( key_clear_i ),
.data_out_clear_i ( data_out_clear_i ),
.mux_sel_err_i ( mux_sel_err ),
.sp_enc_err_i ( sp_enc_err ),
.rnd_ctr_err_i ( rnd_ctr_err ),
.op_err_i ( op_err_i ),
.alert_fatal_i ( alert_fatal_i ),
.alert_o ( mr_alert[i] ), // OR-combine
.prng_update_o ( mr_prng_update[i] ), // OR-combine
.prng_reseed_req_o ( mr_prng_reseed_req[i] ), // OR-combine
.prng_reseed_ack_i ( prng_reseed_ack_i ),
.state_sel_o ( mr_state_sel[i] ), // OR-combine
.state_we_no ( sp_state_we[i] ), // Sparsified
.sub_bytes_en_no ( sp_sub_bytes_en[i] ), // Sparsified
.sub_bytes_out_req_ni ( sp_sub_bytes_out_req[i] ), // Sparsified
.sub_bytes_out_ack_no ( sp_sub_bytes_out_ack[i] ), // Sparsified
.add_rk_sel_o ( mr_add_rk_sel[i] ), // OR-combine
.key_full_sel_o ( mr_key_full_sel[i] ), // OR-combine
.key_full_we_no ( sp_key_full_we[i] ), // Sparsified
.key_dec_sel_o ( mr_key_dec_sel[i] ), // OR-combine
.key_dec_we_no ( sp_key_dec_we[i] ), // Sparsified
.key_expand_en_no ( sp_key_expand_en[i] ), // Sparsified
.key_expand_out_req_ni ( sp_key_expand_out_req[i] ), // Sparsified
.key_expand_out_ack_no ( sp_key_expand_out_ack[i] ), // Sparsified
.key_expand_clear_o ( mr_key_expand_clear[i] ), // OR-combine
.rnd_ctr_o ( mr_rnd_ctr[i] ), // OR-combine
.key_words_sel_o ( mr_key_words_sel[i] ), // OR-combine
.round_key_sel_o ( mr_round_key_sel[i] ), // OR-combine
.crypt_q_ni ( sp_crypt_q[i] ), // Sparsified
.crypt_d_no ( sp_crypt_d[i] ), // Sparsified
.dec_key_gen_q_ni ( sp_dec_key_gen_q[i] ), // Sparsified
.dec_key_gen_d_no ( sp_dec_key_gen_d[i] ), // Sparsified
.prng_reseed_q_i ( prng_reseed_q ),
.prng_reseed_d_o ( mr_prng_reseed_d[i] ), // AND-combine
.key_clear_q_i ( key_clear_q ),
.key_clear_d_o ( mr_key_clear_d[i] ), // AND-combine
.data_out_clear_q_i ( data_out_clear_q ),
.data_out_clear_d_o ( mr_data_out_clear_d[i] ) // AND-combine
);
end
end
// Convert sparsified outputs to sp2v_e type.
assign in_ready_o = sp2v_e'(sp_in_ready);
assign out_valid_o = sp2v_e'(sp_out_valid);
assign state_we_o = sp2v_e'(sp_state_we);
assign sub_bytes_en_o = sp2v_e'(sp_sub_bytes_en);
assign sub_bytes_out_ack_o = sp2v_e'(sp_sub_bytes_out_ack);
assign key_full_we_o = sp2v_e'(sp_key_full_we);
assign key_dec_we_o = sp2v_e'(sp_key_dec_we);
assign key_expand_en_o = sp2v_e'(sp_key_expand_en);
assign key_expand_out_ack_o = sp2v_e'(sp_key_expand_out_ack);
assign crypt_d = sp2v_e'(sp_crypt_d);
assign dec_key_gen_d = sp2v_e'(sp_dec_key_gen_d);
// Combine single-bit FSM outputs.
// OR: One bit is sufficient to drive the corresponding output bit high.
assign alert_o = |mr_alert;
assign prng_update_o = |mr_prng_update;
assign prng_reseed_req_o = |mr_prng_reseed_req;
assign key_expand_clear_o = |mr_key_expand_clear;
// AND: Only if all bits are high, the corresponding status is signaled which will lead to
// the clearing of these trigger bits.
assign prng_reseed_d = &mr_prng_reseed_d;
assign key_clear_d = &mr_key_clear_d;
assign data_out_clear_d = &mr_data_out_clear_d;
// Combine multi-bit, sparse FSM outputs. We simply OR them together. If the FSMs don't provide
// the same outputs, two cases are possible:
// - An invalid encoding results: A downstream checker will fire, see mux_sel_err_i.
// - A valid encoding results: The outputs are compared below to cover this case, see mr_err;
always_comb begin : combine_sparse_signals
state_sel_o = state_sel_e'({StateSelWidth{1'b0}});
add_rk_sel_o = add_rk_sel_e'({AddRKSelWidth{1'b0}});
key_full_sel_o = key_full_sel_e'({KeyFullSelWidth{1'b0}});
key_dec_sel_o = key_dec_sel_e'({KeyDecSelWidth{1'b0}});
key_words_sel_o = key_words_sel_e'({KeyWordsSelWidth{1'b0}});
round_key_sel_o = round_key_sel_e'({RoundKeySelWidth{1'b0}});
mr_err = 1'b0;
for (int i = 0; i < Sp2VWidth; i++) begin
state_sel_o = state_sel_e'({state_sel_o} | {mr_state_sel[i]});
add_rk_sel_o = add_rk_sel_e'({add_rk_sel_o} | {mr_add_rk_sel[i]});
key_full_sel_o = key_full_sel_e'({key_full_sel_o} | {mr_key_full_sel[i]});
key_dec_sel_o = key_dec_sel_e'({key_dec_sel_o} | {mr_key_dec_sel[i]});
key_words_sel_o = key_words_sel_e'({key_words_sel_o} | {mr_key_words_sel[i]});
round_key_sel_o = round_key_sel_e'({round_key_sel_o} | {mr_round_key_sel[i]});
end
for (int i = 0; i < Sp2VWidth; i++) begin
if (state_sel_o != mr_state_sel[i] ||
add_rk_sel_o != mr_add_rk_sel[i] ||
key_full_sel_o != mr_key_full_sel[i] ||
key_dec_sel_o != mr_key_dec_sel[i] ||
key_words_sel_o != mr_key_words_sel[i] ||
round_key_sel_o != mr_round_key_sel[i]) begin
mr_err = 1'b1;
end
end
end
// Collect errors in mux selector signals.
assign mux_sel_err = mux_sel_err_i | mr_err;
// Combine counter signals. We simply OR them together. If the FSMs don't provide the same
// outputs, rnd_ctr_err will be set.
always_comb begin : combine_counter_signals
rnd_ctr = '0;
rnd_ctr_err = 1'b0;
for (int i = 0; i < Sp2VWidth; i++) begin
rnd_ctr |= mr_rnd_ctr[i];
end
for (int i = 0; i < Sp2VWidth; i++) begin
if (rnd_ctr != mr_rnd_ctr[i]) begin
rnd_ctr_err = 1'b1;
end
end
end
always_ff @(posedge clk_i or negedge rst_ni) begin : reg_fsm
if (!rst_ni) begin
prng_reseed_q <= 1'b0;
key_clear_q <= 1'b0;
data_out_clear_q <= 1'b0;
end else begin
prng_reseed_q <= prng_reseed_d;
key_clear_q <= key_clear_d;
data_out_clear_q <= data_out_clear_d;
end
end
// Use separate signal for key expand operation, forward round.
assign key_expand_op_o = (dec_key_gen_d == SP2V_HIGH ||
dec_key_gen_q == SP2V_HIGH) || CiphOpFwdOnly ? CIPH_FWD : op_i;
assign key_expand_round_o = rnd_ctr;
// Let the main controller know whate we are doing.
assign crypt_o = crypt_q;
assign dec_key_gen_o = dec_key_gen_q;
assign prng_reseed_o = prng_reseed_q;
assign key_clear_o = key_clear_q;
assign data_out_clear_o = data_out_clear_q;
//////////////////////////////
// Sparsely Encoded Signals //
//////////////////////////////
// SEC_CM: CTRL.SPARSE
// We use sparse encodings for various critical signals and must ensure that:
// 1. The synthesis tool doesn't optimize away the sparse encoding.
// 2. The sparsely encoded signal is always valid. More precisely, an alert or SVA is triggered
// if a sparse signal takes on an invalid value.
// 3. The alert signal remains asserted until reset even if the sparse signal becomes valid again
// This is achieved by driving the control FSM into the terminal error state whenever any
// sparsely encoded signal becomes invalid.
//
// If any sparsely encoded signal becomes invalid, the cipher core further immediately de-asserts
// the out_valid_o signal to prevent any data from being released.
// The following primitives are used to place a size-only constraint on the
// flops in order to prevent optimizations on these status signals.
logic [Sp2VWidth-1:0] crypt_q_raw;
prim_flop #(
.Width ( Sp2VWidth ),
.ResetValue ( Sp2VWidth'(SP2V_LOW) )
) u_crypt_regs (
.clk_i ( clk_i ),
.rst_ni ( rst_ni ),
.d_i ( crypt_d ),
.q_o ( crypt_q_raw )
);
logic [Sp2VWidth-1:0] dec_key_gen_q_raw;
prim_flop #(
.Width ( Sp2VWidth ),
.ResetValue ( Sp2VWidth'(SP2V_LOW) )
) u_dec_key_gen_regs (
.clk_i ( clk_i ),
.rst_ni ( rst_ni ),
.d_i ( dec_key_gen_d ),
.q_o ( dec_key_gen_q_raw )
);
// We use vectors of sparsely encoded signals to reduce code duplication.
localparam int unsigned NumSp2VSig = 8;
sp2v_e [NumSp2VSig-1:0] sp2v_sig;
sp2v_e [NumSp2VSig-1:0] sp2v_sig_chk;
logic [NumSp2VSig-1:0][Sp2VWidth-1:0] sp2v_sig_chk_raw;
logic [NumSp2VSig-1:0] sp2v_sig_err;
assign sp2v_sig[0] = in_valid_i;
assign sp2v_sig[1] = out_ready_i;
assign sp2v_sig[2] = crypt_i;
assign sp2v_sig[3] = dec_key_gen_i;
assign sp2v_sig[4] = sp2v_e'(crypt_q_raw);
assign sp2v_sig[5] = sp2v_e'(dec_key_gen_q_raw);
assign sp2v_sig[6] = sub_bytes_out_req_i;
assign sp2v_sig[7] = key_expand_out_req_i;
// All signals inside sp2v_sig except for sub_bytes/key_expand_out_req_i are driven and consumed
// by multi-rail FSMs.
localparam bit [NumSp2VSig-1:0] Sp2VEnSecBuf = 8'b1100_0000;
// Individually check sparsely encoded signals.
for (genvar i = 0; i < NumSp2VSig; i++) begin : gen_sel_buf_chk
aes_sel_buf_chk #(
.Num ( Sp2VNum ),
.Width ( Sp2VWidth ),
.EnSecBuf ( Sp2VEnSecBuf[i] )
) u_aes_sp2v_sig_buf_chk_i (
.clk_i ( clk_i ),
.rst_ni ( rst_ni ),
.sel_i ( sp2v_sig[i] ),
.sel_o ( sp2v_sig_chk_raw[i] ),
.err_o ( sp2v_sig_err[i] )
);
assign sp2v_sig_chk[i] = sp2v_e'(sp2v_sig_chk_raw[i]);
end
assign in_valid = sp2v_sig_chk[0];
assign out_ready = sp2v_sig_chk[1];
assign crypt = sp2v_sig_chk[2];
assign dec_key_gen = sp2v_sig_chk[3];
assign crypt_q = sp2v_sig_chk[4];
assign dec_key_gen_q = sp2v_sig_chk[5];
assign sub_bytes_out_req = sp2v_sig_chk[6];
assign key_expand_out_req = sp2v_sig_chk[7];
// Collect encoding errors.
// We instantiate the checker modules as close as possible to where the sparsely encoded signals
// are used. Here, we collect also encoding errors detected in other places of the cipher core.
assign sp_enc_err = |sp2v_sig_err | sp_enc_err_i;
////////////////
// Assertions //
////////////////
// Selectors must be known/valid
`ASSERT(AesCiphOpValid, cfg_valid_i |-> op_i inside {
CIPH_FWD,
CIPH_INV
})
endmodule