pipeline refactoring: centralized issue buffer

This commit is contained in:
Blaise Tine
2020-07-26 11:21:08 -04:00
parent 1f63f9da25
commit 7c86b68977
62 changed files with 923 additions and 820 deletions

View File

@@ -513,8 +513,8 @@ module VX_bank #(
.reset (reset),
.stall (stall_bank_pipe),
.flush (0),
.in ({mrvq_recover_ready_state_st1e, is_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_st1e, 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 , 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 })
.in ({mrvq_recover_ready_state_st1e, is_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_st1e, 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 , 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})
);
`ifdef DBG_CORE_REQ_INFO
@@ -587,7 +587,7 @@ module VX_bank #(
// Broadcast
.is_fill_st1 (is_fill_st1[STAGE_1_CYCLES-1]),
.fill_addr_st1 (addr_st1e),
.pending_hazard (mrvq_pending_hazard_st1e),
.pending_hazard_st1 (mrvq_pending_hazard_st1e),
// Dequeue
.miss_resrv_pop (mrvq_pop),

View File

@@ -133,7 +133,7 @@ module VX_cache #(
wire debug_core_req_wb;
wire[`NR_BITS-1:0] debug_core_req_rd;
wire[`NW_BITS-1:0] debug_core_req_warp_num;
wire[`LOG2UP(CREQ_SIZE)-1:0] debug_core_req_idx;
wire[`UP(CORE_TAG_ID_BITS)-1:0] debug_core_req_idx;
/* verilator lint_on UNUSED */
if (WORD_SIZE != `GLOBAL_BLOCK_SIZE) begin

View File

@@ -41,7 +41,7 @@ module VX_cache_miss_resrv #(
input wire is_fill_st1,
input wire[`LINE_ADDR_WIDTH-1:0] fill_addr_st1,
output wire pending_hazard,
output wire pending_hazard_st1,
// Miss dequeue
input wire miss_resrv_pop,
@@ -84,7 +84,7 @@ module VX_cache_miss_resrv #(
assign make_ready[i] = is_fill_st1 && valid_address_match[i];
end
assign pending_hazard = |(valid_address_match);
assign pending_hazard_st1 = |(valid_address_match);
wire dequeue_possible = valid_table[schedule_ptr] && ready_table[schedule_ptr];
wire [`LOG2UP(MRVQ_SIZE)-1:0] dequeue_index = schedule_ptr;

View File

@@ -41,8 +41,8 @@ module VX_snp_forwarder #(
reg [`REQS_BITS:0] pending_cntrs [SNRQ_SIZE-1:0];
wire [`LOG2UP(SNRQ_SIZE)-1:0] sfq_write_addr, sfq_read_addr, dbg_sfq_write_addr;
wire sfq_push, sfq_pop, sfq_full;
wire [`LOG2UP(SNRQ_SIZE)-1:0] sfq_write_addr, sfq_read_addr;
wire sfq_acquire, sfq_release, sfq_full;
wire fwdin_valid;
wire [`LOG2UP(SNRQ_SIZE)-1:0] fwdin_tag;
@@ -56,27 +56,26 @@ module VX_snp_forwarder #(
assign sfq_read_addr = fwdin_tag;
assign sfq_push = snp_req_valid && !sfq_full && fwdout_ready;
assign sfq_pop = snp_rsp_valid;
assign sfq_acquire = snp_req_valid && !sfq_full && fwdout_ready;
assign sfq_release = snp_rsp_valid;
VX_index_queue #(
.DATAW (`LOG2UP(SNRQ_SIZE) + 1 +`DRAM_ADDR_WIDTH+SNP_REQ_TAG_WIDTH),
VX_cam_buffer #(
.DATAW (`DRAM_ADDR_WIDTH + 1 + SNP_REQ_TAG_WIDTH),
.SIZE (SNRQ_SIZE)
) snp_fwd_queue (
.clk (clk),
.reset (reset),
.write_data ({snp_req_addr, snp_req_invalidate, snp_req_tag}),
.write_addr (sfq_write_addr),
.push (sfq_push),
.pop (sfq_pop),
.full (sfq_full),
.read_addr (sfq_read_addr),
.read_data ({snp_rsp_addr, snp_rsp_invalidate, snp_rsp_tag}),
`UNUSED_PIN (empty)
) snp_fwd_buffer (
.clk (clk),
.reset (reset),
.write_data ({snp_req_addr, snp_req_invalidate, snp_req_tag}),
.write_addr (sfq_write_addr),
.acquire_slot (sfq_acquire),
.release_slot (sfq_release),
.read_addr (sfq_read_addr),
.read_data ({snp_rsp_addr, snp_rsp_invalidate, snp_rsp_tag}),
.full (sfq_full)
);
always @(posedge clk) begin
if (sfq_push) begin
if (sfq_acquire) begin
pending_cntrs[sfq_write_addr] <= NUM_REQUESTS;
end
if (fwdin_fire) begin

View File

