scope refactoring + snoop invalidate

This commit is contained in:
Blaise Tine
2020-06-12 00:04:31 -07:00
parent 19f263c772
commit d6b0ef2b3c
44 changed files with 652 additions and 589 deletions

View File

@@ -92,6 +92,7 @@ module VX_bank #(
// Snp Request
input wire snp_req_valid,
input wire [`LINE_ADDR_WIDTH-1:0] snp_req_addr,
input wire snp_req_invalidate,
input wire [SNP_REQ_TAG_WIDTH-1:0] snp_req_tag,
output wire snp_req_ready,
@@ -134,18 +135,19 @@ module VX_bank #(
wire snrq_full;
wire [`LINE_ADDR_WIDTH-1:0] snrq_addr_st0;
wire snrq_invalidate_st0;
wire [SNP_REQ_TAG_WIDTH-1:0] snrq_tag_st0;
VX_generic_queue #(
.DATAW(`LINE_ADDR_WIDTH + SNP_REQ_TAG_WIDTH),
.DATAW(`LINE_ADDR_WIDTH + 1 + SNP_REQ_TAG_WIDTH),
.SIZE(SNRQ_SIZE)
) snp_req_queue (
.clk (clk),
.reset (reset),
.push (snp_req_valid),
.data_in ({snp_req_addr, snp_req_tag}),
.data_in ({snp_req_addr, snp_req_invalidate, snp_req_tag}),
.pop (snrq_pop),
.data_out({snrq_addr_st0, snrq_tag_st0}),
.data_out({snrq_addr_st0, snrq_invalidate_st0, snrq_tag_st0}),
.empty (snrq_empty),
.full (snrq_full),
`UNUSED_PIN (size)
@@ -236,6 +238,7 @@ module VX_bank #(
wire mrvq_rw_st0;
wire [WORD_SIZE-1:0] mrvq_byteen_st0;
wire mrvq_is_snp_st0;
wire mrvq_snp_invalidate_st0;
wire mrvq_pending_hazard_st1e;
wire st2_pending_hazard_st1e;
@@ -295,6 +298,8 @@ module VX_bank #(
wire [`REQ_INST_META_WIDTH-1:0] qual_inst_meta_st0;
wire qual_going_to_write_st0;
wire qual_is_snp_st0;
wire qual_snp_invalidate_st0;
wire valid_st1 [STAGE_1_CYCLES-1:0];
wire [`LINE_ADDR_WIDTH-1:0] addr_st1 [STAGE_1_CYCLES-1:0];
@@ -303,6 +308,7 @@ module VX_bank #(
wire [`REQ_INST_META_WIDTH-1:0] inst_meta_st1 [STAGE_1_CYCLES-1:0];
wire [`BANK_LINE_WIDTH-1:0] writedata_st1 [STAGE_1_CYCLES-1:0];
wire is_snp_st1 [STAGE_1_CYCLES-1:0];
wire snp_invalidate_st1 [STAGE_1_CYCLES-1:0];
wire from_mrvq_st1 [STAGE_1_CYCLES-1:0];
assign qual_is_fill_st0 = dfpq_pop_unqual;
@@ -339,6 +345,10 @@ module VX_bank #(
snrq_pop_unqual ? 1 :
0;
assign qual_snp_invalidate_st0 = mrvq_pop_unqual ? mrvq_snp_invalidate_st0 :
snrq_pop_unqual ? snrq_invalidate_st0 :
0;
assign qual_writeword_st0 = mrvq_pop_unqual ? mrvq_writeword_st0 :
reqq_pop_unqual ? reqq_req_writeword_st0 :
0;
@@ -352,27 +362,27 @@ module VX_bank #(
)
VX_generic_register #(
.N(1 + 1 + 1 + 1 + `LINE_ADDR_WIDTH + `UP(`WORD_SELECT_WIDTH) + `WORD_WIDTH + `REQ_INST_META_WIDTH + 1 + `BANK_LINE_WIDTH)
.N(1 + 1 + 1 + 1 + 1 + `LINE_ADDR_WIDTH + `UP(`WORD_SELECT_WIDTH) + `WORD_WIDTH + `REQ_INST_META_WIDTH + 1 + `BANK_LINE_WIDTH)
) s0_1_c0 (
.clk (clk),
.reset (reset),
.stall (stall_bank_pipe),
.flush (1'b0),
.in ({qual_from_mrvq_st0, qual_is_snp_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 ({from_mrvq_st1[0] , is_snp_st1[0], going_to_write_st1[0], valid_st1[0], addr_st1[0], wsel_st1[0], writeword_st1[0], inst_meta_st1[0], is_fill_st1[0], writedata_st1[0]})
.in ({qual_from_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 ({from_mrvq_st1[0] , is_snp_st1[0], snp_invalidate_st1[0], going_to_write_st1[0], valid_st1[0], addr_st1[0], wsel_st1[0], writeword_st1[0], inst_meta_st1[0], is_fill_st1[0], writedata_st1[0]})
);
genvar i;
for (i = 1; i < STAGE_1_CYCLES; i++) begin
VX_generic_register #(
.N(1 + 1 + 1 + 1 + `LINE_ADDR_WIDTH + `UP(`WORD_SELECT_WIDTH) + `WORD_WIDTH + `REQ_INST_META_WIDTH + 1 + `BANK_LINE_WIDTH)
.N(1 + 1 + 1 + 1 + 1 + `LINE_ADDR_WIDTH + `UP(`WORD_SELECT_WIDTH) + `WORD_WIDTH + `REQ_INST_META_WIDTH + 1 + `BANK_LINE_WIDTH)
) s0_1_cc (
.clk (clk),
.reset(reset),
.stall(stall_bank_pipe),
.flush(1'b0),
.in ({from_mrvq_st1[i-1], is_snp_st1[i-1], going_to_write_st1[i-1], valid_st1[i-1], addr_st1[i-1], wsel_st1[i-1], writeword_st1[i-1], inst_meta_st1[i-1], is_fill_st1[i-1], writedata_st1[i-1]}),
.out ({from_mrvq_st1[i] , is_snp_st1[i], going_to_write_st1[i], valid_st1[i], addr_st1[i], wsel_st1[i], writeword_st1[i], inst_meta_st1[i], is_fill_st1[i], writedata_st1[i]})
.clk (clk),
.reset (reset),
.stall (stall_bank_pipe),
.flush (1'b0),
.in ({from_mrvq_st1[i-1], is_snp_st1[i-1], snp_invalidate_st1[i-1], going_to_write_st1[i-1], valid_st1[i-1], addr_st1[i-1], wsel_st1[i-1], writeword_st1[i-1], inst_meta_st1[i-1], is_fill_st1[i-1], writedata_st1[i-1]}),
.out ({from_mrvq_st1[i] , is_snp_st1[i], snp_invalidate_st1[i], going_to_write_st1[i], valid_st1[i], addr_st1[i], wsel_st1[i], writeword_st1[i], inst_meta_st1[i], is_fill_st1[i], writedata_st1[i]})
);
end
@@ -390,6 +400,7 @@ module VX_bank #(
wire [WORD_SIZE-1:0] mem_byteen_st1e;
wire fill_saw_dirty_st1e;
wire is_snp_st1e;
wire snp_invalidate_st1e;
wire snp_to_mrvq_st1e;
wire mrvq_init_ready_state_st1e;
wire miss_add_because_miss;
@@ -398,8 +409,9 @@ module VX_bank #(
wire mrvq_recover_ready_state_st1e;
assign from_mrvq_st1e = from_mrvq_st1[STAGE_1_CYCLES-1];
assign valid_st1e = valid_st1 [STAGE_1_CYCLES-1];
assign is_snp_st1e = is_snp_st1 [STAGE_1_CYCLES-1];
assign valid_st1e = valid_st1 [STAGE_1_CYCLES-1];
assign is_snp_st1e = is_snp_st1 [STAGE_1_CYCLES-1];
assign snp_invalidate_st1e = snp_invalidate_st1 [STAGE_1_CYCLES-1];
assign {tag_st1e, mem_rw_st1e, mem_byteen_st1e, tid_st1e} = inst_meta_st1[STAGE_1_CYCLES-1];
@@ -440,6 +452,7 @@ module VX_bank #(
.mem_byteen_st1e (mem_byteen_st1e),
.is_snp_st1e (is_snp_st1e),
.snp_invalidate_st1e (snp_invalidate_st1e),
// Read Data
.readword_st1e (readword_st1e),
@@ -473,6 +486,7 @@ module VX_bank #(
wire [`TAG_SELECT_BITS-1:0] readtag_st2;
wire fill_saw_dirty_st2;
wire is_snp_st2;
wire snp_invalidate_st2;
wire snp_to_mrvq_st2;
wire from_mrvq_st2;
wire mrvq_init_ready_state_st2;
@@ -482,14 +496,14 @@ module VX_bank #(
wire mrvq_init_ready_state_hazard_st1e_st1;
VX_generic_register #(
.N(1+ 1+ 1 + 1 + 1 + 1 + 1 + 1 + `LINE_ADDR_WIDTH + `UP(`WORD_SELECT_WIDTH) + `WORD_WIDTH + `WORD_WIDTH + `BANK_LINE_WIDTH + `TAG_SELECT_BITS + 1 + 1 + BANK_LINE_SIZE + `REQ_INST_META_WIDTH)
.N(1+ 1+ 1 + 1 + 1 + 1 + 1 + 1 + 1 + `LINE_ADDR_WIDTH + `UP(`WORD_SELECT_WIDTH) + `WORD_WIDTH + `WORD_WIDTH + `BANK_LINE_WIDTH + `TAG_SELECT_BITS + 1 + 1 + BANK_LINE_SIZE + `REQ_INST_META_WIDTH)
) st_1e_2 (
.clk (clk),
.reset(reset),
.stall(stall_bank_pipe),
.flush(1'b0),
.in ({mrvq_recover_ready_state_st1e, from_mrvq_st1e_st2, mrvq_init_ready_state_st1e , snp_to_mrvq_st1e, is_snp_st1e, fill_saw_dirty_st1e, is_fill_st1[STAGE_1_CYCLES-1] , qual_valid_st1e_2, addr_st1[STAGE_1_CYCLES-1], wsel_st1[STAGE_1_CYCLES-1], writeword_st1[STAGE_1_CYCLES-1], readword_st1e, readdata_st1e, readtag_st1e, miss_st1e, dirty_st1e, dirtyb_st1e, inst_meta_st1[STAGE_1_CYCLES-1]}),
.out ({mrvq_recover_ready_state_st2 , from_mrvq_st2 , mrvq_init_ready_state_unqual_st2, snp_to_mrvq_st2 , is_snp_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 })
.clk (clk),
.reset (reset),
.stall (stall_bank_pipe),
.flush (1'b0),
.in ({mrvq_recover_ready_state_st1e, from_mrvq_st1e_st2, mrvq_init_ready_state_st1e , snp_to_mrvq_st1e, is_snp_st1e, snp_invalidate_st1e, fill_saw_dirty_st1e, is_fill_st1[STAGE_1_CYCLES-1] , qual_valid_st1e_2, addr_st1[STAGE_1_CYCLES-1], wsel_st1[STAGE_1_CYCLES-1], writeword_st1[STAGE_1_CYCLES-1], readword_st1e, readdata_st1e, readtag_st1e, miss_st1e, dirty_st1e, dirtyb_st1e, inst_meta_st1[STAGE_1_CYCLES-1]}),
.out ({mrvq_recover_ready_state_st2 , from_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 })
);
`DEBUG_BLOCK(
@@ -517,7 +531,8 @@ module VX_bank #(
wire [`UP(`WORD_SELECT_WIDTH)-1:0] miss_add_wsel = wsel_st2;
wire [`WORD_WIDTH-1:0] miss_add_data = writeword_st2;
assign {miss_add_tag, miss_add_rw, miss_add_byteen, miss_add_tid} = inst_meta_st2;
wire miss_add_is_snp = is_snp_st2;
wire miss_add_is_snp = is_snp_st2;
wire miss_add_snp_invalidate = snp_invalidate_st2;
wire miss_add_from_mrvq = valid_st2 && from_mrvq_st2 && !stall_bank_pipe;
@@ -551,6 +566,7 @@ module VX_bank #(
.miss_add_rw (miss_add_rw),
.miss_add_byteen (miss_add_byteen),
.miss_add_is_snp (miss_add_is_snp),
.miss_add_snp_invalidate (miss_add_snp_invalidate),
.miss_resrv_full (mrvq_full),
.miss_resrv_stop (mrvq_stop),
.mrvq_init_ready_state (mrvq_init_ready_state_st2),
@@ -570,7 +586,8 @@ module VX_bank #(
.miss_resrv_tag_st0 (mrvq_tag_st0),
.miss_resrv_rw_st0 (mrvq_rw_st0),
.miss_resrv_byteen_st0 (mrvq_byteen_st0),
.miss_resrv_is_snp_st0 (mrvq_is_snp_st0)
.miss_resrv_is_snp_st0 (mrvq_is_snp_st0),
.miss_resrv_snp_invalidate_st0 (mrvq_snp_invalidate_st0)
);
// Enqueue core response
@@ -760,7 +777,7 @@ module VX_bank #(
$display("%t: bank%0d-%0d dram_fill rsp: addr=%0h, data=%0h", $time, CACHE_ID, BANK_ID, `LINE_TO_BYTE_ADDR(dram_fill_rsp_addr, BANK_ID), dram_fill_rsp_data);
end
if (snp_req_valid && snp_req_ready) begin
$display("%t: bank%0d-%0d snp req: addr=%0h, tag=%0h", $time, CACHE_ID, BANK_ID, `LINE_TO_BYTE_ADDR(snp_req_addr, BANK_ID), snp_req_tag);
$display("%t: bank%0d-%0d snp req: addr=%0h, invalidate=%0d, tag=%0h", $time, CACHE_ID, BANK_ID, `LINE_TO_BYTE_ADDR(snp_req_addr, BANK_ID), snp_req_invalidate, snp_req_tag);
end
if (snp_rsp_valid && snp_rsp_ready) begin
$display("%t: bank%0d-%0d snp rsp: tag=%0h", $time, CACHE_ID, BANK_ID, snp_rsp_tag);

View File

@@ -101,6 +101,7 @@ module VX_cache #(
// Snoop request
input wire snp_req_valid,
input wire [`DRAM_ADDR_WIDTH-1:0] snp_req_addr,
input wire snp_req_invalidate,
input wire [SNP_REQ_TAG_WIDTH-1:0] snp_req_tag,
output wire snp_req_ready,
@@ -112,6 +113,7 @@ module VX_cache #(
// Snoop Forwarding out
output wire [NUM_SNP_REQUESTS-1:0] snp_fwdout_valid,
output wire [NUM_SNP_REQUESTS-1:0][`DRAM_ADDR_WIDTH-1:0] snp_fwdout_addr,
output wire [NUM_SNP_REQUESTS-1:0] snp_fwdout_invalidate,
output wire [NUM_SNP_REQUESTS-1:0][SNP_FWD_TAG_WIDTH-1:0] snp_fwdout_tag,
`IGNORE_WARNINGS_BEGIN
input wire [NUM_SNP_REQUESTS-1:0] snp_fwdout_ready,
@@ -164,6 +166,7 @@ module VX_cache #(
wire snp_req_valid_qual;
wire [`DRAM_ADDR_WIDTH-1:0] snp_req_addr_qual;
wire snp_req_invalidate_qual;
wire [SNP_REQ_TAG_WIDTH-1:0] snp_req_tag_qual;
wire snp_req_ready_qual;
@@ -180,16 +183,19 @@ module VX_cache #(
.snp_req_valid (snp_req_valid),
.snp_req_addr (snp_req_addr),
.snp_req_invalidate (snp_req_invalidate),
.snp_req_tag (snp_req_tag),
.snp_req_ready (snp_req_ready),
.snp_rsp_valid (snp_req_valid_qual),
.snp_rsp_addr (snp_req_addr_qual),
.snp_rsp_invalidate (snp_req_invalidate_qual),
.snp_rsp_tag (snp_req_tag_qual),
.snp_rsp_ready (snp_req_ready_qual),
.snp_fwdout_valid (snp_fwdout_valid),
.snp_fwdout_addr (snp_fwdout_addr),
.snp_fwdout_invalidate(snp_fwdout_invalidate),
.snp_fwdout_tag (snp_fwdout_tag),
.snp_fwdout_ready (snp_fwdout_ready),
@@ -200,14 +206,16 @@ module VX_cache #(
end else begin
assign snp_fwdout_valid = 0;
assign snp_fwdout_addr = 0;
assign snp_fwdout_invalidate = 0;
assign snp_fwdout_tag = 0;
assign snp_fwdin_ready = 0;
assign snp_req_valid_qual = snp_req_valid;
assign snp_req_addr_qual = snp_req_addr;
assign snp_req_tag_qual = snp_req_tag;
assign snp_req_ready = snp_req_ready_qual;
assign snp_req_valid_qual = snp_req_valid;
assign snp_req_addr_qual = snp_req_addr;
assign snp_req_invalidate_qual = snp_req_invalidate;
assign snp_req_tag_qual = snp_req_tag;
assign snp_req_ready = snp_req_ready_qual;
end
if (NUM_BANKS == 1) begin
@@ -266,6 +274,7 @@ module VX_cache #(
wire curr_bank_snp_req_valid;
wire [`LINE_ADDR_WIDTH-1:0] curr_bank_snp_req_addr;
wire curr_bank_snp_req_invalidate;
wire [SNP_REQ_TAG_WIDTH-1:0] curr_bank_snp_req_tag;
wire curr_bank_snp_req_ready;
@@ -330,8 +339,9 @@ module VX_cache #(
assign curr_bank_snp_req_valid = snp_req_valid_qual && (`DRAM_ADDR_BANK(snp_req_addr_qual) == i);
assign curr_bank_snp_req_addr = `DRAM_TO_LINE_ADDR(snp_req_addr_qual);
end
assign curr_bank_snp_req_tag = snp_req_tag_qual;
assign per_bank_snp_req_ready[i] = curr_bank_snp_req_ready;
assign curr_bank_snp_req_invalidate = snp_req_invalidate_qual;
assign curr_bank_snp_req_tag = snp_req_tag_qual;
assign per_bank_snp_req_ready[i] = curr_bank_snp_req_ready;
// Snoop response
assign per_bank_snp_rsp_valid[i] = curr_bank_snp_rsp_valid;
@@ -400,6 +410,7 @@ module VX_cache #(
// Snoop request
.snp_req_valid (curr_bank_snp_req_valid),
.snp_req_addr (curr_bank_snp_req_addr),
.snp_req_invalidate (curr_bank_snp_req_invalidate),
.snp_req_tag (curr_bank_snp_req_tag),
.snp_req_ready (curr_bank_snp_req_ready),

View File

@@ -8,8 +8,8 @@
// tag rw byteen tid
`define REQ_INST_META_WIDTH (`REQ_TAG_WIDTH + 1 + WORD_SIZE + `REQS_BITS)
// data metadata word_sel is_snp
`define MRVQ_METADATA_WIDTH (`WORD_WIDTH + `REQ_INST_META_WIDTH + `UP(`WORD_SELECT_WIDTH) + 1)
// data metadata word_sel is_snp snp_invalidate
`define MRVQ_METADATA_WIDTH (`WORD_WIDTH + `REQ_INST_META_WIDTH + `UP(`WORD_SELECT_WIDTH) + 1 + 1)
`define BANK_BITS `LOG2UP(NUM_BANKS)

View File

@@ -33,6 +33,7 @@ module VX_cache_miss_resrv #(
input wire[WORD_SIZE-1:0] miss_add_byteen,
input wire mrvq_init_ready_state,
input wire miss_add_is_snp,
input wire miss_add_snp_invalidate,
output wire miss_resrv_full,
output wire miss_resrv_stop,
@@ -52,7 +53,8 @@ module VX_cache_miss_resrv #(
output wire[`REQ_TAG_WIDTH-1:0] miss_resrv_tag_st0,
output wire miss_resrv_rw_st0,
output wire[WORD_SIZE-1:0] miss_resrv_byteen_st0,
output wire miss_resrv_is_snp_st0
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];
reg [MRVQ_SIZE-1:0][`LINE_ADDR_WIDTH-1:0] addr_table;
@@ -91,7 +93,7 @@ module VX_cache_miss_resrv #(
assign miss_resrv_valid_st0 = dequeue_possible;
assign miss_resrv_addr_st0 = addr_table[dequeue_index];
assign {miss_resrv_data_st0, miss_resrv_tid_st0, miss_resrv_tag_st0, miss_resrv_rw_st0, miss_resrv_byteen_st0, miss_resrv_wsel_st0, miss_resrv_is_snp_st0} = metadata_table[dequeue_index];
assign {miss_resrv_data_st0, miss_resrv_tid_st0, miss_resrv_tag_st0, miss_resrv_rw_st0, miss_resrv_byteen_st0, miss_resrv_wsel_st0, miss_resrv_is_snp_st0, miss_resrv_snp_invalidate_st0} = metadata_table[dequeue_index];
wire mrvq_push = miss_add && enqueue_possible && !from_mrvq;
wire mrvq_pop = miss_resrv_pop && dequeue_possible;
@@ -119,7 +121,7 @@ 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};
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;
end else if (increment_head) begin
valid_table[head_ptr] <= 0;

View File

@@ -14,18 +14,21 @@ module VX_snp_forwarder #(
// Snoop request
input wire snp_req_valid,
input wire [`DRAM_ADDR_WIDTH-1:0] snp_req_addr,
input wire snp_req_invalidate,
input wire [SNP_REQ_TAG_WIDTH-1:0] snp_req_tag,
output wire snp_req_ready,
// Snoop response
output wire snp_rsp_valid,
output wire [`DRAM_ADDR_WIDTH-1:0] snp_rsp_addr,
output wire snp_rsp_invalidate,
output wire [SNP_REQ_TAG_WIDTH-1:0] snp_rsp_tag,
input wire snp_rsp_ready,
// Snoop Forwarding out
output wire [NUM_REQUESTS-1:0] snp_fwdout_valid,
output wire [NUM_REQUESTS-1:0][`DRAM_ADDR_WIDTH-1:0] snp_fwdout_addr,
output wire [NUM_REQUESTS-1:0] snp_fwdout_invalidate,
output wire [NUM_REQUESTS-1:0][`LOG2UP(SNRQ_SIZE)-1:0] snp_fwdout_tag,
input wire [NUM_REQUESTS-1:0] snp_fwdout_ready,
@@ -58,18 +61,18 @@ module VX_snp_forwarder #(
assign sfq_pop = snp_rsp_valid;
VX_indexable_queue #(
.DATAW (`LOG2UP(SNRQ_SIZE) + `DRAM_ADDR_WIDTH+SNP_REQ_TAG_WIDTH),
.DATAW (`LOG2UP(SNRQ_SIZE) + 1 +`DRAM_ADDR_WIDTH+SNP_REQ_TAG_WIDTH),
.SIZE (SNRQ_SIZE)
) snp_fwd_queue (
.clk (clk),
.reset (reset),
.write_data ({sfq_write_addr, snp_req_addr, snp_req_tag}),
.write_data ({sfq_write_addr, snp_req_addr, snp_req_invalidate, snp_req_tag}),
.write_addr (sfq_write_addr),
.push (sfq_push),
.full (sfq_full),
.pop (sfq_pop),
.read_addr (sfq_read_addr),
.read_data ({dbg_sfq_write_addr, snp_rsp_addr, snp_rsp_tag})
.read_data ({dbg_sfq_write_addr, snp_rsp_addr, snp_rsp_invalidate, snp_rsp_tag})
);
always @(posedge clk) begin
@@ -89,9 +92,10 @@ module VX_snp_forwarder #(
genvar i;
for (i = 0; i < NUM_REQUESTS; i++) begin
assign snp_fwdout_valid[i] = snp_req_valid && !sfq_full;
assign snp_fwdout_addr[i] = snp_req_addr;
assign snp_fwdout_tag[i] = sfq_write_addr;
assign snp_fwdout_valid[i] = snp_req_valid && !sfq_full;
assign snp_fwdout_addr[i] = snp_req_addr;
assign snp_fwdout_invalidate[i] = snp_req_invalidate;
assign snp_fwdout_tag[i] = sfq_write_addr;
end
assign snp_req_ready = !sfq_full && fwdout_ready;
@@ -114,16 +118,16 @@ module VX_snp_forwarder #(
`ifdef DBG_PRINT_CACHE_SNP
always_ff @(posedge clk) begin
if (snp_req_valid && snp_req_ready) begin
$display("%t: cache%0d snp req: addr=%0h, tag=%0h", $time, CACHE_ID, `DRAM_TO_BYTE_ADDR(snp_req_addr), snp_req_tag);
$display("%t: cache%0d snp req: addr=%0h, invalidate=%0d, tag=%0h", $time, CACHE_ID, `DRAM_TO_BYTE_ADDR(snp_req_addr), snp_req_invalidate, snp_req_tag);
end
if (snp_fwdout_valid[0] && snp_fwdout_ready[0]) begin
$display("%t: cache%0d snp fwd_out: addr=%0h, tag=%0h", $time, CACHE_ID, `DRAM_TO_BYTE_ADDR(snp_fwdout_addr[0]), snp_fwdout_tag[0]);
$display("%t: cache%0d snp fwd_out: addr=%0h, invalidate=%0d, tag=%0h", $time, CACHE_ID, `DRAM_TO_BYTE_ADDR(snp_fwdout_addr[0]), snp_fwdout_invalidate[0], snp_fwdout_tag[0]);
end
if (fwdin_valid && fwdin_ready) begin
$display("%t: cache%0d snp fwd_in[%01d]: tag=%0h", $time, CACHE_ID, fwdin_sel, fwdin_tag);
end
if (snp_rsp_valid && snp_rsp_ready) begin
$display("%t: cache%0d snp rsp: addr=%0h, tag=%0h", $time, CACHE_ID, snp_rsp_addr, snp_rsp_tag);
$display("%t: cache%0d snp rsp: addr=%0h, invalidate=%0d, tag=%0h", $time, CACHE_ID, snp_rsp_addr, snp_rsp_invalidate, snp_rsp_tag);
end
end
`endif

View File

@@ -23,6 +23,7 @@ module VX_tag_data_access #(
input wire reset,
input wire stall,
input wire is_snp_st1e,
input wire snp_invalidate_st1e,
input wire stall_bank_pipe,
input wire force_request_miss_st1e,
@@ -113,12 +114,12 @@ module VX_tag_data_access #(
.N(1 + 1 + BANK_LINE_SIZE + `TAG_SELECT_BITS + `BANK_LINE_WIDTH),
.PassThru(1)
) s0_1_c0 (
.clk (clk),
.reset(reset),
.stall(stall),
.flush(1'b0),
.in({qual_read_valid_st1, qual_read_dirty_st1, qual_read_dirtyb_st1, qual_read_tag_st1, qual_read_data_st1}),
.out({read_valid_st1c[0], read_dirty_st1c[0], read_dirtyb_st1c[0], read_tag_st1c[0], read_data_st1c[0]})
.clk (clk),
.reset (reset),
.stall (stall),
.flush (1'b0),
.in ({qual_read_valid_st1, qual_read_dirty_st1, qual_read_dirtyb_st1, qual_read_tag_st1, qual_read_data_st1}),
.out ({read_valid_st1c[0], read_dirty_st1c[0], read_dirtyb_st1c[0], read_tag_st1c[0], read_data_st1c[0]})
);
genvar i;
@@ -126,12 +127,12 @@ module VX_tag_data_access #(
VX_generic_register #(
.N( 1 + 1 + BANK_LINE_SIZE + `TAG_SELECT_BITS + `BANK_LINE_WIDTH)
) s0_1_cc (
.clk (clk),
.reset(reset),
.stall(stall),
.flush(1'b0),
.in({read_valid_st1c[i-1], read_dirty_st1c[i-1], read_dirtyb_st1c[i-1], read_tag_st1c[i-1], read_data_st1c[i-1]}),
.out({read_valid_st1c[i], read_dirty_st1c[i], read_dirtyb_st1c[i], read_tag_st1c[i], read_data_st1c[i]})
.clk (clk),
.reset (reset),
.stall (stall),
.flush (1'b0),
.in ({read_valid_st1c[i-1], read_dirty_st1c[i-1], read_dirtyb_st1c[i-1], read_tag_st1c[i-1], read_data_st1c[i-1]}),
.out ({read_valid_st1c[i], read_dirty_st1c[i], read_dirtyb_st1c[i], read_tag_st1c[i], read_data_st1c[i]})
);
end
@@ -174,20 +175,19 @@ module VX_tag_data_access #(
// use "case equality" to handle uninitialized tag when block entry is not valid
assign tags_match = ((writetag_st1e == use_read_tag_st1e) === 1'b1);
wire snoop_hit_no_pending = valid_req_st1e && is_snp_st1e && use_read_valid_st1e && tags_match && use_read_dirty_st1e && !force_request_miss_st1e;
wire snoop_hit_no_pending = valid_req_st1e && is_snp_st1e && use_read_valid_st1e && tags_match && (use_read_dirty_st1e || snp_invalidate_st1e) && !force_request_miss_st1e;
wire req_invalid = valid_req_st1e && !is_snp_st1e && !use_read_valid_st1e && !writefill_st1e;
wire req_miss = valid_req_st1e && !is_snp_st1e && use_read_valid_st1e && !writefill_st1e && !tags_match;
wire real_miss = req_invalid || req_miss;
wire force_core_miss = (force_request_miss_st1e && !is_snp_st1e && !writefill_st1e && valid_req_st1e && !real_miss);
assign snp_to_mrvq_st1e = valid_req_st1e && is_snp_st1e && force_request_miss_st1e;
// The second term is basically saying always make an entry ready if there's already antoher entry waiting, even if you yourself see a miss
assign mrvq_init_ready_state_st1e = snp_to_mrvq_st1e || (force_request_miss_st1e && !is_snp_st1e && !writefill_st1e && valid_req_st1e);
// assign mrvq_init_ready_state_st1e = snp_to_mrvq_st1e || force_core_miss;
assign mrvq_init_ready_state_st1e = snp_to_mrvq_st1e
|| (force_request_miss_st1e && !is_snp_st1e && !writefill_st1e && valid_req_st1e);
assign miss_st1e = real_miss || snoop_hit_no_pending || force_core_miss;
assign dirty_st1e = valid_req_st1e && use_read_valid_st1e && use_read_dirty_st1e;