blob: cebbc08879cb5753d9e77e65d45924abb9884396 [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 #(
localparam int StateWidth = 9
) (
input logic clk_i,
input logic rst_ni,
input logic edn_enable_i,
input logic boot_req_mode_i,
input logic auto_req_mode_i,
input logic sw_cmd_req_load_i,
output logic boot_wr_cmd_reg_o,
output logic boot_wr_cmd_genfifo_o,
output logic auto_set_intr_gate_o,
output logic auto_clr_intr_gate_o,
output logic auto_first_ack_wait_o,
output logic main_sm_done_pulse_o,
input logic csrng_cmd_ack_i,
output logic capt_gencmd_fifo_cnt_o,
output logic boot_send_gencmd_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,
input logic local_escalate_i,
output logic auto_req_mode_busy_o,
output logic main_sm_busy_o,
output logic [StateWidth-1:0] main_sm_state_o,
output logic main_sm_err_o
);
//
// Hamming distance histogram:
//
// 0: --
// 1: --
// 2: --
// 3: ||||||||||| (17.54%)
// 4: |||||||||||||||||||| (29.82%)
// 5: ||||||||||||||||| (26.32%)
// 6: ||||||||||| (17.54%)
// 7: ||||| (7.60%)
// 8: (1.17%)
// 9: --
//
// Minimum Hamming distance: 3
// Maximum Hamming distance: 8
// Minimum Hamming weight: 2
// Maximum Hamming weight: 7
//
typedef enum logic [StateWidth-1:0] {
Idle = 9'b110000101, // idle
BootLoadIns = 9'b110110111, // boot: load the instantiate command
BootLoadGen = 9'b000000011, // boot: load the generate command
BootInsAckWait = 9'b011010010, // boot: wait for instantiate command ack
BootCaptGenCnt = 9'b010111010, // boot: capture the gen fifo count
BootSendGenCmd = 9'b011100100, // boot: send the generate command
BootGenAckWait = 9'b101101100, // boot: wait for generate command ack
BootPulse = 9'b100001010, // boot: signal a done pulse
BootDone = 9'b011011111, // boot: stay in done state until reset
AutoLoadIns = 9'b001110000, // auto: load the instantiate command
AutoFirstAckWait = 9'b001001101, // auto: wait for first instantiate command ack
AutoAckWait = 9'b101100011, // auto: wait for instantiate command ack
AutoDispatch = 9'b110101110, // auto: determine next command to be sent
AutoCaptGenCnt = 9'b000110101, // auto: capture the gen fifo count
AutoSendGenCmd = 9'b111111000, // auto: send the generate command
AutoCaptReseedCnt = 9'b000100110, // auto: capture the reseed fifo count
AutoSendReseedCmd = 9'b101010110, // auto: send the reseed command
SWPortMode = 9'b100111001, // swport: no hw request mode
Error = 9'b010010001 // illegal state reached and hang
} state_e;
state_e state_d, state_q;
`PRIM_FLOP_SPARSE_FSM(u_state_regs, state_d, state_q, state_e, Idle)
assign main_sm_state_o = state_q;
assign main_sm_busy_o = (state_q != Idle) && (state_q != BootPulse) &&
(state_q != BootDone) && (state_q != SWPortMode);
always_comb begin
state_d = state_q;
boot_wr_cmd_reg_o = 1'b0;
boot_wr_cmd_genfifo_o = 1'b0;
boot_send_gencmd_o = 1'b0;
auto_set_intr_gate_o = 1'b0;
auto_clr_intr_gate_o = 1'b0;
auto_first_ack_wait_o = 1'b0;
auto_req_mode_busy_o = 1'b0;
capt_gencmd_fifo_cnt_o = 1'b0;
send_gencmd_o = 1'b0;
capt_rescmd_fifo_cnt_o = 1'b0;
send_rescmd_o = 1'b0;
main_sm_done_pulse_o = 1'b0;
main_sm_err_o = 1'b0;
unique case (state_q)
Idle: begin
if (boot_req_mode_i && edn_enable_i) begin
state_d = BootLoadIns;
end else if (auto_req_mode_i && edn_enable_i) begin
state_d = AutoLoadIns;
end else if (edn_enable_i) begin
main_sm_done_pulse_o = 1'b1;
state_d = SWPortMode;
end
end
BootLoadIns: begin
boot_wr_cmd_reg_o = 1'b1;
state_d = BootLoadGen;
end
BootLoadGen: begin
boot_wr_cmd_genfifo_o = 1'b1;
state_d = BootInsAckWait;
end
BootInsAckWait: begin
if (csrng_cmd_ack_i) begin
state_d = BootCaptGenCnt;
end
end
BootCaptGenCnt: begin
capt_gencmd_fifo_cnt_o = 1'b1;
state_d = BootSendGenCmd;
end
BootSendGenCmd: begin
boot_send_gencmd_o = 1'b1;
if (cmd_sent_i) begin
state_d = BootGenAckWait;
end
end
BootGenAckWait: begin
if (csrng_cmd_ack_i) begin
state_d = BootPulse;
end
end
BootPulse: begin
main_sm_done_pulse_o = 1'b1;
state_d = BootDone;
end
BootDone: begin
if (!edn_enable_i) begin
state_d = Idle;
end
end
//-----------------------------------
AutoLoadIns: begin
auto_set_intr_gate_o = 1'b1;
auto_first_ack_wait_o = 1'b1;
if (sw_cmd_req_load_i) begin
state_d = AutoFirstAckWait;
end
end
AutoFirstAckWait: begin
auto_first_ack_wait_o = 1'b1;
if (csrng_cmd_ack_i) begin
auto_clr_intr_gate_o = 1'b1;
state_d = AutoDispatch;
end
end
AutoAckWait: begin
auto_req_mode_busy_o = 1'b1;
if (csrng_cmd_ack_i) begin
state_d = AutoDispatch;
end
end
AutoDispatch: begin
auto_req_mode_busy_o = 1'b1;
if (!auto_req_mode_i) begin
main_sm_done_pulse_o = 1'b1;
state_d = Idle;
end else begin
if (max_reqs_cnt_zero_i) begin
state_d = AutoCaptReseedCnt;
end else begin
state_d = AutoCaptGenCnt;
end
end
end
AutoCaptGenCnt: begin
auto_req_mode_busy_o = 1'b1;
capt_gencmd_fifo_cnt_o = 1'b1;
state_d = AutoSendGenCmd;
end
AutoSendGenCmd: begin
auto_req_mode_busy_o = 1'b1;
send_gencmd_o = 1'b1;
if (cmd_sent_i) begin
state_d = AutoAckWait;
end
end
AutoCaptReseedCnt: begin
auto_req_mode_busy_o = 1'b1;
capt_rescmd_fifo_cnt_o = 1'b1;
state_d = AutoSendReseedCmd;
end
AutoSendReseedCmd: begin
auto_req_mode_busy_o = 1'b1;
send_rescmd_o = 1'b1;
if (cmd_sent_i) begin
state_d = AutoAckWait;
end
end
SWPortMode: begin
if (!edn_enable_i) begin
state_d = Idle;
end
end
Error: begin
main_sm_err_o = 1'b1;
end
default: state_d = Error;
endcase
if (local_escalate_i) begin
state_d = Error;
end
end
endmodule