data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/src/cache_subsystem/wt_dcache_wbuffer.sv
1: b"%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/src/cache_subsystem/wt_dcache_wbuffer.sv:52: syntax error, unexpected IDENTIFIER, expecting PACKAGE-IDENTIFIER\nmodule wt_dcache_wbuffer import ariane_pkg::*; import wt_cache_pkg::*; #(\n                                ^~~~~~~~~~\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/src/cache_subsystem/wt_dcache_wbuffer.sv:56: syntax error, unexpected input, expecting IDENTIFIER or '=' or do or final\n  input  logic                               rst_ni,          \n  ^~~~~\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/src/cache_subsystem/wt_dcache_wbuffer.sv:58: syntax error, unexpected input, expecting IDENTIFIER or '=' or do or final\n  input  logic                               cache_en_i,      \n  ^~~~~\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/src/cache_subsystem/wt_dcache_wbuffer.sv:59: syntax error, unexpected output, expecting IDENTIFIER or '=' or do or final\n  output logic                               empty_o,         \n  ^~~~~~\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/src/cache_subsystem/wt_dcache_wbuffer.sv:60: syntax error, unexpected output, expecting IDENTIFIER or '=' or do or final\n  output logic                               not_ni_o,     \n  ^~~~~~\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/src/cache_subsystem/wt_dcache_wbuffer.sv:62: syntax error, unexpected input, expecting IDENTIFIER or '=' or do or final\n  input  dcache_req_i_t                      req_port_i,\n  ^~~~~\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/src/cache_subsystem/wt_dcache_wbuffer.sv:66: syntax error, unexpected output, expecting IDENTIFIER or '=' or do or final\n  output logic [riscv::PLEN-1:0]             miss_paddr_o,\n  ^~~~~~\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/src/cache_subsystem/wt_dcache_wbuffer.sv:66: syntax error, unexpected ::, expecting ':'\n  output logic [riscv::PLEN-1:0]             miss_paddr_o,\n                     ^~\n                                                                                                                                     : ... Perhaps 'riscv' is a package which needs to be predeclared? (IEEE 1800-2017 26.3)\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/src/cache_subsystem/wt_dcache_wbuffer.sv:68: syntax error, unexpected output, expecting IDENTIFIER or '=' or do or final\n  output logic                               miss_we_o,        \n  ^~~~~~\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/src/cache_subsystem/wt_dcache_wbuffer.sv:69: syntax error, unexpected output, expecting IDENTIFIER or '=' or do or final\n  output logic [63:0]                        miss_wdata_o,\n  ^~~~~~\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/src/cache_subsystem/wt_dcache_wbuffer.sv:70: syntax error, unexpected output, expecting IDENTIFIER or '=' or do or final\n  output logic [DCACHE_SET_ASSOC-1:0]        miss_vld_bits_o,  \n  ^~~~~~\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/src/cache_subsystem/wt_dcache_wbuffer.sv:71: syntax error, unexpected output, expecting IDENTIFIER or '=' or do or final\n  output logic                               miss_nc_o,        \n  ^~~~~~\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/src/cache_subsystem/wt_dcache_wbuffer.sv:72: syntax error, unexpected output, expecting IDENTIFIER or '=' or do or final\n  output logic [2:0]                         miss_size_o,     \n  ^~~~~~\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/src/cache_subsystem/wt_dcache_wbuffer.sv:73: syntax error, unexpected output, expecting IDENTIFIER or '=' or do or final\n  output logic [CACHE_ID_WIDTH-1:0]          miss_id_o,        \n  ^~~~~~\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/src/cache_subsystem/wt_dcache_wbuffer.sv:75: syntax error, unexpected input, expecting IDENTIFIER or '=' or do or final\n  input  logic                               miss_rtrn_vld_i,\n  ^~~~~\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/src/cache_subsystem/wt_dcache_wbuffer.sv:76: syntax error, unexpected input, expecting IDENTIFIER or '=' or do or final\n  input  logic [CACHE_ID_WIDTH-1:0]          miss_rtrn_id_i,   \n  ^~~~~\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/src/cache_subsystem/wt_dcache_wbuffer.sv:78: syntax error, unexpected output, expecting IDENTIFIER or '=' or do or final\n  output logic [DCACHE_TAG_WIDTH-1:0]        rd_tag_o,         \n  ^~~~~~\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/src/cache_subsystem/wt_dcache_wbuffer.sv:79: syntax error, unexpected output, expecting IDENTIFIER or '=' or do or final\n  output logic [DCACHE_CL_IDX_WIDTH-1:0]     rd_idx_o,\n  ^~~~~~\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/src/cache_subsystem/wt_dcache_wbuffer.sv:80: syntax error, unexpected output, expecting IDENTIFIER or '=' or do or final\n  output logic [DCACHE_OFFSET_WIDTH-1:0]     rd_off_o,\n  ^~~~~~\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/src/cache_subsystem/wt_dcache_wbuffer.sv:81: syntax error, unexpected output, expecting IDENTIFIER or '=' or do or final\n  output logic                               rd_req_o,         \n  ^~~~~~\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/src/cache_subsystem/wt_dcache_wbuffer.sv:82: syntax error, unexpected output, expecting IDENTIFIER or '=' or do or final\n  output logic                               rd_tag_only_o,    \n  ^~~~~~\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/src/cache_subsystem/wt_dcache_wbuffer.sv:83: syntax error, unexpected input, expecting IDENTIFIER or '=' or do or final\n  input  logic                               rd_ack_i,\n  ^~~~~\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/src/cache_subsystem/wt_dcache_wbuffer.sv:84: syntax error, unexpected input, expecting IDENTIFIER or '=' or do or final\n  input logic  [63:0]                        rd_data_i,        \n  ^~~~~\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/src/cache_subsystem/wt_dcache_wbuffer.sv:85: syntax error, unexpected input, expecting IDENTIFIER or '=' or do or final\n  input logic  [DCACHE_SET_ASSOC-1:0]        rd_vld_bits_i,    \n  ^~~~~\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/src/cache_subsystem/wt_dcache_wbuffer.sv:86: syntax error, unexpected input, expecting IDENTIFIER or '=' or do or final\n  input logic  [DCACHE_SET_ASSOC-1:0]        rd_hit_oh_i,\n  ^~~~~\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/src/cache_subsystem/wt_dcache_wbuffer.sv:88: syntax error, unexpected input, expecting IDENTIFIER or '=' or do or final\n  input logic                                wr_cl_vld_i,\n  ^~~~~\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/src/cache_subsystem/wt_dcache_wbuffer.sv:89: syntax error, unexpected input, expecting IDENTIFIER or '=' or do or final\n  input logic [DCACHE_CL_IDX_WIDTH-1:0]      wr_cl_idx_i,\n  ^~~~~\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/src/cache_subsystem/wt_dcache_wbuffer.sv:91: syntax error, unexpected output, expecting IDENTIFIER or '=' or do or final\n  output logic [DCACHE_SET_ASSOC-1:0]        wr_req_o,\n  ^~~~~~\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/src/cache_subsystem/wt_dcache_wbuffer.sv:92: syntax error, unexpected input, expecting IDENTIFIER or '=' or do or final\n  input  logic                               wr_ack_i,\n  ^~~~~\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/src/cache_subsystem/wt_dcache_wbuffer.sv:93: syntax error, unexpected output, expecting IDENTIFIER or '=' or do or final\n  output logic [DCACHE_CL_IDX_WIDTH-1:0]     wr_idx_o,\n  ^~~~~~\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/src/cache_subsystem/wt_dcache_wbuffer.sv:94: syntax error, unexpected output, expecting IDENTIFIER or '=' or do or final\n  output logic [DCACHE_OFFSET_WIDTH-1:0]     wr_off_o,\n  ^~~~~~\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/src/cache_subsystem/wt_dcache_wbuffer.sv:95: syntax error, unexpected output, expecting IDENTIFIER or '=' or do or final\n  output logic [63:0]                        wr_data_o,\n  ^~~~~~\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/src/cache_subsystem/wt_dcache_wbuffer.sv:96: syntax error, unexpected output, expecting IDENTIFIER or '=' or do or final\n  output logic [7:0]                         wr_data_be_o,\n  ^~~~~~\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/src/cache_subsystem/wt_dcache_wbuffer.sv:98: syntax error, unexpected output, expecting IDENTIFIER or '=' or do or final\n  output wbuffer_t  [DCACHE_WBUF_DEPTH-1:0]  wbuffer_data_o,\n  ^~~~~~\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/src/cache_subsystem/wt_dcache_wbuffer.sv:99: syntax error, unexpected ::, expecting ':'\n  output logic [DCACHE_MAX_TX-1:0][riscv::PLEN-1:0]     tx_paddr_o,       \n                                        ^~\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/src/cache_subsystem/wt_dcache_wbuffer.sv:101: syntax error, unexpected ')', expecting ',' or ';'\n);\n^\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/src/cache_subsystem/wt_dcache_wbuffer.sv:116: syntax error, unexpected ::, expecting ':'\n  logic [riscv::PLEN-1:0] wr_paddr, rd_paddr;\n              ^~\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/src/cache_subsystem/wt_dcache_wbuffer.sv:129: syntax error, unexpected ::, expecting ':'\n  logic [riscv::PLEN-1:0] debug_paddr [DCACHE_WBUF_DEPTH-1:0];\n              ^~\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/src/cache_subsystem/wt_dcache_wbuffer.sv:136: syntax error, unexpected ::, expecting ':'\n  logic [ariane_pkg::DCACHE_TAG_WIDTH-1:0] miss_tag;\n                   ^~\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/src/cache_subsystem/wt_dcache_wbuffer.sv:139: syntax error, unexpected assign\n  assign miss_tag = miss_paddr_o[ariane_pkg::DCACHE_INDEX_WIDTH+:ariane_pkg::DCACHE_TAG_WIDTH];\n  ^~~~~~\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/src/cache_subsystem/wt_dcache_wbuffer.sv:300: syntax error, unexpected assign\n  assign wr_cl_vld_d = wr_cl_vld_i;\n  ^~~~~~\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/src/cache_subsystem/wt_dcache_wbuffer.sv:396: syntax error, unexpected assign\n  assign ni_inside = |ni_pending_q;\n  ^~~~~~\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/src/cache_subsystem/wt_dcache_wbuffer.sv:419: syntax error, unexpected IDENTIFIER\n    for (int k=0; k<DCACHE_WBUF_DEPTH; k++) begin\n                  ^\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/src/cache_subsystem/wt_dcache_wbuffer.sv:428: syntax error, unexpected IDENTIFIER\n      for (int k=0; k<8; k++) begin\n                    ^\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/src/cache_subsystem/wt_dcache_wbuffer.sv:450: syntax error, unexpected IDENTIFIER\n      for (int k=0; k<8; k++) begin\n                    ^\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/src/cache_subsystem/wt_dcache_wbuffer.sv:472: syntax error, unexpected IDENTIFIER\n        for (int k=0; k<8; k++) begin\n                      ^\n%Error: Exiting due to 46 error(s)\n"
module wt_dcache_wbuffer import ariane_pkg::*; import wt_cache_pkg::*; #(
  parameter ariane_pkg::ariane_cfg_t    ArianeCfg          = ariane_pkg::ArianeDefaultConfig
) (
  input  logic                               clk_i,
  input  logic                               rst_ni,

  input  logic                               cache_en_i,
  output logic                               empty_o,
  output logic                               not_ni_o,

  input  dcache_req_i_t                      req_port_i,
  output dcache_req_o_t                      req_port_o,

  input  logic                               miss_ack_i,
  output logic [riscv::PLEN-1:0]             miss_paddr_o,
  output logic                               miss_req_o,
  output logic                               miss_we_o,
  output logic [63:0]                        miss_wdata_o,
  output logic [DCACHE_SET_ASSOC-1:0]        miss_vld_bits_o,
  output logic                               miss_nc_o,
  output logic [2:0]                         miss_size_o,
  output logic [CACHE_ID_WIDTH-1:0]          miss_id_o,

  input  logic                               miss_rtrn_vld_i,
  input  logic [CACHE_ID_WIDTH-1:0]          miss_rtrn_id_i,

  output logic [DCACHE_TAG_WIDTH-1:0]        rd_tag_o,
  output logic [DCACHE_CL_IDX_WIDTH-1:0]     rd_idx_o,
  output logic [DCACHE_OFFSET_WIDTH-1:0]     rd_off_o,
  output logic                               rd_req_o,
  output logic                               rd_tag_only_o,
  input  logic                               rd_ack_i,
  input logic  [63:0]                        rd_data_i,
  input logic  [DCACHE_SET_ASSOC-1:0]        rd_vld_bits_i,
  input logic  [DCACHE_SET_ASSOC-1:0]        rd_hit_oh_i,

  input logic                                wr_cl_vld_i,
  input logic [DCACHE_CL_IDX_WIDTH-1:0]      wr_cl_idx_i,

  output logic [DCACHE_SET_ASSOC-1:0]        wr_req_o,
  input  logic                               wr_ack_i,
  output logic [DCACHE_CL_IDX_WIDTH-1:0]     wr_idx_o,
  output logic [DCACHE_OFFSET_WIDTH-1:0]     wr_off_o,
  output logic [63:0]                        wr_data_o,
  output logic [7:0]                         wr_data_be_o,

  output wbuffer_t  [DCACHE_WBUF_DEPTH-1:0]  wbuffer_data_o,
  output logic [DCACHE_MAX_TX-1:0][riscv::PLEN-1:0]     tx_paddr_o,
  output logic [DCACHE_MAX_TX-1:0]           tx_vld_o
);

  tx_stat_t [DCACHE_MAX_TX-1:0]             tx_stat_d, tx_stat_q;
  wbuffer_t [DCACHE_WBUF_DEPTH-1:0]         wbuffer_d, wbuffer_q;
  logic     [DCACHE_WBUF_DEPTH-1:0]         valid;
  logic     [DCACHE_WBUF_DEPTH-1:0]         dirty;
  logic     [DCACHE_WBUF_DEPTH-1:0]         tocheck;
  logic     [DCACHE_WBUF_DEPTH-1:0]         wbuffer_hit_oh, inval_hit;
  logic     [DCACHE_WBUF_DEPTH-1:0][7:0]    bdirty;

  logic [$clog2(DCACHE_WBUF_DEPTH)-1:0] next_ptr, dirty_ptr, hit_ptr, wr_ptr, check_ptr_d, check_ptr_q, check_ptr_q1, rtrn_ptr;
  logic [CACHE_ID_WIDTH-1:0] tx_id, rtrn_id;

  logic [2:0] bdirty_off;
  logic [7:0] tx_be;
  logic [riscv::PLEN-1:0] wr_paddr, rd_paddr;
  logic [DCACHE_TAG_WIDTH-1:0] rd_tag_d, rd_tag_q;
  logic [DCACHE_SET_ASSOC-1:0] rd_hit_oh_d, rd_hit_oh_q;
  logic check_en_d, check_en_q, check_en_q1;
  logic full, dirty_rd_en, rdy;
  logic rtrn_empty, evict;
  logic [DCACHE_WBUF_DEPTH-1:0] ni_pending_d, ni_pending_q;
  logic wbuffer_wren;
  logic free_tx_slots;

  logic wr_cl_vld_q, wr_cl_vld_d;
  logic [DCACHE_CL_IDX_WIDTH-1:0] wr_cl_idx_q, wr_cl_idx_d;

  logic [riscv::PLEN-1:0] debug_paddr [DCACHE_WBUF_DEPTH-1:0];

  wbuffer_t wbuffer_check_mux, wbuffer_dirty_mux;




  logic [ariane_pkg::DCACHE_TAG_WIDTH-1:0] miss_tag;
  logic is_nc_miss;
  logic is_ni;
  assign miss_tag = miss_paddr_o[ariane_pkg::DCACHE_INDEX_WIDTH+:ariane_pkg::DCACHE_TAG_WIDTH];
  assign is_nc_miss = !ariane_pkg::is_inside_cacheable_regions(ArianeCfg, {{64-DCACHE_TAG_WIDTH{1'b0}}, miss_tag, {DCACHE_INDEX_WIDTH{1'b0}}});
  assign miss_nc_o = !cache_en_i || is_nc_miss; 

  assign is_ni = ariane_pkg::is_inside_nonidempotent_regions(ArianeCfg, {{64-DCACHE_TAG_WIDTH{1'b0}}, req_port_i.address_tag, {DCACHE_INDEX_WIDTH{1'b0}}});

  assign miss_we_o       = 1'b1;
  assign miss_vld_bits_o = '0;
  assign wbuffer_data_o  = wbuffer_q;

  for (genvar k=0; k<DCACHE_MAX_TX;k++) begin : gen_tx_vld
    assign tx_vld_o[k]   = tx_stat_q[k].vld;
    assign tx_paddr_o[k] = wbuffer_q[tx_stat_q[k].ptr].wtag<<3;
  end













  lzc #(
    .WIDTH ( 8 )
  ) i_vld_bdirty (
    .in_i    ( bdirty[dirty_ptr] ),
    .cnt_o   ( bdirty_off        ),
    .empty_o (                   )
  );


  assign miss_paddr_o = {wbuffer_dirty_mux.wtag, bdirty_off};
  assign miss_id_o    = tx_id;


  assign miss_req_o = (|dirty) && free_tx_slots;





  assign miss_size_o  = toSize64(bdirty[dirty_ptr]);


  assign miss_wdata_o = repData64(wbuffer_dirty_mux.data,
                                  bdirty_off,
                                  miss_size_o[1:0]);

  assign tx_be        = toByteEnable8(bdirty_off,
                                      miss_size_o[1:0]);






  fifo_v3 #(
    .FALL_THROUGH ( 1'b0                  ),
    .DATA_WIDTH   ( $clog2(DCACHE_MAX_TX) ),
    .DEPTH        ( DCACHE_MAX_TX         )
  ) i_rtrn_id_fifo (
    .clk_i      ( clk_i            ),
    .rst_ni     ( rst_ni           ),
    .flush_i    ( 1'b0             ),
    .testmode_i ( 1'b0             ),
    .full_o     (                  ),
    .empty_o    ( rtrn_empty       ),
    .usage_o    (                  ),
    .data_i     ( miss_rtrn_id_i   ),
    .push_i     ( miss_rtrn_vld_i  ),
    .data_o     ( rtrn_id          ),
    .pop_i      ( evict            )
  );

  always_comb begin : p_tx_stat
    tx_stat_d = tx_stat_q;
    evict     = 1'b0;
    wr_req_o  = '0;


    if ((!rtrn_empty) && wbuffer_q[rtrn_ptr].checked) begin


      if ((|wr_data_be_o) && (|wbuffer_q[rtrn_ptr].hit_oh)) begin
        wr_req_o = wbuffer_q[rtrn_ptr].hit_oh;
        if (wr_ack_i) begin
          evict    = 1'b1;
          tx_stat_d[rtrn_id].vld = 1'b0;
        end
      end else begin
        evict = 1'b1;
        tx_stat_d[rtrn_id].vld = 1'b0;
      end
    end


    if (dirty_rd_en) begin
      tx_stat_d[tx_id].vld = 1'b1;
      tx_stat_d[tx_id].ptr = dirty_ptr;
      tx_stat_d[tx_id].be  = tx_be;
    end
  end

  assign free_tx_slots = |(~tx_vld_o);


  rr_arb_tree #(
    .NumIn     (DCACHE_MAX_TX),
    .LockIn    (1'b1),
    .DataWidth (1)
  ) i_tx_id_rr (
    .clk_i  (clk_i       ),
    .rst_ni (rst_ni      ),
    .flush_i('0          ),
    .rr_i   ('0          ),
    .req_i  (~tx_vld_o   ),
    .gnt_o  (            ),
    .data_i ('0          ),
    .gnt_i  (dirty_rd_en ),
    .req_o  (            ),
    .data_o (            ),
    .idx_o  (tx_id       )
  );





  assign rd_tag_d   = rd_paddr>>DCACHE_INDEX_WIDTH;


  assign rd_tag_only_o = 1'b1;
  assign rd_paddr   = wbuffer_check_mux.wtag<<3;
  assign rd_req_o   = |tocheck;
  assign rd_tag_o   = rd_tag_q;
  assign rd_idx_o   = rd_paddr[DCACHE_INDEX_WIDTH-1:DCACHE_OFFSET_WIDTH];
  assign rd_off_o   = rd_paddr[DCACHE_OFFSET_WIDTH-1:0];
  assign check_en_d = rd_req_o & rd_ack_i;


  assign rtrn_ptr     = tx_stat_q[rtrn_id].ptr;


  assign wr_data_be_o = tx_stat_q[rtrn_id].be & (~wbuffer_q[rtrn_ptr].dirty);
  assign wr_paddr     = wbuffer_q[rtrn_ptr].wtag<<3;
  assign wr_idx_o     = wr_paddr[DCACHE_INDEX_WIDTH-1:DCACHE_OFFSET_WIDTH];
  assign wr_off_o     = wr_paddr[DCACHE_OFFSET_WIDTH-1:0];
  assign wr_data_o    = wbuffer_q[rtrn_ptr].data;






  logic [DCACHE_WBUF_DEPTH-1:0][DCACHE_CL_IDX_WIDTH-1:0] wtag_comp;

  assign wr_cl_vld_d = wr_cl_vld_i;
  assign wr_cl_idx_d = wr_cl_idx_i;

  for (genvar k=0; k<DCACHE_WBUF_DEPTH; k++) begin : gen_flags

    assign debug_paddr[k] = wbuffer_q[k].wtag << 3;




    assign bdirty[k] = (|wbuffer_q[k].txblock) ? '0 : wbuffer_q[k].dirty & wbuffer_q[k].valid;


    assign dirty[k]          = |bdirty[k];
    assign valid[k]          = |wbuffer_q[k].valid;
    assign wbuffer_hit_oh[k] = valid[k] & (wbuffer_q[k].wtag == {req_port_i.address_tag, req_port_i.address_index[DCACHE_INDEX_WIDTH-1:3]});




    assign wtag_comp[k] = wbuffer_q[k].wtag[DCACHE_INDEX_WIDTH-4:DCACHE_OFFSET_WIDTH-3];
    assign inval_hit[k]  = (wr_cl_vld_d & valid[k] & (wtag_comp[k] == wr_cl_idx_d)) |
                           (wr_cl_vld_q & valid[k] & (wtag_comp[k] == wr_cl_idx_q));


    assign tocheck[k]       = (~wbuffer_q[k].checked) & valid[k];
  end

  assign wr_ptr     = (|wbuffer_hit_oh) ? hit_ptr : next_ptr;
  assign rdy        = (|wbuffer_hit_oh) | (~full);


  lzc #(
    .WIDTH ( DCACHE_WBUF_DEPTH )
  ) i_vld_lzc (
    .in_i    ( ~valid        ),
    .cnt_o   ( next_ptr      ),
    .empty_o ( full          )
  );


  lzc #(
    .WIDTH ( DCACHE_WBUF_DEPTH )
  ) i_hit_lzc (
    .in_i    ( wbuffer_hit_oh ),
    .cnt_o   ( hit_ptr        ),
    .empty_o (                )
  );


  rr_arb_tree #(
    .NumIn     ( DCACHE_WBUF_DEPTH ),
    .LockIn    ( 1'b1              ),
    .DataType  ( wbuffer_t         )
  ) i_dirty_rr (
    .clk_i  ( clk_i             ),
    .rst_ni ( rst_ni            ),
    .flush_i( '0                ),
    .rr_i   ( '0                ),
    .req_i  ( dirty             ),
    .gnt_o  (                   ),
    .data_i ( wbuffer_q         ),
    .gnt_i  ( dirty_rd_en       ),
    .req_o  (                   ),
    .data_o ( wbuffer_dirty_mux ),
    .idx_o  ( dirty_ptr         )
  );


  rr_arb_tree #(
    .NumIn     ( DCACHE_WBUF_DEPTH ),
    .DataType  ( wbuffer_t         )
  ) i_clean_rr (
    .clk_i  ( clk_i             ),
    .rst_ni ( rst_ni            ),
    .flush_i( '0                ),
    .rr_i   ( '0                ),
    .req_i  ( tocheck           ),
    .gnt_o  (                   ),
    .data_i ( wbuffer_q         ),
    .gnt_i  ( check_en_d        ),
    .req_o  (                   ),
    .data_o ( wbuffer_check_mux ),
    .idx_o  ( check_ptr_d       )
  );





  assign req_port_o.data_rvalid = '0;
  assign req_port_o.data_rdata  = '0;

  assign rd_hit_oh_d = rd_hit_oh_i;
 
  logic ni_inside,ni_conflict; 
  assign ni_inside = |ni_pending_q;
  assign ni_conflict = is_ni && ni_inside;
  assign not_ni_o = !ni_inside;
  assign empty_o    = !(|valid);


  always_comb begin : p_buffer
    wbuffer_d           = wbuffer_q;
    ni_pending_d        = ni_pending_q;
    dirty_rd_en         = 1'b0;
    req_port_o.data_gnt = 1'b0;
    wbuffer_wren        = 1'b0;


    if (check_en_q1) begin
      if (wbuffer_q[check_ptr_q1].valid) begin
        wbuffer_d[check_ptr_q1].checked = 1'b1;
        wbuffer_d[check_ptr_q1].hit_oh = rd_hit_oh_q;
      end
    end



    for (int k=0; k<DCACHE_WBUF_DEPTH; k++) begin
      if (inval_hit[k]) begin
        wbuffer_d[k].checked = 1'b0;
      end
    end



    if (evict) begin
      for (int k=0; k<8; k++) begin
        if (tx_stat_q[rtrn_id].be[k]) begin
          wbuffer_d[rtrn_ptr].txblock[k] = 1'b0;
          if (!wbuffer_q[rtrn_ptr].dirty[k]) begin
            wbuffer_d[rtrn_ptr].valid[k] = 1'b0;




          end
        end
      end

      if (wbuffer_d[rtrn_ptr].valid == 0) begin
        wbuffer_d[rtrn_ptr].checked = 1'b0;
        ni_pending_d[rtrn_ptr] = 1'b0;
      end
    end


    if (miss_req_o && miss_ack_i) begin
      dirty_rd_en = 1'b1;
      for (int k=0; k<8; k++) begin
        if (tx_be[k]) begin
          wbuffer_d[dirty_ptr].dirty[k]   = 1'b0;
          wbuffer_d[dirty_ptr].txblock[k] = 1'b1;
        end
      end
    end


    if (req_port_i.data_req && rdy) begin


      if (!ni_conflict) begin
        wbuffer_wren              = 1'b1;

        req_port_o.data_gnt       = 1'b1;
        ni_pending_d[wr_ptr]      = is_ni;

        wbuffer_d[wr_ptr].checked = 1'b0;
        wbuffer_d[wr_ptr].wtag    = {req_port_i.address_tag, req_port_i.address_index[DCACHE_INDEX_WIDTH-1:3]};


        for (int k=0; k<8; k++) begin
          if (req_port_i.data_be[k]) begin
            wbuffer_d[wr_ptr].valid[k]       = 1'b1;
            wbuffer_d[wr_ptr].dirty[k]       = 1'b1;
            wbuffer_d[wr_ptr].data[k*8 +: 8] = req_port_i.data_wdata[k*8 +: 8];
          end
        end
      end
    end
  end






  always_ff @(posedge clk_i or negedge rst_ni) begin : p_regs
    if (!rst_ni) begin
      wbuffer_q     <= '{default: '0};
      tx_stat_q     <= '{default: '0};
      ni_pending_q  <= '0;
      check_ptr_q   <= '0;
      check_ptr_q1  <= '0;
      check_en_q    <= '0;
      check_en_q1   <= '0;
      rd_tag_q      <= '0;
      rd_hit_oh_q   <= '0;
      wr_cl_vld_q   <= '0;
      wr_cl_idx_q   <= '0;
    end else begin
      wbuffer_q     <= wbuffer_d;
      tx_stat_q     <= tx_stat_d;
      ni_pending_q  <= ni_pending_d;
      check_ptr_q   <= check_ptr_d;
      check_ptr_q1  <= check_ptr_q;
      check_en_q    <= check_en_d;
      check_en_q1   <= check_en_q;
      rd_tag_q      <= rd_tag_d;
      rd_hit_oh_q   <= rd_hit_oh_d;
      wr_cl_vld_q   <= wr_cl_vld_d;
      wr_cl_idx_q   <= wr_cl_idx_d;
    end
  end







`ifndef VERILATOR

  hot1: assert property (
    @(posedge clk_i) disable iff (!rst_ni) req_port_i.data_req |-> $onehot0(wbuffer_hit_oh))
      else $fatal(1,"[l1 dcache wbuffer] wbuffer_hit_oh signal must be hot1");

  tx_status: assert property (
    @(posedge clk_i) disable iff (!rst_ni) evict && miss_ack_i && miss_req_o |-> (tx_id != rtrn_id))
      else $fatal(1,"[l1 dcache wbuffer] cannot allocate and clear same tx slot id in the same cycle");

  tx_valid0: assert property (
    @(posedge clk_i) disable iff (!rst_ni) evict |-> tx_stat_q[rtrn_id].vld)
      else $fatal(1,"[l1 dcache wbuffer] evicting invalid transaction slot");

  tx_valid1: assert property (
    @(posedge clk_i) disable iff (!rst_ni) evict |-> |wbuffer_q[rtrn_ptr].valid)
      else $fatal(1,"[l1 dcache wbuffer] wbuffer entry corresponding to this transaction is invalid");

  write_full: assert property (
    @(posedge clk_i) disable iff (!rst_ni) req_port_i.data_req |-> req_port_o.data_gnt |-> ((!full) || (|wbuffer_hit_oh)))
      else $fatal(1,"[l1 dcache wbuffer] cannot write if full or no hit");

  unused0: assert property (
    @(posedge clk_i) disable iff (!rst_ni) !req_port_i.tag_valid)
      else $fatal(1,"[l1 dcache wbuffer] req_port_i.tag_valid should not be asserted");

  unused1: assert property (
    @(posedge clk_i) disable iff (!rst_ni) !req_port_i.kill_req)
      else $fatal(1,"[l1 dcache wbuffer] req_port_i.kill_req should not be asserted");

  for (genvar k=0; k<DCACHE_WBUF_DEPTH; k++) begin : gen_assert1
    for (genvar j=0; j<8; j++) begin : gen_assert2
      byteStates: assert property (
        @(posedge clk_i) disable iff (!rst_ni) {wbuffer_q[k].valid[j], wbuffer_q[k].dirty[j], wbuffer_q[k].txblock[j]} inside {3'b000, 3'b110, 3'b101, 3'b111} )
          else $fatal(1,"[l1 dcache wbuffer] byte %02d of wbuffer entry %02d has invalid state: valid=%01b, dirty=%01b, txblock=%01b",
            j,k,
            wbuffer_q[k].valid[j],
            wbuffer_q[k].dirty[j],
            wbuffer_q[k].txblock[j]);
    end
  end
`endif


endmodule
module wt_dcache_wbuffer import ariane_pkg::*;
 import wt_cache_pkg::*; #(
  parameter ariane_pkg::ariane_cfg_t    ArianeCfg          = ariane_pkg::ArianeDefaultConfig
) (
  input  logic                               clk_i,
  input  logic                               rst_ni,

  input  logic                               cache_en_i,
  output logic                               empty_o,
  output logic                               not_ni_o,

  input  dcache_req_i_t                      req_port_i,
  output dcache_req_o_t                      req_port_o,

  input  logic                               miss_ack_i,
  output logic [riscv::PLEN-1:0]             miss_paddr_o,
  output logic                               miss_req_o,
  output logic                               miss_we_o,
  output logic [63:0]                        miss_wdata_o,
  output logic [DCACHE_SET_ASSOC-1:0]        miss_vld_bits_o,
  output logic                               miss_nc_o,
  output logic [2:0]                         miss_size_o,
  output logic [CACHE_ID_WIDTH-1:0]          miss_id_o,

  input  logic                               miss_rtrn_vld_i,
  input  logic [CACHE_ID_WIDTH-1:0]          miss_rtrn_id_i,

  output logic [DCACHE_TAG_WIDTH-1:0]        rd_tag_o,
  output logic [DCACHE_CL_IDX_WIDTH-1:0]     rd_idx_o,
  output logic [DCACHE_OFFSET_WIDTH-1:0]     rd_off_o,
  output logic                               rd_req_o,
  output logic                               rd_tag_only_o,
  input  logic                               rd_ack_i,
  input logic  [63:0]                        rd_data_i,
  input logic  [DCACHE_SET_ASSOC-1:0]        rd_vld_bits_i,
  input logic  [DCACHE_SET_ASSOC-1:0]        rd_hit_oh_i,

  input logic                                wr_cl_vld_i,
  input logic [DCACHE_CL_IDX_WIDTH-1:0]      wr_cl_idx_i,

  output logic [DCACHE_SET_ASSOC-1:0]        wr_req_o,
  input  logic                               wr_ack_i,
  output logic [DCACHE_CL_IDX_WIDTH-1:0]     wr_idx_o,
  output logic [DCACHE_OFFSET_WIDTH-1:0]     wr_off_o,
  output logic [63:0]                        wr_data_o,
  output logic [7:0]                         wr_data_be_o,

  output wbuffer_t  [DCACHE_WBUF_DEPTH-1:0]  wbuffer_data_o,
  output logic [DCACHE_MAX_TX-1:0][riscv::PLEN-1:0]     tx_paddr_o,
  output logic [DCACHE_MAX_TX-1:0]           tx_vld_o
);

  tx_stat_t [DCACHE_MAX_TX-1:0]             tx_stat_d, tx_stat_q;
  wbuffer_t [DCACHE_WBUF_DEPTH-1:0]         wbuffer_d, wbuffer_q;
  logic     [DCACHE_WBUF_DEPTH-1:0]         valid;
  logic     [DCACHE_WBUF_DEPTH-1:0]         dirty;
  logic     [DCACHE_WBUF_DEPTH-1:0]         tocheck;
  logic     [DCACHE_WBUF_DEPTH-1:0]         wbuffer_hit_oh, inval_hit;
  logic     [DCACHE_WBUF_DEPTH-1:0][7:0]    bdirty;

  logic [$clog2(DCACHE_WBUF_DEPTH)-1:0] next_ptr, dirty_ptr, hit_ptr, wr_ptr, check_ptr_d, check_ptr_q, check_ptr_q1, rtrn_ptr;
  logic [CACHE_ID_WIDTH-1:0] tx_id, rtrn_id;

  logic [2:0] bdirty_off;
  logic [7:0] tx_be;
  logic [riscv::PLEN-1:0] wr_paddr, rd_paddr;
  logic [DCACHE_TAG_WIDTH-1:0] rd_tag_d, rd_tag_q;
  logic [DCACHE_SET_ASSOC-1:0] rd_hit_oh_d, rd_hit_oh_q;
  logic check_en_d, check_en_q, check_en_q1;
  logic full, dirty_rd_en, rdy;
  logic rtrn_empty, evict;
  logic [DCACHE_WBUF_DEPTH-1:0] ni_pending_d, ni_pending_q;
  logic wbuffer_wren;
  logic free_tx_slots;

  logic wr_cl_vld_q, wr_cl_vld_d;
  logic [DCACHE_CL_IDX_WIDTH-1:0] wr_cl_idx_q, wr_cl_idx_d;

  logic [riscv::PLEN-1:0] debug_paddr [DCACHE_WBUF_DEPTH-1:0];

  wbuffer_t wbuffer_check_mux, wbuffer_dirty_mux;




  logic [ariane_pkg::DCACHE_TAG_WIDTH-1:0] miss_tag;
  logic is_nc_miss;
  logic is_ni;
  assign miss_tag = miss_paddr_o[ariane_pkg::DCACHE_INDEX_WIDTH+:ariane_pkg::DCACHE_TAG_WIDTH];
  assign is_nc_miss = !ariane_pkg::is_inside_cacheable_regions(ArianeCfg, {{64-DCACHE_TAG_WIDTH{1'b0}}, miss_tag, {DCACHE_INDEX_WIDTH{1'b0}}});
  assign miss_nc_o = !cache_en_i || is_nc_miss; 

  assign is_ni = ariane_pkg::is_inside_nonidempotent_regions(ArianeCfg, {{64-DCACHE_TAG_WIDTH{1'b0}}, req_port_i.address_tag, {DCACHE_INDEX_WIDTH{1'b0}}});

  assign miss_we_o       = 1'b1;
  assign miss_vld_bits_o = '0;
  assign wbuffer_data_o  = wbuffer_q;

  for (genvar k=0; k<DCACHE_MAX_TX;k++) begin : gen_tx_vld
    assign tx_vld_o[k]   = tx_stat_q[k].vld;
    assign tx_paddr_o[k] = wbuffer_q[tx_stat_q[k].ptr].wtag<<3;
  end













  lzc #(
    .WIDTH ( 8 )
  ) i_vld_bdirty (
    .in_i    ( bdirty[dirty_ptr] ),
    .cnt_o   ( bdirty_off        ),
    .empty_o (                   )
  );


  assign miss_paddr_o = {wbuffer_dirty_mux.wtag, bdirty_off};
  assign miss_id_o    = tx_id;


  assign miss_req_o = (|dirty) && free_tx_slots;





  assign miss_size_o  = toSize64(bdirty[dirty_ptr]);


  assign miss_wdata_o = repData64(wbuffer_dirty_mux.data,
                                  bdirty_off,
                                  miss_size_o[1:0]);

  assign tx_be        = toByteEnable8(bdirty_off,
                                      miss_size_o[1:0]);






  fifo_v3 #(
    .FALL_THROUGH ( 1'b0                  ),
    .DATA_WIDTH   ( $clog2(DCACHE_MAX_TX) ),
    .DEPTH        ( DCACHE_MAX_TX         )
  ) i_rtrn_id_fifo (
    .clk_i      ( clk_i            ),
    .rst_ni     ( rst_ni           ),
    .flush_i    ( 1'b0             ),
    .testmode_i ( 1'b0             ),
    .full_o     (                  ),
    .empty_o    ( rtrn_empty       ),
    .usage_o    (                  ),
    .data_i     ( miss_rtrn_id_i   ),
    .push_i     ( miss_rtrn_vld_i  ),
    .data_o     ( rtrn_id          ),
    .pop_i      ( evict            )
  );

  always_comb begin : p_tx_stat
    tx_stat_d = tx_stat_q;
    evict     = 1'b0;
    wr_req_o  = '0;


    if ((!rtrn_empty) && wbuffer_q[rtrn_ptr].checked) begin


      if ((|wr_data_be_o) && (|wbuffer_q[rtrn_ptr].hit_oh)) begin
        wr_req_o = wbuffer_q[rtrn_ptr].hit_oh;
        if (wr_ack_i) begin
          evict    = 1'b1;
          tx_stat_d[rtrn_id].vld = 1'b0;
        end
      end else begin
        evict = 1'b1;
        tx_stat_d[rtrn_id].vld = 1'b0;
      end
    end


    if (dirty_rd_en) begin
      tx_stat_d[tx_id].vld = 1'b1;
      tx_stat_d[tx_id].ptr = dirty_ptr;
      tx_stat_d[tx_id].be  = tx_be;
    end
  end

  assign free_tx_slots = |(~tx_vld_o);


  rr_arb_tree #(
    .NumIn     (DCACHE_MAX_TX),
    .LockIn    (1'b1),
    .DataWidth (1)
  ) i_tx_id_rr (
    .clk_i  (clk_i       ),
    .rst_ni (rst_ni      ),
    .flush_i('0          ),
    .rr_i   ('0          ),
    .req_i  (~tx_vld_o   ),
    .gnt_o  (            ),
    .data_i ('0          ),
    .gnt_i  (dirty_rd_en ),
    .req_o  (            ),
    .data_o (            ),
    .idx_o  (tx_id       )
  );





  assign rd_tag_d   = rd_paddr>>DCACHE_INDEX_WIDTH;


  assign rd_tag_only_o = 1'b1;
  assign rd_paddr   = wbuffer_check_mux.wtag<<3;
  assign rd_req_o   = |tocheck;
  assign rd_tag_o   = rd_tag_q;
  assign rd_idx_o   = rd_paddr[DCACHE_INDEX_WIDTH-1:DCACHE_OFFSET_WIDTH];
  assign rd_off_o   = rd_paddr[DCACHE_OFFSET_WIDTH-1:0];
  assign check_en_d = rd_req_o & rd_ack_i;


  assign rtrn_ptr     = tx_stat_q[rtrn_id].ptr;


  assign wr_data_be_o = tx_stat_q[rtrn_id].be & (~wbuffer_q[rtrn_ptr].dirty);
  assign wr_paddr     = wbuffer_q[rtrn_ptr].wtag<<3;
  assign wr_idx_o     = wr_paddr[DCACHE_INDEX_WIDTH-1:DCACHE_OFFSET_WIDTH];
  assign wr_off_o     = wr_paddr[DCACHE_OFFSET_WIDTH-1:0];
  assign wr_data_o    = wbuffer_q[rtrn_ptr].data;






  logic [DCACHE_WBUF_DEPTH-1:0][DCACHE_CL_IDX_WIDTH-1:0] wtag_comp;

  assign wr_cl_vld_d = wr_cl_vld_i;
  assign wr_cl_idx_d = wr_cl_idx_i;

  for (genvar k=0; k<DCACHE_WBUF_DEPTH; k++) begin : gen_flags

    assign debug_paddr[k] = wbuffer_q[k].wtag << 3;




    assign bdirty[k] = (|wbuffer_q[k].txblock) ? '0 : wbuffer_q[k].dirty & wbuffer_q[k].valid;


    assign dirty[k]          = |bdirty[k];
    assign valid[k]          = |wbuffer_q[k].valid;
    assign wbuffer_hit_oh[k] = valid[k] & (wbuffer_q[k].wtag == {req_port_i.address_tag, req_port_i.address_index[DCACHE_INDEX_WIDTH-1:3]});




    assign wtag_comp[k] = wbuffer_q[k].wtag[DCACHE_INDEX_WIDTH-4:DCACHE_OFFSET_WIDTH-3];
    assign inval_hit[k]  = (wr_cl_vld_d & valid[k] & (wtag_comp[k] == wr_cl_idx_d)) |
                           (wr_cl_vld_q & valid[k] & (wtag_comp[k] == wr_cl_idx_q));


    assign tocheck[k]       = (~wbuffer_q[k].checked) & valid[k];
  end

  assign wr_ptr     = (|wbuffer_hit_oh) ? hit_ptr : next_ptr;
  assign rdy        = (|wbuffer_hit_oh) | (~full);


  lzc #(
    .WIDTH ( DCACHE_WBUF_DEPTH )
  ) i_vld_lzc (
    .in_i    ( ~valid        ),
    .cnt_o   ( next_ptr      ),
    .empty_o ( full          )
  );


  lzc #(
    .WIDTH ( DCACHE_WBUF_DEPTH )
  ) i_hit_lzc (
    .in_i    ( wbuffer_hit_oh ),
    .cnt_o   ( hit_ptr        ),
    .empty_o (                )
  );


  rr_arb_tree #(
    .NumIn     ( DCACHE_WBUF_DEPTH ),
    .LockIn    ( 1'b1              ),
    .DataType  ( wbuffer_t         )
  ) i_dirty_rr (
    .clk_i  ( clk_i             ),
    .rst_ni ( rst_ni            ),
    .flush_i( '0                ),
    .rr_i   ( '0                ),
    .req_i  ( dirty             ),
    .gnt_o  (                   ),
    .data_i ( wbuffer_q         ),
    .gnt_i  ( dirty_rd_en       ),
    .req_o  (                   ),
    .data_o ( wbuffer_dirty_mux ),
    .idx_o  ( dirty_ptr         )
  );


  rr_arb_tree #(
    .NumIn     ( DCACHE_WBUF_DEPTH ),
    .DataType  ( wbuffer_t         )
  ) i_clean_rr (
    .clk_i  ( clk_i             ),
    .rst_ni ( rst_ni            ),
    .flush_i( '0                ),
    .rr_i   ( '0                ),
    .req_i  ( tocheck           ),
    .gnt_o  (                   ),
    .data_i ( wbuffer_q         ),
    .gnt_i  ( check_en_d        ),
    .req_o  (                   ),
    .data_o ( wbuffer_check_mux ),
    .idx_o  ( check_ptr_d       )
  );





  assign req_port_o.data_rvalid = '0;
  assign req_port_o.data_rdata  = '0;

  assign rd_hit_oh_d = rd_hit_oh_i;
 
  logic ni_inside,ni_conflict; 
  assign ni_inside = |ni_pending_q;
  assign ni_conflict = is_ni && ni_inside;
  assign not_ni_o = !ni_inside;
  assign empty_o    = !(|valid);


  always_comb begin : p_buffer
    wbuffer_d           = wbuffer_q;
    ni_pending_d        = ni_pending_q;
    dirty_rd_en         = 1'b0;
    req_port_o.data_gnt = 1'b0;
    wbuffer_wren        = 1'b0;


    if (check_en_q1) begin
      if (wbuffer_q[check_ptr_q1].valid) begin
        wbuffer_d[check_ptr_q1].checked = 1'b1;
        wbuffer_d[check_ptr_q1].hit_oh = rd_hit_oh_q;
      end
    end



    for (int k=0; k<DCACHE_WBUF_DEPTH; k++) begin
      if (inval_hit[k]) begin
        wbuffer_d[k].checked = 1'b0;
      end
    end



    if (evict) begin
      for (int k=0; k<8; k++) begin
        if (tx_stat_q[rtrn_id].be[k]) begin
          wbuffer_d[rtrn_ptr].txblock[k] = 1'b0;
          if (!wbuffer_q[rtrn_ptr].dirty[k]) begin
            wbuffer_d[rtrn_ptr].valid[k] = 1'b0;




          end
        end
      end

      if (wbuffer_d[rtrn_ptr].valid == 0) begin
        wbuffer_d[rtrn_ptr].checked = 1'b0;
        ni_pending_d[rtrn_ptr] = 1'b0;
      end
    end


    if (miss_req_o && miss_ack_i) begin
      dirty_rd_en = 1'b1;
      for (int k=0; k<8; k++) begin
        if (tx_be[k]) begin
          wbuffer_d[dirty_ptr].dirty[k]   = 1'b0;
          wbuffer_d[dirty_ptr].txblock[k] = 1'b1;
        end
      end
    end


    if (req_port_i.data_req && rdy) begin


      if (!ni_conflict) begin
        wbuffer_wren              = 1'b1;

        req_port_o.data_gnt       = 1'b1;
        ni_pending_d[wr_ptr]      = is_ni;

        wbuffer_d[wr_ptr].checked = 1'b0;
        wbuffer_d[wr_ptr].wtag    = {req_port_i.address_tag, req_port_i.address_index[DCACHE_INDEX_WIDTH-1:3]};


        for (int k=0; k<8; k++) begin
          if (req_port_i.data_be[k]) begin
            wbuffer_d[wr_ptr].valid[k]       = 1'b1;
            wbuffer_d[wr_ptr].dirty[k]       = 1'b1;
            wbuffer_d[wr_ptr].data[k*8 +: 8] = req_port_i.data_wdata[k*8 +: 8];
          end
        end
      end
    end
  end






  always_ff @(posedge clk_i or negedge rst_ni) begin : p_regs
    if (!rst_ni) begin
      wbuffer_q     <= '{default: '0};
      tx_stat_q     <= '{default: '0};
      ni_pending_q  <= '0;
      check_ptr_q   <= '0;
      check_ptr_q1  <= '0;
      check_en_q    <= '0;
      check_en_q1   <= '0;
      rd_tag_q      <= '0;
      rd_hit_oh_q   <= '0;
      wr_cl_vld_q   <= '0;
      wr_cl_idx_q   <= '0;
    end else begin
      wbuffer_q     <= wbuffer_d;
      tx_stat_q     <= tx_stat_d;
      ni_pending_q  <= ni_pending_d;
      check_ptr_q   <= check_ptr_d;
      check_ptr_q1  <= check_ptr_q;
      check_en_q    <= check_en_d;
      check_en_q1   <= check_en_q;
      rd_tag_q      <= rd_tag_d;
      rd_hit_oh_q   <= rd_hit_oh_d;
      wr_cl_vld_q   <= wr_cl_vld_d;
      wr_cl_idx_q   <= wr_cl_idx_d;
    end
  end







`ifndef VERILATOR

  hot1: assert property (
    @(posedge clk_i) disable iff (!rst_ni) req_port_i.data_req |-> $onehot0(wbuffer_hit_oh))
      else $fatal(1,"[l1 dcache wbuffer] wbuffer_hit_oh signal must be hot1");

  tx_status: assert property (
    @(posedge clk_i) disable iff (!rst_ni) evict && miss_ack_i && miss_req_o |-> (tx_id != rtrn_id))
      else $fatal(1,"[l1 dcache wbuffer] cannot allocate and clear same tx slot id in the same cycle");

  tx_valid0: assert property (
    @(posedge clk_i) disable iff (!rst_ni) evict |-> tx_stat_q[rtrn_id].vld)
      else $fatal(1,"[l1 dcache wbuffer] evicting invalid transaction slot");

  tx_valid1: assert property (
    @(posedge clk_i) disable iff (!rst_ni) evict |-> |wbuffer_q[rtrn_ptr].valid)
      else $fatal(1,"[l1 dcache wbuffer] wbuffer entry corresponding to this transaction is invalid");

  write_full: assert property (
    @(posedge clk_i) disable iff (!rst_ni) req_port_i.data_req |-> req_port_o.data_gnt |-> ((!full) || (|wbuffer_hit_oh)))
      else $fatal(1,"[l1 dcache wbuffer] cannot write if full or no hit");

  unused0: assert property (
    @(posedge clk_i) disable iff (!rst_ni) !req_port_i.tag_valid)
      else $fatal(1,"[l1 dcache wbuffer] req_port_i.tag_valid should not be asserted");

  unused1: assert property (
    @(posedge clk_i) disable iff (!rst_ni) !req_port_i.kill_req)
      else $fatal(1,"[l1 dcache wbuffer] req_port_i.kill_req should not be asserted");

  for (genvar k=0; k<DCACHE_WBUF_DEPTH; k++) begin : gen_assert1
    for (genvar j=0; j<8; j++) begin : gen_assert2
      byteStates: assert property (
        @(posedge clk_i) disable iff (!rst_ni) {wbuffer_q[k].valid[j], wbuffer_q[k].dirty[j], wbuffer_q[k].txblock[j]} inside {3'b000, 3'b110, 3'b101, 3'b111} )
          else $fatal(1,"[l1 dcache wbuffer] byte %02d of wbuffer entry %02d has invalid state: valid=%01b, dirty=%01b, txblock=%01b",
            j,k,
            wbuffer_q[k].valid[j],
            wbuffer_q[k].dirty[j],
            wbuffer_q[k].txblock[j]);
    end
  end
`endif


endmodule