| // Copyright lowRISC contributors. |
| // Licensed under the Apache License, Version 2.0, see LICENSE for details. |
| // SPDX-License-Identifier: Apache-2.0 |
| // |
| // Description: csrng instantiation request state machine module |
| // |
| // handles instantiation requests from all requesting interfaces |
| |
| module csrng_main_sm import csrng_pkg::*; ( |
| input logic clk_i, |
| input logic rst_ni, |
| |
| // ins req interface |
| input logic acmd_avail_i, |
| output logic acmd_accept_o, |
| input logic [2:0] acmd_i, |
| input logic acmd_eop_i, |
| input logic ctr_drbg_cmd_req_rdy_i, |
| input logic flag0_i, |
| output logic cmd_entropy_req_o, |
| input logic cmd_entropy_avail_i, |
| output logic instant_req_o, |
| output logic reseed_req_o, |
| output logic generate_req_o, |
| output logic update_req_o, |
| output logic uninstant_req_o |
| ); |
| |
| // Encoding generated with ./sparse-fsm-encode.py -d 3 -m 9 -n 8 -s 3053040243 |
| // Hamming distance histogram: |
| // |
| // 0: -- |
| // 1: -- |
| // 2: -- |
| // 3: |||||||||||||||||||| (30.56%) |
| // 4: |||||||||||||||||||| (30.56%) |
| // 5: |||||||||||| (19.44%) |
| // 6: ||||||||| (13.89%) |
| // 7: ||| (5.56%) |
| // 8: -- |
| // |
| // Minimum Hamming distance: 3 |
| // Maximum Hamming distance: 7 |
| // |
| |
| localparam int StateWidth = 8; |
| typedef enum logic [StateWidth-1:0] { |
| Idle = 8'b01100100, // idle |
| InstantPrep = 8'b11000010, // instantiate prep |
| InstantReq = 8'b11000101, // instantiate request (takes adata or entropy) |
| ReseedPrep = 8'b00010001, // reseed prep |
| ReseedReq = 8'b10110010, // reseed request (takes adata and entropy and Key,V,RC) |
| GenerateReq = 8'b01111010, // generate request (takes adata? and Key,V,RC) |
| UpdatePrep = 8'b00001101, // update prep |
| UpdateReq = 8'b10101011, // update request (takes adata and Key,V,RC) |
| UninstantReq = 8'b00101000 // uninstantiate request (no input) |
| } state_e; |
| |
| state_e state_d, state_q; |
| |
| logic [StateWidth-1:0] state_raw_q; |
| |
| // This primitive is used to place a size-only constraint on the |
| // flops in order to prevent FSM state encoding optimizations. |
| prim_flop #( |
| .Width(StateWidth), |
| .ResetValue(StateWidth'(Idle)) |
| ) u_state_regs ( |
| .clk_i, |
| .rst_ni, |
| .d_i ( state_d ), |
| .q_o ( state_raw_q ) |
| ); |
| |
| assign state_q = state_e'(state_raw_q); |
| |
| always_comb begin |
| state_d = state_q; |
| acmd_accept_o = 1'b0; |
| cmd_entropy_req_o = 1'b0; |
| instant_req_o = 1'b0; |
| reseed_req_o = 1'b0; |
| generate_req_o = 1'b0; |
| update_req_o = 1'b0; |
| uninstant_req_o = 1'b0; |
| unique case (state_q) |
| Idle: begin |
| if (ctr_drbg_cmd_req_rdy_i) begin |
| if (acmd_avail_i) begin |
| acmd_accept_o = 1'b1; |
| if (acmd_i == INS) begin |
| if (acmd_eop_i) begin |
| state_d = InstantPrep; |
| end |
| end else if (acmd_i == RES) begin |
| if (acmd_eop_i) begin |
| state_d = ReseedPrep; |
| end |
| end else if (acmd_i == GEN) begin |
| state_d = GenerateReq; |
| end else if (acmd_i == UPD) begin |
| if (acmd_eop_i) begin |
| state_d = UpdatePrep; |
| end |
| end else if (acmd_i == UNI) begin |
| state_d = UninstantReq; |
| end |
| end |
| end |
| end |
| InstantPrep: begin |
| if (flag0_i) begin |
| // assumes all adata is present now |
| state_d = InstantReq; |
| end else begin |
| // delay one clock to fix timing issue |
| cmd_entropy_req_o = 1'b1; |
| if (cmd_entropy_avail_i) begin |
| state_d = InstantReq; |
| end |
| end |
| end |
| InstantReq: begin |
| instant_req_o = 1'b1; |
| state_d = Idle; |
| end |
| ReseedPrep: begin |
| acmd_accept_o = 1'b1; |
| cmd_entropy_req_o = 1'b1; |
| // assumes all adata is present now |
| if (cmd_entropy_avail_i) begin |
| state_d = ReseedReq; |
| end |
| end |
| ReseedReq: begin |
| reseed_req_o = 1'b1; |
| state_d = Idle; |
| end |
| GenerateReq: begin |
| acmd_accept_o = 1'b1; |
| generate_req_o = 1'b1; |
| state_d = Idle; |
| end |
| UpdatePrep: begin |
| // assumes all adata is present now |
| acmd_accept_o = 1'b1; |
| state_d = UpdateReq; |
| end |
| UpdateReq: begin |
| update_req_o = 1'b1; |
| state_d = Idle; |
| end |
| UninstantReq: begin |
| uninstant_req_o = 1'b1; |
| state_d = Idle; |
| end |
| default: state_d = Idle; |
| endcase |
| end |
| |
| endmodule |