diff --git a/hw/rtl/cache/VX_bank.v b/hw/rtl/cache/VX_bank.v index 05eb476b..f255cf33 100644 --- a/hw/rtl/cache/VX_bank.v +++ b/hw/rtl/cache/VX_bank.v @@ -328,9 +328,9 @@ module VX_bank #( assign writedata_st0 = dfpq_filldata_st0; - assign inst_meta_st0 = msrq_pop_unqual ? {`REQ_TAG_WIDTH'(msrq_tag_st0) , msrq_rw_st0, msrq_byteen_st0, msrq_tid_st0} : + assign inst_meta_st0 = msrq_pop_unqual ? {`REQ_TAG_WIDTH'(msrq_tag_st0), msrq_rw_st0, msrq_byteen_st0, msrq_tid_st0} : reqq_pop_unqual ? {`REQ_TAG_WIDTH'(reqq_tag_st0), reqq_rw_st0, reqq_byteen_st0, reqq_tid_st0} : - snrq_pop_unqual ? {`REQ_TAG_WIDTH'(snrq_tag_st0), 1'b0, WORD_SIZE'(0), `REQS_BITS'(0)} : + snrq_pop_unqual ? {`REQ_TAG_WIDTH'(snrq_tag_st0), 1'b0, WORD_SIZE'(0), `REQS_BITS'(0)} : 0; assign is_snp_st0 = msrq_pop_unqual ? msrq_is_snp_st0 : @@ -712,14 +712,14 @@ module VX_bank #( wire dwbq_empty, dwbq_full; - wire dwbq_is_dfl_in = valid_st3 && miss_st3 && (!force_miss_st3 || is_msrq_st3); - wire dwbq_is_dwb_in = valid_st3 && dirty_st3 && (is_fill_st3 || (!force_miss_st3 && is_snp_st3)); - wire dwbq_push_unqual = dwbq_is_dfl_in || dwbq_is_dwb_in; + wire dwbq_is_fill = valid_st3 && miss_st3 && (!force_miss_st3 || is_msrq_st3); + wire dwbq_is_wb = valid_st3 && dirty_st3 && (is_fill_st3 || (!force_miss_st3 && is_snp_st3)); + wire dwbq_push_unqual = dwbq_is_fill || dwbq_is_wb; assign dwbq_push_stall = dwbq_push_unqual && dwbq_full; wire dwbq_push = dwbq_push_unqual - && !(dwbq_is_dfl_in && incoming_fill) // not in 'dwbq_push_stall' to reduce clock delay + && !(dwbq_is_fill && incoming_fill) // not in 'dwbq_push_stall' to reduce clock delay && !dwbq_full && !msrq_push_stall && !cwbq_push_stall @@ -727,10 +727,10 @@ module VX_bank #( wire dwbq_pop = dram_req_valid && dram_req_ready; - wire [`LINE_ADDR_WIDTH-1:0] dwbq_addr = dwbq_is_dwb_in ? {readtag_st3, addr_st3[`LINE_SELECT_BITS-1:0]} : - addr_st3; + wire [`LINE_ADDR_WIDTH-1:0] dwbq_addr = dwbq_is_wb ? {readtag_st3, addr_st3[`LINE_SELECT_BITS-1:0]} : + addr_st3; - wire [BANK_LINE_SIZE-1:0] dwbq_byteen = dwbq_is_dwb_in ? dirtyb_st3 : {BANK_LINE_SIZE{1'b1}}; + wire [BANK_LINE_SIZE-1:0] dwbq_byteen = dwbq_is_wb ? dirtyb_st3 : {BANK_LINE_SIZE{1'b1}}; if (DRAM_ENABLE) begin VX_generic_queue #( @@ -741,8 +741,8 @@ module VX_bank #( .reset (reset), .push (dwbq_push), .pop (dwbq_pop), - .data_in ({dwbq_is_dwb_in, dwbq_byteen, dwbq_addr, readdata_st3}), - .data_out({dram_req_rw, dram_req_byteen, dram_req_addr, dram_req_data}), + .data_in ({dwbq_is_wb, dwbq_byteen, dwbq_addr, readdata_st3}), + .data_out({dram_req_rw, dram_req_byteen, dram_req_addr, dram_req_data}), .empty (dwbq_empty), .full (dwbq_full), `UNUSED_PIN (size) @@ -856,7 +856,7 @@ module VX_bank #( $display("%t: cache%0d:%0d core-rsp: addr=%0h, tag=%0h, tid=%0d, data=%0h, wid=%0d, PC=%0h", $time, CACHE_ID, BANK_ID, `LINE_TO_BYTE_ADDR(addr_st3, BANK_ID), cwbq_tag_st3, cwbq_tid_st3, cwbq_data_st3, debug_wid_st3, debug_pc_st3); end if (dwbq_push) begin - if (dwbq_is_dwb_in) + if (dwbq_is_wb) $display("%t: cache%0d:%0d writeback: addr=%0h, data=%0h, byteen=%b, wid=%0d, PC=%0h", $time, CACHE_ID, BANK_ID, `LINE_TO_BYTE_ADDR(dwbq_addr, BANK_ID), readdata_st3, dirtyb_st3, debug_wid_st3, debug_pc_st3); else $display("%t: cache%0d:%0d fill-req: addr=%0h, wid=%0d, PC=%0h", $time, CACHE_ID, BANK_ID, `LINE_TO_BYTE_ADDR(dwbq_addr, BANK_ID), debug_wid_st3, debug_pc_st3); diff --git a/hw/rtl/cache/VX_tag_access.v b/hw/rtl/cache/VX_tag_access.v index 8e04d3a2..4fec84cd 100644 --- a/hw/rtl/cache/VX_tag_access.v +++ b/hw/rtl/cache/VX_tag_access.v @@ -60,7 +60,8 @@ module VX_tag_access #( wire use_read_dirty; wire[`TAG_SELECT_BITS-1:0] use_read_tag; - wire use_write_enable; + wire use_do_fill; + wire use_do_write; wire use_invalidate; wire[`TAG_SELECT_BITS-1:0] addrtag = addr_in[`TAG_LINE_ADDR_RNG]; @@ -80,9 +81,9 @@ module VX_tag_access #( .read_dirty (qual_read_dirty), .read_tag (qual_read_tag), + .do_fill (use_do_fill), + .do_write (use_do_write), .invalidate (use_invalidate), - .write_enable(use_write_enable), - .write_fill (is_fill_in), .write_addr (addrline), .write_tag (addrtag) ); @@ -92,52 +93,48 @@ module VX_tag_access #( assign use_read_tag = DRAM_ENABLE ? qual_read_tag : addrtag; // Tag is always the same in SM // use "case equality" to handle uninitialized tag when block entry is not valid - wire tags_match = use_read_valid && (addrtag === use_read_tag); + wire tags_match = use_read_valid && (addrtag === use_read_tag); + + wire core_req_miss = valid_in && !is_snp_in && !is_fill_in + && !tags_match; + + assign use_do_write = valid_in + && is_write_in + && use_read_valid + && !core_req_miss + && !force_miss_in + && !stall; - wire normal_write = valid_in - && is_write_in - && use_read_valid - && !is_fill_in - && !is_snp_in - && !miss_out - && !force_miss_in; + assign use_do_fill = valid_in + && is_fill_in + && !stall; - wire fill_write = valid_in && is_fill_in - && !tags_match; // discard redundant fills because the block could be dirty - - assign use_write_enable = (normal_write || fill_write) - && !stall; - - assign use_invalidate = valid_in && is_snp_in + assign use_invalidate = valid_in + && is_snp_in && tags_match && (use_read_dirty || snp_invalidate_in) // block is dirty or should invalidate && !force_miss_in && !stall; - - wire core_req_miss = valid_in && !is_snp_in && !is_fill_in - && !tags_match; assign miss_out = core_req_miss; - assign dirty_out = valid_in && use_read_valid && use_read_dirty; + assign dirty_out = valid_in && use_read_valid && use_read_dirty + && !(is_fill_in && tags_match); // disable writeback for redundant fills + assign readtag_out = use_read_tag; - assign writeen_out = use_write_enable; + assign writeen_out = (use_do_write || use_do_fill); `ifdef DBG_PRINT_CACHE_DATA always @(posedge clk) begin if (valid_in && !stall) begin - if (is_fill_in && use_read_valid && tags_match) begin + if (use_do_fill && tags_match) begin $display("%t: warning: redundant fill - addr=%0h", $time, `LINE_TO_BYTE_ADDR(addr_in, BANK_ID)); - end - if (miss_out) begin - $display("%t: cache%0d:%0d tag-miss: addr=%0h, wid=%0d, PC=%0h, valid=%b, blk_tag_id=%0h, blk_addr=%0d, tag_id=%0h", $time, CACHE_ID, BANK_ID, `LINE_TO_BYTE_ADDR(addr_in, BANK_ID), debug_wid, debug_pc, use_read_dirty, qual_read_tag, addrline, addrtag); - end else if ((| use_write_enable)) begin - if (is_fill_in) begin - $display("%t: cache%0d:%0d tag-fill: addr=%0h, blk_addr=%0d, tag_id=%0h", $time, CACHE_ID, BANK_ID, `LINE_TO_BYTE_ADDR(addr_in, BANK_ID), addrline, addrtag); - end else begin - $display("%t: cache%0d:%0d tag-write: addr=%0h, wid=%0d, PC=%0h, blk_addr=%0d, tag_id=%0h", $time, CACHE_ID, BANK_ID, `LINE_TO_BYTE_ADDR(addr_in, BANK_ID), debug_wid, debug_pc, addrline, addrtag); - end + end + if (use_do_fill) begin + $display("%t: cache%0d:%0d tag-fill: addr=%0h, blk_addr=%0d, tag_id=%0h, old_tag_id=%0h", $time, CACHE_ID, BANK_ID, `LINE_TO_BYTE_ADDR(addr_in, BANK_ID), addrline, addrtag, qual_read_tag); + end else if (tags_match) begin + $display("%t: cache%0d:%0d tag-hit: addr=%0h, wid=%0d, PC=%0h, dirty=%b, blk_addr=%0d, tag_id=%0h", $time, CACHE_ID, BANK_ID, `LINE_TO_BYTE_ADDR(addr_in, BANK_ID), debug_wid, debug_pc, use_read_dirty, addrline, addrtag); end else begin - $display("%t: cache%0d:%0d tag-read: addr=%0h, wid=%0d, PC=%0h, blk_addr=%0d, tag_id=%0h", $time, CACHE_ID, BANK_ID, `LINE_TO_BYTE_ADDR(addr_in, BANK_ID), debug_wid, debug_pc, addrline, qual_read_tag); + $display("%t: cache%0d:%0d tag-miss: addr=%0h, wid=%0d, PC=%0h, dirty=%b, blk_addr=%0d, tag_id=%0h, old_tag_id=%0h", $time, CACHE_ID, BANK_ID, `LINE_TO_BYTE_ADDR(addr_in, BANK_ID), debug_wid, debug_pc, use_read_dirty, addrline, addrtag, qual_read_tag); end end end diff --git a/hw/rtl/cache/VX_tag_store.v b/hw/rtl/cache/VX_tag_store.v index 154f29fe..e222e307 100644 --- a/hw/rtl/cache/VX_tag_store.v +++ b/hw/rtl/cache/VX_tag_store.v @@ -13,12 +13,12 @@ module VX_tag_store #( input wire clk, input wire reset, - input wire write_enable, - input wire write_fill, + input wire do_fill, + input wire do_write, + input wire invalidate, input wire[`LINE_SELECT_BITS-1:0] write_addr, input wire[`TAG_SELECT_BITS-1:0] write_tag, - input wire invalidate, - + input wire[`LINE_SELECT_BITS-1:0] read_addr, output wire[`TAG_SELECT_BITS-1:0] read_tag, output wire read_valid, @@ -34,10 +34,11 @@ module VX_tag_store #( dirty[i] <= 0; end end else begin - if (write_enable) begin - assert(!invalidate); - dirty[write_addr] <= !write_fill; + if (do_fill) begin valid[write_addr] <= 1; + dirty[write_addr] <= 0; + end else if (do_write) begin + dirty[write_addr] <= 1; end else if (invalidate) begin valid[write_addr] <= 0; end @@ -54,7 +55,7 @@ module VX_tag_store #( .clk(clk), .waddr(write_addr), .raddr(read_addr), - .wren(write_enable), + .wren(do_fill), .byteen(1'b1), .rden(1'b1), .din(write_tag),