Pirmin Vogel | 3650691 | 2021-12-06 16:30:09 +0100 | [diff] [blame] | 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 counter FSM for CTR mode |
| 6 | |
| 7 | `include "prim_assert.sv" |
| 8 | |
| 9 | module aes_ctr_fsm import aes_pkg::*; |
| 10 | ( |
| 11 | input logic clk_i, |
| 12 | input logic rst_ni, |
| 13 | |
| 14 | input logic incr_i, // Sparsify using multi-rail. |
| 15 | output logic ready_o, // Sparsify using multi-rail. |
| 16 | input logic incr_err_i, |
| 17 | input logic mr_err_i, |
| 18 | output logic alert_o, |
| 19 | |
| 20 | output logic [SliceIdxWidth-1:0] ctr_slice_idx_o, |
| 21 | input logic [SliceSizeCtr-1:0] ctr_slice_i, |
| 22 | output logic [SliceSizeCtr-1:0] ctr_slice_o, |
| 23 | output logic ctr_we_o // Sparsify using multi-rail. |
| 24 | ); |
| 25 | |
Pirmin Vogel | 3650691 | 2021-12-06 16:30:09 +0100 | [diff] [blame] | 26 | // Signals |
| 27 | aes_ctr_e aes_ctr_ns, aes_ctr_cs; |
| 28 | logic [SliceIdxWidth-1:0] ctr_slice_idx_d, ctr_slice_idx_q; |
| 29 | logic ctr_carry_d, ctr_carry_q; |
| 30 | |
| 31 | logic [SliceSizeCtr:0] ctr_value; |
| 32 | |
| 33 | ///////////// |
| 34 | // Counter // |
| 35 | ///////////// |
| 36 | |
| 37 | // We do SliceSizeCtr bits at a time. |
| 38 | assign ctr_value = ctr_slice_i + {{(SliceSizeCtr-1){1'b0}}, ctr_carry_q}; |
| 39 | assign ctr_slice_o = ctr_value[SliceSizeCtr-1:0]; |
| 40 | |
| 41 | ///////////// |
| 42 | // Control // |
| 43 | ///////////// |
| 44 | |
| 45 | // FSM |
Pirmin Vogel | 2afff7c | 2021-12-10 09:42:49 +0100 | [diff] [blame] | 46 | always_comb begin : aes_ctr_fsm_comb |
Pirmin Vogel | 3650691 | 2021-12-06 16:30:09 +0100 | [diff] [blame] | 47 | |
| 48 | // Outputs |
| 49 | ready_o = 1'b0; |
| 50 | ctr_we_o = 1'b0; |
| 51 | alert_o = 1'b0; |
| 52 | |
| 53 | // FSM |
| 54 | aes_ctr_ns = aes_ctr_cs; |
| 55 | ctr_slice_idx_d = ctr_slice_idx_q; |
| 56 | ctr_carry_d = ctr_carry_q; |
| 57 | |
| 58 | unique case (aes_ctr_cs) |
Andreas Kurth | f4d64f3 | 2022-11-02 14:37:30 +0000 | [diff] [blame] | 59 | CTR_IDLE: begin |
Pirmin Vogel | 3650691 | 2021-12-06 16:30:09 +0100 | [diff] [blame] | 60 | ready_o = 1'b1; |
| 61 | if (incr_i == 1'b1) begin |
| 62 | // Initialize slice index and carry bit. |
| 63 | ctr_slice_idx_d = '0; |
| 64 | ctr_carry_d = 1'b1; |
Andreas Kurth | f4d64f3 | 2022-11-02 14:37:30 +0000 | [diff] [blame] | 65 | aes_ctr_ns = CTR_INCR; |
Pirmin Vogel | 3650691 | 2021-12-06 16:30:09 +0100 | [diff] [blame] | 66 | end |
| 67 | end |
| 68 | |
Andreas Kurth | f4d64f3 | 2022-11-02 14:37:30 +0000 | [diff] [blame] | 69 | CTR_INCR: begin |
Pirmin Vogel | 3650691 | 2021-12-06 16:30:09 +0100 | [diff] [blame] | 70 | // Increment slice index. |
| 71 | ctr_slice_idx_d = ctr_slice_idx_q + SliceIdxWidth'(1); |
| 72 | ctr_carry_d = ctr_value[SliceSizeCtr]; |
| 73 | ctr_we_o = 1'b1; |
| 74 | |
| 75 | if (ctr_slice_idx_q == {SliceIdxWidth{1'b1}}) begin |
Andreas Kurth | f4d64f3 | 2022-11-02 14:37:30 +0000 | [diff] [blame] | 76 | aes_ctr_ns = CTR_IDLE; |
Pirmin Vogel | 3650691 | 2021-12-06 16:30:09 +0100 | [diff] [blame] | 77 | end |
| 78 | end |
| 79 | |
Andreas Kurth | f4d64f3 | 2022-11-02 14:37:30 +0000 | [diff] [blame] | 80 | CTR_ERROR: begin |
Pirmin Vogel | 9ac6054 | 2022-01-10 15:40:48 +0100 | [diff] [blame] | 81 | // SEC_CM: CTR.FSM.LOCAL_ESC |
Pirmin Vogel | 3650691 | 2021-12-06 16:30:09 +0100 | [diff] [blame] | 82 | // Terminal error state |
| 83 | alert_o = 1'b1; |
| 84 | end |
| 85 | |
| 86 | // We should never get here. If we do (e.g. via a malicious |
| 87 | // glitch), error out immediately. |
| 88 | default: begin |
Andreas Kurth | f4d64f3 | 2022-11-02 14:37:30 +0000 | [diff] [blame] | 89 | aes_ctr_ns = CTR_ERROR; |
Cindy Chen | ad74c38 | 2022-06-06 13:56:57 -0700 | [diff] [blame] | 90 | alert_o = 1'b1; |
Pirmin Vogel | 3650691 | 2021-12-06 16:30:09 +0100 | [diff] [blame] | 91 | end |
| 92 | endcase |
| 93 | |
| 94 | // Unconditionally jump into the terminal error state in case an error is detected. |
| 95 | if (incr_err_i || mr_err_i) begin |
Andreas Kurth | f4d64f3 | 2022-11-02 14:37:30 +0000 | [diff] [blame] | 96 | aes_ctr_ns = CTR_ERROR; |
Pirmin Vogel | 3650691 | 2021-12-06 16:30:09 +0100 | [diff] [blame] | 97 | end |
| 98 | end |
| 99 | |
| 100 | // Registers |
| 101 | always_ff @(posedge clk_i or negedge rst_ni) begin |
| 102 | if (!rst_ni) begin |
| 103 | ctr_slice_idx_q <= '0; |
| 104 | ctr_carry_q <= '0; |
| 105 | end else begin |
| 106 | ctr_slice_idx_q <= ctr_slice_idx_d; |
| 107 | ctr_carry_q <= ctr_carry_d; |
| 108 | end |
| 109 | end |
| 110 | |
Pirmin Vogel | 9ac6054 | 2022-01-10 15:40:48 +0100 | [diff] [blame] | 111 | // SEC_CM: CTR.FSM.SPARSE |
Andreas Kurth | f4d64f3 | 2022-11-02 14:37:30 +0000 | [diff] [blame] | 112 | `PRIM_FLOP_SPARSE_FSM(u_state_regs, aes_ctr_ns, aes_ctr_cs, aes_ctr_e, CTR_IDLE) |
Pirmin Vogel | 3650691 | 2021-12-06 16:30:09 +0100 | [diff] [blame] | 113 | |
| 114 | // Forward slice index. |
| 115 | assign ctr_slice_idx_o = ctr_slice_idx_q; |
| 116 | |
| 117 | //////////////// |
| 118 | // Assertions // |
| 119 | //////////////// |
| 120 | `ASSERT(AesCtrStateValid, !alert_o |-> aes_ctr_cs inside { |
Andreas Kurth | f4d64f3 | 2022-11-02 14:37:30 +0000 | [diff] [blame] | 121 | CTR_IDLE, |
| 122 | CTR_INCR |
Pirmin Vogel | 3650691 | 2021-12-06 16:30:09 +0100 | [diff] [blame] | 123 | }) |
| 124 | |
| 125 | endmodule |