snooping response handling fix

This commit is contained in:
Blaise Tine
2020-05-14 23:05:46 -04:00
parent bcb9514799
commit d623ef4029
13 changed files with 174 additions and 154 deletions

View File

@@ -140,11 +140,6 @@
`define DLLVQ_SIZE 0 `define DLLVQ_SIZE 0
`endif `endif
// Snoop Rsp Queue Size
`ifndef DSRPQ_SIZE
`define DSRPQ_SIZE 8
`endif
// Prefetcher // Prefetcher
`ifndef DPRFQ_SIZE `ifndef DPRFQ_SIZE
`define DPRFQ_SIZE 32 `define DPRFQ_SIZE 32
@@ -378,11 +373,6 @@
`define L2LLVQ_SIZE 32 `define L2LLVQ_SIZE 32
`endif `endif
// Snoop Rsp Queue Size
`ifndef L2SRPQ_SIZE
`define L2SRPQ_SIZE 8
`endif
// Prefetcher // Prefetcher
`ifndef L2PRFQ_SIZE `ifndef L2PRFQ_SIZE
`define L2PRFQ_SIZE 32 `define L2PRFQ_SIZE 32
@@ -464,11 +454,6 @@
`define L3LLVQ_SIZE 0 `define L3LLVQ_SIZE 0
`endif `endif
// Snoop Rsp Queue Size
`ifndef L3SRPQ_SIZE
`define L3SRPQ_SIZE 8
`endif
// Prefetcher // Prefetcher
`ifndef L3PRFQ_SIZE `ifndef L3PRFQ_SIZE
`define L3PRFQ_SIZE 32 `define L3PRFQ_SIZE 32

View File

@@ -67,7 +67,6 @@ module VX_dmem_ctrl # (
.DWBQ_SIZE (`SDWBQ_SIZE), .DWBQ_SIZE (`SDWBQ_SIZE),
.DFQQ_SIZE (`SDFQQ_SIZE), .DFQQ_SIZE (`SDFQQ_SIZE),
.LLVQ_SIZE (`SLLVQ_SIZE), .LLVQ_SIZE (`SLLVQ_SIZE),
.SRPQ_SIZE (0),
.PRFQ_SIZE (`SPRFQ_SIZE), .PRFQ_SIZE (`SPRFQ_SIZE),
.PRFQ_STRIDE (`SPRFQ_STRIDE), .PRFQ_STRIDE (`SPRFQ_STRIDE),
.FILL_INVALIDAOR_SIZE (`SFILL_INVALIDAOR_SIZE), .FILL_INVALIDAOR_SIZE (`SFILL_INVALIDAOR_SIZE),
@@ -151,7 +150,6 @@ module VX_dmem_ctrl # (
.DWBQ_SIZE (`DDWBQ_SIZE), .DWBQ_SIZE (`DDWBQ_SIZE),
.DFQQ_SIZE (`DDFQQ_SIZE), .DFQQ_SIZE (`DDFQQ_SIZE),
.LLVQ_SIZE (`DLLVQ_SIZE), .LLVQ_SIZE (`DLLVQ_SIZE),
.SRPQ_SIZE (`DSRPQ_SIZE),
.PRFQ_SIZE (`DPRFQ_SIZE), .PRFQ_SIZE (`DPRFQ_SIZE),
.PRFQ_STRIDE (`DPRFQ_STRIDE), .PRFQ_STRIDE (`DPRFQ_STRIDE),
.FILL_INVALIDAOR_SIZE (`DFILL_INVALIDAOR_SIZE), .FILL_INVALIDAOR_SIZE (`DFILL_INVALIDAOR_SIZE),
@@ -236,7 +234,6 @@ module VX_dmem_ctrl # (
.DWBQ_SIZE (`IDWBQ_SIZE), .DWBQ_SIZE (`IDWBQ_SIZE),
.DFQQ_SIZE (`IDFQQ_SIZE), .DFQQ_SIZE (`IDFQQ_SIZE),
.LLVQ_SIZE (`ILLVQ_SIZE), .LLVQ_SIZE (`ILLVQ_SIZE),
.SRPQ_SIZE (0),
.PRFQ_SIZE (`IPRFQ_SIZE), .PRFQ_SIZE (`IPRFQ_SIZE),
.PRFQ_STRIDE (`IPRFQ_STRIDE), .PRFQ_STRIDE (`IPRFQ_STRIDE),
.FILL_INVALIDAOR_SIZE (`IFILL_INVALIDAOR_SIZE), .FILL_INVALIDAOR_SIZE (`IFILL_INVALIDAOR_SIZE),

