blob: 85cd78552650cca13bbd5cce728e33180c6d10cb [file] [log] [blame]
// Copyright lowRISC contributors.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
//
// Description: edn csrng application request state machine module
//
// does hardware-based csrng app interface command requests
module edn_main_sm (
input logic clk_i,
input logic rst_ni,
input logic auto_req_mode_i,
output logic seq_auto_req_mode_o,
output logic auto_req_mode_end_o,
input logic csrng_cmd_ack_i,
output logic capt_gencmd_fifo_cnt_o,
output logic send_gencmd_o,
input logic max_reqs_cnt_zero_i,
output logic capt_rescmd_fifo_cnt_o,
output logic send_rescmd_o,
input logic cmd_sent_i
);
// Encoding generated with ./sparse-fsm-encode.py -d 3 -m 7 -n 6 -s 4153446945
// Hamming distance histogram:
//
// 0: --
// 1: --
// 2: --
// 3: |||||||||||||||||||| (57.14%)
// 4: ||||||||||||||| (42.86%)
// 5: --
// 6: --
//
// Minimum Hamming distance: 3
// Maximum Hamming distance: 4
//
localparam int StateWidth = 6;
typedef enum logic [StateWidth-1:0] {
Idle = 6'b011000, // idle (hamming distance = 3)
AckWait = 6'b110001, // wait for csrng req ack
Dispatch = 6'b000100, // dispatch the next cmd after ack
CaptGenCnt = 6'b101101, // capture the generate fifo count
SendGenCmd = 6'b000011, // send the generate cmd req
CaptReseedCnt = 6'b101010, // capture the reseed fifo count
SendReseedCmd = 6'b011111 // send the reseed cmd req
} 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;
capt_gencmd_fifo_cnt_o = 1'b0;
send_gencmd_o = 1'b0;
capt_rescmd_fifo_cnt_o = 1'b0;
send_rescmd_o = 1'b0;
seq_auto_req_mode_o = 1'b1;
auto_req_mode_end_o = 1'b0;
unique case (state_q)
Idle: begin
seq_auto_req_mode_o = 1'b0;
if (auto_req_mode_i) begin
state_d = AckWait;
end
end
AckWait: begin
if (csrng_cmd_ack_i) begin
state_d = Dispatch;
end
end
Dispatch: begin
if (!auto_req_mode_i) begin
auto_req_mode_end_o = 1'b1;
state_d = Idle;
end else begin
if (max_reqs_cnt_zero_i) begin
state_d = CaptReseedCnt;
end else begin
state_d = CaptGenCnt;
end
end
end
CaptGenCnt: begin
capt_gencmd_fifo_cnt_o = 1'b1;
state_d = SendGenCmd;
end
SendGenCmd: begin
send_gencmd_o = 1'b1;
if (cmd_sent_i) begin
state_d = AckWait;
end
end
CaptReseedCnt: begin
capt_rescmd_fifo_cnt_o = 1'b1;
state_d = SendReseedCmd;
end
SendReseedCmd: begin
send_rescmd_o = 1'b1;
if (cmd_sent_i) begin
state_d = AckWait;
end
end
default: state_d = Idle;
endcase
end
endmodule