per_bank_miss added to VX_cache.v

This commit is contained in:
trmontgomery
2020-11-02 12:07:10 -05:00
68 changed files with 2410 additions and 1634 deletions

View File

@@ -50,7 +50,7 @@ module VX_bank #(
// Snooping request tag width
parameter SNP_REQ_TAG_WIDTH = 0
) (
`SCOPE_SIGNALS_CACHE_IO
`SCOPE_IO_VX_bank
input wire clk,
input wire reset,
@@ -146,7 +146,7 @@ module VX_bank #(
) snp_req_queue (
.clk (clk),
.reset (reset),
.push (snp_req_valid),
.push (snp_req_valid && snp_req_ready),
.data_in ({snp_req_addr, snp_req_invalidate, snp_req_tag}),
.pop (snrq_pop),
.data_out({snrq_addr_st0, snrq_invalidate_st0, snrq_tag_st0}),
@@ -169,7 +169,7 @@ module VX_bank #(
) dfp_queue (
.clk (clk),
.reset (reset),
.push (dram_fill_rsp_valid),
.push (dram_fill_rsp_valid && dram_fill_rsp_ready),
.data_in ({dram_fill_rsp_addr, dram_fill_rsp_data}),
.pop (dfpq_pop),
.data_out({dfpq_addr_st0, dfpq_filldata_st0}),
@@ -266,7 +266,9 @@ module VX_bank #(
`DEBUG_BEGIN
wire going_to_write_st1;
`DEBUG_END
//determines if the if it is time to pop a req from the queues
//unqual - the req does NOT qualify for execution in the bank.
wire mrvq_pop_unqual = mrvq_valid_st0;
wire dfpq_pop_unqual = !mrvq_pop_unqual && !dfpq_empty;
wire reqq_pop_unqual = !mrvq_stop && !mrvq_pop_unqual && !dfpq_pop_unqual && !reqq_empty && reqq_req_st0 && !is_fill_st1 && !is_fill_st1;
@@ -276,7 +278,8 @@ module VX_bank #(
assign dfpq_pop = dfpq_pop_unqual && !stall_bank_pipe;
assign reqq_pop = reqq_pop_unqual && !stall_bank_pipe;
assign snrq_pop = snrq_pop_unqual && !stall_bank_pipe;
//signals to progress to the next stage
wire qual_is_fill_st0;
wire qual_valid_st0;
wire [`LINE_ADDR_WIDTH-1:0] qual_addr_st0;
@@ -289,7 +292,8 @@ module VX_bank #(
wire qual_going_to_write_st0;
wire qual_is_snp_st0;
wire qual_snp_invalidate_st0;
//signals to be *used* in the next stage
wire valid_st1;
wire [`LINE_ADDR_WIDTH-1:0] addr_st1;
wire [`UP(`WORD_SELECT_WIDTH)-1:0] wsel_st1;
@@ -300,15 +304,19 @@ module VX_bank #(
wire snp_invalidate_st1;
wire is_mrvq_st1;
assign qual_is_fill_st0 = dfpq_pop_unqual;
//Determine which req will progress to the next stage
assign qual_is_fill_st0 = dfpq_pop_unqual; //dram is filling a request
assign qual_valid_st0 = dfpq_pop || mrvq_pop || reqq_pop || snrq_pop;
assign qual_valid_st0 = dfpq_pop || mrvq_pop || reqq_pop || snrq_pop; //valid if something is being popped
assign qual_addr_st0 = dfpq_pop_unqual ? dfpq_addr_st0 :
mrvq_pop_unqual ? mrvq_addr_st0 :
//Decides which request to deal with. Priority: 1) Miss reserve 2) DRAM fill 3) Core req 4) Snp req
assign qual_addr_st0 = mrvq_pop_unqual ? mrvq_addr_st0 :
dfpq_pop_unqual ? dfpq_addr_st0 :
reqq_pop_unqual ? reqq_req_addr_st0[`LINE_SELECT_ADDR_RNG] :
snrq_pop_unqual ? snrq_addr_st0 :
0;
//Word select does ? Does this just pick a specific word from the line instead of the whole line?
if (`WORD_SELECT_WIDTH != 0) begin
assign qual_wsel_st0 = reqq_pop_unqual ? reqq_req_addr_st0[`WORD_SELECT_WIDTH-1:0] :
mrvq_pop_unqual ? mrvq_wsel_st0 :
@@ -318,30 +326,35 @@ module VX_bank #(
assign qual_wsel_st0 = 0;
end
//if you are filling from dram then that is the write data? What about core? What is 57?
assign qual_writedata_st0 = dfpq_pop_unqual ? dfpq_filldata_st0 : 57;
//note that this is stored even if a DRAM fill is processed
assign qual_inst_meta_st0 = mrvq_pop_unqual ? {`REQ_TAG_WIDTH'(mrvq_tag_st0) , mrvq_rw_st0, mrvq_byteen_st0, mrvq_tid_st0} :
reqq_pop_unqual ? {`REQ_TAG_WIDTH'(reqq_req_tag_st0), reqq_req_rw_st0, reqq_req_byteen_st0, reqq_req_tid_st0} :
snrq_pop_unqual ? {`REQ_TAG_WIDTH'(snrq_tag_st0), 1'b0, WORD_SIZE'(0), `REQS_BITS'(0)} :
0;
assign qual_going_to_write_st0 = dfpq_pop_unqual ? 1 :
(mrvq_pop_unqual && mrvq_rw_st0) ? 1 :
(reqq_pop_unqual && reqq_req_rw_st0) ? 1 :
0;
//snp signals check to see if the miss reserve as a snp in it first.
assign qual_is_snp_st0 = mrvq_pop_unqual ? mrvq_is_snp_st0 :
snrq_pop_unqual ? 1 :
0;
//if we are popping from the miss reserve then assign to the mrvq invalidate. If not and popping from the snoop queue use the snoop invalidate. Else this is 0
assign qual_snp_invalidate_st0 = mrvq_pop_unqual ? mrvq_snp_invalidate_st0 :
snrq_pop_unqual ? snrq_invalidate_st0 :
0;
//choose which word of the lien is being written to
assign qual_writeword_st0 = mrvq_pop_unqual ? mrvq_writeword_st0 :
reqq_pop_unqual ? reqq_req_writeword_st0 :
0;
assign qual_is_mrvq_st0 = mrvq_pop_unqual;
`ifdef DBG_CORE_REQ_INFO
@@ -356,7 +369,7 @@ module VX_bank #(
.clk (clk),
.reset (reset),
.stall (stall_bank_pipe),
.flush (0),
.flush (1'b0),
.in ({qual_is_mrvq_st0, qual_is_snp_st0, qual_snp_invalidate_st0, qual_going_to_write_st0, qual_valid_st0, qual_addr_st0, qual_wsel_st0, qual_writeword_st0, qual_inst_meta_st0, qual_is_fill_st0, qual_writedata_st0}),
.out ({is_mrvq_st1 , is_snp_st1, snp_invalidate_st1, going_to_write_st1, valid_st1, addr_st1, wsel_st1, writeword_st1, inst_meta_st1, is_fill_st1, writedata_st1})
);
@@ -453,6 +466,8 @@ module VX_bank #(
`ifdef DBG_CORE_REQ_INFO
if (WORD_SIZE != `GLOBAL_BLOCK_SIZE) begin
assign {debug_pc_st1, debug_rd_st1, debug_wid_st1, debug_tagid_st1, debug_rw_st1, debug_byteen_st1, debug_tid_st1} = inst_meta_st1;
end else begin
assign {debug_pc_st1, debug_rd_st1, debug_wid_st1, debug_tagid_st1, debug_rw_st1, debug_byteen_st1, debug_tid_st1} = 0;
end
`endif
@@ -486,7 +501,7 @@ module VX_bank #(
.clk (clk),
.reset (reset),
.stall (stall_bank_pipe),
.flush (0),
.flush (1'b0),
.in ({mrvq_recover_ready_state_st1, is_mrvq_st1_st2, mrvq_init_ready_state_st1, snp_to_mrvq_st1, is_snp_st1, snp_invalidate_st1, fill_saw_dirty_st1, is_fill_st1, qual_valid_st1_2, addr_st1, wsel_st1, writeword_st1, readword_st1, readdata_st1, readtag_st1, miss_st1, dirty_st1, dirtyb_st1, inst_meta_st1}),
.out ({mrvq_recover_ready_state_st2 , is_mrvq_st2 , mrvq_init_ready_state_unqual_st2, snp_to_mrvq_st2 , is_snp_st2 , snp_invalidate_st2, fill_saw_dirty_st2 , is_fill_st2 , valid_st2 , addr_st2, wsel_st2, writeword_st2, readword_st2, readdata_st2, readtag_st2, miss_st2, dirty_st2, dirtyb_st2, inst_meta_st2})
);
@@ -728,18 +743,18 @@ module VX_bank #(
end
`endif
`SCOPE_ASSIGN (scope_bank_valid_st0, qual_valid_st0);
`SCOPE_ASSIGN (scope_bank_valid_st1, valid_st1);
`SCOPE_ASSIGN (scope_bank_valid_st2, valid_st2);
`SCOPE_ASSIGN (scope_valid_st0, qual_valid_st0);
`SCOPE_ASSIGN (scope_valid_st1, valid_st1);
`SCOPE_ASSIGN (scope_valid_st2, valid_st2);
`SCOPE_ASSIGN (scope_bank_is_mrvq_st1, is_mrvq_st1);
`SCOPE_ASSIGN (scope_bank_miss_st1, miss_st1);
`SCOPE_ASSIGN (scope_bank_dirty_st1, dirty_st1);
`SCOPE_ASSIGN (scope_bank_force_miss_st1, force_request_miss_st1);
`SCOPE_ASSIGN (scope_bank_stall_pipe, stall_bank_pipe);
`SCOPE_ASSIGN (scope_is_mrvq_st1, is_mrvq_st1);
`SCOPE_ASSIGN (scope_miss_st1, miss_st1);
`SCOPE_ASSIGN (scope_dirty_st1, dirty_st1);
`SCOPE_ASSIGN (scope_force_miss_st1, force_request_miss_st1);
`SCOPE_ASSIGN (scope_stall_pipe, stall_bank_pipe);
`SCOPE_ASSIGN (scope_bank_addr_st0, `LINE_TO_BYTE_ADDR(qual_addr_st0, BANK_ID));
`SCOPE_ASSIGN (scope_bank_addr_st1, `LINE_TO_BYTE_ADDR(addr_st1, BANK_ID));
`SCOPE_ASSIGN (scope_bank_addr_st2, `LINE_TO_BYTE_ADDR(addr_st2, BANK_ID));
`SCOPE_ASSIGN (scope_addr_st0, `LINE_TO_BYTE_ADDR(qual_addr_st0, BANK_ID));
`SCOPE_ASSIGN (scope_addr_st1, `LINE_TO_BYTE_ADDR(addr_st1, BANK_ID));
`SCOPE_ASSIGN (scope_addr_st2, `LINE_TO_BYTE_ADDR(addr_st2, BANK_ID));
endmodule

View File

@@ -51,15 +51,15 @@ module VX_cache #(
parameter DRAM_TAG_WIDTH = 28,
// Number of snoop forwarding requests
parameter NUM_SNP_REQUESTS = 2,
parameter NUM_SNP_REQUESTS = 1,
// Snooping request tag width
parameter SNP_REQ_TAG_WIDTH = 28,
parameter SNP_REQ_TAG_WIDTH = 1,
// Snooping forward tag width
parameter SNP_FWD_TAG_WIDTH = 1
) (
`SCOPE_SIGNALS_CACHE_IO
`SCOPE_IO_VX_cache
input wire clk,
input wire reset,
@@ -167,7 +167,7 @@ module VX_cache #(
wire [NUM_BANKS-1:0] per_bank_miss;
assign miss_vec = per_bank_miss;
`SCOPE_SIGNALS_CACHE_BANK_SELECT
wire snp_req_valid_qual;
wire [`DRAM_ADDR_WIDTH-1:0] snp_req_addr_qual;
@@ -376,7 +376,7 @@ module VX_cache #(
.CORE_TAG_ID_BITS (CORE_TAG_ID_BITS),
.SNP_REQ_TAG_WIDTH (SNP_REQ_TAG_WIDTH)
) bank (
`SCOPE_SIGNALS_CACHE_BANK_BIND
`SCOPE_BIND_VX_cache_bank(i)
.clk (clk),
.reset (reset),

View File

@@ -2,7 +2,6 @@
`define VX_CACHE_CONFIG
`include "VX_platform.vh"
`include "VX_scope.vh"
`ifdef DBG_CORE_REQ_INFO
`include "VX_define.vh"

View File

@@ -91,7 +91,7 @@ module VX_cache_core_rsp_merge #(
.clk (clk),
.reset (reset),
.stall (stall),
.flush (0),
.flush (1'b0),
.in ({core_rsp_valid_unqual, core_rsp_data_unqual, core_rsp_tag_unqual}),
.out ({core_rsp_valid, core_rsp_data, core_rsp_tag})
);

View File

@@ -56,8 +56,9 @@ module VX_cache_miss_resrv #(
output wire miss_resrv_is_snp_st0,
output wire miss_resrv_snp_invalidate_st0
);
reg [`MRVQ_METADATA_WIDTH-1:0] metadata_table[MRVQ_SIZE-1:0];
wire [`MRVQ_METADATA_WIDTH-1:0] metadata_table;
reg [MRVQ_SIZE-1:0][`LINE_ADDR_WIDTH-1:0] addr_table;
reg [MRVQ_SIZE-1:0] valid_table;
reg [MRVQ_SIZE-1:0] ready_table;
reg [`LOG2UP(MRVQ_SIZE)-1:0] schedule_ptr;
@@ -66,13 +67,13 @@ module VX_cache_miss_resrv #(
reg [`LOG2UP(MRVQ_SIZE+1)-1:0] size;
`STATIC_ASSERT(MRVQ_SIZE > 5, "invalid size")
`STATIC_ASSERT(MRVQ_SIZE > 5, ("invalid size"))
assign miss_resrv_full = (size == $bits(size)'(MRVQ_SIZE));
assign miss_resrv_stop = (size > $bits(size)'(MRVQ_SIZE-5)); // need to add 5 cycles to prevent pipeline lock
wire enqueue_possible = !miss_resrv_full;
wire [`LOG2UP(MRVQ_SIZE)-1:0] enqueue_index = tail_ptr;
wire enqueue_possible = !miss_resrv_full;
wire [`LOG2UP(MRVQ_SIZE)-1:0] enqueue_index = tail_ptr;
reg [MRVQ_SIZE-1:0] make_ready;
reg [MRVQ_SIZE-1:0] make_ready_push;
@@ -85,11 +86,11 @@ module VX_cache_miss_resrv #(
assign pending_hazard_st1 = |(valid_address_match);
wire dequeue_possible = valid_table[schedule_ptr] && ready_table[schedule_ptr];
wire dequeue_possible = valid_table[schedule_ptr] && ready_table[schedule_ptr];
wire [`LOG2UP(MRVQ_SIZE)-1:0] dequeue_index = schedule_ptr;
assign miss_resrv_valid_st0 = dequeue_possible;
assign miss_resrv_addr_st0 = addr_table[dequeue_index];
assign miss_resrv_addr_st0 = addr_table[dequeue_index];
assign {miss_resrv_data_st0,
miss_resrv_tid_st0,
miss_resrv_tag_st0,
@@ -97,7 +98,7 @@ module VX_cache_miss_resrv #(
miss_resrv_byteen_st0,
miss_resrv_wsel_st0,
miss_resrv_is_snp_st0,
miss_resrv_snp_invalidate_st0} = metadata_table[dequeue_index];
miss_resrv_snp_invalidate_st0} = metadata_table;
wire mrvq_push = miss_add && enqueue_possible && !is_mrvq;
wire mrvq_pop = miss_resrv_pop && dequeue_possible;
@@ -124,13 +125,12 @@ module VX_cache_miss_resrv #(
valid_table[enqueue_index] <= 1;
ready_table[enqueue_index] <= mrvq_init_ready_state;
addr_table[enqueue_index] <= miss_add_addr;
metadata_table[enqueue_index] <= {miss_add_data, miss_add_tid, miss_add_tag, miss_add_rw, miss_add_byteen, miss_add_wsel, miss_add_is_snp, miss_add_snp_invalidate};
tail_ptr <= tail_ptr + 1;
tail_ptr <= tail_ptr + $bits(tail_ptr)'(1);
end else if (increment_head) begin
valid_table[head_ptr] <= 0;
head_ptr <= head_ptr + 1;
head_ptr <= head_ptr + $bits(head_ptr)'(1);
end else if (recover_state) begin
schedule_ptr <= schedule_ptr - 1;
schedule_ptr <= schedule_ptr - $bits(schedule_ptr)'(1);
end
// update entry as 'ready' during DRAM fill response
@@ -140,20 +140,36 @@ module VX_cache_miss_resrv #(
if (mrvq_pop) begin
ready_table[dequeue_index] <= 0;
schedule_ptr <= schedule_ptr + 1;
schedule_ptr <= schedule_ptr + $bits(schedule_ptr)'(1);
end
if (!(mrvq_push && increment_head)) begin
if (mrvq_push) begin
size <= size + 1;
size <= size + $bits(size)'(1);
end
if (increment_head) begin
size <= size - 1;
size <= size - $bits(size)'(1);
end
end
end
end
VX_dp_ram #(
.DATAW(`MRVQ_METADATA_WIDTH),
.SIZE(MRVQ_SIZE),
.BYTEENW(1),
.BUFFERED(0),
.RWCHECK(1)
) metadata_ram (
.clk(clk),
.waddr(enqueue_index),
.raddr(dequeue_index),
.wren(mrvq_push),
.rden(1'b1),
.din({miss_add_data, miss_add_tid, miss_add_tag, miss_add_rw, miss_add_byteen, miss_add_wsel, miss_add_is_snp, miss_add_snp_invalidate}),
.dout(metadata_table)
);
`ifdef DBG_PRINT_CACHE_MSRQ
always @(posedge clk) begin
if (mrvq_push || mrvq_pop || increment_head || recover_state) begin

View File

@@ -37,7 +37,7 @@ module VX_snp_forwarder #(
input wire [NUM_REQUESTS-1:0][`LOG2UP(SNRQ_SIZE)-1:0] snp_fwdin_tag,
output wire [NUM_REQUESTS-1:0] snp_fwdin_ready
);
`STATIC_ASSERT(NUM_REQUESTS > 1, "invalid value")
`STATIC_ASSERT(NUM_REQUESTS > 1, ("invalid value"))
reg [`REQS_BITS:0] pending_cntrs [SNRQ_SIZE-1:0];

View File

@@ -183,15 +183,15 @@ module VX_tag_data_access #(
if (valid_req_st1) begin
if ((| use_write_enable)) begin
if (writefill_st1) begin
$display("%t: cache%0d:%0d store-fill: wid=%0d, PC=%0h, tag=%0h, rd=%0d, dirty=%b, blk_addr=%0d, tag_id=%0h, data=%0h", $time, CACHE_ID, BANK_ID, debug_wid_st1, debug_pc_st1, debug_tagid_st1, debug_rd_st1, dirty_st1, writeladdr_st1, writetag_st1, use_write_data);
$display("%t: cache%0d:%0d data-fill: wid=%0d, PC=%0h, tag=%0h, rd=%0d, dirty=%b, blk_addr=%0d, tag_id=%0h, data=%0h", $time, CACHE_ID, BANK_ID, debug_wid_st1, debug_pc_st1, debug_tagid_st1, debug_rd_st1, dirty_st1, writeladdr_st1, writetag_st1, use_write_data);
end else begin
$display("%t: cache%0d:%0d store-write: wid=%0d, PC=%0h, tag=%0h, rd=%0d, dirty=%b, blk_addr=%0d, tag_id=%0h, wsel=%0d, data=%0h", $time, CACHE_ID, BANK_ID, debug_wid_st1, debug_pc_st1, debug_tagid_st1, debug_rd_st1, dirty_st1, writeladdr_st1, writetag_st1, wordsel_st1, writeword_st1);
$display("%t: cache%0d:%0d data-write: wid=%0d, PC=%0h, tag=%0h, rd=%0d, dirty=%b, blk_addr=%0d, tag_id=%0h, wsel=%0d, data=%0h", $time, CACHE_ID, BANK_ID, debug_wid_st1, debug_pc_st1, debug_tagid_st1, debug_rd_st1, dirty_st1, writeladdr_st1, writetag_st1, wordsel_st1, writeword_st1);
end
end else
if (miss_st1) begin
$display("%t: cache%0d:%0d store-miss: wid=%0d, PC=%0h, tag=%0h, rd=%0d, dirty=%b", $time, CACHE_ID, BANK_ID, debug_wid_st1, debug_pc_st1, debug_tagid_st1, debug_rd_st1, dirty_st1);
$display("%t: cache%0d:%0d data-miss: wid=%0d, PC=%0h, tag=%0h, rd=%0d, dirty=%b", $time, CACHE_ID, BANK_ID, debug_wid_st1, debug_pc_st1, debug_tagid_st1, debug_rd_st1, dirty_st1);
end else begin
$display("%t: cache%0d:%0d store-read: wid=%0d, PC=%0h, tag=%0h, rd=%0d, dirty=%b, blk_addr=%0d, tag_id=%0h, wsel=%0d, data=%0h", $time, CACHE_ID, BANK_ID, debug_wid_st1, debug_pc_st1, debug_tagid_st1, debug_rd_st1, dirty_st1, readaddr_st1, qual_read_tag_st1, wordsel_st1, qual_read_data_st1);
$display("%t: cache%0d:%0d data-read: wid=%0d, PC=%0h, tag=%0h, rd=%0d, dirty=%b, blk_addr=%0d, tag_id=%0h, wsel=%0d, data=%0h", $time, CACHE_ID, BANK_ID, debug_wid_st1, debug_pc_st1, debug_tagid_st1, debug_rd_st1, dirty_st1, readaddr_st1, qual_read_tag_st1, wordsel_st1, qual_read_data_st1);
end
end
end

View File

@@ -6,7 +6,7 @@ module VX_tag_data_store #(
// Size of line inside a bank in bytes
parameter BANK_LINE_SIZE = 0,
// Number of banks {1, 2, 4, 8,...}
parameter NUM_BANKS = 0,
parameter NUM_BANKS = 0, //unused parameter?
// Size of a word in bytes
parameter WORD_SIZE = 0
) (
@@ -30,7 +30,6 @@ module VX_tag_data_store #(
input wire fill_sent
);
reg [`BANK_LINE_WORDS-1:0][WORD_SIZE-1:0][7:0] data [`BANK_LINE_COUNT-1:0];
reg [`TAG_SELECT_BITS-1:0] tag [`BANK_LINE_COUNT-1:0];
reg [`BANK_LINE_WORDS-1:0][WORD_SIZE-1:0] dirtyb[`BANK_LINE_COUNT-1:0];
reg [`BANK_LINE_COUNT-1:0] dirty;
@@ -40,8 +39,7 @@ module VX_tag_data_store #(
assign read_dirty = dirty [read_addr];
assign read_dirtyb = dirtyb [read_addr];
assign read_tag = tag [read_addr];
assign read_data = data [read_addr];
wire do_write = (| write_enable);
always @(posedge clk) begin
@@ -69,15 +67,26 @@ module VX_tag_data_store #(
if (invalidate) begin
valid[write_addr] <= 0;
end
for (integer j = 0; j < `BANK_LINE_WORDS; j++) begin
for (integer i = 0; i < WORD_SIZE; i++) begin
if (write_enable[j][i]) begin
data[write_addr][j][i] <= write_data[j * `WORD_WIDTH + i * 8 +: 8];
end
end
end
end
end
endmodule
wire [(`BANK_LINE_WORDS * WORD_SIZE)-1:0] ram_wren;
assign ram_wren = write_enable & {(`BANK_LINE_WORDS * WORD_SIZE){!stall_bank_pipe}};
VX_dp_ram #(
.DATAW(`BANK_LINE_WORDS * WORD_SIZE * 8),
.SIZE(`BANK_LINE_COUNT),
.BYTEENW(`BANK_LINE_WORDS * WORD_SIZE),
.BUFFERED(0),
.RWCHECK(1)
) dp_ram (
.clk(clk),
.waddr(write_addr),
.raddr(read_addr),
.wren(ram_wren),
.rden(1'b1),
.din(write_data),
.dout(read_data)
);
endmodule