Project Full coverage report
Current view: Cores-VeeR-EL2—Cores-VeeR-EL2—design—lsu—el2_lsu_dccm_ctl.sv Coverage Hit Total
Test Date: 21-11-2024 Toggle 79.3% 88 111
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     69840565 :    input logic                             lsu_c2_m_clk,            // clocks
      36     69840565 :    input logic                             lsu_c2_r_clk,            // clocks
      37     69840565 :    input logic                             lsu_c1_r_clk,            // clocks
      38     69840565 :    input logic                             lsu_store_c1_r_clk,      // clocks
      39     69840565 :    input logic                             lsu_free_c2_clk,         // clocks
      40            2 :    input logic                             clk_override,            // Override non-functional clock gating
      41     69840565 :    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          338 :    input logic                             rst_l,                   // reset, active low
      44              : 
      45       477821 :    input                                   el2_lsu_pkt_t lsu_pkt_r,// lsu packets
      46       477824 :    input                                   el2_lsu_pkt_t lsu_pkt_m,// lsu packets
      47       477872 :    input                                   el2_lsu_pkt_t lsu_pkt_d,// lsu packets
      48       614422 :    input logic                             addr_in_dccm_d,          // address maps to dccm
      49           12 :    input logic                             addr_in_pic_d,           // address maps to pic
      50           12 :    input logic                             addr_in_pic_m,           // address maps to pic
      51       614422 :    input logic                             addr_in_dccm_m, addr_in_dccm_r,   // address in dccm per pipe stage
      52           12 :    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      2285226 :    input logic                             lsu_commit_r,            // lsu instruction in r commits
      55        36584 :    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       593287 :    input logic [31:0]                      lsu_addr_d,
      59       470950 :    input logic [pt.DCCM_BITS-1:0]          lsu_addr_m,
      60       593285 :    input logic [31:0]                      lsu_addr_r,
      61              : 
      62              :    // lsu address down the pipe - needed to check unaligned
      63       677351 :    input logic [pt.DCCM_BITS-1:0]          end_addr_d,
      64       677524 :    input logic [pt.DCCM_BITS-1:0]          end_addr_m,
      65       677522 :    input logic [pt.DCCM_BITS-1:0]          end_addr_r,
      66              : 
      67              : 
      68       258448 :    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         7576 :    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         4200 :    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        24696 :    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        47176 :    output logic [pt.DCCM_DATA_WIDTH-1:0]   dccm_rdata_hi_m,         // data from the dccm
      96        47176 :    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        54456 :    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        47176 :    input logic [pt.DCCM_DATA_WIDTH-1:0]    sec_data_hi_m,           // corrected dccm data
     103        47176 :    input logic [pt.DCCM_DATA_WIDTH-1:0]    sec_data_lo_m,           // corrected dccm data
     104              : 
     105        81488 :    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         1717 :    output logic [pt.DCCM_DATA_WIDTH-1:0]   store_data_hi_r,
     117        92714 :    output logic [pt.DCCM_DATA_WIDTH-1:0]   store_data_lo_r,
     118         1921 :    output logic [pt.DCCM_DATA_WIDTH-1:0]   store_datafn_hi_r,       // data from the dccm
     119        92714 :    output logic [pt.DCCM_DATA_WIDTH-1:0]   store_datafn_lo_r,       // data from the dccm
     120        56576 :    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       262890 :    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        39564 :    output logic [63:0]                     dccm_dma_rdata,          // dccm data to dma request
     133              : 
     134              :    // DCCM ports
     135       262894 :    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       470956 :    output logic [pt.DCCM_BITS-1:0]         dccm_rd_addr_lo,         // dccm interface -- read address for lo bank
     140       677351 :    output logic [pt.DCCM_BITS-1:0]         dccm_rd_addr_hi,         // dccm interface -- read address for hi bank
     141         5376 :    output logic [pt.DCCM_FDATA_WIDTH-1:0]  dccm_wr_data_lo,         // dccm write data for lo bank
     142         5376 :    output logic [pt.DCCM_FDATA_WIDTH-1:0]  dccm_wr_data_hi,         // dccm write data for hi bank
     143              : 
     144        47176 :    input logic [pt.DCCM_FDATA_WIDTH-1:0]   dccm_rd_data_lo,         // dccm read data back from the dccm
     145        47176 :    input logic [pt.DCCM_FDATA_WIDTH-1:0]   dccm_rd_data_hi,         // dccm read data back from the dccm
     146              : 
     147              :    // PIC ports
     148            8 :    output logic                            picm_wren,               // write to pic
     149            2 :    output logic                            picm_rden,               // read to pick
     150           10 :    output logic                            picm_mken,               // write to pic need a mask
     151          316 :    output logic [31:0]                     picm_rdaddr,             // address for pic read access
     152          316 :    output logic [31:0]                     picm_wraddr,             // address for pic write access
     153        92714 :    output logic [31:0]                     picm_wr_data,            // write data
     154            0 :    input logic [31:0]                      picm_rd_data,            // read data
     155              : 
     156              :    // Excluding scan_mode from coverage as its usage is determined by the integrator of the VeeR core.
     157              :    /*verilator coverage_off*/
     158              :    input logic                             scan_mode                // scan mode
     159              :    /*verilator coverage_on*/
     160              : );
     161              : 
     162              : 
     163              :    localparam DCCM_WIDTH_BITS = $clog2(pt.DCCM_BYTE_WIDTH);
     164              : 
     165            0 :    logic                           lsu_dccm_rden_d, lsu_dccm_wren_d;
     166            0 :    logic                           ld_single_ecc_error_lo_r, ld_single_ecc_error_hi_r;
     167            0 :    logic                           ld_single_ecc_error_lo_r_ns, ld_single_ecc_error_hi_r_ns;
     168            0 :    logic                           ld_single_ecc_error_lo_r_ff, ld_single_ecc_error_hi_r_ff;
     169            4 :    logic                           lsu_double_ecc_error_r_ff;
     170            0 :    logic [pt.DCCM_BITS-1:0]        ld_sec_addr_lo_r_ff, ld_sec_addr_hi_r_ff;
     171        49136 :    logic [pt.DCCM_DATA_WIDTH-1:0]  store_data_lo_r_in, store_data_hi_r_in ;
     172            0 :    logic [63:0]                    picm_rd_data_m;
     173              : 
     174        25520 :    logic                           dccm_wr_bypass_d_m_hi, dccm_wr_bypass_d_r_hi;
     175        25520 :    logic                           dccm_wr_bypass_d_m_lo, dccm_wr_bypass_d_r_lo;
     176            0 :    logic                           kill_ecc_corr_lo_r, kill_ecc_corr_hi_r;
     177              : 
     178              :     // byte_en flowing down
     179       648860 :    logic [3:0]                     store_byteen_m ,store_byteen_r;
     180            0 :    logic [7:0]                     store_byteen_ext_m, store_byteen_ext_r;
     181              : 
     182              :    if (pt.LOAD_TO_USE_PLUS1 == 1) begin: L2U_Plus1_1
     183              :       logic [63:0]  lsu_rdata_r, lsu_rdata_corr_r;
     184              :       logic [63:0]  dccm_rdata_r, dccm_rdata_corr_r;
     185              :       logic [63:0]  stbuf_fwddata_r;
     186              :       logic [7:0]   stbuf_fwdbyteen_r;
     187              :       logic [31:0]  stbuf_fwddata_lo_r, stbuf_fwddata_hi_r;
     188              :       logic [3:0]   stbuf_fwdbyteen_lo_r, stbuf_fwdbyteen_hi_r;
     189              :       logic [31:0]  lsu_rdata_lo_r, lsu_rdata_hi_r;
     190              :       logic [63:0]  picm_rd_data_r;
     191              :       logic [63:32] lsu_ld_data_r_nc, lsu_ld_data_corr_r_nc;
     192              :       logic [2:0]   dma_mem_tag_r;
     193              :       logic         stbuf_fwddata_en;
     194              : 
     195              :       assign dccm_dma_rvalid      = lsu_pkt_r.valid & lsu_pkt_r.load & lsu_pkt_r.dma;
     196              :       assign dccm_dma_ecc_error   = lsu_double_ecc_error_r;
     197              :       assign dccm_dma_rtag[2:0]   = dma_mem_tag_r[2:0];
     198              :       assign dccm_dma_rdata[63:0] = ldst_dual_r ? lsu_rdata_corr_r[63:0] : {2{lsu_rdata_corr_r[31:0]}};
     199              :       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];
     200              :       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];
     201              : 
     202              :       assign picm_rd_data_r[63:32]   = picm_rd_data_r[31:0];
     203              :       assign dccm_rdata_r[63:0]      = {dccm_rdata_hi_r[31:0],dccm_rdata_lo_r[31:0]};
     204              :       assign dccm_rdata_corr_r[63:0] = {sec_data_hi_r[31:0],sec_data_lo_r[31:0]};
     205              :       assign stbuf_fwddata_r[63:0]   = {stbuf_fwddata_hi_r[31:0], stbuf_fwddata_lo_r[31:0]};
     206              :       assign stbuf_fwdbyteen_r[7:0]  = {stbuf_fwdbyteen_hi_r[3:0], stbuf_fwdbyteen_lo_r[3:0]};
     207              :       assign stbuf_fwddata_en        = (|stbuf_fwdbyteen_hi_m[3:0]) | (|stbuf_fwdbyteen_lo_m[3:0]) | clk_override;
     208              : 
     209              :       for (genvar i=0; i<8; i++) begin: GenDMAData
     210              :          assign lsu_rdata_corr_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_corr_r[(8*i)+7:8*i]));
     212              : 
     213              :          assign lsu_rdata_r[(8*i)+7:8*i]       = stbuf_fwdbyteen_r[i] ? stbuf_fwddata_r[(8*i)+7:8*i] :
     214              :                                                                         (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]));
     215              :       end
     216              :       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));
     217              :       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));
     218              :       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]}),
     219              :                                                               .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));
     220              :       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));
     221              :       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));
     222              :       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));
     223              :       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));
     224              : 
     225              :    end else begin: L2U_Plus1_0
     226              : 
     227              :       logic [63:0]  lsu_rdata_m, lsu_rdata_corr_m;
     228              :       logic [63:0]  dccm_rdata_m, dccm_rdata_corr_m;
     229              :       logic [63:0]  stbuf_fwddata_m;
     230              :       logic [7:0]   stbuf_fwdbyteen_m;
     231              :       logic [63:32] lsu_ld_data_m_nc, lsu_ld_data_corr_m_nc;
     232              :       logic [31:0]  lsu_ld_data_corr_m;
     233              : 
     234              :       assign dccm_dma_rvalid      = lsu_pkt_m.valid & lsu_pkt_m.load & lsu_pkt_m.dma;
     235              :       assign dccm_dma_ecc_error   = lsu_double_ecc_error_m;
     236              :       assign dccm_dma_rtag[2:0]   = dma_mem_tag_m[2:0];
     237              :       assign dccm_dma_rdata[63:0] = ldst_dual_m ? lsu_rdata_corr_m[63:0] : {2{lsu_rdata_corr_m[31:0]}};
     238              :       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]);
     239              :       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]);
     240              : 
     241              :       assign dccm_rdata_m[63:0]      = {dccm_rdata_hi_m[31:0],dccm_rdata_lo_m[31:0]};
     242              :       assign dccm_rdata_corr_m[63:0] = {sec_data_hi_m[31:0],sec_data_lo_m[31:0]};
     243              :       assign stbuf_fwddata_m[63:0]   = {stbuf_fwddata_hi_m[31:0], stbuf_fwddata_lo_m[31:0]};
     244              :       assign stbuf_fwdbyteen_m[7:0]  = {stbuf_fwdbyteen_hi_m[3:0], stbuf_fwdbyteen_lo_m[3:0]};
     245              : 
     246              :       for (genvar i=0; i<8; i++) begin: GenLoop
     247              :          assign lsu_rdata_corr_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_corr_m[(8*i)+7:8*i]));
     249              : 
     250              :          assign lsu_rdata_m[(8*i)+7:8*i]      = stbuf_fwdbyteen_m[i] ? stbuf_fwddata_m[(8*i)+7:8*i] :
     251              :                                                                        (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]));
     252              :       end
     253              : 
     254              :       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));
     255              :    end
     256              : 
     257              :    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) |
     258              :                                (((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);
     259              : 
     260              :    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) |
     261              :                                (((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);
     262              : 
     263              :    assign ld_single_ecc_error_lo_r = lsu_pkt_r.load & single_ecc_error_lo_r & ~lsu_raw_fwd_lo_r;
     264              :    assign ld_single_ecc_error_hi_r = lsu_pkt_r.load & single_ecc_error_hi_r & ~lsu_raw_fwd_hi_r;
     265              :    assign ld_single_ecc_error_r    = (ld_single_ecc_error_lo_r | ld_single_ecc_error_hi_r) & ~lsu_double_ecc_error_r;
     266              : 
     267              :    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;
     268              :    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;
     269              :    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;
     270              : 
     271              :    assign lsu_stbuf_commit_any = stbuf_reqvld_any &
     272              :                                  (~(lsu_dccm_rden_d | lsu_dccm_wren_d | ld_single_ecc_error_r_ff) |
     273              :                                   (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]) |
     274              :                                                        (stbuf_addr_any[pt.DCCM_WIDTH_BITS+:pt.DCCM_BANK_BITS] == end_addr_d[pt.DCCM_WIDTH_BITS+:pt.DCCM_BANK_BITS]))));
     275              : 
     276              :    // No need to read for aligned word/dword stores since ECC will come by new data completely
     277              :    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;
     278              : 
     279              :    // DMA will read/write in decode stage
     280              :    assign lsu_dccm_wren_d = dma_dccm_wen;
     281              : 
     282              :    // DCCM inputs
     283              :    assign dccm_wren                             = lsu_dccm_wren_d | lsu_stbuf_commit_any | ld_single_ecc_error_r_ff;
     284              :    assign dccm_rden                             = lsu_dccm_rden_d & addr_in_dccm_d;
     285              :    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]) :
     286              :                                                                              lsu_dccm_wren_d ? lsu_addr_d[pt.DCCM_BITS-1:0] : stbuf_addr_any[pt.DCCM_BITS-1:0];
     287              :    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]) :
     288              :                                                                              lsu_dccm_wren_d ? end_addr_d[pt.DCCM_BITS-1:0] : stbuf_addr_any[pt.DCCM_BITS-1:0];
     289              :    assign dccm_rd_addr_lo[pt.DCCM_BITS-1:0]     = lsu_addr_d[pt.DCCM_BITS-1:0];
     290              :    assign dccm_rd_addr_hi[pt.DCCM_BITS-1:0]     = end_addr_d[pt.DCCM_BITS-1:0];
     291              :    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]} :
     292              :                                                                                                                {sec_data_ecc_hi_r_ff[pt.DCCM_ECC_WIDTH-1:0],sec_data_hi_r_ff[pt.DCCM_DATA_WIDTH-1:0]}) :
     293              :                                                                                 (dma_dccm_wen ? {dma_dccm_wdata_ecc_lo[pt.DCCM_ECC_WIDTH-1:0],dma_dccm_wdata_lo[pt.DCCM_DATA_WIDTH-1:0]} :
     294              :                                                                                                 {stbuf_ecc_any[pt.DCCM_ECC_WIDTH-1:0],stbuf_data_any[pt.DCCM_DATA_WIDTH-1:0]});
     295              :    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]} :
     296              :                                                                                                                {sec_data_ecc_lo_r_ff[pt.DCCM_ECC_WIDTH-1:0],sec_data_lo_r_ff[pt.DCCM_DATA_WIDTH-1:0]}) :
     297              :                                                                                 (dma_dccm_wen ? {dma_dccm_wdata_ecc_hi[pt.DCCM_ECC_WIDTH-1:0],dma_dccm_wdata_hi[pt.DCCM_DATA_WIDTH-1:0]} :
     298              :                                                                                                 {stbuf_ecc_any[pt.DCCM_ECC_WIDTH-1:0],stbuf_data_any[pt.DCCM_DATA_WIDTH-1:0]});
     299              : 
     300              :    // DCCM outputs
     301              :    assign store_byteen_m[3:0] = {4{lsu_pkt_m.store}} &
     302              :                                 (({4{lsu_pkt_m.by}}    & 4'b0001) |
     303              :                                  ({4{lsu_pkt_m.half}}  & 4'b0011) |
     304              :                                  ({4{lsu_pkt_m.word}}  & 4'b1111));
     305              : 
     306              :    assign store_byteen_r[3:0] =  {4{lsu_pkt_r.store}} &
     307              :                                  (({4{lsu_pkt_r.by}}    & 4'b0001) |
     308              :                                   ({4{lsu_pkt_r.half}}  & 4'b0011) |
     309              :                                   ({4{lsu_pkt_r.word}}  & 4'b1111));
     310              : 
     311              :    assign store_byteen_ext_m[7:0] = {4'b0,store_byteen_m[3:0]} << lsu_addr_m[1:0];      // The packet in m
     312              :    assign store_byteen_ext_r[7:0] = {4'b0,store_byteen_r[3:0]} << lsu_addr_r[1:0];
     313              : 
     314              : 
     315              : 
     316              :    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;
     317              :    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;
     318              : 
     319              :    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;
     320              :    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;
     321              : 
     322              : 
     323              :    if (pt.LOAD_TO_USE_PLUS1 == 1) begin: L2U1_Plus1_1
     324              :       logic        dccm_wren_Q;
     325              :       logic [31:0] dccm_wr_data_Q;
     326              :       logic        dccm_wr_bypass_d_m_lo_Q, dccm_wr_bypass_d_m_hi_Q;
     327              :       logic [31:0] store_data_pre_hi_r, store_data_pre_lo_r;
     328              : 
     329              :       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];
     330              : 
     331              :       for (genvar i=0; i<4; i++) begin
     332              :           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)]);
     333              :           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)]);
     334              : 
     335              :           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)] :
     336              :                                                                                                                     ((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)]));
     337              :           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)] :
     338              :                                                                                                                     ((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)]));
     339              :       end
     340              : 
     341              :       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
     342              :       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));
     343              :       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));
     344              :       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));
     345              :       rvdff #(32)  store_data_rff     (.*, .din(store_data_m[31:0]),    .dout(store_data_r[31:0]),      .clk(lsu_store_c1_r_clk));
     346              : 
     347              :    end else begin: L2U1_Plus1_0
     348              : 
     349              :       logic [31:0] store_data_hi_m, store_data_lo_m;
     350              :       logic [63:0] store_data_mask;
     351              :       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];
     352              : 
     353              :       for (genvar i=0; i<4; i++) begin
     354              :          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)] :
     355              :                                                                                ((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)]);
     356              :          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)] :
     357              :                                                                                ((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)]);
     358              : 
     359              :          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)];
     360              :          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)];
     361              :       end // for (genvar i=0; i<BYTE_WIDTH; i++)
     362              : 
     363              :       for (genvar i=0; i<4; i++) begin
     364              :          assign store_data_mask[(8*i)+7:(8*i)] = {8{store_byteen_r[i]}};
     365              :       end
     366              :       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];
     367              : 
     368              :       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));
     369              :       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));
     370              : 
     371              :    end
     372              : 
     373              :    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
     374              :    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
     375              : 
     376              :    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];
     377              :    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];
     378              : 
     379              :    // PIC signals. PIC ignores the lower 2 bits of address since PIC memory registers are 32-bits
     380              :    assign picm_wren          = (lsu_pkt_r.valid & lsu_pkt_r.store & addr_in_pic_r & lsu_commit_r) | dma_pic_wen;
     381              :    assign picm_rden          = lsu_pkt_d.valid & lsu_pkt_d.load  & addr_in_pic_d;
     382              :    assign picm_mken          = lsu_pkt_d.valid & lsu_pkt_d.store & addr_in_pic_d;  // Get the mask for stores
     383              :    assign picm_rdaddr[31:0]  = pt.PIC_BASE_ADDR | {{32-pt.PIC_BITS{1'b0}},lsu_addr_d[pt.PIC_BITS-1:0]};
     384              : 
     385              :    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])};
     386              : 
     387              :    assign picm_wr_data[31:0] = dma_pic_wen ? dma_mem_wdata[31:0] : store_datafn_lo_r[31:0];
     388              : 
     389              :    assign picm_mask_data_m[31:0] = picm_rd_data_m[31:0];
     390              :    assign picm_rd_data_m[63:0]   = {picm_rd_data[31:0],picm_rd_data[31:0]};
     391              : 
     392              :    if (pt.DCCM_ENABLE == 1) begin: Gen_dccm_enable
     393              :       rvdff #(1) dccm_rden_mff (.*, .din(lsu_dccm_rden_d), .dout(lsu_dccm_rden_m), .clk(lsu_c2_m_clk));
     394              :       rvdff #(1) dccm_rden_rff (.*, .din(lsu_dccm_rden_m), .dout(lsu_dccm_rden_r), .clk(lsu_c2_r_clk));
     395              : 
     396              :       // ECC correction flops since dccm write happens next cycle
     397              :       // 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.
     398              :       // In that case these (_ff) flops are needed only in plus1 configuration
     399              :       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));
     400              :       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));
     401              :       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));
     402              :       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));
     403              :       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));
     404              : 
     405              :    end else begin: Gen_dccm_disable
     406              :       assign lsu_dccm_rden_m = '0;
     407              :       assign lsu_dccm_rden_r = '0;
     408              : 
     409              :       assign lsu_double_ecc_error_r_ff = 1'b0;
     410              :       assign ld_single_ecc_error_hi_r_ff = 1'b0;
     411              :       assign ld_single_ecc_error_lo_r_ff = 1'b0;
     412              :       assign ld_sec_addr_hi_r_ff[pt.DCCM_BITS-1:0] = '0;
     413              :       assign ld_sec_addr_lo_r_ff[pt.DCCM_BITS-1:0] = '0;
     414              :    end
     415              : 
     416              : `ifdef RV_ASSERT_ON
     417              : 
     418              :    // Load single ECC error correction implies commit/dma
     419              :    property ld_single_ecc_error_commit;
     420              :       @(posedge clk) disable iff(~rst_l) (ld_single_ecc_error_r_ff & dccm_wren) |-> ($past(lsu_commit_r | lsu_pkt_r.dma));
     421              :    endproperty
     422              :    assert_ld_single_ecc_error_commit: assert property (ld_single_ecc_error_commit) else
     423              :      $display("No commit or DMA but ECC correction happened");
     424              : 
     425              : 
     426              : `endif
     427              : 
     428              : endmodule