From 13c6cbfa5dc926d2b6069fb30b466dd44633e7cb Mon Sep 17 00:00:00 2001 From: felsabbagh3 Date: Tue, 10 Mar 2020 02:41:47 -0700 Subject: [PATCH] L3 and CLUSTRING WORKS --- rtl/VX_cache/VX_bank.v | 29 +- rtl/VX_cache/VX_cache.v | 57 ++- rtl/VX_cache/VX_cache_req_queue.v | 55 +-- rtl/VX_cache/VX_cache_wb_sel_merge.v | 18 +- rtl/VX_cache/VX_snp_fwd_arb.v | 39 ++ rtl/VX_define.v | 22 +- rtl/VX_dmem_controller.v | 31 +- rtl/Vortex.v | 31 ++ rtl/Vortex_SOC.v | 584 ++++++++++++++++++--------- rtl/interfaces/VX_gpu_snp_req_rsp.v | 20 + rtl/simulate/multi_test_bench.h | 30 +- 11 files changed, 654 insertions(+), 262 deletions(-) create mode 100644 rtl/VX_cache/VX_snp_fwd_arb.v create mode 100644 rtl/interfaces/VX_gpu_snp_req_rsp.v diff --git a/rtl/VX_cache/VX_bank.v b/rtl/VX_cache/VX_bank.v index d61a0b9c..d61cc297 100644 --- a/rtl/VX_cache/VX_bank.v +++ b/rtl/VX_cache/VX_bank.v @@ -98,9 +98,11 @@ module VX_bank // Snp Request input wire snp_req, input wire[31:0] snp_req_addr, + output wire snrq_full, output wire snp_fwd, - output wire[31:0] snp_fwd_addr + output wire[31:0] snp_fwd_addr, + input wire snp_fwd_pop ); @@ -108,7 +110,6 @@ module VX_bank wire snrq_pop; wire snrq_empty; - wire snrq_full; wire snrq_valid_st0; wire[31:0] snrq_addr_st0; @@ -516,7 +517,7 @@ module VX_bank // Enqueue to miss reserv if it's a valid miss - assign miss_add = valid_st2 && miss_st2 && !mrvq_full && !(((valid_st2 && !miss_st2) && cwbq_full) || (((valid_st2 && miss_st2 && dirty_st2) || fill_saw_dirty_st2) && dwbq_full) || (valid_st2 && miss_st2 && mrvq_full)); + assign miss_add = valid_st2 && miss_st2 && !mrvq_full && !((is_snp_st2 && valid_st2 && ffsq_full) ||((valid_st2 && !miss_st2) && cwbq_full) || (((valid_st2 && miss_st2 && dirty_st2) || fill_saw_dirty_st2) && dwbq_full) || (valid_st2 && miss_st2 && mrvq_full)); assign miss_add_pc = pc_st2; assign miss_add_addr = addr_st2; assign miss_add_data = writeword_st2; @@ -524,7 +525,7 @@ module VX_bank // Enqueue to CWB Queue - wire cwbq_push = (valid_st2 && !miss_st2) && !cwbq_full && !((FUNC_ID == `LLFUNC_ID) && (miss_add_wb == 0)) && !( (((valid_st2 && miss_st2 && dirty_st2) || fill_saw_dirty_st2) && dwbq_full) || (valid_st2 && miss_st2 && mrvq_full) || (valid_st2 && miss_st2 && !invalidate_fill && dram_fill_req_queue_full)); + wire cwbq_push = (valid_st2 && !miss_st2) && !cwbq_full && !((FUNC_ID == `LLFUNC_ID) && (miss_add_wb == 0)) && !((is_snp_st2 && valid_st2 && ffsq_full) || (((valid_st2 && miss_st2 && dirty_st2) || fill_saw_dirty_st2) && dwbq_full) || (valid_st2 && miss_st2 && mrvq_full) || (valid_st2 && miss_st2 && !invalidate_fill && dram_fill_req_queue_full)); wire [`WORD_SIZE_RNG] cwbq_data = readword_st2; wire [`vx_clog2(NUMBER_REQUESTS)-1:0] cwbq_tid = miss_add_tid; wire [4:0] cwbq_rd = miss_add_rd; @@ -549,7 +550,7 @@ module VX_bank ); // Enqueue to DWB Queue - wire dwbq_push = ((valid_st2 && miss_st2 && dirty_st2) || fill_saw_dirty_st2) && !dwbq_full && !(((valid_st2 && !miss_st2) && cwbq_full) || (valid_st2 && miss_st2 && mrvq_full) || (valid_st2 && miss_st2 && !invalidate_fill && dram_fill_req_queue_full)); + wire dwbq_push = ((valid_st2 && miss_st2 && dirty_st2) || fill_saw_dirty_st2) && !dwbq_full && !((is_snp_st2 && valid_st2 && ffsq_full) ||((valid_st2 && !miss_st2) && cwbq_full) || (valid_st2 && miss_st2 && mrvq_full) || (valid_st2 && miss_st2 && !invalidate_fill && dram_fill_req_queue_full)); wire[31:0] dwbq_req_addr = {readtag_st2, addr_st2[`LINE_SELECT_ADDR_END:0]} & `BASE_ADDR_MASK; wire[`BANK_LINE_SIZE_RNG][`WORD_SIZE-1:0] dwbq_req_data = readdata_st2; wire dwbq_empty; @@ -609,11 +610,25 @@ module VX_bank ); wire snp_fwd_push; - wire snp_fwd_pop; + wire ffsq_full; + wire ffsq_empty; + + assign snp_fwd_push = is_snp_st2 && valid_st2 && !ffsq_full && !(((valid_st2 && !miss_st2) && cwbq_full) || (((valid_st2 && miss_st2 && dirty_st2) || fill_saw_dirty_st2) && dwbq_full) || (valid_st2 && miss_st2 && mrvq_full) || (valid_st2 && miss_st2 && !invalidate_fill && dram_fill_req_queue_full)); + assign snp_fwd = !ffsq_empty; + VX_generic_queue_ll #(.DATAW(32), .SIZE(FFSQ_SIZE)) ffs_queue( + .clk (clk), + .reset (reset), + .push (snp_fwd_push), + .in_data ({addr_st2}), + .pop (snp_fwd_pop), + .out_data({snp_fwd_addr}), + .empty (ffsq_empty), + .full (ffsq_full) + ); - assign stall_bank_pipe = ((valid_st2 && !miss_st2) && cwbq_full) || (((valid_st2 && miss_st2 && dirty_st2) || fill_saw_dirty_st2) && dwbq_full) || (valid_st2 && miss_st2 && mrvq_full) || (valid_st2 && miss_st2 && !invalidate_fill && dram_fill_req_queue_full); + assign stall_bank_pipe = (is_snp_st2 && valid_st2 && ffsq_full) || ((valid_st2 && !miss_st2) && cwbq_full) || (((valid_st2 && miss_st2 && dirty_st2) || fill_saw_dirty_st2) && dwbq_full) || (valid_st2 && miss_st2 && mrvq_full) || (valid_st2 && miss_st2 && !invalidate_fill && dram_fill_req_queue_full); endmodule diff --git a/rtl/VX_cache/VX_cache.v b/rtl/VX_cache/VX_cache.v index 2c30a0b1..05b01f37 100644 --- a/rtl/VX_cache/VX_cache.v +++ b/rtl/VX_cache/VX_cache.v @@ -96,7 +96,13 @@ module VX_cache // Snoop Req input wire snp_req, - input wire[31:0] snp_req_addr + input wire[31:0] snp_req_addr, + output wire snp_req_delay, + + // Snoop Forward + output wire snp_fwd, + output wire[31:0] snp_fwd_addr, + input wire snp_fwd_delay ); @@ -126,9 +132,19 @@ module VX_cache wire[NUMBER_BANKS-1:0] per_bank_reqq_full; + wire[NUMBER_BANKS-1:0] per_bank_snrq_full; + + wire[NUMBER_BANKS-1:0] per_bank_snp_fwd; + wire[NUMBER_BANKS-1:0][31:0] per_bank_snp_fwd_addr; + wire[NUMBER_BANKS-1:0] per_bank_snp_fwd_pop; + + assign delay_req = (|per_bank_reqq_full); + assign snp_req_delay = (|per_bank_snrq_full); + + assign dram_fill_accept = (NUMBER_BANKS == 1) ? per_bank_dram_fill_accept[0] : per_bank_dram_fill_accept[dram_fill_rsp_addr[`BANK_SELECT_ADDR_RNG]]; VX_cache_dram_req_arb #( @@ -238,6 +254,21 @@ module VX_cache .core_wb_pc (core_wb_pc) ); + + + + // Snoop Forward Logic + VX_snp_fwd_arb #(.NUMBER_BANKS(NUMBER_BANKS)) VX_snp_fwd_arb( + .per_bank_snp_fwd (per_bank_snp_fwd), + .per_bank_snp_fwd_addr(per_bank_snp_fwd_addr), + .per_bank_snp_fwd_pop (per_bank_snp_fwd_pop), + .snp_fwd (snp_fwd), + .snp_fwd_addr (snp_fwd_addr), + .snp_fwd_delay (snp_fwd_delay) + ); + + // Snoop Forward Logic + genvar curr_bank; generate for (curr_bank = 0; curr_bank < NUMBER_BANKS; curr_bank=curr_bank+1) begin @@ -282,6 +313,11 @@ module VX_cache wire curr_bank_reqq_full; + wire curr_bank_snp_fwd; + wire[31:0] curr_bank_snp_fwd_addr; + wire curr_bank_snp_fwd_pop; + wire curr_bank_snrq_full; + // Core Req @@ -326,8 +362,15 @@ module VX_cache assign per_bank_dram_wb_req_data[curr_bank] = curr_bank_dram_wb_req_data; // Snoop Request - assign curr_bank_snp_req = snp_req && (snp_req_addr[`BANK_SELECT_ADDR_RNG] == curr_bank); - assign curr_bank_snp_req_addr = snp_req_addr; + assign curr_bank_snp_req = snp_req && (snp_req_addr[`BANK_SELECT_ADDR_RNG] == curr_bank); + assign curr_bank_snp_req_addr = snp_req_addr; + assign per_bank_snrq_full[curr_bank] = curr_bank_snrq_full; + + // Snoop Fwd + assign curr_bank_snp_fwd_pop = per_bank_snp_fwd_pop[curr_bank]; + assign per_bank_snp_fwd[curr_bank] = curr_bank_snp_fwd; + assign per_bank_snp_fwd_addr[curr_bank] = curr_bank_snp_fwd_addr; + VX_bank #( .CACHE_SIZE_BYTES (CACHE_SIZE_BYTES), @@ -398,7 +441,13 @@ module VX_cache // Snoop Request .snp_req (curr_bank_snp_req), - .snp_req_addr (curr_bank_snp_req_addr) + .snp_req_addr (curr_bank_snp_req_addr), + .snrq_full (curr_bank_snrq_full), + + // Snoop Fwd + .snp_fwd (curr_bank_snp_fwd), + .snp_fwd_addr (curr_bank_snp_fwd_addr), + .snp_fwd_pop (curr_bank_snp_fwd_pop) ); diff --git a/rtl/VX_cache/VX_cache_req_queue.v b/rtl/VX_cache/VX_cache_req_queue.v index 937fa7fb..5938d349 100644 --- a/rtl/VX_cache/VX_cache_req_queue.v +++ b/rtl/VX_cache/VX_cache_req_queue.v @@ -110,7 +110,7 @@ module VX_cache_req_queue wire [NUMBER_REQUESTS-1:0][2:0] qual_mem_write; wire [31:0] qual_pc; - wire[NUMBER_REQUESTS-1:0] updated_valids; + reg [NUMBER_REQUESTS-1:0] updated_valids; wire o_empty; @@ -118,7 +118,7 @@ module VX_cache_req_queue wire out_empty = !(|out_per_valids) || o_empty; wire push_qual = reqq_push && !reqq_full; - wire pop_qual = reqq_pop && use_empty && !out_empty; + wire pop_qual = !out_empty && use_empty; VX_generic_queue_ll #(.DATAW( (NUMBER_REQUESTS * (1+32+`WORD_SIZE)) + 5 + (NUMBER_REQUESTS*2) + (`NW_M1+1) + (NUMBER_REQUESTS * (3 + 3)) + 32 ), .SIZE(REQQ_SIZE)) reqq_queue( .clk (clk), @@ -134,15 +134,15 @@ module VX_cache_req_queue wire[NUMBER_REQUESTS-1:0] real_out_per_valids = out_per_valids & {NUMBER_REQUESTS{~out_empty}}; - assign qual_valids = use_empty ? real_out_per_valids : out_empty ? 0 : use_per_valids; - assign qual_addr = use_empty ? out_per_addr : use_per_addr; - assign qual_writedata = use_empty ? out_per_writedata : use_per_writedata; - assign qual_rd = use_empty ? out_per_rd : use_per_rd; - assign qual_wb = use_empty ? out_per_wb : use_per_wb; - assign qual_warp_num = use_empty ? out_per_warp_num : use_per_warp_num; - assign qual_mem_read = use_empty ? out_per_mem_read : use_per_mem_read; - assign qual_mem_write = use_empty ? out_per_mem_write : use_per_mem_write; - assign qual_pc = use_empty ? out_per_pc : use_per_pc; + assign qual_valids = use_per_valids; + assign qual_addr = use_per_addr; + assign qual_writedata = use_per_writedata; + assign qual_rd = use_per_rd; + assign qual_wb = use_per_wb; + assign qual_warp_num = use_per_warp_num; + assign qual_mem_read = use_per_mem_read; + assign qual_mem_write = use_per_mem_write; + assign qual_pc = use_per_pc; wire[`vx_clog2(NUMBER_REQUESTS)-1:0] qual_request_index; wire qual_has_request; @@ -164,7 +164,14 @@ module VX_cache_req_queue assign reqq_req_mem_write_st0 = qual_mem_write[qual_request_index]; assign reqq_req_pc_st0 = qual_pc; - assign updated_valids = qual_valids & (~(1 << qual_request_index)); + + always @(*) begin + assign updated_valids = qual_valids; + if (qual_has_request) begin + assign updated_valids[qual_request_index] = 0; + end + end + always @(posedge clk) begin if (reset) begin @@ -178,17 +185,19 @@ module VX_cache_req_queue use_per_mem_write <= 0; use_per_pc <= 0; end else begin - if (reqq_pop && qual_has_request) begin - use_per_valids <= updated_valids; - use_per_addr <= qual_addr; - use_per_writedata <= qual_writedata; - use_per_rd <= qual_rd; - use_per_wb <= qual_wb; - use_per_warp_num <= qual_warp_num; - use_per_mem_read <= qual_mem_read; - use_per_mem_write <= qual_mem_write; - use_per_pc <= qual_pc; - end + if (pop_qual) begin + use_per_valids <= real_out_per_valids; + use_per_addr <= out_per_addr; + use_per_writedata <= out_per_writedata; + use_per_rd <= out_per_rd; + use_per_wb <= out_per_wb; + use_per_warp_num <= out_per_warp_num; + use_per_mem_read <= out_per_mem_read; + use_per_mem_write <= out_per_mem_write; + use_per_pc <= out_per_pc; + end else if (reqq_pop) begin + use_per_valids[qual_request_index] <= 0; + end // else if (reqq_pop) begin // use_per_valids[qual_request_index] <= updated_valids; // end diff --git a/rtl/VX_cache/VX_cache_wb_sel_merge.v b/rtl/VX_cache/VX_cache_wb_sel_merge.v index 7199c483..148b443b 100644 --- a/rtl/VX_cache/VX_cache_wb_sel_merge.v +++ b/rtl/VX_cache/VX_cache_wb_sel_merge.v @@ -75,20 +75,20 @@ module VX_cache_wb_sel_merge reg [NUMBER_BANKS-1:0] per_bank_wb_pop_unqual; assign per_bank_wb_pop = per_bank_wb_pop_unqual & {NUMBER_BANKS{~core_no_wb_slot}}; - wire[NUMBER_BANKS-1:0] bank_wants_wb; - genvar curr_bank; - generate - for (curr_bank = 0; curr_bank < NUMBER_BANKS; curr_bank=curr_bank+1) begin - assign bank_wants_wb[curr_bank] = (|per_bank_wb_valid[curr_bank]); - end - endgenerate + // wire[NUMBER_BANKS-1:0] bank_wants_wb; + // genvar curr_bank; + // generate + // for (curr_bank = 0; curr_bank < NUMBER_BANKS; curr_bank=curr_bank+1) begin + // assign bank_wants_wb[curr_bank] = (|per_bank_wb_valid[curr_bank]); + // end + // endgenerate wire [(`vx_clog2(NUMBER_BANKS))-1:0] main_bank_index; wire found_bank; VX_generic_priority_encoder #(.N(NUMBER_BANKS)) VX_sel_bank( - .valids(bank_wants_wb), + .valids(per_bank_wb_valid), .index (main_bank_index), .found (found_bank) ); @@ -105,7 +105,7 @@ module VX_cache_wb_sel_merge core_wb_pc = 0; core_wb_address = 0; for (this_bank = 0; this_bank < NUMBER_BANKS; this_bank = this_bank + 1) begin - if (((FUNC_ID == `LLFUNC_ID) && found_bank && per_bank_wb_valid[this_bank]) || (found_bank && (per_bank_wb_valid[this_bank]) && (per_bank_wb_rd[this_bank] == per_bank_wb_rd[main_bank_index]) && (per_bank_wb_warp_num[this_bank] == per_bank_wb_warp_num[main_bank_index]))) begin + if (((FUNC_ID == `LLFUNC_ID) && found_bank && per_bank_wb_valid[this_bank] && ((this_bank == main_bank_index) || (per_bank_wb_tid[this_bank] != per_bank_wb_tid[main_bank_index]))) || ((FUNC_ID != `LLFUNC_ID) && ((this_bank == main_bank_index) || (per_bank_wb_tid[this_bank] != per_bank_wb_tid[main_bank_index])) && found_bank && (per_bank_wb_valid[this_bank]) && (per_bank_wb_rd[this_bank] == per_bank_wb_rd[main_bank_index]) && (per_bank_wb_warp_num[this_bank] == per_bank_wb_warp_num[main_bank_index]))) begin core_wb_valid[per_bank_wb_tid[this_bank]] = 1; core_wb_readdata[per_bank_wb_tid[this_bank]] = per_bank_wb_data[this_bank]; core_wb_pc[per_bank_wb_tid[this_bank]] = per_bank_wb_pc[this_bank]; diff --git a/rtl/VX_cache/VX_snp_fwd_arb.v b/rtl/VX_cache/VX_snp_fwd_arb.v new file mode 100644 index 00000000..7f2d3e64 --- /dev/null +++ b/rtl/VX_cache/VX_snp_fwd_arb.v @@ -0,0 +1,39 @@ + +module VX_snp_fwd_arb + #( + parameter NUMBER_BANKS = 8 + ) + ( + input wire[NUMBER_BANKS-1:0] per_bank_snp_fwd, + input wire[NUMBER_BANKS-1:0][31:0] per_bank_snp_fwd_addr, + output reg[NUMBER_BANKS-1:0] per_bank_snp_fwd_pop, + + output wire snp_fwd, + output wire[31:0] snp_fwd_addr, + input wire snp_fwd_delay + +); + + + wire[NUMBER_BANKS-1:0] qual_per_bank_snp_fwd = per_bank_snp_fwd & {NUMBER_BANKS{!snp_fwd_delay}}; + + wire[`vx_clog2(NUMBER_BANKS)-1:0] fsq_bank; + wire fsq_valid; + + VX_generic_priority_encoder #(.N(NUMBER_BANKS)) VX_sel_ffsq( + .valids(qual_per_bank_snp_fwd), + .index (fsq_bank), + .found (fsq_valid) + ); + + assign snp_fwd = fsq_valid; + assign snp_fwd_addr = per_bank_snp_fwd_addr[fsq_bank]; + + always @(*) begin + assign per_bank_snp_fwd_pop = 0; + if (fsq_valid) begin + per_bank_snp_fwd_pop[fsq_bank] = 1; + end + end + +endmodule \ No newline at end of file diff --git a/rtl/VX_define.v b/rtl/VX_define.v index 45c6c375..19cf8fac 100644 --- a/rtl/VX_define.v +++ b/rtl/VX_define.v @@ -126,9 +126,9 @@ -`define NUMBER_CORES_PER_CLUSTERS (2) -`define NUMBER_CLUSTERS (1) -`define NUMBER_CORES (`NUMBER_CORES_PER_CLUSTERS*`NUMBER_CLUSTERS) +`define NUMBER_CORES_PER_CLUSTER 2 +`define NUMBER_CLUSTERS 2 +`define NUMBER_CORES (`NUMBER_CORES_PER_CLUSTER*`NUMBER_CLUSTERS) // `define SINGLE_CORE_BENCH 0 `define GLOBAL_BLOCK_SIZE_BYTES 16 @@ -303,7 +303,7 @@ // Size of a word in bytes `define LLWORD_SIZE_BYTES (`LLBANK_LINE_SIZE_BYTES) // Number of Word requests per cycle {1, 2, 4, 8, ...} - `define LLNUMBER_REQUESTS (2*`NUMBER_CORES_PER_CLUSTERS) + `define LLNUMBER_REQUESTS (2*`NUMBER_CORES_PER_CLUSTER) // Number of cycles to complete stage 1 (read from memory) `define LLSTAGE_1_CYCLES 2 // Function ID @@ -315,7 +315,7 @@ // Queues feeding into banks Knobs {1, 2, 4, 8, ...} // Core Request Queue Size - `define LLREQQ_SIZE (`NT*`NW*`NUMBER_CORES_PER_CLUSTERS) + `define LLREQQ_SIZE (`NT*`NW*`NUMBER_CORES_PER_CLUSTER) // Miss Reserv Queue Knob `define LLMRVQ_SIZE `LLREQQ_SIZE // Dram Fill Rsp Queue Size @@ -354,17 +354,17 @@ // Number of banks {1, 2, 4, 8,...} `define L3NUMBER_BANKS 8 // Size of a word in bytes - `define L3WORD_SIZE_BYTES (`LLBANK_LINE_SIZE_BYTES) + `define L3WORD_SIZE_BYTES (`L3BANK_LINE_SIZE_BYTES) // Number of Word requests per cycle {1, 2, 4, 8, ...} - `define L3NUMBER_REQUESTS (2*`NUMBER_CLUSTERS) + `define L3NUMBER_REQUESTS (`NUMBER_CLUSTERS) // Number of cycles to complete stage 1 (read from memory) `define L3STAGE_1_CYCLES 2 // Function ID `define L3FUNC_ID 3 // Bank Number of words in a line - `define L3BANK_LINE_SIZE_WORDS (`LLBANK_LINE_SIZE_BYTES / `LLWORD_SIZE_BYTES) - `define L3BANK_LINE_SIZE_RNG `LLBANK_LINE_SIZE_WORDS-1:0 + `define L3BANK_LINE_SIZE_WORDS (`L3BANK_LINE_SIZE_BYTES / `L3WORD_SIZE_BYTES) + `define L3BANK_LINE_SIZE_RNG `L3BANK_LINE_SIZE_WORDS-1:0 // Queues feeding into banks Knobs {1, 2, 4, 8, ...} // Core Request Queue Size @@ -378,11 +378,11 @@ // Queues for writebacks Knobs {1, 2, 4, 8, ...} // Core Writeback Queue Size - `define L3CWBQ_SIZE `LLREQQ_SIZE + `define L3CWBQ_SIZE `L3REQQ_SIZE // Dram Writeback Queue Size `define L3DWBQ_SIZE 4 // Dram Fill Req Queue Size - `define L3DFQQ_SIZE `LLREQQ_SIZE + `define L3DFQQ_SIZE `L3REQQ_SIZE // Lower Level Cache Hit Queue Size `define L3LLVQ_SIZE 0 // Fill Forward SNP Queue diff --git a/rtl/VX_dmem_controller.v b/rtl/VX_dmem_controller.v index 75ba5c00..b9cff01b 100644 --- a/rtl/VX_dmem_controller.v +++ b/rtl/VX_dmem_controller.v @@ -7,10 +7,12 @@ module VX_dmem_controller ( // Dram <-> Dcache VX_gpu_dcache_dram_req_inter VX_gpu_dcache_dram_req, VX_gpu_dcache_dram_res_inter VX_gpu_dcache_dram_res, + VX_gpu_snp_req_rsp VX_gpu_dcache_snp_req, // Dram <-> Icache VX_gpu_dcache_dram_req_inter VX_gpu_icache_dram_req, VX_gpu_dcache_dram_res_inter VX_gpu_icache_dram_res, + VX_gpu_snp_req_rsp VX_gpu_icache_snp_req, // Core <-> Dcache VX_gpu_dcache_res_inter VX_dcache_rsp, @@ -149,7 +151,12 @@ module VX_dmem_controller ( // Snoop Request .snp_req (0), - .snp_req_addr (0) + .snp_req_addr (0), + + // Snoop Forward + .snp_fwd (), + .snp_fwd_addr (), + .snp_fwd_delay (0) ); VX_cache #( @@ -224,8 +231,15 @@ module VX_dmem_controller ( .dram_snp_full (VX_gpu_dcache_dram_req.dram_snp_full), // Snoop Request - .snp_req (0), - .snp_req_addr (0) + .snp_req (VX_gpu_dcache_snp_req.snp_req), + .snp_req_addr (VX_gpu_dcache_snp_req.snp_req_addr), + .snp_req_delay (VX_gpu_dcache_snp_req.snp_delay), + + + // Snoop Forward + .snp_fwd (), + .snp_fwd_addr (), + .snp_fwd_delay (0) ); @@ -301,9 +315,16 @@ module VX_dmem_controller ( .dram_req_because_of_wb(VX_gpu_icache_dram_req.dram_because_of_snp), .dram_snp_full (VX_gpu_icache_dram_req.dram_snp_full), + // Snoop Request - .snp_req (0), - .snp_req_addr (0) + .snp_req (VX_gpu_icache_snp_req.snp_req), + .snp_req_addr (VX_gpu_icache_snp_req.snp_req_addr), + .snp_req_delay (VX_gpu_icache_snp_req.snp_delay), + + // Snoop Forward + .snp_fwd (), + .snp_fwd_addr (), + .snp_fwd_delay (0) ); diff --git a/rtl/Vortex.v b/rtl/Vortex.v index 862e7007..d5454d7d 100644 --- a/rtl/Vortex.v +++ b/rtl/Vortex.v @@ -45,6 +45,15 @@ module Vortex input wire [31:0] I_dram_fill_rsp_addr, input wire [31:0] I_dram_fill_rsp_data[`IBANK_LINE_SIZE_RNG], + input wire snp_req, + input wire [31:0] snp_req_addr, + output wire snp_req_delay, + + input wire I_snp_req, + input wire [31:0] I_snp_req_addr, + output wire I_snp_req_delay, + + output wire out_ebreak `else @@ -86,6 +95,15 @@ module Vortex input wire [`IBANK_LINE_SIZE_RNG][31:0] I_dram_fill_rsp_data, + input wire snp_req, + input wire [31:0] snp_req_addr, + output wire snp_req_delay, + + input wire I_snp_req, + input wire [31:0] I_snp_req_addr, + output wire I_snp_req_delay, + + output wire out_ebreak `endif ); @@ -191,6 +209,17 @@ VX_jal_response_inter VX_jal_rsp(); // Jump resolution to Fetch VX_warp_ctl_inter VX_warp_ctl(); +VX_gpu_snp_req_rsp VX_gpu_icache_snp_req(); +VX_gpu_snp_req_rsp VX_gpu_dcache_snp_req(); + +assign VX_gpu_icache_snp_req.snp_req = I_snp_req; +assign VX_gpu_icache_snp_req.snp_req_addr = I_snp_req_addr; +assign I_snp_req_delay = VX_gpu_icache_snp_req.snp_delay; + +assign VX_gpu_dcache_snp_req.snp_req = snp_req; +assign VX_gpu_dcache_snp_req.snp_req_addr = snp_req_addr; +assign snp_req_delay = VX_gpu_dcache_snp_req.snp_delay; + VX_front_end vx_front_end( .clk (clk), .reset (reset), @@ -240,10 +269,12 @@ VX_dmem_controller VX_dmem_controller( // Dram <-> Dcache .VX_gpu_dcache_dram_req (VX_gpu_dcache_dram_req), .VX_gpu_dcache_dram_res (VX_gpu_dcache_dram_res), + .VX_gpu_dcache_snp_req (VX_gpu_dcache_snp_req), // Dram <-> Icache .VX_gpu_icache_dram_req (VX_gpu_icache_dram_req), .VX_gpu_icache_dram_res (VX_gpu_icache_dram_res), + .VX_gpu_icache_snp_req (VX_gpu_icache_snp_req), // Core <-> Icache .VX_icache_req (VX_icache_req), diff --git a/rtl/Vortex_SOC.v b/rtl/Vortex_SOC.v index d2b47e25..9e9210fe 100644 --- a/rtl/Vortex_SOC.v +++ b/rtl/Vortex_SOC.v @@ -11,274 +11,482 @@ module Vortex_SOC ( output wire[31:0] number_cores, // DRAM Dcache Req - output wire dram_req, - output wire dram_req_write, - output wire dram_req_read, - output wire [31:0] dram_req_addr, - output wire [31:0] dram_req_size, - output wire [31:0] dram_req_data[`DBANK_LINE_SIZE_RNG], - output wire [31:0] dram_expected_lat, + output wire out_dram_req, + output wire out_dram_req_write, + output wire out_dram_req_read, + output wire [31:0] out_dram_req_addr, + output wire [31:0] out_dram_req_size, + output wire [31:0] out_dram_req_data[`DBANK_LINE_SIZE_RNG], + output wire [31:0] out_dram_expected_lat, // DRAM Dcache Res - output wire dram_fill_accept, - input wire dram_fill_rsp, - input wire [31:0] dram_fill_rsp_addr, - input wire [31:0] dram_fill_rsp_data[`DBANK_LINE_SIZE_RNG], + output wire out_dram_fill_accept, + input wire out_dram_fill_rsp, + input wire [31:0] out_dram_fill_rsp_addr, + input wire [31:0] out_dram_fill_rsp_data[`DBANK_LINE_SIZE_RNG], + + input wire l3c_snp_req, + input wire l3c_snp_req_addr, + output wire l3c_snp_req_delay, output wire out_ebreak ); + + // DRAM Dcache Req + wire [`NUMBER_CLUSTERS-1:0] dram_req; + wire [`NUMBER_CLUSTERS-1:0] dram_req_write; + wire [`NUMBER_CLUSTERS-1:0] dram_req_read; + wire [`NUMBER_CLUSTERS-1:0][31:0] dram_req_addr; + wire [`NUMBER_CLUSTERS-1:0][31:0] dram_req_size; + wire [`NUMBER_CLUSTERS-1:0][`DBANK_LINE_SIZE_RNG][31:0] dram_req_data; + wire [`NUMBER_CLUSTERS-1:0][31:0] dram_expected_lat; + + // DRAM Dcache Res + wire [`NUMBER_CLUSTERS-1:0] dram_fill_accept; + wire [`NUMBER_CLUSTERS-1:0] dram_fill_rsp; + wire [`NUMBER_CLUSTERS-1:0][31:0] dram_fill_rsp_addr; + wire [`NUMBER_CLUSTERS-1:0][`DBANK_LINE_SIZE_RNG][31:0] dram_fill_rsp_data; + assign number_cores = `NUMBER_CORES; // IO - wire per_core_io_valid[`NUMBER_CORES-1:0]; - wire[31:0] per_core_io_data[`NUMBER_CORES-1:0]; - - // DRAM Dcache Req - wire[`NUMBER_CORES-1:0] per_core_dram_req; - wire[`NUMBER_CORES-1:0] per_core_dram_req_write; - wire[`NUMBER_CORES-1:0] per_core_dram_req_read; - wire[`NUMBER_CORES-1:0] [31:0] per_core_dram_req_addr; - wire[`NUMBER_CORES-1:0] [31:0] per_core_dram_req_size; - wire[`NUMBER_CORES-1:0][`DBANK_LINE_SIZE_RNG][31:0] per_core_dram_req_data; - wire[`NUMBER_CORES-1:0] [31:0] per_core_dram_expected_lat; - - // DRAM Dcache Res - wire[`NUMBER_CORES-1:0] per_core_dram_fill_accept; - wire[`NUMBER_CORES-1:0] per_core_dram_fill_rsp; - wire[`NUMBER_CORES-1:0] [31:0] per_core_dram_fill_rsp_addr; - wire[`NUMBER_CORES-1:0][`DBANK_LINE_SIZE_RNG][31:0] per_core_dram_fill_rsp_data; - - - // DRAM Icache Req - wire[`NUMBER_CORES-1:0] per_core_I_dram_req; - wire[`NUMBER_CORES-1:0] per_core_I_dram_req_write; - wire[`NUMBER_CORES-1:0] per_core_I_dram_req_read; - wire[`NUMBER_CORES-1:0] [31:0] per_core_I_dram_req_addr; - wire[`NUMBER_CORES-1:0] [31:0] per_core_I_dram_req_size; - wire[`NUMBER_CORES-1:0][`IBANK_LINE_SIZE_RNG][31:0] per_core_I_dram_req_data; - wire[`NUMBER_CORES-1:0] [31:0] per_core_I_dram_expected_lat; - - // DRAM Icache Res - wire[`NUMBER_CORES-1:0] per_core_I_dram_fill_accept; - wire[`NUMBER_CORES-1:0] per_core_I_dram_fill_rsp; - wire[`NUMBER_CORES-1:0] [31:0] per_core_I_dram_fill_rsp_addr; - wire[`NUMBER_CORES-1:0][`IBANK_LINE_SIZE_RNG][31:0] per_core_I_dram_fill_rsp_data; + // wire per_core_io_valid[`NUMBER_CORES-1:0]; + // wire[31:0] per_core_io_data[`NUMBER_CORES-1:0]; // Out ebreak wire[`NUMBER_CORES-1:0] per_core_out_ebreak; - assign out_ebreak = (&per_core_out_ebreak); - genvar curr_core; + wire[`L3NUMBER_REQUESTS-1:0] l3c_core_req; + wire[`L3NUMBER_REQUESTS-1:0][2:0] l3c_core_req_mem_write; + wire[`L3NUMBER_REQUESTS-1:0][2:0] l3c_core_req_mem_read; + wire[`L3NUMBER_REQUESTS-1:0][31:0] l3c_core_req_addr; + wire[`L3NUMBER_REQUESTS-1:0][`IBANK_LINE_SIZE_RNG][31:0] l3c_core_req_data; + wire[`L3NUMBER_REQUESTS-1:0][1:0] l3c_core_req_wb; + + wire l3c_core_accept; + + + wire l3c_snp_fwd; + wire[31:0] l3c_snp_fwd_addr; + wire[`L3NUMBER_REQUESTS-1:0] l3c_snp_fwd_delay_temp; + wire l3c_snp_fwd_delay; + + assign l3c_snp_fwd_delay = (|l3c_snp_fwd_delay_temp); + + + wire[`L3NUMBER_REQUESTS-1:0] l3c_wb; + wire[`L3NUMBER_REQUESTS-1:0] [31:0] l3c_wb_addr; + wire[`L3NUMBER_REQUESTS-1:0][`IBANK_LINE_SIZE_RNG][31:0] l3c_wb_data; + + wire[`IBANK_LINE_SIZE_RNG][31:0] l3c_dram_req_data; + wire[`IBANK_LINE_SIZE_RNG][31:0] l3c_dram_fill_rsp_data; + + genvar curr_l; generate - - for (curr_core = 0; curr_core < `NUMBER_CORES; curr_core=curr_core+1) begin - - wire [`IBANK_LINE_SIZE_RNG][31:0] curr_core_I_dram_req_data; - wire [`DBANK_LINE_SIZE_RNG][31:0] curr_core_dram_req_data ; - - assign io_valid[curr_core] = per_core_io_valid[curr_core]; - assign io_data [curr_core] = per_core_io_data [curr_core]; - Vortex #(.CORE_ID(curr_core)) vortex_core( - .clk (clk), - .reset (reset), - .io_valid (per_core_io_valid [curr_core]), - .io_data (per_core_io_data [curr_core]), - .dram_req (per_core_dram_req [curr_core]), - .dram_req_write (per_core_dram_req_write [curr_core]), - .dram_req_read (per_core_dram_req_read [curr_core]), - .dram_req_addr (per_core_dram_req_addr [curr_core]), - .dram_req_size (per_core_dram_req_size [curr_core]), - .dram_req_data (curr_core_dram_req_data ), - .dram_expected_lat (per_core_dram_expected_lat [curr_core]), - .dram_fill_accept (per_core_dram_fill_accept [curr_core]), - .dram_fill_rsp (per_core_dram_fill_rsp [curr_core]), - .dram_fill_rsp_addr (per_core_dram_fill_rsp_addr [curr_core]), - .dram_fill_rsp_data (per_core_dram_fill_rsp_data [curr_core]), - .I_dram_req (per_core_I_dram_req [curr_core]), - .I_dram_req_write (per_core_I_dram_req_write [curr_core]), - .I_dram_req_read (per_core_I_dram_req_read [curr_core]), - .I_dram_req_addr (per_core_I_dram_req_addr [curr_core]), - .I_dram_req_size (per_core_I_dram_req_size [curr_core]), - .I_dram_req_data (curr_core_I_dram_req_data ), - .I_dram_expected_lat (per_core_I_dram_expected_lat [curr_core]), - .I_dram_fill_accept (per_core_I_dram_fill_accept [curr_core]), - .I_dram_fill_rsp (per_core_I_dram_fill_rsp [curr_core]), - .I_dram_fill_rsp_addr (per_core_I_dram_fill_rsp_addr[curr_core]), - .I_dram_fill_rsp_data (per_core_I_dram_fill_rsp_data[curr_core]), - .out_ebreak (per_core_out_ebreak [curr_core]) - ); - - assign per_core_dram_req_data [curr_core] = curr_core_dram_req_data; - assign per_core_I_dram_req_data[curr_core] = curr_core_I_dram_req_data; + for (curr_l = 0; curr_l < `IBANK_LINE_SIZE_WORDS; curr_l=curr_l+1) begin + assign out_dram_req_data[curr_l][31:0] = l3c_dram_req_data[curr_l][31:0]; + assign l3c_dram_fill_rsp_data[curr_l][31:0] = out_dram_fill_rsp_data[curr_l][31:0]; end endgenerate - //////////////////// L2 Cache //////////////////// - wire[`LLNUMBER_REQUESTS-1:0] l2c_core_req; - wire[`LLNUMBER_REQUESTS-1:0][2:0] l2c_core_req_mem_write; - wire[`LLNUMBER_REQUESTS-1:0][2:0] l2c_core_req_mem_read; - wire[`LLNUMBER_REQUESTS-1:0][31:0] l2c_core_req_addr; - wire[`LLNUMBER_REQUESTS-1:0][`IBANK_LINE_SIZE_RNG][31:0] l2c_core_req_data; - wire[`LLNUMBER_REQUESTS-1:0][1:0] l2c_core_req_wb; - - wire l2c_core_accept; - - - wire[`LLNUMBER_REQUESTS-1:0] l2c_wb; - wire[`LLNUMBER_REQUESTS-1:0] [31:0] l2c_wb_addr; - wire[`LLNUMBER_REQUESTS-1:0][`IBANK_LINE_SIZE_RNG][31:0] l2c_wb_data; - - - wire[`DBANK_LINE_SIZE_RNG][31:0] dram_req_data_port; - wire[`DBANK_LINE_SIZE_RNG][31:0] dram_fill_rsp_data_port; - - genvar llb_index; - generate - for (llb_index = 0; llb_index < `DBANK_LINE_SIZE_WORDS; llb_index=llb_index+1) begin - assign dram_req_data [llb_index] = dram_req_data_port[llb_index]; - assign dram_fill_rsp_data_port[llb_index] = dram_fill_rsp_data[llb_index]; - end - endgenerate - - // genvar l2c_index; - // genvar l2c_bank_index; - // generate - // for (l2c_index = 0; l2c_index < `LLNUMBER_REQUESTS; l2c_index=l2c_index+1) begin - // assign l2c_wb [l2c_index] = l2c_wb_port [l2c_index]; - // assign l2c_wb_addr[l2c_index] = l2c_wb_addr_port[l2c_index]; - // for (l2c_bank_index = 0; l2c_bank_index < `LLNUMBER_REQUESTS; l2c_bank_index=l2c_bank_index+1) begin - // assign l2c_wb_data[l2c_index][l2c_bank_index] = l2c_wb_data_port[l2c_index][l2c_bank_index]; - // end - // end - // endgenerate - // - genvar l2c_curr_core; + genvar l3c_curr_core; generate - for (l2c_curr_core = 0; l2c_curr_core < `LLNUMBER_REQUESTS; l2c_curr_core=l2c_curr_core+2) begin + for (l3c_curr_core = 0; l3c_curr_core < `L3NUMBER_REQUESTS; l3c_curr_core=l3c_curr_core+1) begin // Core Request - assign l2c_core_req [l2c_curr_core] = per_core_dram_req [(l2c_curr_core/2)]; - assign l2c_core_req [l2c_curr_core+1] = per_core_I_dram_req[(l2c_curr_core/2)]; + assign l3c_core_req [l3c_curr_core] = dram_req [(l3c_curr_core)]; - assign l2c_core_req_mem_write [l2c_curr_core] = per_core_dram_req_write ? `SW_MEM_WRITE : `NO_MEM_WRITE; - assign l2c_core_req_mem_write [l2c_curr_core+1] = `NO_MEM_WRITE; // I caches don't write + assign l3c_core_req_mem_write [l3c_curr_core] = dram_req_write ? `SW_MEM_WRITE : `NO_MEM_WRITE; - assign l2c_core_req_mem_read [l2c_curr_core] = per_core_dram_req_read ? `LW_MEM_READ : `NO_MEM_READ; - assign l2c_core_req_mem_read [l2c_curr_core+1] = `LW_MEM_READ; // I caches don't write + assign l3c_core_req_mem_read [l3c_curr_core] = dram_req_read ? `LW_MEM_READ : `NO_MEM_READ; - assign l2c_core_req_wb [l2c_curr_core] = per_core_dram_req_read ? 1 : 0; - assign l2c_core_req_wb [l2c_curr_core+1] = 1; // I caches don't write + assign l3c_core_req_wb [l3c_curr_core] = dram_req_read ? 1 : 0; - assign l2c_core_req_addr [l2c_curr_core] = per_core_dram_req_addr [(l2c_curr_core/2)]; - assign l2c_core_req_addr [l2c_curr_core+1] = per_core_I_dram_req_addr[(l2c_curr_core/2)]; + assign l3c_core_req_addr [l3c_curr_core] = dram_req_addr [(l3c_curr_core)]; - assign l2c_core_req_data [l2c_curr_core] = per_core_dram_req_data [(l2c_curr_core/2)]; - assign l2c_core_req_data [l2c_curr_core+1] = per_core_I_dram_req_data[(l2c_curr_core/2)]; + assign l3c_core_req_data [l3c_curr_core] = dram_req_data [(l3c_curr_core)]; // L2 can't accept requests - assign per_core_dram_fill_accept [(l2c_curr_core/2)] = l2c_core_accept; - assign per_core_I_dram_fill_accept[(l2c_curr_core/2)] = l2c_core_accept; + assign dram_fill_accept [(l3c_curr_core)] = l3c_core_accept; // Cache Fill Response - assign per_core_dram_fill_rsp [(l2c_curr_core/2)] = l2c_wb[l2c_curr_core]; - assign per_core_I_dram_fill_rsp [(l2c_curr_core/2)] = l2c_wb[l2c_curr_core+1]; + assign dram_fill_rsp [(l3c_curr_core)] = l3c_wb[l3c_curr_core]; - assign per_core_dram_fill_rsp_data[(l2c_curr_core/2)] = l2c_wb_data[l2c_curr_core]; - assign per_core_I_dram_fill_rsp_data[(l2c_curr_core/2)] = l2c_wb_data[l2c_curr_core+1]; + assign dram_fill_rsp_data[(l3c_curr_core)] = l3c_wb_data[l3c_curr_core]; - assign per_core_dram_fill_rsp_addr[(l2c_curr_core/2)] = l2c_wb_addr[l2c_curr_core]; - assign per_core_I_dram_fill_rsp_addr[(l2c_curr_core/2)] = l2c_wb_addr[l2c_curr_core+1]; + assign dram_fill_rsp_addr[(l3c_curr_core)] = l3c_wb_addr[l3c_curr_core]; end endgenerate wire dram_snp_full; wire dram_req_because_of_wb; + + VX_cache #( - .CACHE_SIZE_BYTES (`LLCACHE_SIZE_BYTES), - .BANK_LINE_SIZE_BYTES (`LLBANK_LINE_SIZE_BYTES), - .NUMBER_BANKS (`LLNUMBER_BANKS), - .WORD_SIZE_BYTES (`LLWORD_SIZE_BYTES), - .NUMBER_REQUESTS (`LLNUMBER_REQUESTS), - .STAGE_1_CYCLES (`LLSTAGE_1_CYCLES), + .CACHE_SIZE_BYTES (`L3CACHE_SIZE_BYTES), + .BANK_LINE_SIZE_BYTES (`L3BANK_LINE_SIZE_BYTES), + .NUMBER_BANKS (`L3NUMBER_BANKS), + .WORD_SIZE_BYTES (`L3WORD_SIZE_BYTES), + .NUMBER_REQUESTS (`L3NUMBER_REQUESTS), + .STAGE_1_CYCLES (`L3STAGE_1_CYCLES), .FUNC_ID (`LLFUNC_ID), - .REQQ_SIZE (`LLREQQ_SIZE), - .MRVQ_SIZE (`LLMRVQ_SIZE), - .DFPQ_SIZE (`LLDFPQ_SIZE), - .SNRQ_SIZE (`LLSNRQ_SIZE), - .CWBQ_SIZE (`LLCWBQ_SIZE), - .DWBQ_SIZE (`LLDWBQ_SIZE), - .DFQQ_SIZE (`LLDFQQ_SIZE), - .LLVQ_SIZE (`LLLLVQ_SIZE), - .FFSQ_SIZE (`LLFFSQ_SIZE), - .FILL_INVALIDAOR_SIZE (`LLFILL_INVALIDAOR_SIZE), - .SIMULATED_DRAM_LATENCY_CYCLES(`LLSIMULATED_DRAM_LATENCY_CYCLES) + .REQQ_SIZE (`L3REQQ_SIZE), + .MRVQ_SIZE (`L3MRVQ_SIZE), + .DFPQ_SIZE (`L3DFPQ_SIZE), + .SNRQ_SIZE (`L3SNRQ_SIZE), + .CWBQ_SIZE (`L3CWBQ_SIZE), + .DWBQ_SIZE (`L3DWBQ_SIZE), + .DFQQ_SIZE (`L3DFQQ_SIZE), + .LLVQ_SIZE (`L3LLVQ_SIZE), + .FFSQ_SIZE (`L3FFSQ_SIZE), + .FILL_INVALIDAOR_SIZE (`L3FILL_INVALIDAOR_SIZE), + .SIMULATED_DRAM_LATENCY_CYCLES(`L3SIMULATED_DRAM_LATENCY_CYCLES) ) - gpu_l2cache + gpu_l3cache ( .clk (clk), .reset (reset), // Core Req (DRAM Fills/WB) To L2 Request - .core_req_valid (l2c_core_req), - .core_req_addr (l2c_core_req_addr), - .core_req_writedata({l2c_core_req_data}), - .core_req_mem_read (l2c_core_req_mem_read), - .core_req_mem_write(l2c_core_req_mem_write), + .core_req_valid (l3c_core_req), + .core_req_addr (l3c_core_req_addr), + .core_req_writedata({l3c_core_req_data}), + .core_req_mem_read (l3c_core_req_mem_read), + .core_req_mem_write(l3c_core_req_mem_write), .core_req_rd (0), - .core_req_wb (l2c_core_req_wb), + .core_req_wb (l3c_core_req_wb), .core_req_warp_num (0), .core_req_pc (0), // L2 can't accept Core Request - .delay_req (l2c_core_accept), + .delay_req (l3c_core_accept), // Core can't accept L2 Request .core_no_wb_slot (0), // Core Writeback - .core_wb_valid (l2c_wb), + .core_wb_valid (l3c_wb), .core_wb_req_rd (), .core_wb_req_wb (), .core_wb_warp_num (), - .core_wb_readdata ({l2c_wb_data}), - .core_wb_address (l2c_wb_addr), + .core_wb_readdata ({l3c_wb_data}), + .core_wb_address (l3c_wb_addr), .core_wb_pc (), // L2 Cache DRAM Fill response - .dram_fill_rsp (dram_fill_rsp), - .dram_fill_rsp_addr(dram_fill_rsp_addr), - .dram_fill_rsp_data({dram_fill_rsp_data_port}), + .dram_fill_rsp (out_dram_fill_rsp), + .dram_fill_rsp_addr(out_dram_fill_rsp_addr), + .dram_fill_rsp_data({l3c_dram_fill_rsp_data}), // L2 Cache can't accept Fill Response - .dram_fill_accept (dram_fill_accept), + .dram_fill_accept (out_dram_fill_accept), // L2 Cache DRAM Fill Request - .dram_req (dram_req), - .dram_req_write (dram_req_write), - .dram_req_read (dram_req_read), - .dram_req_addr (dram_req_addr), - .dram_req_size (dram_req_size), - .dram_req_data ({dram_req_data_port}), + .dram_req (out_dram_req), + .dram_req_write (out_dram_req_write), + .dram_req_read (out_dram_req_read), + .dram_req_addr (out_dram_req_addr), + .dram_req_size (out_dram_req_size), + .dram_req_data ({l3c_dram_req_data}), // Snoop Response .dram_req_because_of_wb(dram_req_because_of_wb), .dram_snp_full (dram_snp_full), // Snoop Request - .snp_req (0), - .snp_req_addr (0) + .snp_req (l3c_snp_req), + .snp_req_addr (l3c_snp_req_addr), + .snp_req_delay (l3c_snp_req_delay), + + .snp_fwd (l3c_snp_fwd), + .snp_fwd_addr (l3c_snp_fwd_addr), + .snp_fwd_delay (l3c_snp_fwd_delay) ); - //////////////////// L2 Cache //////////////////// + //////////////////// L3 Cache //////////////////// + + + + genvar curr_cluster; + genvar curr_core; + genvar llb_index; + genvar l2c_curr_core; + + generate + for (curr_cluster = 0; curr_cluster < `NUMBER_CLUSTERS; curr_cluster=curr_cluster+1) begin + ////////////////////// BEGIN CLUSTER ///////////////// + + + + // DRAM Dcache Req + wire[`NUMBER_CORES_PER_CLUSTER-1:0] per_core_dram_req; + wire[`NUMBER_CORES_PER_CLUSTER-1:0] per_core_dram_req_write; + wire[`NUMBER_CORES_PER_CLUSTER-1:0] per_core_dram_req_read; + wire[`NUMBER_CORES_PER_CLUSTER-1:0] [31:0] per_core_dram_req_addr; + wire[`NUMBER_CORES_PER_CLUSTER-1:0] [31:0] per_core_dram_req_size; + wire[`NUMBER_CORES_PER_CLUSTER-1:0][`DBANK_LINE_SIZE_RNG][31:0] per_core_dram_req_data; + wire[`NUMBER_CORES_PER_CLUSTER-1:0] [31:0] per_core_dram_expected_lat; + + // DRAM Dcache Res + wire[`NUMBER_CORES_PER_CLUSTER-1:0] per_core_dram_fill_accept; + wire[`NUMBER_CORES_PER_CLUSTER-1:0] per_core_dram_fill_rsp; + wire[`NUMBER_CORES_PER_CLUSTER-1:0] [31:0] per_core_dram_fill_rsp_addr; + wire[`NUMBER_CORES_PER_CLUSTER-1:0][`DBANK_LINE_SIZE_RNG][31:0] per_core_dram_fill_rsp_data; + + + // DRAM Icache Req + wire[`NUMBER_CORES_PER_CLUSTER-1:0] per_core_I_dram_req; + wire[`NUMBER_CORES_PER_CLUSTER-1:0] per_core_I_dram_req_write; + wire[`NUMBER_CORES_PER_CLUSTER-1:0] per_core_I_dram_req_read; + wire[`NUMBER_CORES_PER_CLUSTER-1:0] [31:0] per_core_I_dram_req_addr; + wire[`NUMBER_CORES_PER_CLUSTER-1:0] [31:0] per_core_I_dram_req_size; + wire[`NUMBER_CORES_PER_CLUSTER-1:0][`IBANK_LINE_SIZE_RNG][31:0] per_core_I_dram_req_data; + wire[`NUMBER_CORES_PER_CLUSTER-1:0] [31:0] per_core_I_dram_expected_lat; + + // DRAM Icache Res + wire[`NUMBER_CORES_PER_CLUSTER-1:0] per_core_I_dram_fill_accept; + wire[`NUMBER_CORES_PER_CLUSTER-1:0] per_core_I_dram_fill_rsp; + wire[`NUMBER_CORES_PER_CLUSTER-1:0] [31:0] per_core_I_dram_fill_rsp_addr; + wire[`NUMBER_CORES_PER_CLUSTER-1:0][`IBANK_LINE_SIZE_RNG][31:0] per_core_I_dram_fill_rsp_data; + + + + // Snoop Requests + wire[`NUMBER_CORES_PER_CLUSTER-1:0] per_core_dcache_snp_req; + wire[`NUMBER_CORES_PER_CLUSTER-1:0][31:0] per_core_dcache_snp_req_addr; + wire[`NUMBER_CORES_PER_CLUSTER-1:0] per_core_dcache_snp_req_delay; + + wire[`NUMBER_CORES_PER_CLUSTER-1:0] per_core_icache_snp_req; + wire[`NUMBER_CORES_PER_CLUSTER-1:0][31:0] per_core_icache_snp_req_addr; + wire[`NUMBER_CORES_PER_CLUSTER-1:0] per_core_icache_snp_req_delay; + + + // generate + for (curr_core = 0; curr_core < `NUMBER_CORES_PER_CLUSTER; curr_core=curr_core+1) begin + + wire [`IBANK_LINE_SIZE_RNG][31:0] curr_core_I_dram_req_data; + wire [`DBANK_LINE_SIZE_RNG][31:0] curr_core_dram_req_data ; + + // assign io_valid[curr_core*curr_cluster] = per_core_io_valid[curr_core]; + // assign io_data [curr_core*curr_cluster] = per_core_io_data [curr_core]; + Vortex #(.CORE_ID(curr_core+(curr_cluster*`NUMBER_CORES_PER_CLUSTER))) vortex_core( + .clk (clk), + .reset (reset), + .io_valid (io_valid [curr_core+(curr_cluster*`NUMBER_CORES_PER_CLUSTER)]), + .io_data (io_data [curr_core+(curr_cluster*`NUMBER_CORES_PER_CLUSTER)]), + .out_ebreak (per_core_out_ebreak [curr_core+(curr_cluster*`NUMBER_CORES_PER_CLUSTER)]), + .dram_req (per_core_dram_req [curr_core]), + .dram_req_write (per_core_dram_req_write [curr_core]), + .dram_req_read (per_core_dram_req_read [curr_core]), + .dram_req_addr (per_core_dram_req_addr [curr_core]), + .dram_req_size (per_core_dram_req_size [curr_core]), + .dram_req_data (curr_core_dram_req_data ), + .dram_expected_lat (per_core_dram_expected_lat [curr_core]), + .dram_fill_accept (per_core_dram_fill_accept [curr_core]), + .dram_fill_rsp (per_core_dram_fill_rsp [curr_core]), + .dram_fill_rsp_addr (per_core_dram_fill_rsp_addr [curr_core]), + .dram_fill_rsp_data (per_core_dram_fill_rsp_data [curr_core]), + .I_dram_req (per_core_I_dram_req [curr_core]), + .I_dram_req_write (per_core_I_dram_req_write [curr_core]), + .I_dram_req_read (per_core_I_dram_req_read [curr_core]), + .I_dram_req_addr (per_core_I_dram_req_addr [curr_core]), + .I_dram_req_size (per_core_I_dram_req_size [curr_core]), + .I_dram_req_data (curr_core_I_dram_req_data ), + .I_dram_expected_lat (per_core_I_dram_expected_lat [curr_core]), + .I_dram_fill_accept (per_core_I_dram_fill_accept [curr_core]), + .I_dram_fill_rsp (per_core_I_dram_fill_rsp [curr_core]), + .I_dram_fill_rsp_addr (per_core_I_dram_fill_rsp_addr[curr_core]), + .I_dram_fill_rsp_data (per_core_I_dram_fill_rsp_data[curr_core]), + .snp_req (per_core_dcache_snp_req [curr_core]), + .snp_req_addr (per_core_dcache_snp_req_addr [curr_core]), + .snp_req_delay (per_core_dcache_snp_req_delay[curr_core]), + .I_snp_req (per_core_icache_snp_req [curr_core]), + .I_snp_req_addr (per_core_icache_snp_req_addr [curr_core]), + .I_snp_req_delay (per_core_icache_snp_req_delay[curr_core]) + ); + + assign per_core_dram_req_data [curr_core] = curr_core_dram_req_data; + assign per_core_I_dram_req_data[curr_core] = curr_core_I_dram_req_data; + end + // endgenerate + + + //////////////////// L2 Cache //////////////////// + wire[`LLNUMBER_REQUESTS-1:0] l2c_core_req; + wire[`LLNUMBER_REQUESTS-1:0][2:0] l2c_core_req_mem_write; + wire[`LLNUMBER_REQUESTS-1:0][2:0] l2c_core_req_mem_read; + wire[`LLNUMBER_REQUESTS-1:0][31:0] l2c_core_req_addr; + wire[`LLNUMBER_REQUESTS-1:0][`IBANK_LINE_SIZE_RNG][31:0] l2c_core_req_data; + wire[`LLNUMBER_REQUESTS-1:0][1:0] l2c_core_req_wb; + + wire l2c_core_accept; + + wire l2c_snp_fwd; + wire[31:0] l2c_snp_fwd_addr; + wire l2c_snp_fwd_delay; + + assign l2c_snp_fwd_delay = (|per_core_dcache_snp_req_delay) || (|per_core_icache_snp_req_delay); + + + wire[`LLNUMBER_REQUESTS-1:0] l2c_wb; + wire[`LLNUMBER_REQUESTS-1:0] [31:0] l2c_wb_addr; + wire[`LLNUMBER_REQUESTS-1:0][`IBANK_LINE_SIZE_RNG][31:0] l2c_wb_data; + + // endgenerate + + + + // + // generate + for (l2c_curr_core = 0; l2c_curr_core < `LLNUMBER_REQUESTS; l2c_curr_core=l2c_curr_core+2) begin + // Core Request + assign l2c_core_req [l2c_curr_core] = per_core_dram_req [(l2c_curr_core/2)]; + assign l2c_core_req [l2c_curr_core+1] = per_core_I_dram_req[(l2c_curr_core/2)]; + + assign l2c_core_req_mem_write [l2c_curr_core] = per_core_dram_req_write ? `SW_MEM_WRITE : `NO_MEM_WRITE; + assign l2c_core_req_mem_write [l2c_curr_core+1] = `NO_MEM_WRITE; // I caches don't write + + assign l2c_core_req_mem_read [l2c_curr_core] = per_core_dram_req_read ? `LW_MEM_READ : `NO_MEM_READ; + assign l2c_core_req_mem_read [l2c_curr_core+1] = `LW_MEM_READ; // I caches don't write + + assign l2c_core_req_wb [l2c_curr_core] = per_core_dram_req_read ? 1 : 0; + assign l2c_core_req_wb [l2c_curr_core+1] = 1; // I caches don't write + + assign l2c_core_req_addr [l2c_curr_core] = per_core_dram_req_addr [(l2c_curr_core/2)]; + assign l2c_core_req_addr [l2c_curr_core+1] = per_core_I_dram_req_addr[(l2c_curr_core/2)]; + + assign l2c_core_req_data [l2c_curr_core] = per_core_dram_req_data [(l2c_curr_core/2)]; + assign l2c_core_req_data [l2c_curr_core+1] = per_core_I_dram_req_data[(l2c_curr_core/2)]; + + // L2 can't accept requests + assign per_core_dram_fill_accept [(l2c_curr_core/2)] = l2c_core_accept; + assign per_core_I_dram_fill_accept[(l2c_curr_core/2)] = l2c_core_accept; + + // Cache Fill Response + assign per_core_dram_fill_rsp [(l2c_curr_core/2)] = l2c_wb[l2c_curr_core]; + assign per_core_I_dram_fill_rsp [(l2c_curr_core/2)] = l2c_wb[l2c_curr_core+1]; + + assign per_core_dram_fill_rsp_data[(l2c_curr_core/2)] = l2c_wb_data[l2c_curr_core]; + assign per_core_I_dram_fill_rsp_data[(l2c_curr_core/2)] = l2c_wb_data[l2c_curr_core+1]; + + assign per_core_dram_fill_rsp_addr[(l2c_curr_core/2)] = l2c_wb_addr[l2c_curr_core]; + assign per_core_I_dram_fill_rsp_addr[(l2c_curr_core/2)] = l2c_wb_addr[l2c_curr_core+1]; + + assign per_core_dcache_snp_req [(l2c_curr_core/2)] = l2c_snp_fwd; + assign per_core_dcache_snp_req_addr[(l2c_curr_core/2)] = l2c_snp_fwd_addr; + + assign per_core_icache_snp_req [(l2c_curr_core/2)] = l2c_snp_fwd; + assign per_core_icache_snp_req_addr[(l2c_curr_core/2)] = l2c_snp_fwd_addr; + end + // endgenerate + + wire dram_snp_full; + wire dram_req_because_of_wb; + + + VX_cache #( + .CACHE_SIZE_BYTES (`LLCACHE_SIZE_BYTES), + .BANK_LINE_SIZE_BYTES (`LLBANK_LINE_SIZE_BYTES), + .NUMBER_BANKS (`LLNUMBER_BANKS), + .WORD_SIZE_BYTES (`LLWORD_SIZE_BYTES), + .NUMBER_REQUESTS (`LLNUMBER_REQUESTS), + .STAGE_1_CYCLES (`LLSTAGE_1_CYCLES), + .FUNC_ID (`LLFUNC_ID), + .REQQ_SIZE (`LLREQQ_SIZE), + .MRVQ_SIZE (`LLMRVQ_SIZE), + .DFPQ_SIZE (`LLDFPQ_SIZE), + .SNRQ_SIZE (`LLSNRQ_SIZE), + .CWBQ_SIZE (`LLCWBQ_SIZE), + .DWBQ_SIZE (`LLDWBQ_SIZE), + .DFQQ_SIZE (`LLDFQQ_SIZE), + .LLVQ_SIZE (`LLLLVQ_SIZE), + .FFSQ_SIZE (`LLFFSQ_SIZE), + .FILL_INVALIDAOR_SIZE (`LLFILL_INVALIDAOR_SIZE), + .SIMULATED_DRAM_LATENCY_CYCLES(`LLSIMULATED_DRAM_LATENCY_CYCLES) + ) + gpu_l2cache + ( + .clk (clk), + .reset (reset), + + // Core Req (DRAM Fills/WB) To L2 Request + .core_req_valid (l2c_core_req), + .core_req_addr (l2c_core_req_addr), + .core_req_writedata({l2c_core_req_data}), + .core_req_mem_read (l2c_core_req_mem_read), + .core_req_mem_write(l2c_core_req_mem_write), + .core_req_rd (0), + .core_req_wb (l2c_core_req_wb), + .core_req_warp_num (0), + .core_req_pc (0), + + // L2 can't accept Core Request + .delay_req (l2c_core_accept), + + // Core can't accept L2 Request + .core_no_wb_slot (0), + + // Core Writeback + .core_wb_valid (l2c_wb), + .core_wb_req_rd (), + .core_wb_req_wb (), + .core_wb_warp_num (), + .core_wb_readdata ({l2c_wb_data}), + .core_wb_address (l2c_wb_addr), + .core_wb_pc (), + + // L2 Cache DRAM Fill response + .dram_fill_rsp (dram_fill_rsp[curr_cluster]), + .dram_fill_rsp_addr(dram_fill_rsp_addr[curr_cluster]), + .dram_fill_rsp_data({dram_fill_rsp_data[curr_cluster]}), + + // L2 Cache can't accept Fill Response + .dram_fill_accept (dram_fill_accept), + + // L2 Cache DRAM Fill Request + .dram_req (dram_req[curr_cluster]), + .dram_req_write (dram_req_write[curr_cluster]), + .dram_req_read (dram_req_read[curr_cluster]), + .dram_req_addr (dram_req_addr[curr_cluster]), + .dram_req_size (dram_req_size[curr_cluster]), + .dram_req_data ({dram_req_data[curr_cluster]}), + + // Snoop Response + .dram_req_because_of_wb(dram_req_because_of_wb), + .dram_snp_full (dram_snp_full), + + // Snoop Request + .snp_req (l3c_snp_fwd), + .snp_req_addr (l3c_snp_fwd_addr), + .snp_req_delay (l3c_snp_fwd_delay_temp[curr_cluster]), + + .snp_fwd (l2c_snp_fwd), + .snp_fwd_addr (l2c_snp_fwd_addr), + .snp_fwd_delay (l2c_snp_fwd_delay) + ); + + // // Snoop Request + // .snp_req (VX_gpu_icache_snp_req.snp_req), + // .snp_req_addr (VX_gpu_icache_snp_req.snp_req_addr), + // .snp_req_delay (VX_gpu_icache_snp_req.snp_delay), + + + + //////////////////// L2 Cache //////////////////// + + + //////////////////// END CLUSTER /////////////////// + end + endgenerate diff --git a/rtl/interfaces/VX_gpu_snp_req_rsp.v b/rtl/interfaces/VX_gpu_snp_req_rsp.v new file mode 100644 index 00000000..154abc0b --- /dev/null +++ b/rtl/interfaces/VX_gpu_snp_req_rsp.v @@ -0,0 +1,20 @@ +`include "../VX_cache/VX_cache_config.v" + +`ifndef VX_GPU_SNP_REQ_RSP + +`define VX_GPU_SNP_REQ_RSP + +interface VX_gpu_snp_req_rsp + (); + + // Snoop request + wire snp_req; + wire[31:0] snp_req_addr; + + // Snoop Response + wire snp_delay; + +endinterface + + +`endif \ No newline at end of file diff --git a/rtl/simulate/multi_test_bench.h b/rtl/simulate/multi_test_bench.h index 1b26b483..1e783ca0 100644 --- a/rtl/simulate/multi_test_bench.h +++ b/rtl/simulate/multi_test_bench.h @@ -209,15 +209,15 @@ bool Vortex::dbus_driver() } - if (vortex->dram_req) + if (vortex->out_dram_req) { - if (vortex->dram_req_read) + if (vortex->out_dram_req_read) { // Need to add an element dram_req_t dram_req; - dram_req.cycles_left = vortex->dram_expected_lat; - dram_req.data_length = vortex->dram_req_size / 4; - dram_req.base_addr = vortex->dram_req_addr; + dram_req.cycles_left = vortex->out_dram_expected_lat; + dram_req.data_length = vortex->out_dram_req_size / 4; + dram_req.base_addr = vortex->out_dram_req_addr; dram_req.data = (unsigned *) malloc(dram_req.data_length * sizeof(unsigned)); for (int i = 0; i < dram_req.data_length; i++) @@ -231,29 +231,29 @@ bool Vortex::dbus_driver() this->dram_req_vec.push_back(dram_req); } - if (vortex->dram_req_write) + if (vortex->out_dram_req_write) { - unsigned base_addr = vortex->dram_req_addr; - unsigned data_length = vortex->dram_req_size / 4; + unsigned base_addr = vortex->out_dram_req_addr; + unsigned data_length = vortex->out_dram_req_size / 4; for (int i = 0; i < data_length; i++) { unsigned curr_addr = base_addr + (i*4); - unsigned data_wr = vortex->dram_req_data[i]; + unsigned data_wr = vortex->out_dram_req_data[i]; ram.writeWord(curr_addr, &data_wr); } } } - if (vortex->dram_fill_accept && dequeue_valid) + if (vortex->out_dram_fill_accept && dequeue_valid) { - vortex->dram_fill_rsp = 1; - vortex->dram_fill_rsp_addr = this->dram_req_vec[dequeue_index].base_addr; + vortex->out_dram_fill_rsp = 1; + vortex->out_dram_fill_rsp_addr = this->dram_req_vec[dequeue_index].base_addr; // std::cout << "Fill Rsp -> Addr: " << std::hex << (this->dram_req_vec[dequeue_index].base_addr) << std::dec << "\n"; for (int i = 0; i < this->dram_req_vec[dequeue_index].data_length; i++) { - vortex->dram_fill_rsp_data[i] = this->dram_req_vec[dequeue_index].data[i]; + vortex->out_dram_fill_rsp_data[i] = this->dram_req_vec[dequeue_index].data[i]; } free(this->dram_req_vec[dequeue_index].data); @@ -261,8 +261,8 @@ bool Vortex::dbus_driver() } else { - vortex->dram_fill_rsp = 0; - vortex->dram_fill_rsp_addr = 0; + vortex->out_dram_fill_rsp = 0; + vortex->out_dram_fill_rsp_addr = 0; } return false;