|  | // 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  bit EnMasking = 1'b0, | 
|  | 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 [sha3_pkg::StateW-1:0] state_i [Share], | 
|  |  | 
|  | // Config | 
|  | input endian_swap_i | 
|  | ); | 
|  |  | 
|  | localparam int StateAddrW = $clog2(sha3_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 (32), | 
|  | .Outstanding (1), | 
|  | .ByteAccess  (1), | 
|  | .ErrOnWrite  (1), | 
|  | .ErrOnRead   (0) | 
|  | ) u_tlul_adapter ( | 
|  | .clk_i, | 
|  | .rst_ni, | 
|  |  | 
|  | .tl_i, | 
|  | .tl_o, | 
|  | .en_ifetch_i (prim_mubi_pkg::MuBi4False), | 
|  | .req_o       (tlram_req), | 
|  | .req_type_o  (), | 
|  | .gnt_i       (tlram_gnt), | 
|  | .we_o        (tlram_we ), | 
|  | .addr_o      (tlram_addr), | 
|  | .wdata_o     (unused_tlram_wdata), | 
|  | .wmask_o     (unused_tlram_wmask), | 
|  | .intg_error_o(), | 
|  | .rdata_i     (tlram_rdata), | 
|  | .rvalid_i    (tlram_rvalid), | 
|  | .rerror_i    (tlram_rerror) | 
|  | ); | 
|  |  | 
|  | always_ff @(posedge clk_i or negedge rst_ni) begin | 
|  | if (!rst_ni) begin | 
|  | tlram_rdata <= '0; | 
|  | end else if (tlram_req & ~tlram_we) begin | 
|  | tlram_rdata <= conv_endian32(tlram_rdata_endian, endian_swap_i); | 
|  | end | 
|  | end | 
|  |  | 
|  | // 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 (sha3_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]; | 
|  |  | 
|  | assign tlram_rdata_endian = int'(addr_sel) < Share ? muxed_state[addr_sel] : 0; | 
|  |  | 
|  | endmodule |