mirror of
https://github.com/vortexgpgpu/vortex.git
synced 2025-04-24 13:57:17 -04:00
fixed redundnat cache fill with dirty block, fixed cache tag_store critical path
This commit is contained in:
parent
725322807e
commit
c1f23cf3ad
3 changed files with 52 additions and 54 deletions
24
hw/rtl/cache/VX_bank.v
vendored
24
hw/rtl/cache/VX_bank.v
vendored
|
@ -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);
|
||||
|
|
65
hw/rtl/cache/VX_tag_access.v
vendored
65
hw/rtl/cache/VX_tag_access.v
vendored
|
@ -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
|
||||
|
|
17
hw/rtl/cache/VX_tag_store.v
vendored
17
hw/rtl/cache/VX_tag_store.v
vendored
|
@ -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),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue