Project Full coverage report
Current view: Cores-VeeR-EL2—Cores-VeeR-EL2—design—lsu—el2_lsu_dccm_mem.sv Coverage Hit Total
Test Date: 14-11-2024 Toggle 88.0% 22 25
Test: all Branch 100.0% 9 9

            Line data    Source code
       1              : // SPDX-License-Identifier: Apache-2.0
       2              : // Copyright 2020 Western Digital Corporation or its affiliates.
       3              : // Copyright (c) 2023 Antmicro <www.antmicro.com>
       4              : //
       5              : // Licensed under the Apache License, Version 2.0 (the "License");
       6              : // you may not use this file except in compliance with the License.
       7              : // You may obtain a copy of the License at
       8              : //
       9              : // http://www.apache.org/licenses/LICENSE-2.0
      10              : //
      11              : // Unless required by applicable law or agreed to in writing, software
      12              : // distributed under the License is distributed on an "AS IS" BASIS,
      13              : // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      14              : // See the License for the specific language governing permissions and
      15              : // limitations under the License.
      16              : 
      17              : //********************************************************************************
      18              : // $Id$
      19              : //
      20              : //
      21              : // Owner:
      22              : // Function: DCCM for LSU pipe
      23              : // Comments: Single ported memory
      24              : //
      25              : //
      26              : // DC1 -> DC2 -> DC3 -> DC4 (Commit)
      27              : //
      28              : // //********************************************************************************
      29              : 
      30              : module el2_lsu_dccm_mem
      31              :   import el2_pkg::*;
      32              : #(
      33              : `include "el2_param.vh"
      34              :  )(
      35     69834488 :    input logic         clk,                                             // Clock only while core active.  Through one clock header.  For flops with    second clock header built in.  Connected to ACTIVE_L2CLK.
      36     69834488 :    input logic         active_clk,                                      // Clock only while core active.  Through two clock headers. For flops without second clock header built in.
      37          339 :    input logic         rst_l,                                           // reset, active low
      38            2 :    input logic         clk_override,                                    // Override non-functional clock gating
      39              : 
      40       263894 :    input logic         dccm_wren,                                       // write enable
      41       562000 :    input logic         dccm_rden,                                       // read enable
      42        18924 :    input logic [pt.DCCM_BITS-1:0]  dccm_wr_addr_lo,                     // write address
      43        18924 :    input logic [pt.DCCM_BITS-1:0]  dccm_wr_addr_hi,                     // write address
      44       471547 :    input logic [pt.DCCM_BITS-1:0]  dccm_rd_addr_lo,                     // read address
      45       677942 :    input logic [pt.DCCM_BITS-1:0]  dccm_rd_addr_hi,                     // read address for the upper bank in case of a misaligned access
      46         5615 :    input logic [pt.DCCM_FDATA_WIDTH-1:0]  dccm_wr_data_lo,              // write data
      47         5615 :    input logic [pt.DCCM_FDATA_WIDTH-1:0]  dccm_wr_data_hi,              // write data
      48              :    el2_mem_if.veer_dccm                   dccm_mem_export,              // RAM repositioned in testbench and connected by this interface
      49              : 
      50        47433 :    output logic [pt.DCCM_FDATA_WIDTH-1:0] dccm_rd_data_lo,              // read data from the lo bank
      51        47433 :    output logic [pt.DCCM_FDATA_WIDTH-1:0] dccm_rd_data_hi,              // read data from the hi bank
      52              : 
      53              :    // Excluding scan_mode from coverage as its usage is determined by the integrator of the VeeR core.
      54              :    /*verilator coverage_off*/
      55              :    input  logic         scan_mode
      56              :    /*verilator coverage_on*/
      57              : );
      58              : 
      59              : 
      60              :    localparam logic [5:0]  DCCM_WIDTH_BITS = $clog2(pt.DCCM_BYTE_WIDTH);
      61              :    localparam logic [7:0]  DCCM_INDEX_BITS = 8'(pt.DCCM_BITS - pt.DCCM_BANK_BITS - pt.DCCM_WIDTH_BITS);
      62              :    localparam logic [31:0] DCCM_INDEX_DEPTH = ((pt.DCCM_SIZE)*1024)/((pt.DCCM_BYTE_WIDTH)*(pt.DCCM_NUM_BANKS));  // Depth of memory bank
      63              : 
      64        59820 :    logic [pt.DCCM_NUM_BANKS-1:0]                                        wren_bank;
      65       143252 :    logic [pt.DCCM_NUM_BANKS-1:0]                                        rden_bank;
      66       688996 :    logic [pt.DCCM_NUM_BANKS-1:0] [pt.DCCM_BITS-1:(pt.DCCM_BANK_BITS+2)] addr_bank;
      67            0 :    logic [pt.DCCM_BITS-1:(pt.DCCM_BANK_BITS+DCCM_WIDTH_BITS)]           rd_addr_even, rd_addr_odd;
      68            0 :    logic                                                                rd_unaligned, wr_unaligned;
      69         1846 :    logic [pt.DCCM_NUM_BANKS-1:0] [pt.DCCM_FDATA_WIDTH-1:0]              dccm_bank_dout;
      70            0 :    logic [pt.DCCM_FDATA_WIDTH-1:0]                                      wrdata;
      71              : 
      72         5615 :    logic [pt.DCCM_NUM_BANKS-1:0][pt.DCCM_FDATA_WIDTH-1:0]               wr_data_bank;
      73              : 
      74      1200873 :    logic [(DCCM_WIDTH_BITS+pt.DCCM_BANK_BITS-1):DCCM_WIDTH_BITS]        dccm_rd_addr_lo_q;
      75      1200953 :    logic [(DCCM_WIDTH_BITS+pt.DCCM_BANK_BITS-1):DCCM_WIDTH_BITS]        dccm_rd_addr_hi_q;
      76              : 
      77       190016 :    logic [pt.DCCM_NUM_BANKS-1:0]            dccm_clken;
      78              : 
      79              :    assign rd_unaligned = (dccm_rd_addr_lo[DCCM_WIDTH_BITS+:pt.DCCM_BANK_BITS] != dccm_rd_addr_hi[DCCM_WIDTH_BITS+:pt.DCCM_BANK_BITS]);
      80              :    assign wr_unaligned = (dccm_wr_addr_lo[DCCM_WIDTH_BITS+:pt.DCCM_BANK_BITS] != dccm_wr_addr_hi[DCCM_WIDTH_BITS+:pt.DCCM_BANK_BITS]);
      81              : 
      82              :    // Align the read data
      83              :    assign dccm_rd_data_lo[pt.DCCM_FDATA_WIDTH-1:0]  = dccm_bank_dout[dccm_rd_addr_lo_q[pt.DCCM_WIDTH_BITS+:pt.DCCM_BANK_BITS]][pt.DCCM_FDATA_WIDTH-1:0];
      84              :    assign dccm_rd_data_hi[pt.DCCM_FDATA_WIDTH-1:0]  = dccm_bank_dout[dccm_rd_addr_hi_q[DCCM_WIDTH_BITS+:pt.DCCM_BANK_BITS]][pt.DCCM_FDATA_WIDTH-1:0];
      85              : 
      86              : 
      87              :    // 8 Banks, 16KB each (2048 x 72)
      88         1360 :    for (genvar i=0; i<pt.DCCM_NUM_BANKS; i++) begin: mem_bank
      89              :       assign  wren_bank[i]        = dccm_wren & ((dccm_wr_addr_hi[2+:pt.DCCM_BANK_BITS] == i) | (dccm_wr_addr_lo[2+:pt.DCCM_BANK_BITS] == i));
      90              :       assign  rden_bank[i]        = dccm_rden & ((dccm_rd_addr_hi[2+:pt.DCCM_BANK_BITS] == i) | (dccm_rd_addr_lo[2+:pt.DCCM_BANK_BITS] == i));
      91              :       assign  addr_bank[i][(pt.DCCM_BANK_BITS+DCCM_WIDTH_BITS)+:DCCM_INDEX_BITS] = wren_bank[i] ? (((dccm_wr_addr_hi[2+:pt.DCCM_BANK_BITS] == i) & wr_unaligned) ?
      92              :                                                                                                         dccm_wr_addr_hi[(pt.DCCM_BANK_BITS+DCCM_WIDTH_BITS)+:DCCM_INDEX_BITS] :
      93              :                                                                                                         dccm_wr_addr_lo[(pt.DCCM_BANK_BITS+DCCM_WIDTH_BITS)+:DCCM_INDEX_BITS])  :
      94              :                                                                                                   (((dccm_rd_addr_hi[2+:pt.DCCM_BANK_BITS] == i) & rd_unaligned) ?
      95              :                                                                                                         dccm_rd_addr_hi[(pt.DCCM_BANK_BITS+DCCM_WIDTH_BITS)+:DCCM_INDEX_BITS] :
      96              :                                                                                                         dccm_rd_addr_lo[(pt.DCCM_BANK_BITS+DCCM_WIDTH_BITS)+:DCCM_INDEX_BITS]);
      97              : 
      98              :       assign wr_data_bank[i]     = ((dccm_wr_addr_hi[2+:pt.DCCM_BANK_BITS] == i) & wr_unaligned) ? dccm_wr_data_hi[pt.DCCM_FDATA_WIDTH-1:0] : dccm_wr_data_lo[pt.DCCM_FDATA_WIDTH-1:0];
      99              : 
     100              :       // clock gating section
     101              :       assign  dccm_clken[i] = (wren_bank[i] | rden_bank[i] | clk_override) ;
     102              :       // end clock gating section
     103              : 
     104              :       // Connect to exported RAM Banks
     105         1360 :       always_comb begin
     106         1360 :          dccm_mem_export.dccm_clken[i]                               = dccm_clken[i];
     107         1360 :          dccm_mem_export.dccm_wren_bank[i]                           = wren_bank[i];
     108         1360 :          dccm_mem_export.dccm_addr_bank[i]                           = addr_bank[i];
     109         1360 :          dccm_mem_export.dccm_wr_data_bank[i]                        = wr_data_bank[i][pt.DCCM_DATA_WIDTH-1:0];
     110         1360 :          dccm_mem_export.dccm_wr_ecc_bank[i]                         = wr_data_bank[i][pt.DCCM_FDATA_WIDTH-1:pt.DCCM_DATA_WIDTH];
     111         1360 :          dccm_bank_dout[i][pt.DCCM_DATA_WIDTH-1:0]                   = dccm_mem_export.dccm_bank_dout[i];
     112         1360 :          dccm_bank_dout[i][pt.DCCM_FDATA_WIDTH-1:pt.DCCM_DATA_WIDTH] = dccm_mem_export.dccm_bank_ecc[i];
     113              :       end
     114              : 
     115              :    end : mem_bank
     116              : 
     117              :    // Flops
     118              :    rvdff  #(pt.DCCM_BANK_BITS) rd_addr_lo_ff (.*, .din(dccm_rd_addr_lo[DCCM_WIDTH_BITS+:pt.DCCM_BANK_BITS]), .dout(dccm_rd_addr_lo_q[DCCM_WIDTH_BITS+:pt.DCCM_BANK_BITS]), .clk(active_clk));
     119              :    rvdff  #(pt.DCCM_BANK_BITS) rd_addr_hi_ff (.*, .din(dccm_rd_addr_hi[DCCM_WIDTH_BITS+:pt.DCCM_BANK_BITS]), .dout(dccm_rd_addr_hi_q[DCCM_WIDTH_BITS+:pt.DCCM_BANK_BITS]), .clk(active_clk));
     120              : 
     121              : endmodule // el2_lsu_dccm_mem
     122              : 
     123              :