fixed redundnat cache fill with dirty block, fixed cache tag_store critical path

This commit is contained in:
Blaise Tine 2020-11-10 08:32:34 -08:00
parent 725322807e
commit c1f23cf3ad
3 changed files with 52 additions and 54 deletions

View file

@ -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);

View file

@ -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

View file

@ -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),