Project Full coverage report
Current view: Cores-VeeR-EL2—Cores-VeeR-EL2—design—lsu—el2_lsu_bus_buffer.sv Coverage Hit Total
Test Date: 27-12-2024 Toggle 96.7% 235 243
Test: all Branch 100.0% 146 146

            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: lsu interface with interface queue
      22              : // Comments:
      23              : //
      24              : //********************************************************************************
      25              : 
      26              : module el2_lsu_bus_buffer
      27              : import el2_pkg::*;
      28              : #(
      29              : `include "el2_param.vh"
      30              :  )(
      31    115884880 :    input logic                          clk,                                // Clock only while core active.  Through one clock header.  For flops with    second clock header built in.  Connected to ACTIVE_L2CLK.
      32            2 :    input logic                          clk_override,                       // Override non-functional clock gating
      33          299 :    input logic                          rst_l,                              // reset, active low
      34              :    // Excluding scan_mode from coverage as its usage is determined by the integrator of the VeeR core.
      35              :    /*pragma coverage off*/
      36              :    input logic                          scan_mode,                          // scan mode
      37              :    /*pragma coverage on*/
      38            0 :    input logic                          dec_tlu_external_ldfwd_disable,     // disable load to load forwarding for externals
      39            9 :    input logic                          dec_tlu_wb_coalescing_disable,      // disable write buffer coalescing
      40          283 :    input logic                          dec_tlu_sideeffect_posted_disable,  // Don't block the sideeffect load store to the bus
      41            0 :    input logic                          dec_tlu_force_halt,
      42              : 
      43              :    // various clocks needed for the bus reads and writes
      44      2319254 :    input logic                          lsu_bus_obuf_c1_clken,
      45      1219435 :    input logic                          lsu_busm_clken,
      46    115884880 :    input logic                          lsu_c2_r_clk,
      47    115884880 :    input logic                          lsu_bus_ibuf_c1_clk,
      48            0 :    input logic                          lsu_bus_obuf_c1_clk,
      49    115884880 :    input logic                          lsu_bus_buf_c1_clk,
      50    115884880 :    input logic                          lsu_free_c2_clk,
      51            0 :    input logic                          lsu_busm_clk,
      52              : 
      53              : 
      54      3803483 :    input logic                          dec_lsu_valid_raw_d,            // Raw valid for address computation
      55      3807141 :    input el2_lsu_pkt_t                 lsu_pkt_m,                      // lsu packet flowing down the pipe
      56      3807139 :    input el2_lsu_pkt_t                 lsu_pkt_r,                      // lsu packet flowing down the pipe
      57              : 
      58      1876037 :    input logic [31:0]                   lsu_addr_m,                     // lsu address flowing down the pipe
      59      1876261 :    input logic [31:0]                   end_addr_m,                     // lsu address flowing down the pipe
      60      1866834 :    input logic [31:0]                   lsu_addr_r,                     // lsu address flowing down the pipe
      61      1867058 :    input logic [31:0]                   end_addr_r,                     // lsu address flowing down the pipe
      62       350196 :    input logic [31:0]                   store_data_r,                   // store data flowing down the pipe
      63              : 
      64       410815 :    input logic                          no_word_merge_r,                // r store doesn't need to wait in ibuf since it will not coalesce
      65       391125 :    input logic                          no_dword_merge_r,               // r store doesn't need to wait in ibuf since it will not coalesce
      66      1877441 :    input logic                          lsu_busreq_m,                   // bus request is in m
      67      1868284 :    output logic                         lsu_busreq_r,                   // bus request is in r
      68         9314 :    input logic                          ld_full_hit_m,                  // load can get all its byte from a write buffer entry
      69      1277508 :    input logic                          flush_m_up,                     // flush
      70       252372 :    input logic                          flush_r,                        // flush
      71      2572720 :    input logic                          lsu_commit_r,                   // lsu instruction in r commits
      72        20721 :    input logic                          is_sideeffects_r,               // lsu attribute is side_effects
      73        26182 :    input logic                          ldst_dual_d,                    // load/store is unaligned at 32 bit boundary
      74        26182 :    input logic                          ldst_dual_m,                    // load/store is unaligned at 32 bit boundary
      75        26182 :    input logic                          ldst_dual_r,                    // load/store is unaligned at 32 bit boundary
      76              : 
      77      1988166 :    input logic [7:0]                    ldst_byteen_ext_m,              // HI and LO signals
      78              : 
      79       778481 :    output logic                         lsu_bus_buffer_pend_any,          // bus buffer has a pending bus entry
      80       259452 :    output logic                         lsu_bus_buffer_full_any,          // bus buffer is full
      81      1295586 :    output logic                         lsu_bus_buffer_empty_any,         // bus buffer is empty
      82              : 
      83        24356 :    output logic [3:0]                   ld_byte_hit_buf_lo, ld_byte_hit_buf_hi,    // Byte enables for forwarding data
      84        19720 :    output logic [31:0]                  ld_fwddata_buf_lo, ld_fwddata_buf_hi,      // load forwarding data
      85              : 
      86            2 :    output logic                         lsu_imprecise_error_load_any,     // imprecise load bus error
      87            2 :    output logic                         lsu_imprecise_error_store_any,    // imprecise store bus error
      88       788355 :    output logic [31:0]                  lsu_imprecise_error_addr_any,     // address of the imprecise error
      89              : 
      90              :    // Non-blocking loads
      91      1109559 :    output logic                               lsu_nonblock_load_valid_m,     // there is an external load -> put in the cam
      92      1651331 :    output logic [pt.LSU_NUM_NBLOAD_WIDTH-1:0] lsu_nonblock_load_tag_m,       // the tag of the external non block load
      93            0 :    output logic                               lsu_nonblock_load_inv_r,       // invalidate signal for the cam entry for non block loads
      94      1651329 :    output logic [pt.LSU_NUM_NBLOAD_WIDTH-1:0] lsu_nonblock_load_inv_tag_r,   // tag of the enrty which needs to be invalidated
      95      1129044 :    output logic                               lsu_nonblock_load_data_valid,  // the non block is valid - sending information back to the cam
      96            2 :    output logic                               lsu_nonblock_load_data_error,  // non block load has an error
      97       435592 :    output logic [pt.LSU_NUM_NBLOAD_WIDTH-1:0] lsu_nonblock_load_data_tag,    // the tag of the non block load sending the data/error
      98       332494 :    output logic [31:0]                        lsu_nonblock_load_data,        // Data of the non block load
      99              : 
     100              :    // PMU events
     101      1860410 :    output logic                         lsu_pmu_bus_trxn,
     102        25958 :    output logic                         lsu_pmu_bus_misaligned,
     103            4 :    output logic                         lsu_pmu_bus_error,
     104        47098 :    output logic                         lsu_pmu_bus_busy,
     105              : 
     106              :    // AXI Write Channels
     107       820482 :    output logic                            lsu_axi_awvalid,
     108      1365255 :    input  logic                            lsu_axi_awready,
     109       607034 :    output logic [pt.LSU_BUS_TAG-1:0]       lsu_axi_awid,
     110       614263 :    output logic [31:0]                     lsu_axi_awaddr,
     111       224636 :    output logic [3:0]                      lsu_axi_awregion,
     112              :    /* exclude signals that are tied to constant value in this file */
     113              :    /*pragma coverage off*/
     114              :    output logic [7:0]                      lsu_axi_awlen,
     115              :    /*pragma coverage on*/
     116         3043 :    output logic [2:0]                      lsu_axi_awsize,
     117              :    /* exclude signals that are tied to constant value in this file */
     118              :    /*pragma coverage off*/
     119              :    output logic [1:0]                      lsu_axi_awburst,
     120              :    output logic                            lsu_axi_awlock,
     121              :    /*pragma coverage on*/
     122         1957 :    output logic [3:0]                      lsu_axi_awcache,
     123              :    /* exclude signals that are tied to constant value in this file */
     124              :    /*pragma coverage off*/
     125              :    output logic [2:0]                      lsu_axi_awprot,
     126              :    output logic [3:0]                      lsu_axi_awqos,
     127              :    /*pragma coverage on*/
     128              : 
     129       820482 :    output logic                            lsu_axi_wvalid,
     130      1365255 :    input  logic                            lsu_axi_wready,
     131       217764 :    output logic [63:0]                     lsu_axi_wdata,
     132       430439 :    output logic [7:0]                      lsu_axi_wstrb,
     133          298 :    output logic                            lsu_axi_wlast,
     134              : 
     135       828182 :    input  logic                            lsu_axi_bvalid,
     136              :    /* exclude signals that are tied to constant value in this file */
     137              :    /*pragma coverage off*/
     138              :    output logic                            lsu_axi_bready,
     139              :    /*pragma coverage on*/
     140            2 :    input  logic [1:0]                      lsu_axi_bresp,
     141       332383 :    input  logic [pt.LSU_BUS_TAG-1:0]       lsu_axi_bid,
     142              : 
     143              :    // AXI Read Channels
     144      1103398 :    output logic                            lsu_axi_arvalid,
     145      1381994 :    input  logic                            lsu_axi_arready,
     146       607034 :    output logic [pt.LSU_BUS_TAG-1:0]       lsu_axi_arid,
     147       614263 :    output logic [31:0]                     lsu_axi_araddr,
     148       224636 :    output logic [3:0]                      lsu_axi_arregion,
     149              :    /* exclude signals that are tied to constant value in this file */
     150              :    /*pragma coverage off*/
     151              :    output logic [7:0]                      lsu_axi_arlen,
     152              :    /*pragma coverage on*/
     153         3043 :    output logic [2:0]                      lsu_axi_arsize,
     154              :    /* exclude signals that are tied to constant value in this file */
     155              :    /*pragma coverage off*/
     156              :    output logic [1:0]                      lsu_axi_arburst,
     157              :    output logic                            lsu_axi_arlock,
     158              :    /*pragma coverage on*/
     159         1957 :    output logic [3:0]                      lsu_axi_arcache,
     160              :    /* exclude signals that are tied to constant value in this file */
     161              :    /*pragma coverage off*/
     162              :    output logic [2:0]                      lsu_axi_arprot,
     163              :    output logic [3:0]                      lsu_axi_arqos,
     164              :    /*pragma coverage on*/
     165              : 
     166      1135692 :    input  logic                            lsu_axi_rvalid,
     167              :    /* exclude signals that are tied to constant value in this file */
     168              :    /*pragma coverage off*/
     169              :    output logic                            lsu_axi_rready,
     170              :    /*pragma coverage on*/
     171       258175 :    input  logic [pt.LSU_BUS_TAG-1:0]       lsu_axi_rid,
     172        97123 :    input  logic [63:0]                     lsu_axi_rdata,
     173            2 :    input  logic [1:0]                      lsu_axi_rresp,
     174              : 
     175          327 :    input logic                             lsu_bus_clk_en,
     176          329 :    input logic                             lsu_bus_clk_en_q
     177              : 
     178              : );
     179              : 
     180              :    // For Ld: IDLE -> START_WAIT -> CMD -> RESP -> DONE_PARTIAL(?) -> DONE_WAIT(?) -> DONE -> IDLE
     181              :    // For St: IDLE -> START_WAIT -> CMD -> RESP(?) -> IDLE
     182              :    typedef enum logic [2:0] {IDLE=3'b000, START_WAIT=3'b001, CMD=3'b010, RESP=3'b011, DONE_PARTIAL=3'b100, DONE_WAIT=3'b101, DONE=3'b110} state_t;
     183              : 
     184              :    localparam DEPTH     = pt.LSU_NUM_NBLOAD;
     185              :    localparam DEPTH_LOG2 = pt.LSU_NUM_NBLOAD_WIDTH;
     186              :    localparam TIMER     = 8;   // This can be only power of 2
     187              :    localparam TIMER_MAX = TIMER - 1;  // Maximum value of timer
     188              :    localparam TIMER_LOG2 = (TIMER < 2) ? 1 : $clog2(TIMER);
     189              : 
     190      1988166 :    logic [3:0]                          ldst_byteen_hi_m, ldst_byteen_lo_m;
     191        25760 :    logic [DEPTH-1:0]                    ld_addr_hitvec_lo, ld_addr_hitvec_hi;
     192        10858 :    logic [3:0][DEPTH-1:0]               ld_byte_hitvec_lo, ld_byte_hitvec_hi;
     193        10722 :    logic [3:0][DEPTH-1:0]               ld_byte_hitvecfn_lo, ld_byte_hitvecfn_hi;
     194              : 
     195        13826 :    logic                                ld_addr_ibuf_hit_lo, ld_addr_ibuf_hit_hi;
     196         5618 :    logic [3:0]                          ld_byte_ibuf_hit_lo, ld_byte_ibuf_hit_hi;
     197              : 
     198      1701165 :    logic [3:0]                          ldst_byteen_r;
     199      1982454 :    logic [3:0]                          ldst_byteen_hi_r, ldst_byteen_lo_r;
     200       315776 :    logic [31:0]                         store_data_hi_r, store_data_lo_r;
     201        40463 :    logic                                is_aligned_r;                   // Aligned load/store
     202        13202 :    logic                                ldst_samedw_r;
     203              : 
     204      1109413 :    logic                                lsu_nonblock_load_valid_r;
     205       415108 :    logic [31:0]                         lsu_nonblock_load_data_hi, lsu_nonblock_load_data_lo, lsu_nonblock_data_unalgn;
     206       270869 :    logic [1:0]                          lsu_nonblock_addr_offset;
     207       127544 :    logic [1:0]                          lsu_nonblock_sz;
     208       341304 :    logic                                lsu_nonblock_unsign;
     209      1129046 :    logic                                lsu_nonblock_load_data_ready;
     210              : 
     211       634503 :    logic [DEPTH-1:0]                    CmdPtr0Dec, CmdPtr1Dec;
     212       176354 :    logic [DEPTH-1:0]                    RspPtrDec;
     213       230604 :    logic [DEPTH_LOG2-1:0]               CmdPtr0, CmdPtr1;
     214       334718 :    logic [DEPTH_LOG2-1:0]               RspPtr;
     215      1651331 :    logic [DEPTH_LOG2-1:0]               WrPtr0_m, WrPtr0_r;
     216      1601698 :    logic [DEPTH_LOG2-1:0]               WrPtr1_m, WrPtr1_r;
     217      1002113 :    logic                                found_wrptr0, found_wrptr1, found_cmdptr0, found_cmdptr1;
     218      2164541 :    logic [3:0]                          buf_numvld_any, buf_numvld_wrcmd_any, buf_numvld_cmd_any, buf_numvld_pend_any;
     219       339704 :    logic                                any_done_wait_state;
     220        11123 :    logic                                bus_sideeffect_pend;
     221           27 :    logic                                bus_coalescing_disable;
     222              : 
     223       386934 :    logic                                bus_addr_match_pending;
     224      1862514 :    logic                                bus_cmd_sent, bus_cmd_ready;
     225       827750 :    logic                                bus_wcmd_sent, bus_wdata_sent;
     226      1300907 :    logic                                bus_rsp_read, bus_rsp_write;
     227       344053 :    logic [pt.LSU_BUS_TAG-1:0]           bus_rsp_read_tag, bus_rsp_write_tag;
     228            4 :    logic                                bus_rsp_read_error, bus_rsp_write_error;
     229        97123 :    logic [63:0]                         bus_rsp_rdata;
     230              : 
     231              :    // Bus buffer signals
     232      1628048 :    state_t [DEPTH-1:0]                  buf_state;
     233       101402 :    logic   [DEPTH-1:0][1:0]             buf_sz;
     234       496321 :    logic   [DEPTH-1:0][31:0]            buf_addr;
     235       282733 :    logic   [DEPTH-1:0][3:0]             buf_byteen;
     236          525 :    logic   [DEPTH-1:0]                  buf_sideeffect;
     237       323386 :    logic   [DEPTH-1:0]                  buf_write;
     238       302444 :    logic   [DEPTH-1:0]                  buf_unsign;
     239        13054 :    logic   [DEPTH-1:0]                  buf_dual;
     240         7905 :    logic   [DEPTH-1:0]                  buf_samedw;
     241        89577 :    logic   [DEPTH-1:0]                  buf_nomerge;
     242         7049 :    logic   [DEPTH-1:0]                  buf_dualhi;
     243       410361 :    logic   [DEPTH-1:0][DEPTH_LOG2-1:0]  buf_dualtag;
     244       176354 :    logic   [DEPTH-1:0]                  buf_ldfwd;
     245       161460 :    logic   [DEPTH-1:0][DEPTH_LOG2-1:0]  buf_ldfwdtag;
     246            4 :    logic   [DEPTH-1:0]                  buf_error;
     247       420217 :    logic   [DEPTH-1:0][31:0]            buf_data;
     248      1486523 :    logic   [DEPTH-1:0][DEPTH-1:0]       buf_age, buf_age_younger;
     249       298546 :    logic   [DEPTH-1:0][DEPTH-1:0]       buf_rspage, buf_rsp_pickage;
     250              : 
     251      1630880 :    state_t [DEPTH-1:0]                  buf_nxtstate;
     252       859960 :    logic   [DEPTH-1:0]                  buf_rst;
     253      2731535 :    logic   [DEPTH-1:0]                  buf_state_en;
     254      1477950 :    logic   [DEPTH-1:0]                  buf_cmd_state_bus_en;
     255      1476294 :    logic   [DEPTH-1:0]                  buf_resp_state_bus_en;
     256      2097000 :    logic   [DEPTH-1:0]                  buf_state_bus_en;
     257        31862 :    logic   [DEPTH-1:0]                  buf_dual_in;
     258        16590 :    logic   [DEPTH-1:0]                  buf_samedw_in;
     259       515549 :    logic   [DEPTH-1:0]                  buf_nomerge_in;
     260        20721 :    logic   [DEPTH-1:0]                  buf_sideeffect_in;
     261       664062 :    logic   [DEPTH-1:0]                  buf_unsign_in;
     262      1690108 :    logic   [DEPTH-1:0][1:0]             buf_sz_in;
     263      1545697 :    logic   [DEPTH-1:0]                  buf_write_in;
     264      1478153 :    logic   [DEPTH-1:0]                  buf_wr_en;
     265        15768 :    logic   [DEPTH-1:0]                  buf_dualhi_in;
     266      2072443 :    logic   [DEPTH-1:0][DEPTH_LOG2-1:0]  buf_dualtag_in;
     267      1012468 :    logic   [DEPTH-1:0]                  buf_ldfwd_en;
     268      1477977 :    logic   [DEPTH-1:0]                  buf_ldfwd_in;
     269       293700 :    logic   [DEPTH-1:0][DEPTH_LOG2-1:0]  buf_ldfwdtag_in;
     270      2158432 :    logic   [DEPTH-1:0][3:0]             buf_byteen_in;
     271      2095648 :    logic   [DEPTH-1:0][31:0]            buf_addr_in;
     272       933207 :    logic   [DEPTH-1:0][31:0]            buf_data_in;
     273            4 :    logic   [DEPTH-1:0]                  buf_error_en;
     274      2336313 :    logic   [DEPTH-1:0]                  buf_data_en;
     275        80962 :    logic   [DEPTH-1:0][DEPTH-1:0]       buf_age_in;
     276        80962 :    logic   [DEPTH-1:0][DEPTH-1:0]       buf_ageQ;
     277       307306 :    logic   [DEPTH-1:0][DEPTH-1:0]       buf_rspage_set;
     278       307304 :    logic   [DEPTH-1:0][DEPTH-1:0]       buf_rspage_in;
     279       307304 :    logic   [DEPTH-1:0][DEPTH-1:0]       buf_rspageQ;
     280              : 
     281              :    // Input buffer signals
     282       761992 :    logic                               ibuf_valid;
     283         8415 :    logic                               ibuf_dual;
     284         5367 :    logic                               ibuf_samedw;
     285          170 :    logic                               ibuf_nomerge;
     286       143939 :    logic [DEPTH_LOG2-1:0]              ibuf_tag;
     287       144158 :    logic [DEPTH_LOG2-1:0]              ibuf_dualtag;
     288          173 :    logic                               ibuf_sideeffect;
     289            2 :    logic                               ibuf_unsign;
     290          341 :    logic                               ibuf_write;
     291        45123 :    logic [1:0]                         ibuf_sz;
     292        68535 :    logic [3:0]                         ibuf_byteen;
     293       170989 :    logic [31:0]                        ibuf_addr;
     294       130645 :    logic [31:0]                        ibuf_data;
     295      2882218 :    logic [TIMER_LOG2-1:0]              ibuf_timer;
     296              : 
     297      1158251 :    logic                               ibuf_byp;
     298       767087 :    logic                               ibuf_wr_en;
     299       761978 :    logic                               ibuf_rst;
     300       234586 :    logic                               ibuf_force_drain;
     301       762414 :    logic                               ibuf_drain_vld;
     302       571968 :    logic [DEPTH-1:0]                   ibuf_drainvec_vld;
     303      1671181 :    logic [DEPTH_LOG2-1:0]              ibuf_tag_in;
     304      1651329 :    logic [DEPTH_LOG2-1:0]              ibuf_dualtag_in;
     305      1542540 :    logic [1:0]                         ibuf_sz_in;
     306      1866834 :    logic [31:0]                        ibuf_addr_in;
     307      1958877 :    logic [3:0]                         ibuf_byteen_in;
     308       315976 :    logic [31:0]                        ibuf_data_in;
     309      2882256 :    logic [TIMER_LOG2-1:0]              ibuf_timer_in;
     310        68541 :    logic [3:0]                         ibuf_byteen_out;
     311       130645 :    logic [31:0]                        ibuf_data_out;
     312        30992 :    logic                               ibuf_merge_en, ibuf_merge_in;
     313              : 
     314              :    // Output buffer signals
     315      1788340 :    logic                               obuf_valid;
     316       370166 :    logic                               obuf_write;
     317       339701 :    logic                               obuf_nosend;
     318      1134312 :    logic                               obuf_rdrsp_pend;
     319         1659 :    logic                               obuf_sideeffect;
     320       860789 :    logic [31:0]                        obuf_addr;
     321       217764 :    logic [63:0]                        obuf_data;
     322       132317 :    logic [1:0]                         obuf_sz;
     323       843494 :    logic [7:0]                         obuf_byteen;
     324         5916 :    logic                               obuf_merge;
     325            0 :    logic                               obuf_cmd_done, obuf_data_done;
     326       607034 :    logic [pt.LSU_BUS_TAG-1:0]          obuf_tag0;
     327       525370 :    logic [pt.LSU_BUS_TAG-1:0]          obuf_tag1;
     328       240167 :    logic [pt.LSU_BUS_TAG-1:0]          obuf_rdrsp_tag;
     329              : 
     330      1040997 :    logic                               ibuf_buf_byp;
     331        55926 :    logic                               obuf_force_wr_en;
     332       310812 :    logic                               obuf_wr_wait;
     333      1806860 :    logic                               obuf_wr_en, obuf_wr_enQ;
     334      1788338 :    logic                               obuf_rst;
     335       412936 :    logic                               obuf_write_in;
     336       993834 :    logic                               obuf_nosend_in;
     337          327 :    logic                               obuf_rdrsp_pend_en;
     338      1134312 :    logic                               obuf_rdrsp_pend_in;
     339         1729 :    logic                               obuf_sideeffect_in;
     340        32954 :    logic                               obuf_aligned_in;
     341       899304 :    logic [31:0]                        obuf_addr_in;
     342       350814 :    logic [63:0]                        obuf_data_in;
     343       150766 :    logic [1:0]                         obuf_sz_in;
     344       881677 :    logic [7:0]                         obuf_byteen_in;
     345        11414 :    logic                               obuf_merge_in;
     346            0 :    logic                               obuf_cmd_done_in, obuf_data_done_in;
     347       610776 :    logic [pt.LSU_BUS_TAG-1:0]          obuf_tag0_in;
     348      1007283 :    logic [pt.LSU_BUS_TAG-1:0]          obuf_tag1_in;
     349       240167 :    logic [pt.LSU_BUS_TAG-1:0]          obuf_rdrsp_tag_in;
     350              : 
     351        11414 :    logic                               obuf_merge_en;
     352      1139151 :    logic [TIMER_LOG2-1:0]              obuf_wr_timer, obuf_wr_timer_in;
     353       897141 :    logic [7:0]                         obuf_byteen0_in, obuf_byteen1_in;
     354       350814 :    logic [63:0]                        obuf_data0_in, obuf_data1_in;
     355              : 
     356      1365297 :    logic                               lsu_axi_awvalid_q, lsu_axi_awready_q;
     357      1365297 :    logic                               lsu_axi_wvalid_q, lsu_axi_wready_q;
     358      1381991 :    logic                               lsu_axi_arvalid_q, lsu_axi_arready_q;
     359       828149 :    logic                               lsu_axi_bvalid_q, lsu_axi_bready_q;
     360      1135743 :    logic                               lsu_axi_rvalid_q, lsu_axi_rready_q;
     361       344055 :    logic [pt.LSU_BUS_TAG-1:0]          lsu_axi_bid_q, lsu_axi_rid_q;
     362            4 :    logic [1:0]                         lsu_axi_bresp_q, lsu_axi_rresp_q;
     363            0 :    logic [pt.LSU_BUS_TAG-1:0]          lsu_imprecise_error_store_tag;
     364        96835 :    logic [63:0]                        lsu_axi_rdata_q;
     365              : 
     366              :    //------------------------------------------------------------------------------
     367              :    // Load forwarding logic start
     368              :    //------------------------------------------------------------------------------
     369              : 
     370              :    // Function to do 8 to 3 bit encoding
     371    362793921 :    function automatic logic [2:0] f_Enc8to3;
     372              :       input logic [7:0] Dec_value;
     373              : 
     374              :       logic [2:0]       Enc_value;
     375    362793921 :       Enc_value[0] = Dec_value[1] | Dec_value[3] | Dec_value[5] | Dec_value[7];
     376    362793921 :       Enc_value[1] = Dec_value[2] | Dec_value[3] | Dec_value[6] | Dec_value[7];
     377    362793921 :       Enc_value[2] = Dec_value[4] | Dec_value[5] | Dec_value[6] | Dec_value[7];
     378              : 
     379    362793921 :       return Enc_value[2:0];
     380              :    endfunction // f_Enc8to3
     381              : 
     382              :    // Buffer hit logic for bus load forwarding
     383              :    assign ldst_byteen_hi_m[3:0]   = ldst_byteen_ext_m[7:4];
     384              :    assign ldst_byteen_lo_m[3:0]   = ldst_byteen_ext_m[3:0];
     385              :    for (genvar i=0; i<DEPTH; i++) begin
     386              :       assign ld_addr_hitvec_lo[i] = (lsu_addr_m[31:2] == buf_addr[i][31:2]) & buf_write[i] & (buf_state[i] != IDLE) & lsu_busreq_m;
     387              :       assign ld_addr_hitvec_hi[i] = (end_addr_m[31:2] == buf_addr[i][31:2]) & buf_write[i] & (buf_state[i] != IDLE) & lsu_busreq_m;
     388              :    end
     389              : 
     390              :    for (genvar j=0; j<4; j++) begin
     391              :      assign ld_byte_hit_buf_lo[j] = |(ld_byte_hitvecfn_lo[j]) | ld_byte_ibuf_hit_lo[j];
     392              :      assign ld_byte_hit_buf_hi[j] = |(ld_byte_hitvecfn_hi[j]) | ld_byte_ibuf_hit_hi[j];
     393              :      for (genvar i=0; i<DEPTH; i++) begin
     394              :          assign ld_byte_hitvec_lo[j][i] = ld_addr_hitvec_lo[i] & buf_byteen[i][j] & ldst_byteen_lo_m[j];
     395              :          assign ld_byte_hitvec_hi[j][i] = ld_addr_hitvec_hi[i] & buf_byteen[i][j] & ldst_byteen_hi_m[j];
     396              : 
     397              :          assign ld_byte_hitvecfn_lo[j][i] = ld_byte_hitvec_lo[j][i] & ~(|(ld_byte_hitvec_lo[j] & buf_age_younger[i])) & ~ld_byte_ibuf_hit_lo[j];  // Kill the byte enable if younger entry exists or byte exists in ibuf
     398              :          assign ld_byte_hitvecfn_hi[j][i] = ld_byte_hitvec_hi[j][i] & ~(|(ld_byte_hitvec_hi[j] & buf_age_younger[i])) & ~ld_byte_ibuf_hit_hi[j];  // Kill the byte enable if younger entry exists or byte exists in ibuf
     399              :       end
     400              :    end
     401              : 
     402              :    // Hit in the ibuf
     403              :    assign ld_addr_ibuf_hit_lo = (lsu_addr_m[31:2] == ibuf_addr[31:2]) & ibuf_write & ibuf_valid & lsu_busreq_m;
     404              :    assign ld_addr_ibuf_hit_hi = (end_addr_m[31:2] == ibuf_addr[31:2]) & ibuf_write & ibuf_valid & lsu_busreq_m;
     405              : 
     406              :    for (genvar i=0; i<4; i++) begin
     407              :       assign ld_byte_ibuf_hit_lo[i] = ld_addr_ibuf_hit_lo & ibuf_byteen[i] & ldst_byteen_lo_m[i];
     408              :       assign ld_byte_ibuf_hit_hi[i] = ld_addr_ibuf_hit_hi & ibuf_byteen[i] & ldst_byteen_hi_m[i];
     409              :    end
     410              : 
     411          298 :    always_comb begin
     412          298 :       ld_fwddata_buf_lo[31:0] = {{8{ld_byte_ibuf_hit_lo[3]}},{8{ld_byte_ibuf_hit_lo[2]}},{8{ld_byte_ibuf_hit_lo[1]}},{8{ld_byte_ibuf_hit_lo[0]}}} & ibuf_data[31:0];
     413          298 :       ld_fwddata_buf_hi[31:0] = {{8{ld_byte_ibuf_hit_hi[3]}},{8{ld_byte_ibuf_hit_hi[2]}},{8{ld_byte_ibuf_hit_hi[1]}},{8{ld_byte_ibuf_hit_hi[0]}}} & ibuf_data[31:0];
     414         1192 :       for (int i=0; i<DEPTH; i++) begin
     415         1192 :          ld_fwddata_buf_lo[7:0]   |= {8{ld_byte_hitvecfn_lo[0][i]}} & buf_data[i][7:0];
     416         1192 :          ld_fwddata_buf_lo[15:8]  |= {8{ld_byte_hitvecfn_lo[1][i]}} & buf_data[i][15:8];
     417         1192 :          ld_fwddata_buf_lo[23:16] |= {8{ld_byte_hitvecfn_lo[2][i]}} & buf_data[i][23:16];
     418         1192 :          ld_fwddata_buf_lo[31:24] |= {8{ld_byte_hitvecfn_lo[3][i]}} & buf_data[i][31:24];
     419              : 
     420         1192 :          ld_fwddata_buf_hi[7:0]   |= {8{ld_byte_hitvecfn_hi[0][i]}} & buf_data[i][7:0];
     421         1192 :          ld_fwddata_buf_hi[15:8]  |= {8{ld_byte_hitvecfn_hi[1][i]}} & buf_data[i][15:8];
     422         1192 :          ld_fwddata_buf_hi[23:16] |= {8{ld_byte_hitvecfn_hi[2][i]}} & buf_data[i][23:16];
     423         1192 :          ld_fwddata_buf_hi[31:24] |= {8{ld_byte_hitvecfn_hi[3][i]}} & buf_data[i][31:24];
     424              :       end
     425              :    end
     426              : 
     427              :    //------------------------------------------------------------------------------
     428              :    // Load forwarding logic end
     429              :    //------------------------------------------------------------------------------
     430              : 
     431              :    assign bus_coalescing_disable = dec_tlu_wb_coalescing_disable | pt.BUILD_AHB_LITE;
     432              : 
     433              :    // Get the hi/lo byte enable
     434              :    assign ldst_byteen_r[3:0] = ({4{lsu_pkt_r.by}}   & 4'b0001) |
     435              :                                  ({4{lsu_pkt_r.half}} & 4'b0011) |
     436              :                                  ({4{lsu_pkt_r.word}} & 4'b1111);
     437              : 
     438              :    assign {ldst_byteen_hi_r[3:0], ldst_byteen_lo_r[3:0]} = {4'b0,ldst_byteen_r[3:0]} << lsu_addr_r[1:0];
     439              :    assign {store_data_hi_r[31:0], store_data_lo_r[31:0]} = {32'b0,store_data_r[31:0]} << 8*lsu_addr_r[1:0];
     440              :    assign ldst_samedw_r    = (lsu_addr_r[3] == end_addr_r[3]);
     441              :    assign is_aligned_r    = (lsu_pkt_r.word & (lsu_addr_r[1:0] == 2'b0)) |
     442              :                             (lsu_pkt_r.half & (lsu_addr_r[0] == 1'b0))   |
     443              :                             lsu_pkt_r.by;
     444              : 
     445              :    //------------------------------------------------------------------------------
     446              :    // Input buffer logic starts here
     447              :    //------------------------------------------------------------------------------
     448              : 
     449              :    assign ibuf_byp = lsu_busreq_r & (lsu_pkt_r.load | no_word_merge_r) & ~ibuf_valid;
     450              :    assign ibuf_wr_en = lsu_busreq_r & lsu_commit_r & ~ibuf_byp;
     451              :    assign ibuf_rst   = (ibuf_drain_vld & ~ibuf_wr_en) | dec_tlu_force_halt;
     452              :    assign ibuf_force_drain = lsu_busreq_m & ~lsu_busreq_r & ibuf_valid & (lsu_pkt_m.load | (ibuf_addr[31:2] != lsu_addr_m[31:2]));  // Move the ibuf to buf if there is a non-colaescable ld/st in m but nothing in r
     453              :    assign ibuf_drain_vld = ibuf_valid & (((ibuf_wr_en | (ibuf_timer == TIMER_MAX)) & ~(ibuf_merge_en & ibuf_merge_in)) | ibuf_byp | ibuf_force_drain | ibuf_sideeffect | ~ibuf_write | bus_coalescing_disable);
     454              :    assign ibuf_tag_in[DEPTH_LOG2-1:0] = (ibuf_merge_en & ibuf_merge_in) ? ibuf_tag[DEPTH_LOG2-1:0] : (ldst_dual_r ? WrPtr1_r : WrPtr0_r);
     455              :    assign ibuf_dualtag_in[DEPTH_LOG2-1:0] = WrPtr0_r;
     456              :    assign ibuf_sz_in[1:0]   = {lsu_pkt_r.word, lsu_pkt_r.half};
     457              :    assign ibuf_addr_in[31:0] = ldst_dual_r ? end_addr_r[31:0] : lsu_addr_r[31:0];
     458              :    assign ibuf_byteen_in[3:0] = (ibuf_merge_en & ibuf_merge_in) ? (ibuf_byteen[3:0] | ldst_byteen_lo_r[3:0]) : (ldst_dual_r ? ldst_byteen_hi_r[3:0] : ldst_byteen_lo_r[3:0]);
     459              :    for (genvar i=0; i<4; i++) begin
     460              :       assign ibuf_data_in[(8*i)+7:(8*i)] = (ibuf_merge_en & ibuf_merge_in) ? (ldst_byteen_lo_r[i] ? store_data_lo_r[(8*i)+7:(8*i)] : ibuf_data[(8*i)+7:(8*i)]) :
     461              :                                                                              (ldst_dual_r ? store_data_hi_r[(8*i)+7:(8*i)] : store_data_lo_r[(8*i)+7:(8*i)]);
     462              :    end
     463              :    assign ibuf_timer_in = ibuf_wr_en ? '0 : (ibuf_timer < TIMER_MAX) ? (ibuf_timer + 1'b1) : ibuf_timer;
     464              : 
     465              : 
     466              :    assign ibuf_merge_en = lsu_busreq_r & lsu_commit_r & lsu_pkt_r.store & ibuf_valid & ibuf_write & (lsu_addr_r[31:2] == ibuf_addr[31:2]) & ~is_sideeffects_r & ~bus_coalescing_disable;
     467              :    assign ibuf_merge_in = ~ldst_dual_r;   // If it's a unaligned store, merge needs to happen on the way out of ibuf
     468              : 
     469              :    // ibuf signals going to bus buffer after merging
     470              :    for (genvar i=0; i<4; i++) begin
     471              :       assign ibuf_byteen_out[i] = (ibuf_merge_en & ~ibuf_merge_in) ? (ibuf_byteen[i] | ldst_byteen_lo_r[i]) : ibuf_byteen[i];
     472              :       assign ibuf_data_out[(8*i)+7:(8*i)] = (ibuf_merge_en & ~ibuf_merge_in) ? (ldst_byteen_lo_r[i] ? store_data_lo_r[(8*i)+7:(8*i)] : ibuf_data[(8*i)+7:(8*i)]) :
     473              :                                                                                                         ibuf_data[(8*i)+7:(8*i)];
     474              :    end
     475              : 
     476              :    rvdffsc #(.WIDTH(1))              ibuf_valid_ff     (.din(1'b1),                      .dout(ibuf_valid),      .en(ibuf_wr_en), .clear(ibuf_rst), .clk(lsu_free_c2_clk), .*);
     477              :    rvdffs  #(.WIDTH(DEPTH_LOG2))     ibuf_tagff        (.din(ibuf_tag_in),               .dout(ibuf_tag),        .en(ibuf_wr_en),                   .clk(lsu_bus_ibuf_c1_clk), .*);
     478              :    rvdffs  #(.WIDTH(DEPTH_LOG2))     ibuf_dualtagff    (.din(ibuf_dualtag_in),           .dout(ibuf_dualtag),    .en(ibuf_wr_en),                   .clk(lsu_bus_ibuf_c1_clk), .*);
     479              :    rvdffs  #(.WIDTH(1))              ibuf_dualff       (.din(ldst_dual_r),               .dout(ibuf_dual),       .en(ibuf_wr_en),                   .clk(lsu_bus_ibuf_c1_clk), .*);
     480              :    rvdffs  #(.WIDTH(1))              ibuf_samedwff     (.din(ldst_samedw_r),             .dout(ibuf_samedw),     .en(ibuf_wr_en),                   .clk(lsu_bus_ibuf_c1_clk), .*);
     481              :    rvdffs  #(.WIDTH(1))              ibuf_nomergeff    (.din(no_dword_merge_r),          .dout(ibuf_nomerge),    .en(ibuf_wr_en),                   .clk(lsu_bus_ibuf_c1_clk), .*);
     482              :    rvdffs  #(.WIDTH(1))              ibuf_sideeffectff (.din(is_sideeffects_r),          .dout(ibuf_sideeffect), .en(ibuf_wr_en),                   .clk(lsu_bus_ibuf_c1_clk), .*);
     483              :    rvdffs  #(.WIDTH(1))              ibuf_unsignff     (.din(lsu_pkt_r.unsign),          .dout(ibuf_unsign),     .en(ibuf_wr_en),                   .clk(lsu_bus_ibuf_c1_clk), .*);
     484              :    rvdffs  #(.WIDTH(1))              ibuf_writeff      (.din(lsu_pkt_r.store),           .dout(ibuf_write),      .en(ibuf_wr_en),                   .clk(lsu_bus_ibuf_c1_clk), .*);
     485              :    rvdffs  #(.WIDTH(2))              ibuf_szff         (.din(ibuf_sz_in[1:0]),           .dout(ibuf_sz),         .en(ibuf_wr_en),                   .clk(lsu_bus_ibuf_c1_clk), .*);
     486              :    rvdffe  #(.WIDTH(32))             ibuf_addrff       (.din(ibuf_addr_in[31:0]),        .dout(ibuf_addr),       .en(ibuf_wr_en),                                              .*);
     487              :    rvdffs  #(.WIDTH(4))              ibuf_byteenff     (.din(ibuf_byteen_in[3:0]),       .dout(ibuf_byteen),     .en(ibuf_wr_en),                   .clk(lsu_bus_ibuf_c1_clk), .*);
     488              :    rvdffe  #(.WIDTH(32))             ibuf_dataff       (.din(ibuf_data_in[31:0]),        .dout(ibuf_data),       .en(ibuf_wr_en),                                              .*);
     489              :    rvdff   #(.WIDTH(TIMER_LOG2))     ibuf_timerff      (.din(ibuf_timer_in),             .dout(ibuf_timer),                                         .clk(lsu_free_c2_clk),     .*);
     490              : 
     491              : 
     492              :    //------------------------------------------------------------------------------
     493              :    // Input buffer logic ends here
     494              :    //------------------------------------------------------------------------------
     495              : 
     496              : 
     497              :    //------------------------------------------------------------------------------
     498              :    // Output buffer logic starts here
     499              :    //------------------------------------------------------------------------------
     500              : 
     501              :    assign obuf_wr_wait = (buf_numvld_wrcmd_any[3:0] == 4'b1) & (buf_numvld_cmd_any[3:0] == 4'b1) & (obuf_wr_timer != TIMER_MAX) &
     502              :                          ~bus_coalescing_disable & ~buf_nomerge[CmdPtr0] & ~buf_sideeffect[CmdPtr0] & ~obuf_force_wr_en;
     503              :    assign obuf_wr_timer_in = obuf_wr_en ? 3'b0: (((buf_numvld_cmd_any > 4'b0) & (obuf_wr_timer < TIMER_MAX)) ? (obuf_wr_timer + 1'b1) : obuf_wr_timer);
     504              :    assign obuf_force_wr_en = lsu_busreq_m & ~lsu_busreq_r & ~ibuf_valid & (buf_numvld_cmd_any[3:0] == 4'b1) & (lsu_addr_m[31:2] != buf_addr[CmdPtr0][31:2]);   // Entry in m can't merge with entry going to obuf and there is no entry in between
     505              :    assign ibuf_buf_byp = ibuf_byp & (buf_numvld_pend_any[3:0] == 4'b0) & (~lsu_pkt_r.store | no_dword_merge_r);
     506              : 
     507              :    assign obuf_wr_en = ((ibuf_buf_byp & lsu_commit_r & ~(is_sideeffects_r & bus_sideeffect_pend)) |
     508              :                         ((buf_state[CmdPtr0] == CMD) & found_cmdptr0 & ~buf_cmd_state_bus_en[CmdPtr0] & ~(buf_sideeffect[CmdPtr0] & bus_sideeffect_pend) &
     509              :                          (~(buf_dual[CmdPtr0] & buf_samedw[CmdPtr0] & ~buf_write[CmdPtr0]) | found_cmdptr1 | buf_nomerge[CmdPtr0] | obuf_force_wr_en))) &
     510              :                        (bus_cmd_ready | ~obuf_valid | obuf_nosend) & ~obuf_wr_wait  & ~bus_addr_match_pending & lsu_bus_clk_en;
     511              : 
     512              :    assign obuf_rst   = ((bus_cmd_sent | (obuf_valid & obuf_nosend)) & ~obuf_wr_en & lsu_bus_clk_en) | dec_tlu_force_halt;
     513              : 
     514              :    assign obuf_write_in      = ibuf_buf_byp ? lsu_pkt_r.store : buf_write[CmdPtr0];
     515              :    assign obuf_sideeffect_in = ibuf_buf_byp ? is_sideeffects_r : buf_sideeffect[CmdPtr0];
     516              :    assign obuf_addr_in[31:0] = ibuf_buf_byp ? lsu_addr_r[31:0] : buf_addr[CmdPtr0];
     517              :    assign obuf_sz_in[1:0]    = ibuf_buf_byp ? {lsu_pkt_r.word, lsu_pkt_r.half} : buf_sz[CmdPtr0];
     518              :    assign obuf_merge_in      = obuf_merge_en;
     519              :    assign obuf_tag0_in[pt.LSU_BUS_TAG-1:0] = ibuf_buf_byp ? (pt.LSU_BUS_TAG)'(WrPtr0_r) : (pt.LSU_BUS_TAG)'(CmdPtr0);
     520              :    assign obuf_tag1_in[pt.LSU_BUS_TAG-1:0] = ibuf_buf_byp ? (pt.LSU_BUS_TAG)'(WrPtr1_r) : (pt.LSU_BUS_TAG)'(CmdPtr1);
     521              : 
     522              :    assign obuf_cmd_done_in    = ~(obuf_wr_en | obuf_rst) & (obuf_cmd_done | bus_wcmd_sent);
     523              :    assign obuf_data_done_in   = ~(obuf_wr_en | obuf_rst) & (obuf_data_done | bus_wdata_sent);
     524              : 
     525              :    assign obuf_aligned_in    = ibuf_buf_byp ? is_aligned_r : ((obuf_sz_in[1:0] == 2'b0) |
     526              :                                                               (obuf_sz_in[0] & ~obuf_addr_in[0]) |
     527              :                                                               (obuf_sz_in[1] & ~(|obuf_addr_in[1:0])));
     528              : 
     529              :    assign obuf_rdrsp_pend_in  = ((~(obuf_wr_en & ~obuf_nosend_in) & obuf_rdrsp_pend & ~(bus_rsp_read & (bus_rsp_read_tag == obuf_rdrsp_tag))) | (bus_cmd_sent & ~obuf_write)) & ~dec_tlu_force_halt;
     530              :    assign obuf_rdrsp_pend_en  = lsu_bus_clk_en | dec_tlu_force_halt;
     531              :    assign obuf_rdrsp_tag_in[pt.LSU_BUS_TAG-1:0] = (bus_cmd_sent & ~obuf_write) ? obuf_tag0[pt.LSU_BUS_TAG-1:0] : obuf_rdrsp_tag[pt.LSU_BUS_TAG-1:0];
     532              :    // No ld to ld fwd for aligned
     533              :    assign obuf_nosend_in      = (obuf_addr_in[31:3] == obuf_addr[31:3]) & obuf_aligned_in & ~obuf_sideeffect & ~obuf_write & ~obuf_write_in & ~dec_tlu_external_ldfwd_disable &
     534              :                                 ((obuf_valid & ~obuf_nosend) | (obuf_rdrsp_pend & ~(bus_rsp_read & (bus_rsp_read_tag == obuf_rdrsp_tag))));
     535              : 
     536              :    assign obuf_byteen0_in[7:0] = ibuf_buf_byp ? (lsu_addr_r[2] ? {ldst_byteen_lo_r[3:0],4'b0} : {4'b0,ldst_byteen_lo_r[3:0]}) :
     537              :                                                 (buf_addr[CmdPtr0][2] ? {buf_byteen[CmdPtr0],4'b0} : {4'b0,buf_byteen[CmdPtr0]});
     538              :    assign obuf_byteen1_in[7:0] = ibuf_buf_byp ? (end_addr_r[2] ? {ldst_byteen_hi_r[3:0],4'b0} : {4'b0,ldst_byteen_hi_r[3:0]}) :
     539              :                                                 (buf_addr[CmdPtr1][2] ? {buf_byteen[CmdPtr1],4'b0} : {4'b0,buf_byteen[CmdPtr1]});
     540              :    assign obuf_data0_in[63:0]  = ibuf_buf_byp ? (lsu_addr_r[2] ? {store_data_lo_r[31:0],32'b0} : {32'b0,store_data_lo_r[31:0]}) :
     541              :                                                 (buf_addr[CmdPtr0][2] ? {buf_data[CmdPtr0],32'b0} : {32'b0,buf_data[CmdPtr0]});
     542              :    assign obuf_data1_in[63:0]  = ibuf_buf_byp ? (end_addr_r[2] ? {store_data_hi_r[31:0],32'b0} :{32'b0,store_data_hi_r[31:0]}) :
     543              :                                                 (buf_addr[CmdPtr1][2] ? {buf_data[CmdPtr1],32'b0} : {32'b0,buf_data[CmdPtr1]});
     544              : 
     545              :    for (genvar i=0 ;i<8; i++) begin
     546              :       assign obuf_byteen_in[i] = obuf_byteen0_in[i] | (obuf_merge_en & obuf_byteen1_in[i]);
     547              :       assign obuf_data_in[(8*i)+7:(8*i)] = (obuf_merge_en & obuf_byteen1_in[i]) ? obuf_data1_in[(8*i)+7:(8*i)] : obuf_data0_in[(8*i)+7:(8*i)];
     548              :    end
     549              : 
     550              :    // No store obuf merging for AXI since all stores are sent non-posted. Can't track the second id right now
     551              :    assign obuf_merge_en = ((CmdPtr0 != CmdPtr1) & found_cmdptr0 & found_cmdptr1 & (buf_state[CmdPtr0] == CMD) & (buf_state[CmdPtr1] == CMD) &
     552              :                            ~buf_cmd_state_bus_en[CmdPtr0] & ~buf_sideeffect[CmdPtr0] &
     553              :                            (~buf_write[CmdPtr0] & buf_dual[CmdPtr0] & ~buf_dualhi[CmdPtr0] & buf_samedw[CmdPtr0])) |  // CmdPtr0/CmdPtr1 are for same load which is within a DW
     554              :                           (ibuf_buf_byp & ldst_samedw_r & ldst_dual_r);
     555              : 
     556              : 
     557              :    rvdff_fpga  #(.WIDTH(1))              obuf_wren_ff      (.din(obuf_wr_en),                  .dout(obuf_wr_enQ),                                        .clk(lsu_busm_clk),        .clken(lsu_busm_clken), .rawclk(clk),        .*);
     558              :    rvdffsc     #(.WIDTH(1))              obuf_valid_ff     (.din(1'b1),                        .dout(obuf_valid),      .en(obuf_wr_en), .clear(obuf_rst), .clk(lsu_free_c2_clk),                                                  .*);
     559              :    rvdffs      #(.WIDTH(1))              obuf_nosend_ff    (.din(obuf_nosend_in),              .dout(obuf_nosend),     .en(obuf_wr_en),                   .clk(lsu_free_c2_clk),                                                  .*);
     560              :    rvdffs      #(.WIDTH(1))              obuf_rdrsp_pend_ff(.din(obuf_rdrsp_pend_in),          .dout(obuf_rdrsp_pend), .en(obuf_rdrsp_pend_en),           .clk(lsu_free_c2_clk),                                                  .*);
     561              :    rvdff_fpga  #(.WIDTH(1))              obuf_cmd_done_ff  (.din(obuf_cmd_done_in),            .dout(obuf_cmd_done),                                      .clk(lsu_busm_clk),        .clken(lsu_busm_clken),        .rawclk(clk), .*);
     562              :    rvdff_fpga  #(.WIDTH(1))              obuf_data_done_ff (.din(obuf_data_done_in),           .dout(obuf_data_done),                                     .clk(lsu_busm_clk),        .clken(lsu_busm_clken),        .rawclk(clk), .*);
     563              :    rvdff_fpga  #(.WIDTH(pt.LSU_BUS_TAG)) obuf_rdrsp_tagff  (.din(obuf_rdrsp_tag_in),           .dout(obuf_rdrsp_tag),                                     .clk(lsu_busm_clk),        .clken(lsu_busm_clken),        .rawclk(clk), .*);
     564              :    rvdffs_fpga #(.WIDTH(pt.LSU_BUS_TAG)) obuf_tag0ff       (.din(obuf_tag0_in),                .dout(obuf_tag0),       .en(obuf_wr_en),                   .clk(lsu_bus_obuf_c1_clk), .clken(lsu_bus_obuf_c1_clken), .rawclk(clk), .*);
     565              :    rvdffs_fpga #(.WIDTH(pt.LSU_BUS_TAG)) obuf_tag1ff       (.din(obuf_tag1_in),                .dout(obuf_tag1),       .en(obuf_wr_en),                   .clk(lsu_bus_obuf_c1_clk), .clken(lsu_bus_obuf_c1_clken), .rawclk(clk), .*);
     566              :    rvdffs_fpga #(.WIDTH(1))              obuf_mergeff      (.din(obuf_merge_in),               .dout(obuf_merge),      .en(obuf_wr_en),                   .clk(lsu_bus_obuf_c1_clk), .clken(lsu_bus_obuf_c1_clken), .rawclk(clk), .*);
     567              :    rvdffs_fpga #(.WIDTH(1))              obuf_writeff      (.din(obuf_write_in),               .dout(obuf_write),      .en(obuf_wr_en),                   .clk(lsu_bus_obuf_c1_clk), .clken(lsu_bus_obuf_c1_clken), .rawclk(clk), .*);
     568              :    rvdffs_fpga #(.WIDTH(1))              obuf_sideeffectff (.din(obuf_sideeffect_in),          .dout(obuf_sideeffect), .en(obuf_wr_en),                   .clk(lsu_bus_obuf_c1_clk), .clken(lsu_bus_obuf_c1_clken), .rawclk(clk), .*);
     569              :    rvdffs_fpga #(.WIDTH(2))              obuf_szff         (.din(obuf_sz_in[1:0]),             .dout(obuf_sz),         .en(obuf_wr_en),                   .clk(lsu_bus_obuf_c1_clk), .clken(lsu_bus_obuf_c1_clken), .rawclk(clk), .*);
     570              :    rvdffs_fpga #(.WIDTH(8))              obuf_byteenff     (.din(obuf_byteen_in[7:0]),         .dout(obuf_byteen),     .en(obuf_wr_en),                   .clk(lsu_bus_obuf_c1_clk), .clken(lsu_bus_obuf_c1_clken), .rawclk(clk), .*);
     571              :    rvdffe     #(.WIDTH(32))              obuf_addrff       (.din(obuf_addr_in[31:0]),          .dout(obuf_addr),       .en(obuf_wr_en),                                                                                           .*);
     572              :    rvdffe     #(.WIDTH(64))              obuf_dataff       (.din(obuf_data_in[63:0]),          .dout(obuf_data),       .en(obuf_wr_en),                                                                                           .*);
     573              :    rvdff_fpga #(.WIDTH(TIMER_LOG2))      obuf_timerff      (.din(obuf_wr_timer_in),            .dout(obuf_wr_timer),                                      .clk(lsu_busm_clk),        .clken(lsu_busm_clken), .rawclk(clk),        .*);
     574              : 
     575              : 
     576              :    //------------------------------------------------------------------------------
     577              :    // Output buffer logic ends here
     578              :    //------------------------------------------------------------------------------
     579              : 
     580              :    // Find the entry to allocate and entry to send
     581     42436767 :    always_comb begin
     582     42436767 :       WrPtr0_m[DEPTH_LOG2-1:0] = '0;
     583     42436767 :       WrPtr1_m[DEPTH_LOG2-1:0] = '0;
     584     42436767 :       found_wrptr0  = '0;
     585     42436767 :       found_wrptr1  = '0;
     586              : 
     587              :       // Find first write pointer
     588    169747068 :       for (int i=0; i<DEPTH; i++) begin
     589    119478368 :          if (~found_wrptr0) begin
     590     50268700 :             WrPtr0_m[DEPTH_LOG2-1:0] = DEPTH_LOG2'(i);
     591     50268700 :             found_wrptr0 = (buf_state[i] == IDLE) & ~((ibuf_valid & (ibuf_tag == i))                                               |
     592     50268700 :                                                       (lsu_busreq_r & ((WrPtr0_r == i) | (ldst_dual_r & (WrPtr1_r == i)))));
     593              :          end
     594              :       end
     595              : 
     596              :       // Find second write pointer
     597    169747068 :       for (int i=0; i<DEPTH; i++) begin
     598    118277131 :          if (~found_wrptr1) begin
     599     51469937 :             WrPtr1_m[DEPTH_LOG2-1:0] = DEPTH_LOG2'(i);
     600     51469937 :             found_wrptr1 = (buf_state[i] == IDLE) & ~((ibuf_valid & (ibuf_tag == i))                                               |
     601     51469937 :                                                       (lsu_busreq_m & (WrPtr0_m == i))                                         |
     602     51469937 :                                                       (lsu_busreq_r & ((WrPtr0_r == i) | (ldst_dual_r & (WrPtr1_r == i)))));
     603              :          end
     604              :       end
     605              :    end
     606              : 
     607              :    // Get the command ptr
     608              :    for (genvar i=0; i<DEPTH; i++) begin
     609              :       // These should be one-hot
     610              :       assign CmdPtr0Dec[i] = ~(|buf_age[i]) & (buf_state[i] == CMD) & ~buf_cmd_state_bus_en[i];
     611              :       assign CmdPtr1Dec[i] = ~(|(buf_age[i] & ~CmdPtr0Dec)) & ~CmdPtr0Dec[i] & (buf_state[i] == CMD) & ~buf_cmd_state_bus_en[i];
     612              :       assign RspPtrDec[i]  = ~(|buf_rsp_pickage[i]) & (buf_state[i] == DONE_WAIT);
     613              :    end
     614              : 
     615              :    assign found_cmdptr0 = |CmdPtr0Dec;
     616              :    assign found_cmdptr1 = |CmdPtr1Dec;
     617              :    assign CmdPtr0 = f_Enc8to3(8'(CmdPtr0Dec[DEPTH-1:0]));
     618              :    assign CmdPtr1 = f_Enc8to3(8'(CmdPtr1Dec[DEPTH-1:0]));
     619              :    assign RspPtr  = f_Enc8to3(8'(RspPtrDec[DEPTH-1:0]));
     620              : 
     621              :    // Age vector
     622              :    for (genvar i=0; i<DEPTH; i++) begin: GenAgeVec
     623              :       for (genvar j=0; j<DEPTH; j++) begin
     624              :          assign buf_age_in[i][j] = (((buf_state[i] == IDLE) & buf_state_en[i]) &
     625              :                                     (((buf_state[j] == START_WAIT) | ((buf_state[j] == CMD) & ~buf_cmd_state_bus_en[j]))                   |       // Set age bit for older entries
     626              :                                      (ibuf_drain_vld & lsu_busreq_r & (ibuf_byp | ldst_dual_r) & (i == WrPtr0_r) & (j == ibuf_tag))  |       // Set case for dual lo
     627              :                                      (ibuf_byp & lsu_busreq_r & ldst_dual_r & (i == WrPtr1_r) & (j == WrPtr0_r))))                      |     // ibuf bypass case
     628              :                                    buf_age[i][j];
     629              : 
     630              : 
     631              :          assign buf_age[i][j]    = buf_ageQ[i][j] & ~((buf_state[j] == CMD) & buf_cmd_state_bus_en[j]) & ~dec_tlu_force_halt;  // Reset case
     632              : 
     633              :          assign buf_age_younger[i][j] = (i == j) ? 1'b0: (~buf_age[i][j] & (buf_state[j] != IDLE));   // Younger entries
     634              :       end
     635              :    end
     636              : 
     637              :    // Age vector for responses
     638              :    for (genvar i=0; i<DEPTH; i++) begin: GenRspAgeVec
     639              :       for (genvar j=0; j<DEPTH; j++) begin
     640              :          assign buf_rspage_set[i][j] = ((buf_state[i] == IDLE) & buf_state_en[i]) &
     641              :                                            (~((buf_state[j] == IDLE) | (buf_state[j] == DONE))                                         |       // Set age bit for older entries
     642              :                                             (ibuf_drain_vld & lsu_busreq_r & (ibuf_byp | ldst_dual_r) & (DEPTH_LOG2'(i) == WrPtr0_r) & (DEPTH_LOG2'(j) == ibuf_tag))  |       // Set case for dual lo
     643              :                                             (ibuf_byp & lsu_busreq_r & ldst_dual_r & (DEPTH_LOG2'(i) == WrPtr1_r) & (DEPTH_LOG2'(j) == WrPtr0_r)));
     644              :          assign buf_rspage_in[i][j] = buf_rspage_set[i][j] | buf_rspage[i][j];
     645              :          assign buf_rspage[i][j]    = buf_rspageQ[i][j] & ~((buf_state[j] == DONE) | (buf_state[j] == IDLE)) & ~dec_tlu_force_halt;  // Reset case
     646              :          assign buf_rsp_pickage[i][j] = buf_rspageQ[i][j] & (buf_state[j] == DONE_WAIT);
     647              :      end
     648              :    end
     649              : 
     650              :    //------------------------------------------------------------------------------
     651              :    // Buffer logic
     652              :    //------------------------------------------------------------------------------
     653    640823124 :    for (genvar i=0; i<DEPTH; i++) begin : genblock
     654              : 
     655              :       assign ibuf_drainvec_vld[i] = (ibuf_drain_vld & (i == ibuf_tag));
     656              :       assign buf_byteen_in[i]     = ibuf_drainvec_vld[i] ? ibuf_byteen_out[3:0] : ((ibuf_byp & ldst_dual_r & (i == WrPtr1_r)) ? ldst_byteen_hi_r[3:0] : ldst_byteen_lo_r[3:0]);
     657              :       assign buf_addr_in[i]       = ibuf_drainvec_vld[i] ? ibuf_addr[31:0] : ((ibuf_byp & ldst_dual_r & (i == WrPtr1_r)) ? end_addr_r[31:0] : lsu_addr_r[31:0]);
     658              :       assign buf_dual_in[i]       = ibuf_drainvec_vld[i] ? ibuf_dual : ldst_dual_r;
     659              :       assign buf_samedw_in[i]     = ibuf_drainvec_vld[i] ? ibuf_samedw : ldst_samedw_r;
     660              :       assign buf_nomerge_in[i]    = ibuf_drainvec_vld[i] ? (ibuf_nomerge | ibuf_force_drain) : no_dword_merge_r;
     661              :       assign buf_dualhi_in[i]     = ibuf_drainvec_vld[i] ? ibuf_dual : (ibuf_byp & ldst_dual_r & (i == WrPtr1_r));   // If it's dual, ibuf will always have the high
     662              :       assign buf_dualtag_in[i]    = ibuf_drainvec_vld[i] ? ibuf_dualtag : ((ibuf_byp & ldst_dual_r & (i == WrPtr1_r)) ? WrPtr0_r : WrPtr1_r);
     663              :       assign buf_sideeffect_in[i] = ibuf_drainvec_vld[i] ? ibuf_sideeffect : is_sideeffects_r;
     664              :       assign buf_unsign_in[i]     = ibuf_drainvec_vld[i] ? ibuf_unsign : lsu_pkt_r.unsign;
     665              :       assign buf_sz_in[i]         = ibuf_drainvec_vld[i] ? ibuf_sz : {lsu_pkt_r.word, lsu_pkt_r.half};
     666              :       assign buf_write_in[i]      = ibuf_drainvec_vld[i] ? ibuf_write : lsu_pkt_r.store;
     667              : 
     668              :       // Buffer entry state machine
     669    640823124 :       always_comb begin
     670    640823124 :          buf_nxtstate[i]          = IDLE;
     671    640823124 :          buf_state_en[i]          = '0;
     672    640823124 :          buf_resp_state_bus_en[i] = '0;
     673    640823124 :          buf_state_bus_en[i]      = '0;
     674    640823124 :          buf_wr_en[i]             = '0;
     675    640823124 :          buf_data_in[i]           = '0;
     676    640823124 :          buf_data_en[i]           = '0;
     677    640823124 :          buf_error_en[i]          = '0;
     678    640823124 :          buf_rst[i]               = dec_tlu_force_halt;
     679    640823124 :          buf_ldfwd_en[i]          = dec_tlu_force_halt;
     680    640823124 :          buf_ldfwd_in[i]          = '0;
     681    640823124 :          buf_ldfwdtag_in[i]       = '0;
     682              : 
     683    640823124 :          case (buf_state[i])
     684    612645415 :             IDLE: begin
     685    612645415 :                      buf_nxtstate[i] = lsu_bus_clk_en ? CMD : START_WAIT;
     686    612645415 :                      buf_state_en[i] = (lsu_busreq_r & lsu_commit_r & (((ibuf_byp | ldst_dual_r) & ~ibuf_merge_en & (i == WrPtr0_r)) | (ibuf_byp & ldst_dual_r & (i == WrPtr1_r)))) |
     687    612645415 :                                        (ibuf_drain_vld & (i == ibuf_tag));
     688    612645415 :                      buf_wr_en[i]    = buf_state_en[i];
     689    612645415 :                      buf_data_en[i]  = buf_state_en[i];
     690    612645415 :                      buf_data_in[i]   = (ibuf_drain_vld & (i == ibuf_tag)) ? ibuf_data_out[31:0] : store_data_lo_r[31:0];
     691    612645415 :                      buf_cmd_state_bus_en[i]  = '0;
     692              :             end
     693           58 :             START_WAIT: begin
     694           58 :                      buf_nxtstate[i] = dec_tlu_force_halt ? IDLE : CMD;
     695           58 :                      buf_state_en[i] = lsu_bus_clk_en | dec_tlu_force_halt;
     696           58 :                      buf_cmd_state_bus_en[i]  = '0;
     697              :             end
     698     11193906 :             CMD: begin
     699     11193906 :                      buf_nxtstate[i]          = dec_tlu_force_halt ? IDLE : (obuf_nosend & bus_rsp_read & (bus_rsp_read_tag == obuf_rdrsp_tag)) ? DONE_WAIT : RESP;
     700     11193906 :                      buf_cmd_state_bus_en[i]  = ((obuf_tag0 == i) | (obuf_merge & (obuf_tag1 == i))) & obuf_valid & obuf_wr_enQ;  // Just use the recently written obuf_valid
     701     11193906 :                      buf_state_bus_en[i]      = buf_cmd_state_bus_en[i];
     702     11193906 :                      buf_state_en[i]          = (buf_state_bus_en[i] & lsu_bus_clk_en) | dec_tlu_force_halt;
     703     11193906 :                      buf_ldfwd_in[i]          = 1'b1;
     704     11193906 :                      buf_ldfwd_en[i]          = buf_state_en[i] & ~buf_write[i] & obuf_nosend & ~dec_tlu_force_halt;
     705     11193906 :                      buf_ldfwdtag_in[i]       = DEPTH_LOG2'(obuf_rdrsp_tag[pt.LSU_BUS_TAG-2:0]);
     706     11193906 :                      buf_data_en[i]           = buf_state_bus_en[i] & lsu_bus_clk_en & obuf_nosend & bus_rsp_read;
     707     11193906 :                      buf_error_en[i]          = buf_state_bus_en[i] & lsu_bus_clk_en & obuf_nosend & bus_rsp_read_error;
     708     11193906 :                      buf_data_in[i]           = buf_error_en[i] ? bus_rsp_rdata[31:0] : (buf_addr[i][2] ? bus_rsp_rdata[63:32] : bus_rsp_rdata[31:0]);
     709              :             end
     710     12717711 :             RESP: begin
     711     12717711 :                      buf_nxtstate[i]           = (dec_tlu_force_halt | (buf_write[i] & ~bus_rsp_write_error)) ? IDLE :    // Side-effect writes will be non-posted
     712     12717711 :                                                       (buf_dual[i] & ~buf_samedw[i] & ~buf_write[i] & (buf_state[buf_dualtag[i]] != DONE_PARTIAL)) ? DONE_PARTIAL : // Goto DONE_PARTIAL if this is the first return of dual
     713     12717711 :                                                            (buf_ldfwd[i] | any_done_wait_state |
     714     12717711 :                                                             (buf_dual[i] & ~buf_samedw[i] & ~buf_write[i] & buf_ldfwd[buf_dualtag[i]] &
     715     12717711 :                                                              (buf_state[buf_dualtag[i]] == DONE_PARTIAL) & any_done_wait_state)) ? DONE_WAIT : DONE;
     716     12717711 :                      buf_resp_state_bus_en[i]  = (bus_rsp_write & (bus_rsp_write_tag == (pt.LSU_BUS_TAG)'(i))) |
     717     12717711 :                                                  (bus_rsp_read  & ((bus_rsp_read_tag == (pt.LSU_BUS_TAG)'(i)) |
     718     12717711 :                                                                    (buf_ldfwd[i] & (bus_rsp_read_tag == (pt.LSU_BUS_TAG)'(buf_ldfwdtag[i]))) |
     719     12717711 :                                                                    (buf_dual[i] & buf_dualhi[i] & ~buf_write[i] & buf_samedw[i] & (bus_rsp_read_tag == (pt.LSU_BUS_TAG)'(buf_dualtag[i])))));
     720     12717711 :                      buf_state_bus_en[i]       = buf_resp_state_bus_en[i];
     721     12717711 :                      buf_state_en[i]           = (buf_state_bus_en[i] & lsu_bus_clk_en) | dec_tlu_force_halt;
     722     12717711 :                      buf_data_en[i]            = buf_state_bus_en[i] & bus_rsp_read & lsu_bus_clk_en;
     723              :                       // Need to capture the error for stores as well for AXI
     724     12717711 :                      buf_error_en[i]           = buf_state_bus_en[i] & lsu_bus_clk_en & ((bus_rsp_read_error  & (bus_rsp_read_tag  == (pt.LSU_BUS_TAG)'(i))) |
     725     12717711 :                                                                                          (bus_rsp_read_error  & buf_ldfwd[i] & (bus_rsp_read_tag == (pt.LSU_BUS_TAG)'(buf_ldfwdtag[i]))) |
     726     12717711 :                                                                                          (bus_rsp_write_error & (bus_rsp_write_tag == (pt.LSU_BUS_TAG)'(i))));
     727     12717711 :                      buf_data_in[i][31:0]      = (buf_state_en[i] & ~buf_error_en[i]) ? (buf_addr[i][2] ? bus_rsp_rdata[63:32] : bus_rsp_rdata[31:0]) : bus_rsp_rdata[31:0];
     728     12717711 :                      buf_cmd_state_bus_en[i]  = '0;
     729              :             end
     730        33264 :             DONE_PARTIAL: begin   // Other part of dual load hasn't returned
     731        33264 :                      buf_nxtstate[i]           = dec_tlu_force_halt ? IDLE : (buf_ldfwd[i] | buf_ldfwd[buf_dualtag[i]] | any_done_wait_state) ? DONE_WAIT : DONE;
     732        33264 :                      buf_state_bus_en[i]       = bus_rsp_read & ((bus_rsp_read_tag == (pt.LSU_BUS_TAG)'(buf_dualtag[i])) |
     733        33264 :                                                                  (buf_ldfwd[buf_dualtag[i]] & (bus_rsp_read_tag == (pt.LSU_BUS_TAG)'(buf_ldfwdtag[buf_dualtag[i]]))));
     734        33264 :                      buf_state_en[i]           = (buf_state_bus_en[i] & lsu_bus_clk_en) | dec_tlu_force_halt;
     735        33264 :                      buf_cmd_state_bus_en[i]  = '0;
     736              :             end
     737       849310 :             DONE_WAIT: begin  // START_WAIT state if there are multiple outstanding nb returns
     738       849310 :                       buf_nxtstate[i]           = dec_tlu_force_halt ? IDLE : DONE;
     739       849310 :                       buf_state_en[i]           = ((RspPtr == DEPTH_LOG2'(i)) | (buf_dual[i] & (buf_dualtag[i] == RspPtr))) | dec_tlu_force_halt;
     740       849310 :                       buf_cmd_state_bus_en[i]  = '0;
     741              :             end
     742      3383460 :             DONE: begin
     743      3383460 :                      buf_nxtstate[i]           = IDLE;
     744      3383460 :                      buf_rst[i]                = 1'b1;
     745      3383460 :                      buf_state_en[i]           = 1'b1;
     746      3383460 :                      buf_ldfwd_in[i]           = 1'b0;
     747      3383460 :                      buf_ldfwd_en[i]           = buf_state_en[i];
     748      3383460 :                      buf_cmd_state_bus_en[i]  = '0;
     749              :             end
     750              :             /* buf_state is an enum and the existing members are handled above */
     751              :             /*pragma coverage off*/
     752              :             default : begin
     753              :                      buf_nxtstate[i]          = IDLE;
     754              :                      buf_state_en[i]          = '0;
     755              :                      buf_resp_state_bus_en[i] = '0;
     756              :                      buf_state_bus_en[i]      = '0;
     757              :                      buf_wr_en[i]             = '0;
     758              :                      buf_data_in[i]           = '0;
     759              :                      buf_data_en[i]           = '0;
     760              :                      buf_error_en[i]          = '0;
     761              :                      buf_rst[i]               = '0;
     762              :                      buf_cmd_state_bus_en[i]  = '0;
     763              :             end
     764              :             /*pragma coverage on*/
     765              :          endcase
     766              :       end
     767              : 
     768              :       rvdffs  #(.WIDTH($bits(state_t))) buf_state_ff     (.din(buf_nxtstate[i]),             .dout({buf_state[i]}),    .en(buf_state_en[i]),                                        .clk(lsu_bus_buf_c1_clk), .*);
     769              :       rvdff   #(.WIDTH(DEPTH))          buf_ageff        (.din(buf_age_in[i]),               .dout(buf_ageQ[i]),                                                                    .clk(lsu_bus_buf_c1_clk), .*);
     770              :       rvdff   #(.WIDTH(DEPTH))          buf_rspageff     (.din(buf_rspage_in[i]),            .dout(buf_rspageQ[i]),                                                                 .clk(lsu_bus_buf_c1_clk), .*);
     771              :       rvdffs  #(.WIDTH(DEPTH_LOG2))     buf_dualtagff    (.din(buf_dualtag_in[i]),           .dout(buf_dualtag[i]),    .en(buf_wr_en[i]),                                           .clk(lsu_bus_buf_c1_clk), .*);
     772              :       rvdffs  #(.WIDTH(1))              buf_dualff       (.din(buf_dual_in[i]),              .dout(buf_dual[i]),       .en(buf_wr_en[i]),                                           .clk(lsu_bus_buf_c1_clk), .*);
     773              :       rvdffs  #(.WIDTH(1))              buf_samedwff     (.din(buf_samedw_in[i]),            .dout(buf_samedw[i]),     .en(buf_wr_en[i]),                                           .clk(lsu_bus_buf_c1_clk), .*);
     774              :       rvdffs  #(.WIDTH(1))              buf_nomergeff    (.din(buf_nomerge_in[i]),           .dout(buf_nomerge[i]),    .en(buf_wr_en[i]),                                           .clk(lsu_bus_buf_c1_clk), .*);
     775              :       rvdffs  #(.WIDTH(1))              buf_dualhiff     (.din(buf_dualhi_in[i]),            .dout(buf_dualhi[i]),     .en(buf_wr_en[i]),                                           .clk(lsu_bus_buf_c1_clk), .*);
     776              :       rvdffs  #(.WIDTH(1))              buf_ldfwdff      (.din(buf_ldfwd_in[i]),             .dout(buf_ldfwd[i]),      .en(buf_ldfwd_en[i]),                                        .clk(lsu_bus_buf_c1_clk), .*);
     777              :       rvdffs  #(.WIDTH(DEPTH_LOG2))     buf_ldfwdtagff   (.din(buf_ldfwdtag_in[i]),          .dout(buf_ldfwdtag[i]),   .en(buf_ldfwd_en[i]),                                        .clk(lsu_bus_buf_c1_clk), .*);
     778              :       rvdffs  #(.WIDTH(1))              buf_sideeffectff (.din(buf_sideeffect_in[i]),        .dout(buf_sideeffect[i]), .en(buf_wr_en[i]),                                           .clk(lsu_bus_buf_c1_clk), .*);
     779              :       rvdffs  #(.WIDTH(1))              buf_unsignff     (.din(buf_unsign_in[i]),            .dout(buf_unsign[i]),     .en(buf_wr_en[i]),                                           .clk(lsu_bus_buf_c1_clk), .*);
     780              :       rvdffs  #(.WIDTH(1))              buf_writeff      (.din(buf_write_in[i]),             .dout(buf_write[i]),      .en(buf_wr_en[i]),                                           .clk(lsu_bus_buf_c1_clk), .*);
     781              :       rvdffs  #(.WIDTH(2))              buf_szff         (.din(buf_sz_in[i]),                .dout(buf_sz[i]),         .en(buf_wr_en[i]),                                           .clk(lsu_bus_buf_c1_clk), .*);
     782              :       rvdffe  #(.WIDTH(32))             buf_addrff       (.din(buf_addr_in[i][31:0]),        .dout(buf_addr[i]),       .en(buf_wr_en[i]),                                                                     .*);
     783              :       rvdffs  #(.WIDTH(4))              buf_byteenff     (.din(buf_byteen_in[i][3:0]),       .dout(buf_byteen[i]),     .en(buf_wr_en[i]),                                           .clk(lsu_bus_buf_c1_clk), .*);
     784              :       rvdffe  #(.WIDTH(32))             buf_dataff       (.din(buf_data_in[i][31:0]),        .dout(buf_data[i]),       .en(buf_data_en[i]),                                                                   .*);
     785              :       rvdffsc #(.WIDTH(1))              buf_errorff      (.din(1'b1),                        .dout(buf_error[i]),      .en(buf_error_en[i]),                    .clear(buf_rst[i]), .clk(lsu_bus_buf_c1_clk), .*);
     786              : 
     787              :    end
     788              : 
     789              :    // buffer full logic
     790          298 :    always_comb begin
     791          298 :       buf_numvld_any[3:0] =  4'(({1'b0,lsu_busreq_m} << ldst_dual_m) +
     792          298 :                                 ({1'b0,lsu_busreq_r} << ldst_dual_r) +
     793          298 :                                 ibuf_valid);
     794          298 :       buf_numvld_wrcmd_any[3:0] = 4'b0;
     795          298 :       buf_numvld_cmd_any[3:0] = 4'b0;
     796          298 :       buf_numvld_pend_any[3:0] = 4'b0;
     797          298 :       any_done_wait_state = 1'b0;
     798         1192 :       for (int i=0; i<DEPTH; i++) begin
     799         1192 :          buf_numvld_any[3:0] += {3'b0, (buf_state[i] != IDLE)};
     800         1192 :          buf_numvld_wrcmd_any[3:0] += {3'b0, (buf_write[i] & (buf_state[i] == CMD) & ~buf_cmd_state_bus_en[i])};
     801         1192 :          buf_numvld_cmd_any[3:0]   += {3'b0, ((buf_state[i] == CMD) & ~buf_cmd_state_bus_en[i])};
     802         1192 :          buf_numvld_pend_any[3:0]   += {3'b0, ((buf_state[i] == START_WAIT) | ((buf_state[i] == CMD) & ~buf_cmd_state_bus_en[i]))};
     803         1192 :          any_done_wait_state |= (buf_state[i] == DONE_WAIT);
     804              :       end
     805              :    end
     806              : 
     807              :    assign lsu_bus_buffer_pend_any = (buf_numvld_pend_any != 0);
     808              :    assign lsu_bus_buffer_full_any = (ldst_dual_d & dec_lsu_valid_raw_d) ? (buf_numvld_any[3:0] >= (DEPTH-1)) : (buf_numvld_any[3:0] == DEPTH);
     809              :    assign lsu_bus_buffer_empty_any = ~(|buf_state[DEPTH-1:0]) & ~ibuf_valid & ~obuf_valid;
     810              : 
     811              : 
     812              :    // Non blocking ports
     813              :    assign lsu_nonblock_load_valid_m = lsu_busreq_m & lsu_pkt_m.valid & lsu_pkt_m.load & ~flush_m_up & ~ld_full_hit_m;
     814              :    assign lsu_nonblock_load_tag_m[DEPTH_LOG2-1:0] = WrPtr0_m[DEPTH_LOG2-1:0];
     815              :    assign lsu_nonblock_load_inv_r = lsu_nonblock_load_valid_r & ~lsu_commit_r;
     816              :    assign lsu_nonblock_load_inv_tag_r[DEPTH_LOG2-1:0] = WrPtr0_r[DEPTH_LOG2-1:0];      // r tag needs to be accurate even if there is no invalidate
     817              : 
     818          298 :    always_comb begin
     819          298 :       lsu_nonblock_load_data_ready = '0;
     820          298 :       lsu_nonblock_load_data_error = '0;
     821          298 :       lsu_nonblock_load_data_tag[DEPTH_LOG2-1:0] = '0;
     822          298 :       lsu_nonblock_load_data_lo[31:0] = '0;
     823          298 :       lsu_nonblock_load_data_hi[31:0] = '0;
     824         1192 :       for (int i=0; i<DEPTH; i++) begin
     825              :           // Use buf_rst[i] instead of buf_state_en[i] for timing
     826         1192 :           lsu_nonblock_load_data_ready      |= (buf_state[i] == DONE) & ~buf_write[i];
     827         1192 :           lsu_nonblock_load_data_error      |= (buf_state[i] == DONE) & buf_error[i] & ~buf_write[i];
     828         1192 :           lsu_nonblock_load_data_tag[DEPTH_LOG2-1:0]   |= DEPTH_LOG2'(i) & {DEPTH_LOG2{((buf_state[i] == DONE) & ~buf_write[i] & (~buf_dual[i] | ~buf_dualhi[i]))}};
     829         1192 :           lsu_nonblock_load_data_lo[31:0]     |= buf_data[i][31:0] & {32{((buf_state[i] == DONE) & ~buf_write[i] & (~buf_dual[i] | ~buf_dualhi[i]))}};
     830         1192 :           lsu_nonblock_load_data_hi[31:0]     |= buf_data[i][31:0] & {32{((buf_state[i] == DONE) & ~buf_write[i] & (buf_dual[i] & buf_dualhi[i]))}};
     831              :       end
     832              :    end
     833              : 
     834              :    assign lsu_nonblock_addr_offset[1:0] = buf_addr[lsu_nonblock_load_data_tag][1:0];
     835              :    assign lsu_nonblock_sz[1:0]          = buf_sz[lsu_nonblock_load_data_tag][1:0];
     836              :    assign lsu_nonblock_unsign           = buf_unsign[lsu_nonblock_load_data_tag];
     837              :    assign lsu_nonblock_data_unalgn[31:0] = 32'({lsu_nonblock_load_data_hi[31:0], lsu_nonblock_load_data_lo[31:0]} >> 8*lsu_nonblock_addr_offset[1:0]);
     838              : 
     839              :    assign lsu_nonblock_load_data_valid = lsu_nonblock_load_data_ready & ~lsu_nonblock_load_data_error;
     840              :    assign lsu_nonblock_load_data[31:0] = ({32{ lsu_nonblock_unsign & (lsu_nonblock_sz[1:0] == 2'b00)}} & {24'b0,lsu_nonblock_data_unalgn[7:0]}) |
     841              :                                          ({32{ lsu_nonblock_unsign & (lsu_nonblock_sz[1:0] == 2'b01)}} & {16'b0,lsu_nonblock_data_unalgn[15:0]}) |
     842              :                                          ({32{~lsu_nonblock_unsign & (lsu_nonblock_sz[1:0] == 2'b00)}} & {{24{lsu_nonblock_data_unalgn[7]}}, lsu_nonblock_data_unalgn[7:0]}) |
     843              :                                          ({32{~lsu_nonblock_unsign & (lsu_nonblock_sz[1:0] == 2'b01)}} & {{16{lsu_nonblock_data_unalgn[15]}},lsu_nonblock_data_unalgn[15:0]}) |
     844              :                                          ({32{(lsu_nonblock_sz[1:0] == 2'b10)}} & lsu_nonblock_data_unalgn[31:0]);
     845              : 
     846              :    // Determine if there is a pending return to sideeffect load/store
     847          298 :    always_comb begin
     848          298 :       bus_sideeffect_pend = obuf_valid & obuf_sideeffect & dec_tlu_sideeffect_posted_disable;
     849         1192 :       for (int i=0; i<DEPTH; i++) begin
     850         1192 :          bus_sideeffect_pend |= ((buf_state[i] == RESP) & buf_sideeffect[i] & dec_tlu_sideeffect_posted_disable);
     851              :       end
     852              :    end
     853              : 
     854              :    // We have no ordering rules for AXI. Need to check outstanding trxns to same address for AXI
     855          298 :    always_comb begin
     856          298 :       bus_addr_match_pending = '0;
     857         1192 :       for (int i=0; i<DEPTH; i++) begin
     858         1192 :          bus_addr_match_pending |= (obuf_valid & (obuf_addr[31:3] == buf_addr[i][31:3]) & (buf_state[i] == RESP) & ~((obuf_tag0 == (pt.LSU_BUS_TAG)'(i)) | (obuf_merge & (obuf_tag1 == (pt.LSU_BUS_TAG)'(i)))));
     859              :       end
     860              :    end
     861              : 
     862              :    // Generic bus signals
     863              :    assign bus_cmd_ready                      = obuf_write ? ((obuf_cmd_done | obuf_data_done) ? (obuf_cmd_done ? lsu_axi_wready : lsu_axi_awready) : (lsu_axi_awready & lsu_axi_wready)) : lsu_axi_arready;
     864              :    assign bus_wcmd_sent                      = lsu_axi_awvalid & lsu_axi_awready;
     865              :    assign bus_wdata_sent                     = lsu_axi_wvalid & lsu_axi_wready;
     866              :    assign bus_cmd_sent                       = ((obuf_cmd_done | bus_wcmd_sent) & (obuf_data_done | bus_wdata_sent)) | (lsu_axi_arvalid & lsu_axi_arready);
     867              : 
     868              :    assign bus_rsp_read                       = lsu_axi_rvalid & lsu_axi_rready;
     869              :    assign bus_rsp_write                      = lsu_axi_bvalid & lsu_axi_bready;
     870              :    assign bus_rsp_read_tag[pt.LSU_BUS_TAG-1:0]  = lsu_axi_rid[pt.LSU_BUS_TAG-1:0];
     871              :    assign bus_rsp_write_tag[pt.LSU_BUS_TAG-1:0] = lsu_axi_bid[pt.LSU_BUS_TAG-1:0];
     872              :    assign bus_rsp_write_error                = bus_rsp_write & (lsu_axi_bresp[1:0] != 2'b0);
     873              :    assign bus_rsp_read_error                 = bus_rsp_read  & (lsu_axi_rresp[1:0] != 2'b0);
     874              :    assign bus_rsp_rdata[63:0]                = lsu_axi_rdata[63:0];
     875              : 
     876              :    // AXI command signals
     877              :    assign lsu_axi_awvalid               = obuf_valid & obuf_write & ~obuf_cmd_done & ~bus_addr_match_pending;
     878              :    assign lsu_axi_awid[pt.LSU_BUS_TAG-1:0] = (pt.LSU_BUS_TAG)'(obuf_tag0);
     879              :    assign lsu_axi_awaddr[31:0]          = obuf_sideeffect ? obuf_addr[31:0] : {obuf_addr[31:3],3'b0};
     880              :    assign lsu_axi_awsize[2:0]           = obuf_sideeffect ? {1'b0, obuf_sz[1:0]} : 3'b011;
     881              :    assign lsu_axi_awprot[2:0]           = 3'b001;
     882              :    assign lsu_axi_awcache[3:0]          = obuf_sideeffect ? 4'b0 : 4'b1111;
     883              :    assign lsu_axi_awregion[3:0]         = obuf_addr[31:28];
     884              :    assign lsu_axi_awlen[7:0]            = '0;
     885              :    assign lsu_axi_awburst[1:0]          = 2'b01;
     886              :    assign lsu_axi_awqos[3:0]            = '0;
     887              :    assign lsu_axi_awlock                = '0;
     888              : 
     889              :    assign lsu_axi_wvalid                = obuf_valid & obuf_write & ~obuf_data_done & ~bus_addr_match_pending;
     890              :    assign lsu_axi_wstrb[7:0]            = obuf_byteen[7:0] & {8{obuf_write}};
     891              :    assign lsu_axi_wdata[63:0]           = obuf_data[63:0];
     892              :    assign lsu_axi_wlast                 = '1;
     893              : 
     894              :    assign lsu_axi_arvalid               = obuf_valid & ~obuf_write & ~obuf_nosend & ~bus_addr_match_pending;
     895              :    assign lsu_axi_arid[pt.LSU_BUS_TAG-1:0] = (pt.LSU_BUS_TAG)'(obuf_tag0);
     896              :    assign lsu_axi_araddr[31:0]          = obuf_sideeffect ? obuf_addr[31:0] : {obuf_addr[31:3],3'b0};
     897              :    assign lsu_axi_arsize[2:0]           = obuf_sideeffect ? {1'b0, obuf_sz[1:0]} : 3'b011;
     898              :    assign lsu_axi_arprot[2:0]           = 3'b001;
     899              :    assign lsu_axi_arcache[3:0]          = obuf_sideeffect ? 4'b0 : 4'b1111;
     900              :    assign lsu_axi_arregion[3:0]         = obuf_addr[31:28];
     901              :    assign lsu_axi_arlen[7:0]            = '0;
     902              :    assign lsu_axi_arburst[1:0]          = 2'b01;
     903              :    assign lsu_axi_arqos[3:0]            = '0;
     904              :    assign lsu_axi_arlock                = '0;
     905              : 
     906              :    assign lsu_axi_bready = 1;
     907              :    assign lsu_axi_rready = 1;
     908              : 
     909          298 :    always_comb begin
     910          298 :       lsu_imprecise_error_store_any = '0;
     911          298 :       lsu_imprecise_error_store_tag = '0;
     912         1192 :       for (int i=0; i<DEPTH; i++) begin
     913         1192 :          lsu_imprecise_error_store_any |= lsu_bus_clk_en_q & (buf_state[i] == DONE) & buf_error[i] & buf_write[i];
     914         1192 :          lsu_imprecise_error_store_tag |= DEPTH_LOG2'(i) & {DEPTH_LOG2{((buf_state[i] == DONE) & buf_error[i] & buf_write[i])}};
     915              :       end
     916              :    end
     917              :    assign lsu_imprecise_error_load_any       = lsu_nonblock_load_data_error & ~lsu_imprecise_error_store_any;   // This is to make sure we send only one imprecise error for load/store
     918              :    assign lsu_imprecise_error_addr_any[31:0] = lsu_imprecise_error_store_any ? buf_addr[lsu_imprecise_error_store_tag[DEPTH_LOG2-1:0]] : buf_addr[lsu_nonblock_load_data_tag[DEPTH_LOG2-1:0]];
     919              : 
     920              :    // PMU signals
     921              :    assign lsu_pmu_bus_trxn  = (lsu_axi_awvalid & lsu_axi_awready) | (lsu_axi_wvalid & lsu_axi_wready) | (lsu_axi_arvalid & lsu_axi_arready);
     922              :    assign lsu_pmu_bus_misaligned = lsu_busreq_r & ldst_dual_r & lsu_commit_r;
     923              :    assign lsu_pmu_bus_error = lsu_imprecise_error_load_any | lsu_imprecise_error_store_any;
     924              :    assign lsu_pmu_bus_busy  = (lsu_axi_awvalid & ~lsu_axi_awready) | (lsu_axi_wvalid & ~lsu_axi_wready) | (lsu_axi_arvalid & ~lsu_axi_arready);
     925              : 
     926              :    rvdff_fpga #(.WIDTH(1))               lsu_axi_awvalid_ff (.din(lsu_axi_awvalid),                .dout(lsu_axi_awvalid_q),                .clk(lsu_busm_clk), .clken(lsu_busm_clken), .rawclk(clk), .*);
     927              :    rvdff_fpga #(.WIDTH(1))               lsu_axi_awready_ff (.din(lsu_axi_awready),                .dout(lsu_axi_awready_q),                .clk(lsu_busm_clk), .clken(lsu_busm_clken), .rawclk(clk), .*);
     928              :    rvdff_fpga #(.WIDTH(1))               lsu_axi_wvalid_ff  (.din(lsu_axi_wvalid),                 .dout(lsu_axi_wvalid_q),                 .clk(lsu_busm_clk), .clken(lsu_busm_clken), .rawclk(clk), .*);
     929              :    rvdff_fpga #(.WIDTH(1))               lsu_axi_wready_ff  (.din(lsu_axi_wready),                 .dout(lsu_axi_wready_q),                 .clk(lsu_busm_clk), .clken(lsu_busm_clken), .rawclk(clk), .*);
     930              :    rvdff_fpga #(.WIDTH(1))               lsu_axi_arvalid_ff (.din(lsu_axi_arvalid),                .dout(lsu_axi_arvalid_q),                .clk(lsu_busm_clk), .clken(lsu_busm_clken), .rawclk(clk), .*);
     931              :    rvdff_fpga #(.WIDTH(1))               lsu_axi_arready_ff (.din(lsu_axi_arready),                .dout(lsu_axi_arready_q),                .clk(lsu_busm_clk), .clken(lsu_busm_clken), .rawclk(clk), .*);
     932              : 
     933              :    rvdff_fpga  #(.WIDTH(1))              lsu_axi_bvalid_ff  (.din(lsu_axi_bvalid),                 .dout(lsu_axi_bvalid_q),                 .clk(lsu_busm_clk), .clken(lsu_busm_clken), .rawclk(clk), .*);
     934              :    rvdff_fpga  #(.WIDTH(1))              lsu_axi_bready_ff  (.din(lsu_axi_bready),                 .dout(lsu_axi_bready_q),                 .clk(lsu_busm_clk), .clken(lsu_busm_clken), .rawclk(clk), .*);
     935              :    rvdff_fpga  #(.WIDTH(2))              lsu_axi_bresp_ff   (.din(lsu_axi_bresp[1:0]),             .dout(lsu_axi_bresp_q[1:0]),             .clk(lsu_busm_clk), .clken(lsu_busm_clken), .rawclk(clk), .*);
     936              :    rvdff_fpga  #(.WIDTH(pt.LSU_BUS_TAG)) lsu_axi_bid_ff     (.din(lsu_axi_bid[pt.LSU_BUS_TAG-1:0]),.dout(lsu_axi_bid_q[pt.LSU_BUS_TAG-1:0]),.clk(lsu_busm_clk), .clken(lsu_busm_clken), .rawclk(clk), .*);
     937              :    rvdffe      #(.WIDTH(64))             lsu_axi_rdata_ff   (.din(lsu_axi_rdata[63:0]),            .dout(lsu_axi_rdata_q[63:0]),            .en((lsu_axi_rvalid | clk_override) & lsu_bus_clk_en), .*);
     938              : 
     939              :    rvdff_fpga  #(.WIDTH(1))              lsu_axi_rvalid_ff  (.din(lsu_axi_rvalid),                 .dout(lsu_axi_rvalid_q),                 .clk(lsu_busm_clk), .clken(lsu_busm_clken), .rawclk(clk), .*);
     940              :    rvdff_fpga  #(.WIDTH(1))              lsu_axi_rready_ff  (.din(lsu_axi_rready),                 .dout(lsu_axi_rready_q),                 .clk(lsu_busm_clk), .clken(lsu_busm_clken), .rawclk(clk), .*);
     941              :    rvdff_fpga  #(.WIDTH(2))              lsu_axi_rresp_ff   (.din(lsu_axi_rresp[1:0]),             .dout(lsu_axi_rresp_q[1:0]),             .clk(lsu_busm_clk), .clken(lsu_busm_clken), .rawclk(clk), .*);
     942              :    rvdff_fpga  #(.WIDTH(pt.LSU_BUS_TAG)) lsu_axi_rid_ff     (.din(lsu_axi_rid[pt.LSU_BUS_TAG-1:0]),.dout(lsu_axi_rid_q[pt.LSU_BUS_TAG-1:0]),.clk(lsu_busm_clk), .clken(lsu_busm_clken), .rawclk(clk), .*);
     943              : 
     944              :    rvdff #(.WIDTH(DEPTH_LOG2)) lsu_WrPtr0_rff (.din(WrPtr0_m), .dout(WrPtr0_r), .clk(lsu_c2_r_clk), .*);
     945              :    rvdff #(.WIDTH(DEPTH_LOG2)) lsu_WrPtr1_rff (.din(WrPtr1_m), .dout(WrPtr1_r), .clk(lsu_c2_r_clk), .*);
     946              : 
     947              :    rvdff #(.WIDTH(1)) lsu_busreq_rff (.din(lsu_busreq_m & ~flush_r & ~ld_full_hit_m),      .dout(lsu_busreq_r), .clk(lsu_c2_r_clk), .*);
     948              :    rvdff #(.WIDTH(1)) lsu_nonblock_load_valid_rff  (.din(lsu_nonblock_load_valid_m),  .dout(lsu_nonblock_load_valid_r), .clk(lsu_c2_r_clk), .*);
     949              : 
     950              : `ifdef RV_ASSERT_ON
     951              : 
     952              :    for (genvar i=0; i<4; i++) begin: GenByte
     953              :       assert_ld_byte_hitvecfn_lo_onehot: assert #0 ($onehot0(ld_byte_hitvecfn_lo[i][DEPTH-1:0]));
     954              :       assert_ld_byte_hitvecfn_hi_onehot: assert #0 ($onehot0(ld_byte_hitvecfn_hi[i][DEPTH-1:0]));
     955              :    end
     956              : 
     957              :    for (genvar i=0; i<DEPTH; i++) begin: GenAssertAge
     958              :       assert_bufempty_agevec: assert #0 (~(lsu_bus_buffer_empty_any & |(buf_age[i])));
     959              :    end
     960              : 
     961              :    assert_CmdPtr0Dec_onehot: assert #0 ($onehot0(CmdPtr0Dec[DEPTH-1:0] & ~{DEPTH{dec_tlu_force_halt}}));
     962              :    assert_CmdPtr1Dec_onehot: assert #0 ($onehot0(CmdPtr1Dec[DEPTH-1:0] & ~{DEPTH{dec_tlu_force_halt}}));
     963              : 
     964              : `endif
     965              : 
     966              : endmodule // el2_lsu_bus_buffer