View File

@@ -62,14 +62,14 @@ module VX_lsu_unit #(
assign dcache_rsp_if.core_rsp_ready = ~no_slot_mem; assign dcache_rsp_if.core_rsp_ready = ~no_slot_mem;
assign {mem_wb_if.pc, mem_wb_if.wb, mem_wb_if.rd, mem_wb_if.warp_num} = dcache_rsp_if.core_rsp_tag; assign {mem_wb_if.pc, mem_wb_if.wb, mem_wb_if.rd, mem_wb_if.warp_num} = dcache_rsp_if.core_rsp_tag;
/*always_comb begin always_comb begin
if (1'($time & 1) && dcache_req_if.core_req_ready && (| dcache_req_if.core_req_valid)) begin if (1'($time & 1) && dcache_req_if.core_req_ready && (| dcache_req_if.core_req_valid)) begin
$display("*** %t: D%01d$ req: valid=%b, addr=%0h, tag=%0h, r=%0d, w=%0d, pc=%0h, rd=%0d, warp=%0d, data=%0h", $time, CORE_ID, use_valid, use_address, dcache_req_if.core_req_tag, use_mem_read, use_mem_write, use_pc, use_rd, use_warp_num, use_store_data); $display("*** %t: D%01d$ req: valid=%b, addr=%0h, tag=%0h, r=%0d, w=%0d, pc=%0h, rd=%0d, warp=%0d, data=%0h", $time, CORE_ID, use_valid, use_address, dcache_req_if.core_req_tag, use_mem_read, use_mem_write, use_pc, use_rd, use_warp_num, use_store_data);
end end
if (1'($time & 1) && dcache_rsp_if.core_rsp_ready && (| dcache_rsp_if.core_rsp_valid)) begin if (1'($time & 1) && dcache_rsp_if.core_rsp_ready && (| dcache_rsp_if.core_rsp_valid)) begin
$display("*** %t: D%01d$ rsp: valid=%b, tag=%0h, pc=%0h, rd=%0d, warp=%0d, data=%0h", $time, CORE_ID, mem_wb_if.valid, dcache_rsp_if.core_rsp_tag, mem_wb_if.pc, mem_wb_if.rd, mem_wb_if.warp_num, mem_wb_if.data); $display("*** %t: D%01d$ rsp: valid=%b, tag=%0h, pc=%0h, rd=%0d, warp=%0d, data=%0h", $time, CORE_ID, mem_wb_if.valid, dcache_rsp_if.core_rsp_tag, mem_wb_if.pc, mem_wb_if.rd, mem_wb_if.warp_num, mem_wb_if.data);
end end
end*/ end
endmodule endmodule

View File

@@ -253,7 +253,6 @@ module Vortex_Cluster #(
.DWBQ_SIZE (`L2DWBQ_SIZE), .DWBQ_SIZE (`L2DWBQ_SIZE),
.DFQQ_SIZE (`L2DFQQ_SIZE), .DFQQ_SIZE (`L2DFQQ_SIZE),
.LLVQ_SIZE (`L2LLVQ_SIZE), .LLVQ_SIZE (`L2LLVQ_SIZE),
.SRPQ_SIZE (`L2SRPQ_SIZE),
.PRFQ_SIZE (`L2PRFQ_SIZE), .PRFQ_SIZE (`L2PRFQ_SIZE),
.PRFQ_STRIDE (`L2PRFQ_STRIDE), .PRFQ_STRIDE (`L2PRFQ_STRIDE),
.FILL_INVALIDAOR_SIZE (`L2FILL_INVALIDAOR_SIZE), .FILL_INVALIDAOR_SIZE (`L2FILL_INVALIDAOR_SIZE),

View File

@@ -259,7 +259,6 @@ module Vortex_Socket (
.DWBQ_SIZE (`L3DWBQ_SIZE), .DWBQ_SIZE (`L3DWBQ_SIZE),
.DFQQ_SIZE (`L3DFQQ_SIZE), .DFQQ_SIZE (`L3DFQQ_SIZE),
.LLVQ_SIZE (`L3LLVQ_SIZE), .LLVQ_SIZE (`L3LLVQ_SIZE),
.SRPQ_SIZE (`L3SRPQ_SIZE),
.PRFQ_SIZE (`L3PRFQ_SIZE), .PRFQ_SIZE (`L3PRFQ_SIZE),
.PRFQ_STRIDE (`L3PRFQ_STRIDE), .PRFQ_STRIDE (`L3PRFQ_STRIDE),
.FILL_INVALIDAOR_SIZE (`L3FILL_INVALIDAOR_SIZE), .FILL_INVALIDAOR_SIZE (`L3FILL_INVALIDAOR_SIZE),
@@ -329,13 +328,13 @@ module Vortex_Socket (
); );
end end
/*always_comb begin always_comb begin
if (1'($time & 1) && (dram_req_read || dram_req_write) && dram_req_ready) begin if (1'($time & 1) && (dram_req_read || dram_req_write) && dram_req_ready) begin
$display("*** %t: DRAM req: w=%b addr=%0h, tag=%0h, data=%0h", $time, dram_req_write, {dram_req_addr, `CLOG2(`GLOBAL_BLOCK_SIZE)'(0)}, dram_req_tag, dram_req_data); $display("*** %t: DRAM req: w=%b addr=%0h, tag=%0h, data=%0h", $time, dram_req_write, {dram_req_addr, `CLOG2(`GLOBAL_BLOCK_SIZE)'(0)}, dram_req_tag, dram_req_data);
end end
if (1'($time & 1) && dram_rsp_valid && dram_rsp_ready) begin if (1'($time & 1) && dram_rsp_valid && dram_rsp_ready) begin
$display("*** %t: DRAM rsp: tag=%0h, data=%0h", $time, dram_rsp_tag, dram_rsp_data); $display("*** %t: DRAM rsp: tag=%0h, data=%0h", $time, dram_rsp_tag, dram_rsp_data);
end end
end*/ end
endmodule endmodule

