//******************************************************************************** // SPDX-License-Identifier: Apache-2.0 // Copyright 2020 Western Digital Corporation or its affiliates. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. //******************************************************************************** //******************************************************************************** // Icache closely coupled memory --- ICCM //******************************************************************************** module el2_ifu_iccm_mem #( parameter ICCM_BITS, parameter ICCM_BANK_INDEX_LO, parameter ICCM_INDEX_BITS, parameter ICCM_BANK_HI, parameter ICCM_NUM_BANKS, parameter ICCM_BANK_BITS )( input logic clk, // Clock only while core active. Through one clock header. For flops with second clock header built in. Connected to ACTIVE_L2CLK. input logic active_clk, // Clock only while core active. Through two clock headers. For flops without second clock header built in. input logic rst_l, // reset, active low input logic clk_override, // Override non-functional clock gating input logic iccm_wren, // ICCM write enable input logic iccm_rden, // ICCM read enable input logic [ICCM_BITS-1:1] iccm_rw_addr, // ICCM read/write address input logic iccm_buf_correct_ecc, // ICCM is doing a single bit error correct cycle input logic iccm_correction_state, // ICCM under a correction - This is needed to guard replacements when hit input logic [2:0] iccm_wr_size, // ICCM write size input logic [77:0] iccm_wr_data, // ICCM write data //input el2_ccm_ext_in_pkt_t [ICCM_NUM_BANKS-1:0] iccm_ext_in_pkt, // External packet input [ICCM_NUM_BANKS-1:0] TEST1, input [ICCM_NUM_BANKS-1:0] RME, input [ICCM_NUM_BANKS-1:0][3:0] RM, input [ICCM_NUM_BANKS-1:0] LS, input [ICCM_NUM_BANKS-1:0] DS, input [ICCM_NUM_BANKS-1:0] TEST-RNM, input [ICCM_NUM_BANKS-1:0] BC1, input [ICCM_NUM_BANKS-1:0] BC2, output logic [63:0] iccm_rd_data, // ICCM read data output logic [77:0] iccm_rd_data_ecc, // ICCM read ecc input logic scan_mode // Scan mode control ); logic [ICCM_NUM_BANKS-1:0] wren_bank; logic [ICCM_NUM_BANKS-1:0] rden_bank; logic [ICCM_NUM_BANKS-1:0] iccm_clken; logic [ICCM_NUM_BANKS-1:0] [ICCM_BITS-1:ICCM_BANK_INDEX_LO] addr_bank; logic [ICCM_NUM_BANKS-1:0] [38:0] iccm_bank_dout, iccm_bank_dout_fn; logic [ICCM_NUM_BANKS-1:0] [38:0] iccm_bank_wr_data; logic [ICCM_BITS-1:1] addr_bank_inc; logic [ICCM_BANK_HI : 2] iccm_rd_addr_hi_q; logic [ICCM_BANK_HI : 1] iccm_rd_addr_lo_q; logic [63:0] iccm_rd_data_pre; logic [63:0] iccm_data; logic [1:0] addr_incr; logic [ICCM_NUM_BANKS-1:0] [38:0] iccm_bank_wr_data_vec; // logic to handle hard persisten faults logic [1:0] [ICCM_BITS-1:2] redundant_address; logic [1:0] [38:0] redundant_data; logic [1:0] redundant_valid; logic [ICCM_NUM_BANKS-1:0] sel_red1, sel_red0, sel_red1_q, sel_red0_q; logic [38:0] redundant_data0_in, redundant_data1_in; logic redundant_lru, redundant_lru_in, redundant_lru_en; logic redundant_data0_en; logic redundant_data1_en; logic r0_addr_en, r1_addr_en; // Testing persistent flip // logic [3:0] not_iccm_bank_dout; // logic [15:3] ecc_insert_flip_in, ecc_insert_flip; // logic flip_en, flip_match, flip_match_q; // // assign flip_in = (iccm_rw_addr[3:2] != 2'b00); // dont flip when bank0 - this is to make some progress in DMA streaming cases // assign flip_en = iccm_rden; // // rvdffs #(1) flipmatch (.*, // .clk(clk), // .din(flip_in), // .en(flip_en), // .dout(flip_match_q)); // // end of testing flip assign addr_incr[1:0] = (iccm_wr_size[1:0] == 2'b11) ? 2'b10: 2'b01; assign addr_bank_inc[ICCM_BITS-1 : 1] = iccm_rw_addr[ICCM_BITS-1 : 1] + addr_incr[1:0]; for (genvar i=0; i> (16*iccm_rd_addr_lo_q[1]))}); assign iccm_rd_data[63:0] = {iccm_data[63:0]}; assign iccm_rd_data_ecc[77:0] = {iccm_bank_dout_fn[iccm_rd_addr_hi_q][38:0], iccm_bank_dout_fn[iccm_rd_addr_lo_q[ICCM_BANK_HI:2]][38:0]}; endmodule // el2_ifu_iccm_mem