Project Full coverage report
Current view: Cores-VeeR-EL2—Cores-VeeR-EL2—design—lsu—el2_lsu_dccm_ctl.sv Coverage Hit Total
Test Date: 19-09-2024 Toggle 72.3% 81 112
Test: all Branch 0.0% 0 0

            Line data    Source code
       1              : // SPDX-License-Identifier: Apache-2.0
       2              : // Copyright 2020 Western Digital Corporation or its affiliates.
       3              : //
       4              : // Licensed under the Apache License, Version 2.0 (the "License");
       5              : // you may not use this file except in compliance with the License.
       6              : // You may obtain a copy of the License at
       7              : //
       8              : // http://www.apache.org/licenses/LICENSE-2.0
       9              : //
      10              : // Unless required by applicable law or agreed to in writing, software
      11              : // distributed under the License is distributed on an "AS IS" BASIS,
      12              : // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      13              : // See the License for the specific language governing permissions and
      14              : // limitations under the License.
      15              : 
      16              : //********************************************************************************
      17              : // $Id$
      18              : //
      19              : //
      20              : // Owner:
      21              : // Function: DCCM for LSU pipe
      22              : // Comments: Single ported memory
      23              : //
      24              : //
      25              : // DC1 -> DC2 -> DC3 -> DC4 (Commit)
      26              : //
      27              : // //********************************************************************************
      28              : 
      29              : module el2_lsu_dccm_ctl
      30              : import el2_pkg::*;
      31              : #(
      32              : `include "el2_param.vh"
      33              :  )
      34              :   (
      35     61843746 :    input logic                             lsu_c2_m_clk,            // clocks
      36     61843746 :    input logic                             lsu_c2_r_clk,            // clocks
      37     61843746 :    input logic                             lsu_c1_r_clk,            // clocks
      38     61843746 :    input logic                             lsu_store_c1_r_clk,      // clocks
      39     61843746 :    input logic                             lsu_free_c2_clk,         // clocks
      40            0 :    input logic                             clk_override,            // Override non-functional clock gating
      41     61843746 :    input logic                             clk,                     // Clock only while core active.  Through one clock header.  For flops with    second clock header built in.  Connected to ACTIVE_L2CLK.
      42              : 
      43          316 :    input logic                             rst_l,                   // reset, active low
      44              : 
      45       478181 :    input                                   el2_lsu_pkt_t lsu_pkt_r,// lsu packets
      46       478184 :    input                                   el2_lsu_pkt_t lsu_pkt_m,// lsu packets
      47       478232 :    input                                   el2_lsu_pkt_t lsu_pkt_d,// lsu packets
      48       614420 :    input logic                             addr_in_dccm_d,          // address maps to dccm
      49            0 :    input logic                             addr_in_pic_d,           // address maps to pic
      50            0 :    input logic                             addr_in_pic_m,           // address maps to pic
      51       614420 :    input logic                             addr_in_dccm_m, addr_in_dccm_r,   // address in dccm per pipe stage
      52            0 :    input logic                             addr_in_pic_r,                    // address in pic  per pipe stage
      53        18768 :    input logic                             lsu_raw_fwd_lo_r, lsu_raw_fwd_hi_r,
      54      2279496 :    input logic                             lsu_commit_r,            // lsu instruction in r commits
      55        36568 :    input logic                             ldst_dual_m, ldst_dual_r,// load/store is unaligned at 32 bit boundary per pipe stage
      56              : 
      57              :    // lsu address down the pipe
      58       594111 :    input logic [31:0]                      lsu_addr_d,
      59       471774 :    input logic [pt.DCCM_BITS-1:0]          lsu_addr_m,
      60       594109 :    input logic [31:0]                      lsu_addr_r,
      61              : 
      62              :    // lsu address down the pipe - needed to check unaligned
      63       678187 :    input logic [pt.DCCM_BITS-1:0]          end_addr_d,
      64       678348 :    input logic [pt.DCCM_BITS-1:0]          end_addr_m,
      65       678346 :    input logic [pt.DCCM_BITS-1:0]          end_addr_r,
      66              : 
      67              : 
      68       258446 :    input logic                             stbuf_reqvld_any,        // write enable
      69        18811 :    input logic [pt.LSU_SB_BITS-1:0]        stbuf_addr_any,          // stbuf address (aligned)
      70              : 
      71         7574 :    input logic [pt.DCCM_DATA_WIDTH-1:0]    stbuf_data_any,          // the read out from stbuf
      72        50849 :    input logic [pt.DCCM_ECC_WIDTH-1:0]     stbuf_ecc_any,           // the encoded data with ECC bits
      73         5218 :    input logic [pt.DCCM_DATA_WIDTH-1:0]    stbuf_fwddata_hi_m,      // stbuf fowarding to load
      74         4892 :    input logic [pt.DCCM_DATA_WIDTH-1:0]    stbuf_fwddata_lo_m,      // stbuf fowarding to load
      75         4198 :    input logic [pt.DCCM_BYTE_WIDTH-1:0]    stbuf_fwdbyteen_hi_m,    // stbuf fowarding to load
      76         4202 :    input logic [pt.DCCM_BYTE_WIDTH-1:0]    stbuf_fwdbyteen_lo_m,    // stbuf fowarding to load
      77              : 
      78            0 :    output logic [pt.DCCM_DATA_WIDTH-1:0]   dccm_rdata_hi_r,         // data from the dccm
      79            0 :    output logic [pt.DCCM_DATA_WIDTH-1:0]   dccm_rdata_lo_r,         // data from the dccm
      80            0 :    output logic [pt.DCCM_ECC_WIDTH-1:0]    dccm_data_ecc_hi_r,      // data from the dccm + ecc
      81            0 :    output logic [pt.DCCM_ECC_WIDTH-1:0]    dccm_data_ecc_lo_r,
      82            0 :    output logic [pt.DCCM_DATA_WIDTH-1:0]   lsu_ld_data_r,           // right justified, ie load byte will have data at 7:0
      83        24694 :    output logic [pt.DCCM_DATA_WIDTH-1:0]   lsu_ld_data_corr_r,      // right justified & ECC corrected, ie load byte will have data at 7:0
      84              : 
      85            4 :    input logic                             lsu_double_ecc_error_r,  // lsu has a DED
      86            0 :    input logic                             single_ecc_error_hi_r,   // sec detected on hi dccm bank
      87            4 :    input logic                             single_ecc_error_lo_r,   // sec detected on lower dccm bank
      88            2 :    input logic [pt.DCCM_DATA_WIDTH-1:0]    sec_data_hi_r,           // corrected dccm data
      89            2 :    input logic [pt.DCCM_DATA_WIDTH-1:0]    sec_data_lo_r,           // corrected dccm data
      90            2 :    input logic [pt.DCCM_DATA_WIDTH-1:0]    sec_data_hi_r_ff,        // corrected dccm data
      91            2 :    input logic [pt.DCCM_DATA_WIDTH-1:0]    sec_data_lo_r_ff,        // corrected dccm data
      92            0 :    input logic [pt.DCCM_ECC_WIDTH-1:0]     sec_data_ecc_hi_r_ff,    // the encoded data with ECC bits
      93        50849 :    input logic [pt.DCCM_ECC_WIDTH-1:0]     sec_data_ecc_lo_r_ff,    // the encoded data with ECC bits
      94              : 
      95        47172 :    output logic [pt.DCCM_DATA_WIDTH-1:0]   dccm_rdata_hi_m,         // data from the dccm
      96        47172 :    output logic [pt.DCCM_DATA_WIDTH-1:0]   dccm_rdata_lo_m,         // data from the dccm
      97       154095 :    output logic [pt.DCCM_ECC_WIDTH-1:0]    dccm_data_ecc_hi_m,      // data from the dccm + ecc
      98       154095 :    output logic [pt.DCCM_ECC_WIDTH-1:0]    dccm_data_ecc_lo_m,
      99        54452 :    output logic [pt.DCCM_DATA_WIDTH-1:0]   lsu_ld_data_m,           // right justified, ie load byte will have data at 7:0
     100              : 
     101            4 :    input logic                             lsu_double_ecc_error_m,  // lsu has a DED
     102        47172 :    input logic [pt.DCCM_DATA_WIDTH-1:0]    sec_data_hi_m,           // corrected dccm data
     103        47172 :    input logic [pt.DCCM_DATA_WIDTH-1:0]    sec_data_lo_m,           // corrected dccm data
     104              : 
     105        81386 :    input logic [31:0]                      store_data_m,            // Store data M-stage
     106            0 :    input logic                             dma_dccm_wen,            // Perform DMA writes only for word/dword
     107            0 :    input logic                             dma_pic_wen,             // Perform PIC writes
     108           12 :    input logic [2:0]                       dma_mem_tag_m,           // DMA Buffer entry number M-stage
     109            0 :    input logic [31:0]                      dma_mem_addr,            // DMA request address
     110           12 :    input logic [63:0]                      dma_mem_wdata,           // DMA write data
     111           12 :    input logic [31:0]                      dma_dccm_wdata_lo,       // Shift the dma data to lower bits to make it consistent to lsu stores
     112            0 :    input logic [31:0]                      dma_dccm_wdata_hi,       // Shift the dma data to lower bits to make it consistent to lsu stores
     113            0 :    input logic [pt.DCCM_ECC_WIDTH-1:0]     dma_dccm_wdata_ecc_hi,   // ECC bits for the DMA wdata
     114        50849 :    input logic [pt.DCCM_ECC_WIDTH-1:0]     dma_dccm_wdata_ecc_lo,   // ECC bits for the DMA wdata
     115              : 
     116         1716 :    output logic [pt.DCCM_DATA_WIDTH-1:0]   store_data_hi_r,
     117        92644 :    output logic [pt.DCCM_DATA_WIDTH-1:0]   store_data_lo_r,
     118         1920 :    output logic [pt.DCCM_DATA_WIDTH-1:0]   store_datafn_hi_r,       // data from the dccm
     119        92644 :    output logic [pt.DCCM_DATA_WIDTH-1:0]   store_datafn_lo_r,       // data from the dccm
     120        56474 :    output logic [31:0]                     store_data_r,            // raw store data to be sent to bus
     121            4 :    output logic                            ld_single_ecc_error_r,
     122            4 :    output logic                            ld_single_ecc_error_r_ff,
     123              : 
     124            0 :    output logic [31:0]                     picm_mask_data_m,        // pic data to stbuf
     125       262888 :    output logic                            lsu_stbuf_commit_any,    // stbuf wins the dccm port or is to pic
     126       561000 :    output logic                            lsu_dccm_rden_m,         // dccm read
     127       561000 :    output logic                            lsu_dccm_rden_r,         // dccm read
     128              : 
     129            0 :    output logic                            dccm_dma_rvalid,         // dccm serviving the dma load
     130            4 :    output logic                            dccm_dma_ecc_error,      // DMA load had ecc error
     131           12 :    output logic [2:0]                      dccm_dma_rtag,           // DMA return tag
     132        39560 :    output logic [63:0]                     dccm_dma_rdata,          // dccm data to dma request
     133              : 
     134              :    // DCCM ports
     135       262892 :    output logic                            dccm_wren,               // dccm interface -- write
     136       561000 :    output logic                            dccm_rden,               // dccm interface -- write
     137        18811 :    output logic [pt.DCCM_BITS-1:0]         dccm_wr_addr_lo,         // dccm interface -- wr addr for lo bank
     138        18811 :    output logic [pt.DCCM_BITS-1:0]         dccm_wr_addr_hi,         // dccm interface -- wr addr for hi bank
     139       471780 :    output logic [pt.DCCM_BITS-1:0]         dccm_rd_addr_lo,         // dccm interface -- read address for lo bank
     140       678187 :    output logic [pt.DCCM_BITS-1:0]         dccm_rd_addr_hi,         // dccm interface -- read address for hi bank
     141         5374 :    output logic [pt.DCCM_FDATA_WIDTH-1:0]  dccm_wr_data_lo,         // dccm write data for lo bank
     142         5374 :    output logic [pt.DCCM_FDATA_WIDTH-1:0]  dccm_wr_data_hi,         // dccm write data for hi bank
     143              : 
     144        47172 :    input logic [pt.DCCM_FDATA_WIDTH-1:0]   dccm_rd_data_lo,         // dccm read data back from the dccm
     145        47172 :    input logic [pt.DCCM_FDATA_WIDTH-1:0]   dccm_rd_data_hi,         // dccm read data back from the dccm
     146              : 
     147              :    // PIC ports
     148            0 :    output logic                            picm_wren,               // write to pic
     149            0 :    output logic                            picm_rden,               // read to pick
     150            0 :    output logic                            picm_mken,               // write to pic need a mask
     151          430 :    output logic [31:0]                     picm_rdaddr,             // address for pic read access
     152          430 :    output logic [31:0]                     picm_wraddr,             // address for pic write access
     153        92644 :    output logic [31:0]                     picm_wr_data,            // write data
     154            0 :    input logic [31:0]                      picm_rd_data,            // read data
     155              : 
     156            0 :    input logic                             scan_mode                // scan mode
     157              : );
     158              : 
     159              : 
     160              :    localparam DCCM_WIDTH_BITS = $clog2(pt.DCCM_BYTE_WIDTH);
     161              : 
     162            0 :    logic                           lsu_dccm_rden_d, lsu_dccm_wren_d;
     163            0 :    logic                           ld_single_ecc_error_lo_r, ld_single_ecc_error_hi_r;
     164            0 :    logic                           ld_single_ecc_error_lo_r_ns, ld_single_ecc_error_hi_r_ns;
     165            0 :    logic                           ld_single_ecc_error_lo_r_ff, ld_single_ecc_error_hi_r_ff;
     166            4 :    logic                           lsu_double_ecc_error_r_ff;
     167            0 :    logic [pt.DCCM_BITS-1:0]        ld_sec_addr_lo_r_ff, ld_sec_addr_hi_r_ff;
     168        49130 :    logic [pt.DCCM_DATA_WIDTH-1:0]  store_data_lo_r_in, store_data_hi_r_in ;
     169            0 :    logic [63:0]                    picm_rd_data_m;
     170              : 
     171        25518 :    logic                           dccm_wr_bypass_d_m_hi, dccm_wr_bypass_d_r_hi;
     172        25518 :    logic                           dccm_wr_bypass_d_m_lo, dccm_wr_bypass_d_r_lo;
     173            0 :    logic                           kill_ecc_corr_lo_r, kill_ecc_corr_hi_r;
     174              : 
     175              :     // byte_en flowing down
     176       648834 :    logic [3:0]                     store_byteen_m ,store_byteen_r;
     177            0 :    logic [7:0]                     store_byteen_ext_m, store_byteen_ext_r;
     178              : 
     179              :    if (pt.LOAD_TO_USE_PLUS1 == 1) begin: L2U_Plus1_1
     180              :       logic [63:0]  lsu_rdata_r, lsu_rdata_corr_r;
     181              :       logic [63:0]  dccm_rdata_r, dccm_rdata_corr_r;
     182              :       logic [63:0]  stbuf_fwddata_r;
     183              :       logic [7:0]   stbuf_fwdbyteen_r;
     184              :       logic [31:0]  stbuf_fwddata_lo_r, stbuf_fwddata_hi_r;
     185              :       logic [3:0]   stbuf_fwdbyteen_lo_r, stbuf_fwdbyteen_hi_r;
     186              :       logic [31:0]  lsu_rdata_lo_r, lsu_rdata_hi_r;
     187              :       logic [63:0]  picm_rd_data_r;
     188              :       logic [63:32] lsu_ld_data_r_nc, lsu_ld_data_corr_r_nc;
     189              :       logic [2:0]   dma_mem_tag_r;
     190              :       logic         stbuf_fwddata_en;
     191              : 
     192              :       assign dccm_dma_rvalid      = lsu_pkt_r.valid & lsu_pkt_r.load & lsu_pkt_r.dma;
     193              :       assign dccm_dma_ecc_error   = lsu_double_ecc_error_r;
     194              :       assign dccm_dma_rtag[2:0]   = dma_mem_tag_r[2:0];
     195              :       assign dccm_dma_rdata[63:0] = ldst_dual_r ? lsu_rdata_corr_r[63:0] : {2{lsu_rdata_corr_r[31:0]}};
     196              :       assign {lsu_ld_data_r_nc[63:32], lsu_ld_data_r[31:0]}           = lsu_rdata_r[63:0] >> 8*lsu_addr_r[1:0];
     197              :       assign {lsu_ld_data_corr_r_nc[63:32], lsu_ld_data_corr_r[31:0]} = lsu_rdata_corr_r[63:0] >> 8*lsu_addr_r[1:0];
     198              : 
     199              :       assign picm_rd_data_r[63:32]   = picm_rd_data_r[31:0];
     200              :       assign dccm_rdata_r[63:0]      = {dccm_rdata_hi_r[31:0],dccm_rdata_lo_r[31:0]};
     201              :       assign dccm_rdata_corr_r[63:0] = {sec_data_hi_r[31:0],sec_data_lo_r[31:0]};
     202              :       assign stbuf_fwddata_r[63:0]   = {stbuf_fwddata_hi_r[31:0], stbuf_fwddata_lo_r[31:0]};
     203              :       assign stbuf_fwdbyteen_r[7:0]  = {stbuf_fwdbyteen_hi_r[3:0], stbuf_fwdbyteen_lo_r[3:0]};
     204              :       assign stbuf_fwddata_en        = (|stbuf_fwdbyteen_hi_m[3:0]) | (|stbuf_fwdbyteen_lo_m[3:0]) | clk_override;
     205              : 
     206              :       for (genvar i=0; i<8; i++) begin: GenDMAData
     207              :          assign lsu_rdata_corr_r[(8*i)+7:8*i]  = stbuf_fwdbyteen_r[i] ? stbuf_fwddata_r[(8*i)+7:8*i] :
     208              :                                                                         (addr_in_pic_r ? picm_rd_data_r[(8*i)+7:8*i] :  ({8{addr_in_dccm_r}} & dccm_rdata_corr_r[(8*i)+7:8*i]));
     209              : 
     210              :          assign lsu_rdata_r[(8*i)+7:8*i]       = stbuf_fwdbyteen_r[i] ? stbuf_fwddata_r[(8*i)+7:8*i] :
     211              :                                                                         (addr_in_pic_r ? picm_rd_data_r[(8*i)+7:8*i] :  ({8{addr_in_dccm_r}} & dccm_rdata_r[(8*i)+7:8*i]));
     212              :       end
     213              :       rvdffe #(pt.DCCM_DATA_WIDTH) dccm_rdata_hi_r_ff    (.*, .din(dccm_rdata_hi_m[pt.DCCM_DATA_WIDTH-1:0]), .dout(dccm_rdata_hi_r[pt.DCCM_DATA_WIDTH-1:0]), .en((lsu_dccm_rden_m & ldst_dual_m) | clk_override));
     214              :       rvdffe #(pt.DCCM_DATA_WIDTH) dccm_rdata_lo_r_ff    (.*, .din(dccm_rdata_lo_m[pt.DCCM_DATA_WIDTH-1:0]), .dout(dccm_rdata_lo_r[pt.DCCM_DATA_WIDTH-1:0]), .en(lsu_dccm_rden_m | clk_override));
     215              :       rvdffe #(2*pt.DCCM_ECC_WIDTH)  dccm_data_ecc_r_ff  (.*, .din({dccm_data_ecc_hi_m[pt.DCCM_ECC_WIDTH-1:0], dccm_data_ecc_lo_m[pt.DCCM_ECC_WIDTH-1:0]}),
     216              :                                                               .dout({dccm_data_ecc_hi_r[pt.DCCM_ECC_WIDTH-1:0], dccm_data_ecc_lo_r[pt.DCCM_ECC_WIDTH-1:0]}),                                  .en(lsu_dccm_rden_m | clk_override));
     217              :       rvdff #(8)                   stbuf_fwdbyteen_ff    (.*, .din({stbuf_fwdbyteen_hi_m[3:0], stbuf_fwdbyteen_lo_m[3:0]}), .dout({stbuf_fwdbyteen_hi_r[3:0], stbuf_fwdbyteen_lo_r[3:0]}), .clk(lsu_c2_r_clk));
     218              :       rvdffe #(64)                 stbuf_fwddata_ff      (.*, .din({stbuf_fwddata_hi_m[31:0], stbuf_fwddata_lo_m[31:0]}),   .dout({stbuf_fwddata_hi_r[31:0], stbuf_fwddata_lo_r[31:0]}),   .en(stbuf_fwddata_en));
     219              :       rvdffe #(32)                 picm_rddata_rff       (.*, .din(picm_rd_data_m[31:0]),                                   .dout(picm_rd_data_r[31:0]),                                   .en(addr_in_pic_m | clk_override));
     220              :       rvdff #(3)                   dma_mem_tag_rff       (.*, .din(dma_mem_tag_m[2:0]),                                     .dout(dma_mem_tag_r[2:0]),                                     .clk(lsu_c1_r_clk));
     221              : 
     222              :    end else begin: L2U_Plus1_0
     223              : 
     224              :       logic [63:0]  lsu_rdata_m, lsu_rdata_corr_m;
     225              :       logic [63:0]  dccm_rdata_m, dccm_rdata_corr_m;
     226              :       logic [63:0]  stbuf_fwddata_m;
     227              :       logic [7:0]   stbuf_fwdbyteen_m;
     228              :       logic [63:32] lsu_ld_data_m_nc, lsu_ld_data_corr_m_nc;
     229              :       logic [31:0]  lsu_ld_data_corr_m;
     230              : 
     231              :       assign dccm_dma_rvalid      = lsu_pkt_m.valid & lsu_pkt_m.load & lsu_pkt_m.dma;
     232              :       assign dccm_dma_ecc_error   = lsu_double_ecc_error_m;
     233              :       assign dccm_dma_rtag[2:0]   = dma_mem_tag_m[2:0];
     234              :       assign dccm_dma_rdata[63:0] = ldst_dual_m ? lsu_rdata_corr_m[63:0] : {2{lsu_rdata_corr_m[31:0]}};
     235              :       assign {lsu_ld_data_m_nc[63:32], lsu_ld_data_m[31:0]} = 64'(lsu_rdata_m[63:0] >> 8*lsu_addr_m[1:0]);
     236              :       assign {lsu_ld_data_corr_m_nc[63:32], lsu_ld_data_corr_m[31:0]} = 64'(lsu_rdata_corr_m[63:0] >> 8*lsu_addr_m[1:0]);
     237              : 
     238              :       assign dccm_rdata_m[63:0]      = {dccm_rdata_hi_m[31:0],dccm_rdata_lo_m[31:0]};
     239              :       assign dccm_rdata_corr_m[63:0] = {sec_data_hi_m[31:0],sec_data_lo_m[31:0]};
     240              :       assign stbuf_fwddata_m[63:0]   = {stbuf_fwddata_hi_m[31:0], stbuf_fwddata_lo_m[31:0]};
     241              :       assign stbuf_fwdbyteen_m[7:0]  = {stbuf_fwdbyteen_hi_m[3:0], stbuf_fwdbyteen_lo_m[3:0]};
     242              : 
     243              :       for (genvar i=0; i<8; i++) begin: GenLoop
     244              :          assign lsu_rdata_corr_m[(8*i)+7:8*i] = stbuf_fwdbyteen_m[i] ? stbuf_fwddata_m[(8*i)+7:8*i] :
     245              :                                                                        (addr_in_pic_m ? picm_rd_data_m[(8*i)+7:8*i] : ({8{addr_in_dccm_m}} & dccm_rdata_corr_m[(8*i)+7:8*i]));
     246              : 
     247              :          assign lsu_rdata_m[(8*i)+7:8*i]      = stbuf_fwdbyteen_m[i] ? stbuf_fwddata_m[(8*i)+7:8*i] :
     248              :                                                                        (addr_in_pic_m ? picm_rd_data_m[(8*i)+7:8*i] : ({8{addr_in_dccm_m}} & dccm_rdata_m[(8*i)+7:8*i]));
     249              :       end
     250              : 
     251              :       rvdffe #(32) lsu_ld_data_corr_rff(.*, .din(lsu_ld_data_corr_m[31:0]), .dout(lsu_ld_data_corr_r[31:0]), .en((lsu_pkt_m.valid & lsu_pkt_m.load & (addr_in_pic_m | addr_in_dccm_m)) | clk_override));
     252              :    end
     253              : 
     254              :    assign kill_ecc_corr_lo_r = (((lsu_addr_d[pt.DCCM_BITS-1:2] == lsu_addr_r[pt.DCCM_BITS-1:2]) | (end_addr_d[pt.DCCM_BITS-1:2] == lsu_addr_r[pt.DCCM_BITS-1:2])) & lsu_pkt_d.valid & lsu_pkt_d.store & lsu_pkt_d.dma & addr_in_dccm_d) |
     255              :                                (((lsu_addr_m[pt.DCCM_BITS-1:2] == lsu_addr_r[pt.DCCM_BITS-1:2]) | (end_addr_m[pt.DCCM_BITS-1:2] == lsu_addr_r[pt.DCCM_BITS-1:2])) & lsu_pkt_m.valid & lsu_pkt_m.store & lsu_pkt_m.dma & addr_in_dccm_m);
     256              : 
     257              :    assign kill_ecc_corr_hi_r = (((lsu_addr_d[pt.DCCM_BITS-1:2] == end_addr_r[pt.DCCM_BITS-1:2]) | (end_addr_d[pt.DCCM_BITS-1:2] == end_addr_r[pt.DCCM_BITS-1:2])) & lsu_pkt_d.valid & lsu_pkt_d.store & lsu_pkt_d.dma & addr_in_dccm_d) |
     258              :                                (((lsu_addr_m[pt.DCCM_BITS-1:2] == end_addr_r[pt.DCCM_BITS-1:2]) | (end_addr_m[pt.DCCM_BITS-1:2] == end_addr_r[pt.DCCM_BITS-1:2])) & lsu_pkt_m.valid & lsu_pkt_m.store & lsu_pkt_m.dma & addr_in_dccm_m);
     259              : 
     260              :    assign ld_single_ecc_error_lo_r = lsu_pkt_r.load & single_ecc_error_lo_r & ~lsu_raw_fwd_lo_r;
     261              :    assign ld_single_ecc_error_hi_r = lsu_pkt_r.load & single_ecc_error_hi_r & ~lsu_raw_fwd_hi_r;
     262              :    assign ld_single_ecc_error_r    = (ld_single_ecc_error_lo_r | ld_single_ecc_error_hi_r) & ~lsu_double_ecc_error_r;
     263              : 
     264              :    assign ld_single_ecc_error_lo_r_ns = ld_single_ecc_error_lo_r & (lsu_commit_r | lsu_pkt_r.dma) & ~kill_ecc_corr_lo_r;
     265              :    assign ld_single_ecc_error_hi_r_ns = ld_single_ecc_error_hi_r & (lsu_commit_r | lsu_pkt_r.dma) & ~kill_ecc_corr_hi_r;
     266              :    assign ld_single_ecc_error_r_ff = (ld_single_ecc_error_lo_r_ff | ld_single_ecc_error_hi_r_ff) & ~lsu_double_ecc_error_r_ff;
     267              : 
     268              :    assign lsu_stbuf_commit_any = stbuf_reqvld_any &
     269              :                                  (~(lsu_dccm_rden_d | lsu_dccm_wren_d | ld_single_ecc_error_r_ff) |
     270              :                                   (lsu_dccm_rden_d & ~((stbuf_addr_any[pt.DCCM_WIDTH_BITS+:pt.DCCM_BANK_BITS] == lsu_addr_d[pt.DCCM_WIDTH_BITS+:pt.DCCM_BANK_BITS]) |
     271              :                                                        (stbuf_addr_any[pt.DCCM_WIDTH_BITS+:pt.DCCM_BANK_BITS] == end_addr_d[pt.DCCM_WIDTH_BITS+:pt.DCCM_BANK_BITS]))));
     272              : 
     273              :    // No need to read for aligned word/dword stores since ECC will come by new data completely
     274              :    assign lsu_dccm_rden_d = lsu_pkt_d.valid & (lsu_pkt_d.load | (lsu_pkt_d.store & (~(lsu_pkt_d.word | lsu_pkt_d.dword) | (lsu_addr_d[1:0] != 2'b0)))) & addr_in_dccm_d;
     275              : 
     276              :    // DMA will read/write in decode stage
     277              :    assign lsu_dccm_wren_d = dma_dccm_wen;
     278              : 
     279              :    // DCCM inputs
     280              :    assign dccm_wren                             = lsu_dccm_wren_d | lsu_stbuf_commit_any | ld_single_ecc_error_r_ff;
     281              :    assign dccm_rden                             = lsu_dccm_rden_d & addr_in_dccm_d;
     282              :    assign dccm_wr_addr_lo[pt.DCCM_BITS-1:0]     = ld_single_ecc_error_r_ff ? (ld_single_ecc_error_lo_r_ff ? ld_sec_addr_lo_r_ff[pt.DCCM_BITS-1:0] : ld_sec_addr_hi_r_ff[pt.DCCM_BITS-1:0]) :
     283              :                                                                              lsu_dccm_wren_d ? lsu_addr_d[pt.DCCM_BITS-1:0] : stbuf_addr_any[pt.DCCM_BITS-1:0];
     284              :    assign dccm_wr_addr_hi[pt.DCCM_BITS-1:0]     = ld_single_ecc_error_r_ff ? (ld_single_ecc_error_hi_r_ff ? ld_sec_addr_hi_r_ff[pt.DCCM_BITS-1:0] : ld_sec_addr_lo_r_ff[pt.DCCM_BITS-1:0]) :
     285              :                                                                              lsu_dccm_wren_d ? end_addr_d[pt.DCCM_BITS-1:0] : stbuf_addr_any[pt.DCCM_BITS-1:0];
     286              :    assign dccm_rd_addr_lo[pt.DCCM_BITS-1:0]     = lsu_addr_d[pt.DCCM_BITS-1:0];
     287              :    assign dccm_rd_addr_hi[pt.DCCM_BITS-1:0]     = end_addr_d[pt.DCCM_BITS-1:0];
     288              :    assign dccm_wr_data_lo[pt.DCCM_FDATA_WIDTH-1:0] = ld_single_ecc_error_r_ff ? (ld_single_ecc_error_lo_r_ff ? {sec_data_ecc_lo_r_ff[pt.DCCM_ECC_WIDTH-1:0],sec_data_lo_r_ff[pt.DCCM_DATA_WIDTH-1:0]} :
     289              :                                                                                                                {sec_data_ecc_hi_r_ff[pt.DCCM_ECC_WIDTH-1:0],sec_data_hi_r_ff[pt.DCCM_DATA_WIDTH-1:0]}) :
     290              :                                                                                 (dma_dccm_wen ? {dma_dccm_wdata_ecc_lo[pt.DCCM_ECC_WIDTH-1:0],dma_dccm_wdata_lo[pt.DCCM_DATA_WIDTH-1:0]} :
     291              :                                                                                                 {stbuf_ecc_any[pt.DCCM_ECC_WIDTH-1:0],stbuf_data_any[pt.DCCM_DATA_WIDTH-1:0]});
     292              :    assign dccm_wr_data_hi[pt.DCCM_FDATA_WIDTH-1:0] = ld_single_ecc_error_r_ff ? (ld_single_ecc_error_hi_r_ff ? {sec_data_ecc_hi_r_ff[pt.DCCM_ECC_WIDTH-1:0],sec_data_hi_r_ff[pt.DCCM_DATA_WIDTH-1:0]} :
     293              :                                                                                                                {sec_data_ecc_lo_r_ff[pt.DCCM_ECC_WIDTH-1:0],sec_data_lo_r_ff[pt.DCCM_DATA_WIDTH-1:0]}) :
     294              :                                                                                 (dma_dccm_wen ? {dma_dccm_wdata_ecc_hi[pt.DCCM_ECC_WIDTH-1:0],dma_dccm_wdata_hi[pt.DCCM_DATA_WIDTH-1:0]} :
     295              :                                                                                                 {stbuf_ecc_any[pt.DCCM_ECC_WIDTH-1:0],stbuf_data_any[pt.DCCM_DATA_WIDTH-1:0]});
     296              : 
     297              :    // DCCM outputs
     298              :    assign store_byteen_m[3:0] = {4{lsu_pkt_m.store}} &
     299              :                                 (({4{lsu_pkt_m.by}}    & 4'b0001) |
     300              :                                  ({4{lsu_pkt_m.half}}  & 4'b0011) |
     301              :                                  ({4{lsu_pkt_m.word}}  & 4'b1111));
     302              : 
     303              :    assign store_byteen_r[3:0] =  {4{lsu_pkt_r.store}} &
     304              :                                  (({4{lsu_pkt_r.by}}    & 4'b0001) |
     305              :                                   ({4{lsu_pkt_r.half}}  & 4'b0011) |
     306              :                                   ({4{lsu_pkt_r.word}}  & 4'b1111));
     307              : 
     308              :    assign store_byteen_ext_m[7:0] = {4'b0,store_byteen_m[3:0]} << lsu_addr_m[1:0];      // The packet in m
     309              :    assign store_byteen_ext_r[7:0] = {4'b0,store_byteen_r[3:0]} << lsu_addr_r[1:0];
     310              : 
     311              : 
     312              : 
     313              :    assign dccm_wr_bypass_d_m_lo   = (stbuf_addr_any[pt.DCCM_BITS-1:2] == lsu_addr_m[pt.DCCM_BITS-1:2]) & addr_in_dccm_m;
     314              :    assign dccm_wr_bypass_d_m_hi   = (stbuf_addr_any[pt.DCCM_BITS-1:2] == end_addr_m[pt.DCCM_BITS-1:2]) & addr_in_dccm_m;
     315              : 
     316              :    assign dccm_wr_bypass_d_r_lo   = (stbuf_addr_any[pt.DCCM_BITS-1:2] == lsu_addr_r[pt.DCCM_BITS-1:2]) & addr_in_dccm_r;
     317              :    assign dccm_wr_bypass_d_r_hi   = (stbuf_addr_any[pt.DCCM_BITS-1:2] == end_addr_r[pt.DCCM_BITS-1:2]) & addr_in_dccm_r;
     318              : 
     319              : 
     320              :    if (pt.LOAD_TO_USE_PLUS1 == 1) begin: L2U1_Plus1_1
     321              :       logic        dccm_wren_Q;
     322              :       logic [31:0] dccm_wr_data_Q;
     323              :       logic        dccm_wr_bypass_d_m_lo_Q, dccm_wr_bypass_d_m_hi_Q;
     324              :       logic [31:0] store_data_pre_hi_r, store_data_pre_lo_r;
     325              : 
     326              :       assign {store_data_pre_hi_r[31:0], store_data_pre_lo_r[31:0]} = {32'b0,store_data_r[31:0]} << 8*lsu_addr_r[1:0];
     327              : 
     328              :       for (genvar i=0; i<4; i++) begin
     329              :           assign store_data_lo_r[(8*i)+7:(8*i)]   = store_byteen_ext_r[i] ? store_data_pre_lo_r[(8*i)+7:(8*i)] : ((dccm_wren_Q & dccm_wr_bypass_d_m_lo_Q) ? dccm_wr_data_Q[(8*i)+7:(8*i)] : sec_data_lo_r[(8*i)+7:(8*i)]);
     330              :           assign store_data_hi_r[(8*i)+7:(8*i)]   = store_byteen_ext_r[i+4] ? store_data_pre_hi_r[(8*i)+7:(8*i)] : ((dccm_wren_Q & dccm_wr_bypass_d_m_hi_Q) ? dccm_wr_data_Q[(8*i)+7:(8*i)] : sec_data_hi_r[(8*i)+7:(8*i)]);
     331              : 
     332              :           assign store_datafn_lo_r[(8*i)+7:(8*i)] = store_byteen_ext_r[i] ? store_data_pre_lo_r[(8*i)+7:(8*i)] : ((lsu_stbuf_commit_any & dccm_wr_bypass_d_r_lo) ? stbuf_data_any[(8*i)+7:(8*i)] :
     333              :                                                                                                                     ((dccm_wren_Q & dccm_wr_bypass_d_m_lo_Q) ? dccm_wr_data_Q[(8*i)+7:(8*i)] : sec_data_lo_r[(8*i)+7:(8*i)]));
     334              :           assign store_datafn_hi_r[(8*i)+7:(8*i)] = store_byteen_ext_r[i+4] ? store_data_pre_hi_r[(8*i)+7:(8*i)] : ((lsu_stbuf_commit_any & dccm_wr_bypass_d_r_hi) ? stbuf_data_any[(8*i)+7:(8*i)] :
     335              :                                                                                                                     ((dccm_wren_Q & dccm_wr_bypass_d_m_hi_Q) ? dccm_wr_data_Q[(8*i)+7:(8*i)] : sec_data_hi_r[(8*i)+7:(8*i)]));
     336              :       end
     337              : 
     338              :       rvdff #(1)   dccm_wren_ff       (.*, .din(lsu_stbuf_commit_any),  .dout(dccm_wren_Q),             .clk(lsu_free_c2_clk));   // ECC load errors writing to dccm shouldn't fwd to stores in pipe
     339              :       rvdffe #(32) dccm_wrdata_ff     (.*, .din(stbuf_data_any[31:0]),  .dout(dccm_wr_data_Q[31:0]),    .en(lsu_stbuf_commit_any | clk_override), .clk(clk));
     340              :       rvdff #(1)   dccm_wrbyp_dm_loff (.*, .din(dccm_wr_bypass_d_m_lo), .dout(dccm_wr_bypass_d_m_lo_Q), .clk(lsu_free_c2_clk));
     341              :       rvdff #(1)   dccm_wrbyp_dm_hiff (.*, .din(dccm_wr_bypass_d_m_hi), .dout(dccm_wr_bypass_d_m_hi_Q), .clk(lsu_free_c2_clk));
     342              :       rvdff #(32)  store_data_rff     (.*, .din(store_data_m[31:0]),    .dout(store_data_r[31:0]),      .clk(lsu_store_c1_r_clk));
     343              : 
     344              :    end else begin: L2U1_Plus1_0
     345              : 
     346              :       logic [31:0] store_data_hi_m, store_data_lo_m;
     347              :       logic [63:0] store_data_mask;
     348              :       assign {store_data_hi_m[31:0] , store_data_lo_m[31:0]} = {32'b0,store_data_m[31:0]} << 8*lsu_addr_m[1:0];
     349              : 
     350              :       for (genvar i=0; i<4; i++) begin
     351              :          assign store_data_hi_r_in[(8*i)+7:(8*i)]  = store_byteen_ext_m[i+4] ? store_data_hi_m[(8*i)+7:(8*i)] :
     352              :                                                                                ((lsu_stbuf_commit_any &  dccm_wr_bypass_d_m_hi)   ? stbuf_data_any[(8*i)+7:(8*i)] : sec_data_hi_m[(8*i)+7:(8*i)]);
     353              :          assign store_data_lo_r_in[(8*i)+7:(8*i)]  = store_byteen_ext_m[i]   ? store_data_lo_m[(8*i)+7:(8*i)] :
     354              :                                                                                ((lsu_stbuf_commit_any &  dccm_wr_bypass_d_m_lo) ? stbuf_data_any[(8*i)+7:(8*i)] : sec_data_lo_m[(8*i)+7:(8*i)]);
     355              : 
     356              :          assign store_datafn_lo_r[(8*i)+7:(8*i)]   = (lsu_stbuf_commit_any & dccm_wr_bypass_d_r_lo & ~store_byteen_ext_r[i])   ? stbuf_data_any[(8*i)+7:(8*i)] : store_data_lo_r[(8*i)+7:(8*i)];
     357              :          assign store_datafn_hi_r[(8*i)+7:(8*i)]   = (lsu_stbuf_commit_any & dccm_wr_bypass_d_r_hi & ~store_byteen_ext_r[i+4]) ? stbuf_data_any[(8*i)+7:(8*i)] : store_data_hi_r[(8*i)+7:(8*i)];
     358              :       end // for (genvar i=0; i<BYTE_WIDTH; i++)
     359              : 
     360              :       for (genvar i=0; i<4; i++) begin
     361              :          assign store_data_mask[(8*i)+7:(8*i)] = {8{store_byteen_r[i]}};
     362              :       end
     363              :       assign store_data_r[31:0]      = 32'({store_data_hi_r[31:0],store_data_lo_r[31:0]} >> 8*lsu_addr_r[1:0]) & store_data_mask[31:0];
     364              : 
     365              :       rvdffe #(pt.DCCM_DATA_WIDTH) store_data_hi_rff (.*, .din(store_data_hi_r_in[pt.DCCM_DATA_WIDTH-1:0]), .dout(store_data_hi_r[pt.DCCM_DATA_WIDTH-1:0]), .en((ldst_dual_m & lsu_pkt_m.valid & lsu_pkt_m.store) | clk_override), .clk(clk));
     366              :       rvdff  #(pt.DCCM_DATA_WIDTH) store_data_lo_rff (.*, .din(store_data_lo_r_in[pt.DCCM_DATA_WIDTH-1:0]), .dout(store_data_lo_r[pt.DCCM_DATA_WIDTH-1:0]), .clk(lsu_store_c1_r_clk));
     367              : 
     368              :    end
     369              : 
     370              :    assign dccm_rdata_lo_m[pt.DCCM_DATA_WIDTH-1:0]   = dccm_rd_data_lo[pt.DCCM_DATA_WIDTH-1:0]; // for ld choose dccm_out
     371              :    assign dccm_rdata_hi_m[pt.DCCM_DATA_WIDTH-1:0]   = dccm_rd_data_hi[pt.DCCM_DATA_WIDTH-1:0]; // for ld this is used for ecc
     372              : 
     373              :    assign dccm_data_ecc_lo_m[pt.DCCM_ECC_WIDTH-1:0] = dccm_rd_data_lo[pt.DCCM_FDATA_WIDTH-1:pt.DCCM_DATA_WIDTH];
     374              :    assign dccm_data_ecc_hi_m[pt.DCCM_ECC_WIDTH-1:0] = dccm_rd_data_hi[pt.DCCM_FDATA_WIDTH-1:pt.DCCM_DATA_WIDTH];
     375              : 
     376              :    // PIC signals. PIC ignores the lower 2 bits of address since PIC memory registers are 32-bits
     377              :    assign picm_wren          = (lsu_pkt_r.valid & lsu_pkt_r.store & addr_in_pic_r & lsu_commit_r) | dma_pic_wen;
     378              :    assign picm_rden          = lsu_pkt_d.valid & lsu_pkt_d.load  & addr_in_pic_d;
     379              :    assign picm_mken          = lsu_pkt_d.valid & lsu_pkt_d.store & addr_in_pic_d;  // Get the mask for stores
     380              :    assign picm_rdaddr[31:0]  = pt.PIC_BASE_ADDR | {{32-pt.PIC_BITS{1'b0}},lsu_addr_d[pt.PIC_BITS-1:0]};
     381              : 
     382              :    assign picm_wraddr[31:0]  = pt.PIC_BASE_ADDR | {{32-pt.PIC_BITS{1'b0}},(dma_pic_wen ? dma_mem_addr[pt.PIC_BITS-1:0] : lsu_addr_r[pt.PIC_BITS-1:0])};
     383              : 
     384              :    assign picm_wr_data[31:0] = dma_pic_wen ? dma_mem_wdata[31:0] : store_datafn_lo_r[31:0];
     385              : 
     386              :    assign picm_mask_data_m[31:0] = picm_rd_data_m[31:0];
     387              :    assign picm_rd_data_m[63:0]   = {picm_rd_data[31:0],picm_rd_data[31:0]};
     388              : 
     389              :    if (pt.DCCM_ENABLE == 1) begin: Gen_dccm_enable
     390              :       rvdff #(1) dccm_rden_mff (.*, .din(lsu_dccm_rden_d), .dout(lsu_dccm_rden_m), .clk(lsu_c2_m_clk));
     391              :       rvdff #(1) dccm_rden_rff (.*, .din(lsu_dccm_rden_m), .dout(lsu_dccm_rden_r), .clk(lsu_c2_r_clk));
     392              : 
     393              :       // ECC correction flops since dccm write happens next cycle
     394              :       // We are writing to dccm in r+1 for ecc correction since fast_int needs to be blocked in decode - 1. We can probably write in r for plus0 configuration since we know ecc error in M.
     395              :       // In that case these (_ff) flops are needed only in plus1 configuration
     396              :       rvdff #(1) ld_double_ecc_error_rff    (.*, .din(lsu_double_ecc_error_r),   .dout(lsu_double_ecc_error_r_ff),   .clk(lsu_free_c2_clk));
     397              :       rvdff #(1) ld_single_ecc_error_hi_rff (.*, .din(ld_single_ecc_error_hi_r_ns), .dout(ld_single_ecc_error_hi_r_ff), .clk(lsu_free_c2_clk));
     398              :       rvdff #(1) ld_single_ecc_error_lo_rff (.*, .din(ld_single_ecc_error_lo_r_ns), .dout(ld_single_ecc_error_lo_r_ff), .clk(lsu_free_c2_clk));
     399              :       rvdffe #(pt.DCCM_BITS) ld_sec_addr_hi_rff (.*, .din(end_addr_r[pt.DCCM_BITS-1:0]), .dout(ld_sec_addr_hi_r_ff[pt.DCCM_BITS-1:0]), .en(ld_single_ecc_error_r | clk_override), .clk(clk));
     400              :       rvdffe #(pt.DCCM_BITS) ld_sec_addr_lo_rff (.*, .din(lsu_addr_r[pt.DCCM_BITS-1:0]), .dout(ld_sec_addr_lo_r_ff[pt.DCCM_BITS-1:0]), .en(ld_single_ecc_error_r | clk_override), .clk(clk));
     401              : 
     402              :    end else begin: Gen_dccm_disable
     403              :       assign lsu_dccm_rden_m = '0;
     404              :       assign lsu_dccm_rden_r = '0;
     405              : 
     406              :       assign lsu_double_ecc_error_r_ff = 1'b0;
     407              :       assign ld_single_ecc_error_hi_r_ff = 1'b0;
     408              :       assign ld_single_ecc_error_lo_r_ff = 1'b0;
     409              :       assign ld_sec_addr_hi_r_ff[pt.DCCM_BITS-1:0] = '0;
     410              :       assign ld_sec_addr_lo_r_ff[pt.DCCM_BITS-1:0] = '0;
     411              :    end
     412              : 
     413              : `ifdef RV_ASSERT_ON
     414              : 
     415              :    // Load single ECC error correction implies commit/dma
     416              :    property ld_single_ecc_error_commit;
     417              :       @(posedge clk) disable iff(~rst_l) (ld_single_ecc_error_r_ff & dccm_wren) |-> ($past(lsu_commit_r | lsu_pkt_r.dma));
     418              :    endproperty
     419              :    assert_ld_single_ecc_error_commit: assert property (ld_single_ecc_error_commit) else
     420              :      $display("No commit or DMA but ECC correction happened");
     421              : 
     422              : 
     423              : `endif
     424              : 
     425              : endmodule