197
hw/rtl/cache/VX_bank.v vendored
View File

@@ -34,9 +34,7 @@ module VX_bank #(
// Dram Fill Req Queue Size // Dram Fill Req Queue Size
parameter DFQQ_SIZE = 0, parameter DFQQ_SIZE = 0,
// Lower Level Cache Hit Queue Size // Lower Level Cache Hit Queue Size
parameter LLVQ_SIZE = 0, parameter LLVQ_SIZE = 0,
// Snoop Rsp Queue Size
parameter SRPQ_SIZE = 0,
// Fill Invalidator Size {Fill invalidator must be active} // Fill Invalidator Size {Fill invalidator must be active}
parameter FILL_INVALIDAOR_SIZE = 0, parameter FILL_INVALIDAOR_SIZE = 0,
@@ -218,10 +216,6 @@ module VX_bank #(
wire force_request_miss_st1e; wire force_request_miss_st1e;
`DEBUG_END `DEBUG_END
wire miss_add;
wire miss_add_unqual;
wire miss_add_because_miss;
wire miss_add_because_pending;
wire[`LINE_ADDR_WIDTH-1:0] miss_add_addr; wire[`LINE_ADDR_WIDTH-1:0] miss_add_addr;
wire[`BASE_ADDR_BITS-1:0] miss_add_wsel; wire[`BASE_ADDR_BITS-1:0] miss_add_wsel;
wire[`WORD_WIDTH-1:0] miss_add_data; wire[`WORD_WIDTH-1:0] miss_add_data;
@@ -233,7 +227,12 @@ module VX_bank #(
wire[`LINE_ADDR_WIDTH-1:0] addr_st2; wire[`LINE_ADDR_WIDTH-1:0] addr_st2;
wire is_fill_st2; wire is_fill_st2;
wire msrq_push_stall;
wire cwbq_push_stall;
wire dwbq_push_stall;
wire dram_fill_req_stall;
wire stall_bank_pipe; wire stall_bank_pipe;
reg is_fill_in_pipe; reg is_fill_in_pipe;
wire is_fill_st1 [STAGE_1_CYCLES-1:0]; wire is_fill_st1 [STAGE_1_CYCLES-1:0];
@@ -430,38 +429,26 @@ module VX_bank #(
.flush(0), .flush(0),
.in ({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, inst_meta_st1[STAGE_1_CYCLES-1]}), .in ({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, inst_meta_st1[STAGE_1_CYCLES-1]}),
.out ({mrvq_init_ready_state_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 , inst_meta_st2 }) .out ({mrvq_init_ready_state_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 , inst_meta_st2 })
); );
wire dram_fill_req_stall = (valid_st2 && miss_st2 && !invalidate_fill && ~dram_fill_req_ready);
wire dwbq_push;
wire dwbq_pop;
wire dwbq_empty;
wire dwbq_full;
wire cwbq_full;
wire srpq_full;
wire invalidate_fill;
wire miss_add_is_snp;
// Enqueue to miss reserv if it's a valid miss // Enqueue to miss reserv if it's a valid miss
assign miss_add_because_miss = valid_st2 && !is_snp_st2 && miss_st2; wire miss_add_because_miss = valid_st2 && !is_snp_st2 && miss_st2;
assign miss_add_because_pending = snp_to_mrvq_st2; wire miss_add_because_pending = snp_to_mrvq_st2;
assign miss_add_unqual = (miss_add_because_miss || miss_add_because_pending); wire miss_add_unqual = (miss_add_because_miss || miss_add_because_pending);
assign miss_add = miss_add_unqual assign msrq_push_stall = miss_add_unqual && mrvq_full;
wire miss_add = miss_add_unqual
&& !mrvq_full && !mrvq_full
&& !((snp_rsp_push_unqual && srpq_full) && !(cwbq_push_stall
|| (cwbq_push_unqual && cwbq_full) || dwbq_push_stall
|| (dwbq_push_unqual && dwbq_full) || dram_fill_req_stall);
|| dram_fill_req_stall);
assign miss_add_addr = addr_st2; wire miss_add_addr = addr_st2;
assign miss_add_wsel = wsel_st2; wire miss_add_wsel = wsel_st2;
assign miss_add_data = writeword_st2; wire miss_add_data = writeword_st2;
assign {miss_add_tag, miss_add_mem_read, miss_add_mem_write, miss_add_tid} = inst_meta_st2; assign {miss_add_tag, miss_add_mem_read, miss_add_mem_write, miss_add_tid} = inst_meta_st2;
assign miss_add_is_snp = is_snp_st2; wire miss_add_is_snp = is_snp_st2;
VX_cache_miss_resrv #( VX_cache_miss_resrv #(
.BANK_LINE_SIZE (BANK_LINE_SIZE), .BANK_LINE_SIZE (BANK_LINE_SIZE),
@@ -507,25 +494,26 @@ module VX_bank #(
.miss_resrv_is_snp_st0 (mrvq_is_snp_st0) .miss_resrv_is_snp_st0 (mrvq_is_snp_st0)
); );
// Enqueue to CWB Queue // Enqueue core response
wire cwbq_push;
wire cwbq_pop;
wire cwbq_empty;
wire cwbq_full;
wire cwbq_push_unqual = valid_st2 && !miss_st2 && !is_fill_st2 && !is_snp_st2; wire cwbq_push_unqual = valid_st2 && !miss_st2 && !is_fill_st2 && !is_snp_st2;
wire cwbq_push = cwbq_push_unqual assign cwbq_push_stall = cwbq_push_unqual && cwbq_full;
&& !cwbq_full
&& (miss_add_mem_write == `BYTE_EN_NO) assign cwbq_push = cwbq_push_unqual
&& !((snp_rsp_push_unqual && srpq_full) && !cwbq_full
|| (dwbq_push_unqual && dwbq_full) && (miss_add_mem_write == `BYTE_EN_NO)
|| (miss_add_unqual && mrvq_full) && !(dwbq_push_stall
|| dram_fill_req_stall); || msrq_push_stall
|| dram_fill_req_stall);
wire [`WORD_WIDTH-1:0] cwbq_data = readword_st2; wire [`WORD_WIDTH-1:0] cwbq_data = readword_st2;
wire [`REQS_BITS-1:0] cwbq_tid = miss_add_tid; wire [`REQS_BITS-1:0] cwbq_tid = miss_add_tid;
wire [CORE_TAG_WIDTH-1:0] cwbq_tag = CORE_TAG_WIDTH'(miss_add_tag); wire [CORE_TAG_WIDTH-1:0] cwbq_tag = CORE_TAG_WIDTH'(miss_add_tag);
wire cwbq_empty;
wire cwbq_pop;
assign core_rsp_valid = !cwbq_empty;
assign cwbq_pop = core_rsp_valid && core_rsp_ready;
VX_generic_queue #( VX_generic_queue #(
.DATAW(`REQS_BITS + CORE_TAG_WIDTH + `WORD_WIDTH), .DATAW(`REQS_BITS + CORE_TAG_WIDTH + `WORD_WIDTH),
@@ -541,20 +529,14 @@ module VX_bank #(
.data_out({core_rsp_tid, core_rsp_tag, core_rsp_data}), .data_out({core_rsp_tid, core_rsp_tag, core_rsp_data}),
.empty (cwbq_empty), .empty (cwbq_empty),
.full (cwbq_full) .full (cwbq_full)
); );
// Enqueue to DWB Queue assign core_rsp_valid = !cwbq_empty;
wire dwbq_push_unqual = ((valid_st2 && miss_st2 && dirty_st2) || fill_saw_dirty_st2); assign cwbq_pop = core_rsp_valid && core_rsp_ready;
assign dwbq_push = dwbq_push_unqual
&& !dwbq_full
&& !((snp_rsp_push_unqual && srpq_full)
|| (cwbq_push_unqual && cwbq_full)
|| (miss_add_unqual && mrvq_full)
|| dram_fill_req_stall);
wire [`BANK_LINE_WIDTH-1:0] dwbq_req_data = readdata_st2; // Enqueue DRAM fill request
wire [`LINE_ADDR_WIDTH-1:0] dwbq_req_addr = {readtag_st2, addr_st2[`LINE_SELECT_BITS-1:0]};
wire invalidate_fill;
wire possible_fill = valid_st2 && miss_st2 && dram_fill_req_ready && ~is_snp_st2; wire possible_fill = valid_st2 && miss_st2 && dram_fill_req_ready && ~is_snp_st2;
wire [`LINE_ADDR_WIDTH-1:0] fill_invalidator_addr = addr_st2; wire [`LINE_ADDR_WIDTH-1:0] fill_invalidator_addr = addr_st2;
@@ -571,73 +553,78 @@ module VX_bank #(
.invalidate_fill (invalidate_fill) .invalidate_fill (invalidate_fill)
); );
// Enqueue in dram_fill_req
assign dram_fill_req_valid = possible_fill && !invalidate_fill; assign dram_fill_req_valid = possible_fill && !invalidate_fill;
assign dram_fill_req_addr = addr_st2; assign dram_fill_req_addr = addr_st2;
assign dram_fill_req_stall = (valid_st2 && miss_st2 && !invalidate_fill && ~dram_fill_req_ready);
assign dram_wb_req_valid = !dwbq_empty; // Enqueue DRAM writeback request
assign dwbq_pop = dram_wb_req_valid && dram_wb_req_ready; wire dwbq_push;
wire dwbq_pop;
wire dwbq_empty;
wire dwbq_full;
wire dwbq_is_dwb_in, dwbq_is_snp_in;
wire dwbq_is_dwb_out, dwbq_is_snp_out;
assign dwbq_is_snp_in = is_snp_st2 && valid_st2 && !snp_to_mrvq_st2;
assign dwbq_is_dwb_in = (valid_st2 && miss_st2 && dirty_st2) || fill_saw_dirty_st2;
wire dwbq_push_unqual = dwbq_is_dwb_in || dwbq_is_snp_in;
assign dwbq_push_stall = dwbq_push_unqual && dwbq_full;
assign dwbq_push = dwbq_push_unqual
&& !dwbq_full
&& !(cwbq_push_stall
|| msrq_push_stall
|| dram_fill_req_stall);
wire [`BANK_LINE_WIDTH-1:0] dwbq_req_data = readdata_st2;
wire [`LINE_ADDR_WIDTH-1:0] dwbq_req_addr = {readtag_st2, addr_st2[`LINE_SELECT_BITS-1:0]};
wire [SNP_REQ_TAG_WIDTH-1:0] snrq_tag_st2 = SNP_REQ_TAG_WIDTH'(miss_add_tag);
VX_generic_queue #( VX_generic_queue #(
.DATAW(`LINE_ADDR_WIDTH + `BANK_LINE_WIDTH), .DATAW(1 + 1 + `LINE_ADDR_WIDTH + `BANK_LINE_WIDTH + SNP_REQ_TAG_WIDTH),
.SIZE(DWBQ_SIZE) .SIZE(DWBQ_SIZE)
) dwb_queue ( ) dwb_queue (
.clk (clk), .clk (clk),
.reset (reset), .reset (reset),
.push (dwbq_push), .push (dwbq_push),
.data_in ({dwbq_req_addr, dwbq_req_data}), .data_in ({dwbq_is_dwb_in, dwbq_is_snp_in, dwbq_req_addr, dwbq_req_data, snrq_tag_st2}),
.pop (dwbq_pop), .pop (dwbq_pop),
.data_out({dram_wb_req_addr, dram_wb_req_data}), .data_out({dwbq_is_dwb_out, dwbq_is_snp_out, dram_wb_req_addr, dram_wb_req_data, snp_rsp_tag}),
.empty (dwbq_empty), .empty (dwbq_empty),
.full (dwbq_full) .full (dwbq_full)
); );
wire srpq_push; wire dram_wb_req_fire = dram_wb_req_valid && dram_wb_req_ready;
wire srpq_pop; wire snp_rsp_fire = snp_rsp_valid && snp_rsp_ready;
wire srpq_empty;
wire snp_rsp_push_unqual = is_snp_st2 && valid_st2 && !snp_to_mrvq_st2; reg dwbq_dual_valid_sel;
always @(posedge clk) begin
if (reset) begin
dwbq_dual_valid_sel <= 0;
end else if (dwbq_is_dwb_out && dwbq_is_snp_out && (dram_wb_req_fire || snp_rsp_fire)) begin
dwbq_dual_valid_sel <= ~dwbq_dual_valid_sel;
end
end
// when both dwb and snp are asserted, first release the cwb, then release the snp.
assign dram_wb_req_valid = ~dwbq_empty && dwbq_is_dwb_out && (~dwbq_is_snp_out || dwbq_dual_valid_sel == 0);
assign snp_rsp_valid = ~dwbq_empty && dwbq_is_snp_out && (~dwbq_is_dwb_out || dwbq_dual_valid_sel == 1);
wire [SNP_REQ_TAG_WIDTH-1:0] snrq_tag_st2 = SNP_REQ_TAG_WIDTH'(miss_add_tag); assign dwbq_pop = (dwbq_is_dwb_out && ~dwbq_is_snp_out && dram_wb_req_fire)
|| (dwbq_is_snp_out && ~dwbq_is_dwb_out && snp_rsp_fire)
|| (dwbq_is_dwb_out && dwbq_is_snp_out && snp_rsp_fire);
assign srpq_push = snp_rsp_push_unqual // bank pipeline stall
&& !srpq_full assign stall_bank_pipe = cwbq_push_stall
&& !((cwbq_push_unqual && cwbq_full) || dwbq_push_stall
|| (dwbq_push_unqual && dwbq_full) || msrq_push_stall
|| (miss_add_unqual && mrvq_full)
|| dram_fill_req_stall);
assign srpq_pop = snp_rsp_valid && snp_rsp_ready;
assign snp_rsp_valid = !srpq_empty;
VX_generic_queue #(
.DATAW(SNP_REQ_TAG_WIDTH),
.SIZE(SRPQ_SIZE)
) snp_rsp_queue (
.clk (clk),
.reset (reset),
.push (srpq_push),
.data_in (snrq_tag_st2),
.pop (srpq_pop),
.data_out(snp_rsp_tag),
.empty (srpq_empty),
.full (srpq_full)
);
assign stall_bank_pipe = (snp_rsp_push_unqual && srpq_full)
|| (cwbq_push_unqual && cwbq_full)
|| (dwbq_push_unqual && dwbq_full)
|| (miss_add_unqual && mrvq_full)
|| dram_fill_req_stall; || dram_fill_req_stall;
/*always_comb begin
if (1'($time & 1) && snp_rsp_push) begin
$display("*** %t: bank%01d:%01d snp rsp in: addr=%0h, tag=%0h", $time, CACHE_ID, BANK_ID, addr_st2, snrq_tag_st2);
end
end*/
endmodule : VX_bank endmodule : VX_bank

