module arc4 ( input logic clk, input logic rst_n, input logic en, output logic rdy, input logic [23:0] key, output logic [7:0] ct_addr, input logic [7:0] ct_rddata, output logic [7:0] pt_addr, input logic [7:0] pt_rddata, output logic [7:0] pt_wrdata, output logic pt_wren ); logic s_wren; logic [7:0] s_addr; logic [7:0] s_wrdata, s_rddata; logic i_en, i_rdy, i_wren; logic [7:0] i_addr; logic [7:0] i_wrdata; logic k_en, k_rdy, k_wren; logic [7:0] k_addr; logic [7:0] k_wrdata; logic p_en, p_rdy, p_s_wren, p_pt_wren; logic [7:0] p_s_addr, p_ct_addr, p_pt_addr; logic [7:0] p_s_wrdata, p_pt_wrdata; enum logic [2:0] { IDLE, INIT_BEGIN, INIT, KSA_BEGIN, KSA, PRGA_BEGIN, PRGA, DONE } state; s_core_mem s ( .address(s_addr), .clock(clk), .data(s_wrdata), .wren(s_wren), .q(s_rddata) ); init i ( .clk, .rst_n, .en(i_en), .rdy(i_rdy), .addr(i_addr), .wrdata(i_wrdata), .wren(i_wren) ); ksa k ( .clk, .rst_n, .en(k_en), .rdy(k_rdy), .key, .addr(k_addr), .rddata(s_rddata), .wrdata(k_wrdata), .wren(k_wren) ); prga p ( .clk, .rst_n, .en(p_en), .rdy(p_rdy), .key, .s_addr(p_s_addr), .s_rddata, .s_wrdata(p_s_wrdata), .s_wren(p_s_wren), .ct_addr(p_ct_addr), .ct_rddata, .pt_addr(p_pt_addr), .pt_rddata, .pt_wrdata(p_pt_wrdata), .pt_wren(p_pt_wren) ); always_ff @(posedge clk) begin: fsm if (~rst_n) begin state <= IDLE; end else unique case (state) IDLE: if (en) state <= INIT_BEGIN; INIT_BEGIN: if (i_rdy) state <= INIT; INIT: if (i_rdy) state <= KSA_BEGIN; KSA_BEGIN: if (k_rdy) state <= KSA; KSA: if (k_rdy) state <= PRGA_BEGIN; PRGA_BEGIN: if (p_rdy) state <= PRGA; PRGA: if (p_rdy) state <= DONE; DONE: state <= DONE; default: state <= IDLE; endcase end: fsm always_comb begin: controller rdy = '0; i_en = '0; k_en = '0; p_en = '0; s_wren = '0; s_addr = '0; s_wrdata = '0; ct_addr = '0; pt_wren = '0; pt_addr = '0; pt_wrdata = '0; unique case (state) IDLE: rdy = '1; INIT_BEGIN: i_en = i_rdy; INIT: begin s_wren = i_wren; s_addr = i_addr; s_wrdata = i_wrdata; end KSA_BEGIN: k_en = k_rdy; KSA: begin s_wren = k_wren; s_addr = k_addr; s_wrdata = k_wrdata; end PRGA_BEGIN: p_en = p_rdy; PRGA: begin s_wren = p_s_wren; s_addr = p_s_addr; s_wrdata = p_s_wrdata; ct_addr = p_ct_addr; pt_wren = p_pt_wren; pt_addr = p_pt_addr; pt_wrdata = p_pt_wrdata; end DONE: rdy = '1; default: begin end endcase end: controller endmodule: arc4