blob: c7eb613f522046c6c032c39429c59e0c97c90b13 [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: csrng app cmd request state machine module
//
// - handles all app cmd requests from all requesting interfaces
module csrng_main_sm import csrng_pkg::*; #(
parameter int StateWidth = 8
) (
input logic clk_i,
input logic rst_ni,
input logic enable_i,
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,
output logic clr_adata_packer_o,
input logic cmd_complete_i,
input logic local_escalate_i,
output logic [StateWidth-1:0] main_sm_state_o,
output logic main_sm_alert_o,
output logic main_sm_err_o
);
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};
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;
clr_adata_packer_o = 1'b0;
main_sm_alert_o = 1'b0;
main_sm_err_o = 1'b0;
unique case (state_q)
Idle: begin
if (enable_i) begin
if (ctr_drbg_cmd_req_rdy_i) begin
// signal the arbiter to grant this request
if (acmd_avail_i) begin
acmd_accept_o = 1'b1;
state_d = ParseCmd;
end
end
end
end
ParseCmd: begin
if (!enable_i) begin
state_d = Idle;
end else begin
if (ctr_drbg_cmd_req_rdy_i) begin
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
if (acmd_eop_i) begin
state_d = GeneratePrep;
end
end else if (acmd_i == UPD) begin
if (acmd_eop_i) begin
state_d = UpdatePrep;
end
end else if (acmd_i == UNI) begin
if (acmd_eop_i) begin
state_d = UninstantPrep;
end
end else begin
// command was not supported
main_sm_alert_o = 1'b1;
end
end
end
end
InstantPrep: begin
if (!enable_i) begin
state_d = Idle;
end else 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
end
InstantReq: begin
if (!enable_i) begin
state_d = Idle;
end else begin
instant_req_o = 1'b1;
state_d = ClrAData;
end
end
ReseedPrep: begin
if (!enable_i) begin
state_d = Idle;
end else begin
if (flag0_i) begin
// assumes all adata is present now
state_d = ReseedReq;
end else begin
// delay one clock to fix timing issue
cmd_entropy_req_o = 1'b1;
if (cmd_entropy_avail_i) begin
state_d = ReseedReq;
end
end
end
end
ReseedReq: begin
if (!enable_i) begin
state_d = Idle;
end else begin
reseed_req_o = 1'b1;
state_d = ClrAData;
end
end
GeneratePrep: begin
if (!enable_i) begin
state_d = Idle;
end else begin
// assumes all adata is present now
state_d = GenerateReq;
end
end
GenerateReq: begin
if (!enable_i) begin
state_d = Idle;
end else begin
generate_req_o = 1'b1;
state_d = ClrAData;
end
end
UpdatePrep: begin
if (!enable_i) begin
state_d = Idle;
end else begin
// assumes all adata is present now
state_d = UpdateReq;
end
end
UpdateReq: begin
if (!enable_i) begin
state_d = Idle;
end else begin
update_req_o = 1'b1;
state_d = ClrAData;
end
end
UninstantPrep: begin
if (!enable_i) begin
state_d = Idle;
end else begin
// assumes all adata is present now
state_d = UninstantReq;
end
end
UninstantReq: begin
if (!enable_i) begin
state_d = Idle;
end else begin
uninstant_req_o = 1'b1;
state_d = ClrAData;
end
end
ClrAData: begin
if (!enable_i) begin
state_d = Idle;
end else begin
clr_adata_packer_o = 1'b1;
state_d = CmdCompWait;
end
end
CmdCompWait: begin
if (!enable_i) begin
state_d = Idle;
end else begin
if (cmd_complete_i) begin
state_d = Idle;
end
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