View File

@@ -34,9 +34,7 @@ module VX_cache #(
// Dram Fill Req Queue Size // Dram Fill Req Queue Size
parameter DFQQ_SIZE = 8, parameter DFQQ_SIZE = 8,
// Lower Level Cache Hit Queue Size // Lower Level Cache Hit Queue Size
parameter LLVQ_SIZE = 16, parameter LLVQ_SIZE = 16,
// Snoop Rsp Queue Size
parameter SRPQ_SIZE = 8,
// Fill Invalidator Size {Fill invalidator must be active} // Fill Invalidator Size {Fill invalidator must be active}
parameter FILL_INVALIDAOR_SIZE = 16, parameter FILL_INVALIDAOR_SIZE = 16,
@@ -323,7 +321,6 @@ module VX_cache #(
.DWBQ_SIZE (DWBQ_SIZE), .DWBQ_SIZE (DWBQ_SIZE),
.DFQQ_SIZE (DFQQ_SIZE), .DFQQ_SIZE (DFQQ_SIZE),
.LLVQ_SIZE (LLVQ_SIZE), .LLVQ_SIZE (LLVQ_SIZE),
.SRPQ_SIZE (SRPQ_SIZE),
.FILL_INVALIDAOR_SIZE (FILL_INVALIDAOR_SIZE), .FILL_INVALIDAOR_SIZE (FILL_INVALIDAOR_SIZE),
.DRAM_ENABLE (DRAM_ENABLE), .DRAM_ENABLE (DRAM_ENABLE),
.WRITE_ENABLE (WRITE_ENABLE), .WRITE_ENABLE (WRITE_ENABLE),
@@ -428,6 +425,8 @@ module VX_cache #(
.BANK_LINE_SIZE (BANK_LINE_SIZE), .BANK_LINE_SIZE (BANK_LINE_SIZE),
.SNP_REQ_TAG_WIDTH (SNP_REQ_TAG_WIDTH) .SNP_REQ_TAG_WIDTH (SNP_REQ_TAG_WIDTH)
) snp_rsp_arb ( ) snp_rsp_arb (
//.clk(clk),
//.reset(reset),
.per_bank_snp_rsp_valid (per_bank_snp_rsp_valid), .per_bank_snp_rsp_valid (per_bank_snp_rsp_valid),
.per_bank_snp_rsp_tag (per_bank_snp_rsp_tag), .per_bank_snp_rsp_tag (per_bank_snp_rsp_tag),
.per_bank_snp_rsp_ready (per_bank_snp_rsp_ready), .per_bank_snp_rsp_ready (per_bank_snp_rsp_ready),

View File

@@ -20,17 +20,16 @@ module VX_cache_dfq_queue #(
output wire dfqq_empty, output wire dfqq_empty,
output wire dfqq_full output wire dfqq_full
); );
wire[NUM_BANKS-1:0] out_per_bank_dram_fill_req_valid;
wire[NUM_BANKS-1:0][`DRAM_ADDR_WIDTH-1:0] out_per_bank_dram_fill_req_addr;
reg [NUM_BANKS-1:0] use_per_bank_dram_fill_req_valid; reg [NUM_BANKS-1:0] use_per_bank_dram_fill_req_valid;
reg [NUM_BANKS-1:0][`DRAM_ADDR_WIDTH-1:0] use_per_bank_dram_fill_req_addr; reg [NUM_BANKS-1:0][`DRAM_ADDR_WIDTH-1:0] use_per_bank_dram_fill_req_addr;
wire[NUM_BANKS-1:0] use_per_bqual_bank_dram_fill_req_valid; wire [NUM_BANKS-1:0] out_per_bank_dram_fill_req_valid;
wire[NUM_BANKS-1:0][`DRAM_ADDR_WIDTH-1:0] qual_bank_dram_fill_req_addr; wire [NUM_BANKS-1:0][`DRAM_ADDR_WIDTH-1:0] out_per_bank_dram_fill_req_addr;
wire[NUM_BANKS-1:0] updated_bank_dram_fill_req_valid; wire [NUM_BANKS-1:0] use_per_bqual_bank_dram_fill_req_valid;
wire [NUM_BANKS-1:0][`DRAM_ADDR_WIDTH-1:0] qual_bank_dram_fill_req_addr;
wire [NUM_BANKS-1:0] updated_bank_dram_fill_req_valid;
wire o_empty; wire o_empty;

