| // Copyright lowRISC contributors. | 
 | // Licensed under the Apache License, Version 2.0, see LICENSE for details. | 
 | // SPDX-License-Identifier: Apache-2.0 | 
 | // | 
 | // Keccak state read | 
 |  | 
 | `include "prim_assert.sv" | 
 |  | 
 | module kmac_staterd | 
 |   import kmac_pkg::*; | 
 | #( | 
 |   // TL-UL Address Width. Should be bigger than | 
 |   // $clog2(kmac_pkg::StateW) * Share | 
 |   parameter int AddrW = 9, | 
 |  | 
 |   // EnMasking: Enable masking security hardening inside keccak_round | 
 |   // If it is enabled, the result digest will be two set of 1600bit. | 
 |   parameter  int EnMasking = 0, | 
 |   localparam int Share = (EnMasking) ? 2 : 1  // derived parameter | 
 | ) ( | 
 |   input clk_i, | 
 |   input rst_ni, | 
 |  | 
 |   input  tlul_pkg::tl_h2d_t tl_i, | 
 |   output tlul_pkg::tl_d2h_t tl_o, | 
 |  | 
 |   // State in | 
 |   input valid_i, | 
 |   input [StateW-1:0] state_i [Share], | 
 |  | 
 |   // Config | 
 |   input endian_swap_i | 
 | ); | 
 |  | 
 |   localparam int StateAddrW = $clog2(kmac_pkg::StateW/32); | 
 |   localparam int SelAddrW   = AddrW-2-StateAddrW; | 
 |  | 
 |   ///////////// | 
 |   // Signals // | 
 |   ///////////// | 
 |  | 
 |   // TL-UL Adapter signals | 
 |   logic             tlram_req; | 
 |   logic             tlram_gnt; | 
 |   logic             tlram_we; | 
 |   logic [AddrW-3:0] tlram_addr;   // Word base | 
 |   logic [31:0]      unused_tlram_wdata; | 
 |   logic [31:0]      unused_tlram_wmask; | 
 |   logic [31:0]      tlram_rdata; | 
 |   logic             tlram_rvalid; | 
 |   logic [1:0]       tlram_rerror; | 
 |   logic [31:0]      tlram_rdata_endian; | 
 |  | 
 |   // TL Adapter | 
 |   tlul_adapter_sram #( | 
 |     .SramAw (AddrW-2), | 
 |     .SramDw (323), | 
 |     .Outstanding (1), | 
 |     .ByteAccess  (1), | 
 |     .ErrOnWrite  (1), | 
 |     .ErrOnRead   (0) | 
 |   ) u_tlul_adapter ( | 
 |     .clk_i, | 
 |     .rst_ni, | 
 |  | 
 |     .tl_i, | 
 |     .tl_o, | 
 |  | 
 |     .req_o    (tlram_req), | 
 |     .gnt_i    (tlram_gnt), | 
 |     .we_o     (tlram_we ), | 
 |     .addr_o   (tlram_addr), | 
 |     .wdata_o  (unused_tlram_wdata), | 
 |     .wmask_o  (unused_tlram_wmask), | 
 |     .rdata_i  (tlram_rdata), | 
 |     .rvalid_i (tlram_rvalid), | 
 |     .rerror_i (tlram_rerror) | 
 |   ); | 
 |  | 
 |   assign tlram_rdata = conv_endian32(tlram_rdata_endian, endian_swap_i); | 
 |  | 
 |   // Always grant | 
 |   assign tlram_gnt = tlram_req & ~tlram_we; | 
 |  | 
 |   // always no error on reading | 
 |   assign tlram_rerror = '0; | 
 |  | 
 |   always_ff @(posedge clk_i or negedge rst_ni) begin | 
 |     if (!rst_ni) tlram_rvalid <= 1'b0; | 
 |     else         tlram_rvalid <= tlram_req & !tlram_we; | 
 |   end | 
 |  | 
 |   logic [31:0] muxed_state [Share]; | 
 |  | 
 |  | 
 |   for (genvar i = 0 ; i < Share ; i++) begin : gen_slicer | 
 |     prim_slicer #( | 
 |       .InW (kmac_pkg::StateW), | 
 |       .OutW (32), | 
 |       .IndexW (StateAddrW) | 
 |     ) u_state_slice ( | 
 |       .sel_i (tlram_addr[StateAddrW-1:0]), | 
 |       .data_i (state_i[i]), | 
 |       .data_o (muxed_state[i]) | 
 |     ); | 
 |   end : gen_slicer | 
 |  | 
 |   logic [SelAddrW-1:0] addr_sel; | 
 |   assign addr_sel = tlram_addr[StateAddrW+:SelAddrW]; | 
 |  | 
 |   always_comb begin | 
 |     tlram_rdata_endian = '0; | 
 |     for (int i = 0 ; i < Share ; i++) begin | 
 |       if ($unsigned(i) == addr_sel) begin | 
 |         tlram_rdata_endian = muxed_state[i]; | 
 |       end | 
 |     end | 
 |   end | 
 |  | 
 | endmodule | 
 |  |