@@ -2,25 +2,26 @@
module VX_tag_data_access #(
// Size of cache in bytes
parameter CACHE_SIZE = 0,
parameter CACHE_SIZE = 0,
// Size of line inside a bank in bytes
parameter BANK_LINE_SIZE = 0,
parameter BANK_LINE_SIZE = 0,
// Number of banks {1, 2, 4, 8,...}
parameter NUM_BANKS = 0,
parameter NUM_BANKS = 0,
// Size of a word in bytes
parameter WORD_SIZE = 0,
parameter WORD_SIZE = 0,
// Number of cycles to complete stage 1 (read from memory)
parameter STAGE_1_CYCLES = 0,
parameter STAGE_1_CYCLES = 0,
// Enable cache writeable
parameter WRITE_ENABLE = 0,
parameter WRITE_ENABLE = 0,
// Enable dram update
parameter DRAM_ENABLE = 0
parameter DRAM_ENABLE = 0
) (
input wire clk,
input wire reset,
input wire stall,
input wire is_snp_st1e,
input wire snp_invalidate_st1e,
@@ -78,17 +79,17 @@ module VX_tag_data_access #(
wire tags_match;
wire real_writefill = valid_req_st1e && writefill_st1e
&& ((!use_read_valid_st1e) || (use_read_valid_st1e && !tags_match));
&& ((~use_read_valid_st1e) || (use_read_valid_st1e && ~tags_match));
wire[`TAG_SELECT_BITS-1:0] writetag_st1e = writeaddr_st1e[`TAG_LINE_ADDR_RNG];
wire[`LINE_SELECT_BITS-1:0] writeladdr_st1e = writeaddr_st1e[`LINE_SELECT_BITS-1:0];
VX_tag_data_structure #(
VX_tag_data_store #(
.CACHE_SIZE (CACHE_SIZE),
.BANK_LINE_SIZE (BANK_LINE_SIZE),
.NUM_BANKS (NUM_BANKS),
.WORD_SIZE (WORD_SIZE)
) tag_data_structure (
) tag_data_store (
.clk (clk),
.reset (reset),
.stall_bank_pipe(stall_bank_pipe),
@@ -141,10 +142,12 @@ module VX_tag_data_access #(
assign use_read_dirtyb_st1e= read_dirtyb_st1c[STAGE_1_CYCLES-1];
assign use_read_data_st1e = read_data_st1c[STAGE_1_CYCLES-1];
if (`WORD_SELECT_WIDTH != 0) begin
assign readword_st1e = use_read_data_st1e[wordsel_st1e * `WORD_WIDTH +: `WORD_WIDTH];
end else begin
assign readword_st1e = use_read_data_st1e;
for (i = 0; i < WORD_SIZE; i++) begin
if (`WORD_SELECT_WIDTH != 0) begin
assign readword_st1e[i * 8 +: 8] = use_read_data_st1e[wordsel_st1e * `WORD_WIDTH +: `WORD_WIDTH][i * 8 +: 8] & {8{mem_byteen_st1e[i]}};
end else begin
assign readword_st1e[i * 8 +: 8] = use_read_data_st1e[i * 8 +: 8] & {8{mem_byteen_st1e[i]}};
end
end
wire [`BANK_LINE_WORDS-1:0][WORD_SIZE-1:0] we;
@@ -153,9 +156,9 @@ module VX_tag_data_access #(
wire should_write = mem_rw_st1e
&& valid_req_st1e
&& use_read_valid_st1e
&& !miss_st1e
&& !is_snp_st1e
&& !real_writefill;
&& ~miss_st1e
&& ~is_snp_st1e
&& ~real_writefill;
for (i = 0; i < `BANK_LINE_WORDS; i++) begin
wire normal_write = ((`WORD_SELECT_WIDTH == 0) || (wordsel_st1e == `UP(`WORD_SELECT_WIDTH)'(i)))
@@ -168,22 +171,22 @@ module VX_tag_data_access #(
assign data_write[i * `WORD_WIDTH +: `WORD_WIDTH] = real_writefill ? writedata_st1e[i * `WORD_WIDTH +: `WORD_WIDTH] : writeword_st1e;
end
assign use_write_enable = (writefill_st1e && !real_writefill) ? 0 : we;
assign use_write_enable = (writefill_st1e && ~real_writefill) ? 0 : we;
assign use_write_data = data_write;
// use "case equality" to handle uninitialized tag when block entry is not valid
assign tags_match = (writetag_st1e === use_read_tag_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 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);
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);
|| (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;
@@ -194,7 +197,4 @@ module VX_tag_data_access #(
assign fill_saw_dirty_st1e = real_writefill && dirty_st1e;
assign invalidate_line = snoop_hit_no_pending;
endmodule
endmodule

View File

@@ -1,6 +1,6 @@
`include "VX_cache_config.vh"
module VX_tag_data_structure #(
module VX_tag_data_store #(
// Size of cache in bytes
parameter CACHE_SIZE = 0,
// Size of line inside a bank in bytes