View File

@@ -89,21 +89,22 @@ module VX_cache_dram_req_arb #(
.dfqq_full (dfqq_full) .dfqq_full (dfqq_full)
); );
wire [`BANK_BITS-1:0] dwb_bank; assign dram_fill_req_ready = ~dfqq_full;
wire [NUM_BANKS-1:0] use_wb_valid = per_bank_dram_wb_req_valid; wire [`BANK_BITS-1:0] dwb_bank;
VX_generic_priority_encoder #( VX_generic_priority_encoder #(
.N(NUM_BANKS) .N(NUM_BANKS)
) sel_dwb ( ) sel_dwb (
.valids(use_wb_valid), .valids(per_bank_dram_wb_req_valid),
.index (dwb_bank), .index (dwb_bank),
.found (dwb_valid) .found (dwb_valid)
); );
assign dram_fill_req_ready = ~dfqq_full; genvar i;
for (i = 0; i < NUM_BANKS; i++) begin
assign per_bank_dram_wb_req_ready = dram_req_ready ? (use_wb_valid & ((1 << dwb_bank))) : 0; assign per_bank_dram_wb_req_ready[i] = dram_req_ready && (dwb_bank == `BANK_BITS'(i));
end
wire dram_req_valid = dwb_valid || dfqq_req || pref_pop; wire dram_req_valid = dwb_valid || dfqq_req || pref_pop;

View File

@@ -112,7 +112,7 @@ module VX_snp_forwarder #(
assign snp_fwdin_ready[i] = fwdin_ready && (fwdin_sel == `REQS_BITS'(i)); assign snp_fwdin_ready[i] = fwdin_ready && (fwdin_sel == `REQS_BITS'(i));
end end
/*9always_comb begin always_comb begin
if (1'($time & 1) && snp_req_valid && snp_req_ready) begin if (1'($time & 1) && snp_req_valid && snp_req_ready) begin
$display("*** %t: snp req: addr=%0h, tag=%0h", $time, snp_req_addr, snp_req_tag); $display("*** %t: snp req: addr=%0h, tag=%0h", $time, snp_req_addr, snp_req_tag);
end end
@@ -125,6 +125,6 @@ module VX_snp_forwarder #(
if (1'($time & 1) && snp_rsp_valid && snp_rsp_ready) begin if (1'($time & 1) && snp_rsp_valid && snp_rsp_ready) begin
$display("*** %t: snp rsp: addr=%0h, tag=%0h", $time, snp_rsp_addr, snp_rsp_tag); $display("*** %t: snp rsp: addr=%0h, tag=%0h", $time, snp_rsp_addr, snp_rsp_tag);
end end
end*/ end
endmodule endmodule

View File

@@ -14,15 +14,13 @@ module VX_snp_rsp_arb #(
input wire snp_rsp_ready input wire snp_rsp_ready
); );
wire [NUM_BANKS-1:0] qual_per_bank_snp_rsp = per_bank_snp_rsp_valid & {NUM_BANKS{snp_rsp_ready}};
wire [`BANK_BITS-1:0] fsq_bank; wire [`BANK_BITS-1:0] fsq_bank;
wire fsq_valid; wire fsq_valid;
VX_generic_priority_encoder #( VX_generic_priority_encoder #(
.N(NUM_BANKS) .N(NUM_BANKS)
) sel_ffsq ( ) sel_ffsq (
.valids (qual_per_bank_snp_rsp), .valids (per_bank_snp_rsp_valid),
.index (fsq_bank), .index (fsq_bank),
.found (fsq_valid) .found (fsq_valid)
); );
@@ -32,7 +30,7 @@ module VX_snp_rsp_arb #(
genvar i; genvar i;
for (i = 0; i < NUM_BANKS; i++) begin for (i = 0; i < NUM_BANKS; i++) begin
assign per_bank_snp_rsp_ready[i] = fsq_valid && (fsq_bank == `BANK_BITS'(i)); assign per_bank_snp_rsp_ready[i] = snp_rsp_ready && (fsq_bank == `BANK_BITS'(i));
end end
endmodule endmodule

View File

@@ -0,0 +1,56 @@
`include "VX_define.vh"
module VX_matrix_arbiter #(
parameter N = 0
) (
input wire clk,
input wire reset,
input wire [N-1:0] inputs,
output wire [N-1:0] grant
);
reg [N-1:1][N-1:0] pri;
always @(posedge clk) begin
if (reset) begin
integer i, j;
for (i = 0; i < N; ++i) begin
for (j = 0; j < N; ++j) begin
pri[i][j] <= 1;
end
end
end else begin
integer i, j;
for (i = 0; i < N; ++i) begin
if (grant[i]) begin
for (j = 0; j < N; ++j) begin
if (j > i)
pri[j][i] <= 1;
else if (j < i)
pri[i][j] <= 0;
end
end
end
end
end
genvar i, j;
for (i = 0; i < N; ++i) begin
wire [N-1:0] dis;
for (j = 0; j < N; ++j) begin
if (j > i) begin
assign dis[j] = inputs[j] & pri[j][i];
end else if (j < i) begin
assign dis[j] = inputs[j] & ~pri[i][j];
end else begin
assign dis[j] = 0;
end
end
assign grant[i] = inputs[i] & ~(| dis);
end
endmodule

View File

@@ -16,7 +16,7 @@ module VX_priority_encoder #(
found_r = 0; found_r = 0;
for (i = `NUM_WARPS-1; i >= 0; i = i - 1) begin for (i = `NUM_WARPS-1; i >= 0; i = i - 1) begin
if (valids[i]) begin if (valids[i]) begin
index_r = i[`NW_BITS-1:0]; index_r = `NW_BITS'(i);
found_r = 1; found_r = 1;
end end
end end