From 6340ffcc2ab06c4d27002e6bbcc0facfe30a2969 Mon Sep 17 00:00:00 2001 From: felsabbagh3 Date: Wed, 23 Oct 2019 15:07:14 -0400 Subject: [PATCH] new cache states --- rtl/VX_dmem_controller.v | 12 +- rtl/cache/VX_cache_bank_valid.v | 23 ++ rtl/cache/VX_d_cache.v | 538 ++++-------------------------- rtl/cache/VX_d_cache_old.v | 568 ++++++++++++++++++++++++++++++++ 4 files changed, 661 insertions(+), 480 deletions(-) create mode 100644 rtl/cache/VX_cache_bank_valid.v create mode 100644 rtl/cache/VX_d_cache_old.v diff --git a/rtl/VX_dmem_controller.v b/rtl/VX_dmem_controller.v index df9d50da..d6711e67 100644 --- a/rtl/VX_dmem_controller.v +++ b/rtl/VX_dmem_controller.v @@ -33,7 +33,7 @@ module VX_dmem_controller ( wire[`NT_M1:0][31:0] sm_driver_out_data; wire[`NT_M1:0] cache_driver_out_valid; // Not used for now wire sm_delay; - wire cache_delay; + wire cache_done; VX_shared_memory #(.NB(7), .BITS_PER_BANK(3)) shared_memory ( @@ -49,18 +49,15 @@ module VX_dmem_controller ( ); - VX_d_cache dcache( .clk (clk), .rst (reset), - .i_p_valid (cache_driver_in_valid), + .i_p_valid (cache_driver_in_valid), .i_p_addr (cache_driver_in_address), - .i_p_initial_request(), .i_p_writedata (cache_driver_in_data), .i_p_read_or_write (read_or_write), .o_p_readdata (cache_driver_out_data), - .o_p_readdata_valid (), - .o_p_waitrequest (cache_delay), + .o_p_waitrequest (cache_done), .o_m_addr (VX_dram_req_rsp.o_m_addr), .o_m_valid (VX_dram_req_rsp.o_m_valid), .o_m_writedata (VX_dram_req_rsp.o_m_writedata), @@ -71,7 +68,8 @@ module VX_dmem_controller ( assign VX_dcache_rsp.in_cache_driver_out_data = to_shm ? sm_driver_out_data : cache_driver_out_data; - assign VX_dcache_rsp.delay = sm_delay || cache_delay; + // assign VX_dcache_rsp.delay = sm_delay; + assign VX_dcache_rsp.delay = sm_delay || (!cache_done); endmodule \ No newline at end of file diff --git a/rtl/cache/VX_cache_bank_valid.v b/rtl/cache/VX_cache_bank_valid.v new file mode 100644 index 00000000..e3dd144e --- /dev/null +++ b/rtl/cache/VX_cache_bank_valid.v @@ -0,0 +1,23 @@ +`include "../VX_define.v" + +module VX_cache_bank_valid +#( + parameter NUMBER_BANKS = 0 +) +( + input wire [`NT_M1:0] i_p_valid, + input wire [`NT_M1:0][31:0] i_p_addr, + output wire [NUMBER_BANKS - 1 : 0][`NT_M1:0] thread_track_banks +); + + + + + genvar t_id; + for (t_id = 0; t_id <= `NT_M1; t_id = t_id + 1) + begin + wire[2:0] threads_bank = i_p_addr[t_id][4:2]; + assign thread_track_banks[threads_bank][t_id] = i_p_valid[t_id]; + end + +endmodule \ No newline at end of file diff --git a/rtl/cache/VX_d_cache.v b/rtl/cache/VX_d_cache.v index 82216b99..0c1637f2 100644 --- a/rtl/cache/VX_d_cache.v +++ b/rtl/cache/VX_d_cache.v @@ -16,7 +16,6 @@ module VX_d_cache(clk, rst, - i_p_initial_request, i_p_addr, //i_p_byte_en, i_p_writedata, @@ -24,7 +23,6 @@ module VX_d_cache(clk, i_p_valid, //i_p_write, o_p_readdata, - o_p_readdata_valid, o_p_waitrequest, // 0 = all threads done | 1 = Still threads that need to o_m_addr, @@ -90,503 +88,102 @@ module VX_d_cache(clk, //input wire i_m_waitrequest; input wire i_m_ready; - //output reg [31:0] cnt_r; - //output reg [31:0] cnt_w; - //output reg [31:0] cnt_hit_r; - //output reg [31:0] cnt_hit_w; - //output reg [31:0] cnt_wb_r; - //output reg [31:0] cnt_wb_w; - - //wire [1:0] tag [`NT_M1:0]; - //wire [3:0] index [`NT_M1:0]; - //wire [2:0] bank [`NT_M1:0]; - //wire all_done; - - //integer i; - reg [`NT_M1:0] thread_done; // Maybe should have "thread_serviced" and "thread_done", serviced==checked cache - //reg [`NT_M1:0] thread_serviced; // Maybe should have "thread_serviced" and "thread_done", serviced==checked cache - reg [NUMBER_BANKS - 1:0] banks_ready; - //reg [NUMBER_BANKS - 1:0] banks_missed; - reg [NUMBER_BANKS - 1:0] banks_to_service; - reg [NUMBER_BANKS - 1:0] banks_wb_needed; - reg [NUMBER_BANKS - 1:0][31:0] banks_wb_addr; - //reg [NUMBER_BANKS - 1:0] bank_states; - //reg [NUMBER_BANKS - 1:0][31:0] banks_wb_data; - //reg [NUMBER_BANKS - 1:0][13:0] banks_in_addr; - +// Actual logic reg [3:0] state; - reg [NUMBER_BANKS - 1:0][31:0] data_from_bank; - //reg got_valid_data; - //reg [31:0] data_to_write; + wire[3:0] new_state; + + reg [`NT_M1:0][31:0] final_data_read; + wire[`NT_M1:0][31:0] new_final_data_read; + + wire[NUMBER_BANKS-1:0] readdata_per_bank; + + wire[NUMBER_BANKS-1:0] hit_per_bank; + + wire[`NT_M1:0] use_valid; + reg[`NT_M1:0] stored_valid; + wire[`NT_M1:0] new_stored_valid; - //reg [`NT_M1:0] thread_track_bank_0; - //reg [`NT_M1:0] thread_track_bank_1; - //reg [`NT_M1:0] thread_track_bank_2; - //reg [`NT_M1:0] thread_track_bank_3; - //reg [`NT_M1:0] thread_track_bank_4; - //reg [`NT_M1:0] thread_track_bank_5; - //reg [`NT_M1:0] thread_track_bank_6; - //reg [`NT_M1:0] thread_track_bank_7; - reg [NUMBER_BANKS - 1 : 0][`NT_M1:0] thread_track_banks; - reg [NUMBER_BANKS - 1 : 0] bank_has_access; // Will track if a bank has been accessed in this cycle - reg [NUMBER_BANKS - 1 : 0][31:0] bank_access_addr; - reg [NUMBER_BANKS - 1 : 0][31:0] bank_access_data; - reg [NUMBER_BANKS - 1 : 0][1:0] threads_in_banks; + wire[NUMBER_BANKS - 1 : 0][$clog2(`NT)-1:0] index_per_bank; + wire[NUMBER_BANKS - 1 : 0] valid_per_bank; - //reg [1:0] thread_in_memory; // keeps track of threadID which is in memory - reg rd_or_wr; - //reg did_miss, needs_service; Commented out Oct 21 + assign use_valid = (stored_valid == 0) ? i_p_valid : stored_valid; - integer bnk; - integer found; - integer t_id; - //integer num_misses; - //integer num_evictions_to_wb; - integer i; //reg [1:0] correct_tag; - integer index; - //reg [3:0] correct_index; - //assign tag = i_p_addr[13:12]; + wire[NUMBER_BANKS - 1 : 0][`NT_M1:0] thread_track_banks; - assign o_p_waitrequest = (thread_done == 4'hF) ? 1'b0 : 1'b1; // change thread_done to be generic - //assign did_miss = (banks_missed != 8'h0) ? 1'b1 : 1'b0; - //assign needs_service = ((banks_to_service != 8'b0 || banks_to_service_temp != 8'b0)) ? 1'b1 : 1'b0; // added banks_to_service temp - //assign w_Test1 = r_Check ? 1'b1 : 1'b0; - //for ( i = 0;i < `NT_M1;i = i + 1) begin - // assign tag[i] = i_p_addr[i][13:12]; + VX_cache_bank_valid #(.NUMBER_BANKS(NUMBER_BANKS)) multip_banks( + .i_p_valid (use_valid), + .i_p_addr (i_p_addr), + .thread_track_banks(thread_track_banks) + ); - // Fares -// wire no_bank_misses; -// assign no_bank_misses = banks_to_service != 8'b0; - reg[NUMBER_BANKS - 1:0] banks_to_service_temp; - reg[NUMBER_BANKS - 1:0] banks_to_wb; - reg[NUMBER_BANKS - 1:0] banks_to_wb_temp; - reg[NUMBER_BANKS - 1:0] banks_all_help; + reg detect_bank_conflict; + genvar bank_ind; + for (bank_ind = 0; bank_ind < NUMBER_BANKS; bank_ind=bank_ind+1) + begin + detect_bank_conflict = detect_bank_conflict | ($countones(thread_track_banks[bank_ind]) > 1); + VX_generic_priority_encoder #(.N(1)) choose_thread( + .valids(thread_track_banks[bank_ind]), + .index (index_per_bank[bank_ind]), + .found (valid_per_bank[bank_ind]) + ); - always @(posedge clk) begin - if (rst) begin - state <= 0; - //banks_ready <= 8'b0; - //cnt_r <= 0; - //cnt_w <= 0; - //cnt_hit_r <= 0; - //cnt_hit_w <= 0; - //cnt_wb_r <= 0; - //cnt_wb_w <= 0; + //////////////// - end else begin - // Change Logic of which state the cache is in - case (state) - CACHE_IDLE:begin - if (i_p_initial_request == 1'b1) begin - state <= SORT_BY_BANK; - end else begin - state <= CACHE_IDLE; - end - end - SORT_BY_BANK:begin - state <= INITIAL_ACCESS; - end - INITIAL_ACCESS:begin - if (thread_done == 4'hF) begin - state <= CACHE_IDLE; - end else begin - state <= INITIAL_PROCESSING; - end - end - INITIAL_PROCESSING:begin - if (bank_has_access == banks_ready ) begin // if all hits - state <= INITIAL_ACCESS; - end else begin - state <= CONTINUED_PROCESSING; - end + assign new_final_data_read[index_per_bank[bank_ind]] = hit_per_bank ? readdata_per_bank[bank_ind] : 0; - end - CONTINUED_PROCESSING:begin - if (banks_to_wb == 8'b0 && banks_to_service == 8'b0) begin // If all threads are done, then the cache can go back into idle state (not currently fetching any requests) - state <= INITIAL_ACCESS; - //end else if (num_misses > 0) begin - end else if ((banks_to_wb != 8'b0)) begin // change 1pm - state <= DIRTY_EVICT_GRAB_BLOCK; - //end else if (did_miss == 1'b1 || needs_service == 1'b1) begin - end else if(banks_to_service != 8'b0) begin - state <= FETCH_FROM_MEM; - // end else if (did_miss == 1'b0 && num_evictions_to_wb > 0) begin - //end else if (needs_service == 1'b0 && did_miss == 1'b0 && (banks_to_wb != 8'b0)) begin - //end else if (did_miss == 1'b0 && needs_service == 1'b0) begin - //state <= INITIAL_ACCESS; - end - end - FETCH_FROM_MEM:begin - state <= FETCH2; - end - FETCH2:begin - if (i_m_ready == 1'b1) begin - state <= UPDATE_CACHE; // Not sure about this one !!!!!! Check - end else begin - state <= FETCH2; - end - end - UPDATE_CACHE:begin - state <= RE_ACCESS; - end - RE_ACCESS:begin - state <= RE_ACCESS_PROCESSING; - end - RE_ACCESS_PROCESSING: begin - state <= CONTINUED_PROCESSING; - end - DIRTY_EVICT_GRAB_BLOCK:begin - state <= DIRTY_EVICT_WB; - end - DIRTY_EVICT_WB:begin - state <= CONTINUED_PROCESSING; - end - endcase - end - - //tag[`NT_M1:0] <= i_p_addr[`NT_M1:0][13:12]; end - // Change values which will be fed into the cache - always @(*) begin - case (state) - CACHE_IDLE:begin - thread_done = 0; - o_m_read_or_write = 0; - o_m_valid = 0; - o_m_writedata = 0; - o_p_readdata = 0; - o_p_readdata_valid = 0; - bank_has_access = 8'b0; - //bank_states = CACHE_IDLE; - //thread_track_bank_0 = 4'b0; - //thread_track_bank_1 = 4'b0; - //thread_track_bank_2 = 4'b0; - //thread_track_bank_3 = 4'b0; - //thread_track_bank_4 = 4'b0; - //thread_track_bank_5 = 4'b0; - //thread_track_bank_6 = 4'b0; - //thread_track_bank_7 = 4'b0; - for (bnk = 0; bnk < NUMBER_BANKS; bnk = bnk + 1) begin - thread_track_banks[bnk] = 4'b0; - end - end - SORT_BY_BANK:begin - //bank_states = SORT_BY_BANK; - rd_or_wr = i_p_read_or_write; - for (t_id = 0; t_id <= `NT_M1; t_id = t_id + 1) begin - //t_id = {1'b0,t_id}; - if (i_p_valid[t_id] == 1'b0) begin - thread_done[t_id] = 1'b1; - end - //if (i_p_valid[t_id] == 1'b1 && thread_done[t_id] == 1'b0) begin // Need logic for thread done - else if (i_p_addr[t_id][4:2] == 3'b000) begin - //banks_in_addr[0] = i_p_addr[t_id]; // WIll need to do this later - //thread_track_bank_0[t_id] = 1'b1; - thread_track_banks[0][t_id] = 1'b1; - end - else if (i_p_addr[t_id][4:2] == 3'b001) begin // !!!!!!! - //banks_in_addr[0] = i_p_addr[t_id]; // WIll need to do this later - //thread_track_bank_1[t_id] = 1'b1; - thread_track_banks[1][t_id] = 1'b1; - end - else if (i_p_addr[t_id][4:2] == 3'b010) begin - //banks_in_addr[0] = i_p_addr[t_id]; // WIll need to do this later - //thread_track_bank_2[t_id] = 1'b1; - thread_track_banks[2][t_id] = 1'b1; - end - else if (i_p_addr[t_id][4:2] == 3'b011) begin - //banks_in_addr[0] = i_p_addr[t_id]; // WIll need to do this later - //thread_track_bank_3[t_id] = 1'b1; - thread_track_banks[3][t_id] = 1'b1; - end - else if (i_p_addr[t_id][4:2] == 3'b100) begin - //banks_in_addr[0] = i_p_addr[t_id]; // WIll need to do this later - //thread_track_bank_4[t_id] = 1'b1; - thread_track_banks[4][t_id] = 1'b1; - end - else if (i_p_addr[t_id][4:2] == 3'b101) begin - //banks_in_addr[0] = i_p_addr[t_id]; // WIll need to do this later - //thread_track_bank_5[t_id] = 1'b1; - thread_track_banks[5][t_id] = 1'b1; - end - else if (i_p_addr[t_id][4:2] == 3'b110) begin - //banks_in_addr[0] = i_p_addr[t_id]; // WIll need to do this later - //thread_track_bank_6[t_id] = 1'b1; - thread_track_banks[6][t_id] = 1'b1; - end - else if (i_p_addr[t_id][4:2] == 3'b111) begin - //banks_in_addr[0] = i_p_addr[t_id]; // WIll need to do this later - //thread_track_bank_7[t_id] = 1'b1; - thread_track_banks[7][t_id] = 1'b1; - end - end - end - INITIAL_ACCESS:begin - //bank_states = INITIAL_ACCESS; - o_m_valid = 1'b0; - // Before Access -// if (no_bank_misses) begin - // Dont do anything, next clock cycle it will switch back to (Fetch from mem) -// end else begin // Do logic to send requests to each bank (look through thread_track_bank regs) - bank_has_access = 8'b0; - for (t_id = 0; t_id <= `NT_M1; t_id = t_id + 1) begin - for (bnk = 0; bnk < NUMBER_BANKS; bnk = bnk + 1) begin - if(thread_track_banks[bnk][t_id] == 1'b1 && bank_has_access[bnk] == 1'b0) begin - bank_has_access[bnk] = 1'b1; - bank_access_data[bnk] = i_p_writedata[t_id]; - bank_access_addr[bnk] = i_p_addr[t_id]; - threads_in_banks[bnk] = t_id[1:0]; - end - end - //if (banks_wb_needed[bnk]) begin // need to fix this for multiple misses - //o_m_read_or_write = 1'b0; - //o_m_addr = banks_wb_addr[bnk]; - //o_m_valid = 1'b1; - //o_m_writedata = {banks_wb_data[bnk], 96'b0}; - //end - //if(thread_track_bank_0[t_id] == 1'b1 && bank_has_access[0] == 1'b0) begin - //bank_has_access[0] = 1'b1; - //bank_access_data[0] = i_p_writedata[t_id]; - //bank_access_addr[0] = i_p_addr[t_id]; - //threads_in_banks[0] = t_id; - //end - // NEED TO UPDATE HITS (STORE IN THREADS_DONE) - end - //num_misses = {28'b0, $countones(banks_missed)}; - //did_miss = (banks_missed == 4'hF); - -// end + wire[NUMBER_BANKS - 1 : 0] detect_bank_miss = (valid_per_bank & ~hit_per_bank); + + wire delay; + assign delay = (new_stored_valid != 0); // add other states + // assign delay = detect_bank_conflict || (|detect_bank_miss) || (state != CACHE_IDLE); // add other states - end - INITIAL_PROCESSING:begin - //bank_has_access = 8'b0; - for (bnk = 0; bnk < NUMBER_BANKS; bnk = bnk + 1) begin - if(banks_ready[bnk]) begin // FIX to handle hits - thread_done[threads_in_banks[bnk]] = 1'b1; - o_p_readdata[threads_in_banks[bnk]] = data_from_bank[bnk]; - if(i_p_read_or_write == 1'b0) begin - o_p_readdata_valid[threads_in_banks[bnk]] = 1'b1; - end - thread_track_banks[bnk][threads_in_banks[bnk]] = 1'b0; // Update that this thread does not need to be serviced again - end - end - //banks_to_service_temp = !banks_ready; // These are clean misses - for (bnk = 0; bnk < NUMBER_BANKS; bnk = bnk + 1) begin - assign banks_to_service_temp[bnk] = (banks_ready[bnk] || (bank_has_access[bnk] == 0)) ? 1'b0 : 1'b1; - assign banks_to_wb_temp[bnk] = (banks_wb_needed[bnk]); - assign banks_all_help[bnk] = banks_to_service_temp[bnk] || banks_to_wb_temp[bnk]; - end - end - CONTINUED_PROCESSING:begin - //for (i = `NW-1; i >= 0; i = i - 1) begin - // if (thread_done[threads_in_banks[bnk]] == 1'b1) begin // Not sure about this logic - // //index = i[`NW_M1:0]; - // banks_to_service_temp[i] = 1'b0; - // banks_to_wb_temp[i] = 1'b0; - // end - //end - end - FETCH_FROM_MEM:begin - // NEED TO ADD LOGIC TO SEE IF MISSES GO TO SAME BLOCK - index = 0; - found = 0; - for (i = `NW-1; i >= 0; i = i - 1) begin - if (banks_to_service[i]) begin // Not sure about this logic - //index = i[`NW_M1:0]; - index = i; - found = 1; - end - end - if (found == 1) begin - //banks_missed[index] = 0; - //thread_done - - //thread_in_memory = threads_in_banks[index]; - //o_m_writedata = bank_access_data[index]; - banks_to_service_temp[index] = 0; - o_m_addr = bank_access_addr[index]; - o_m_valid = 1'b1; - o_m_read_or_write = 1'b0; - end - //bank_states = FETCH_FROM_MEM; - end - FETCH2:begin - o_m_valid = 1'b0; - end - UPDATE_CACHE:begin - for (bnk = 0; bnk < NUMBER_BANKS; bnk = bnk + 1) begin - //if(thread_track_banks[bnk][t_id] == 1'b1 && bank_has_access[bnk] == 1'b0) begin - bank_has_access[bnk] = 1'b1; - //bank_access_data[bnk] = i_m_readdata[(bnk+1)*32 - 1:bnk*32]; - bank_access_addr[bnk] = o_m_addr; - threads_in_banks[bnk] = t_id[1:0]; - //end - end - //bank_access_data = i_m_readdata; - rd_or_wr = 1'b1; - //thread_done[thread_in_memory] = 1'b1; // Removed, new cache style - Oct 21 - //o_p_readdata[thread_in_memory] = i_m_readdata[i_p_addr[thread_in_memory][9:5]]; // Removed, new cache style - end - DIRTY_EVICT_WB:begin // this begininng logic should be added to dirty evict grab block + wire[NUMBER_BANKS - 1 : 0][$clog2(`NT)-1:0] send_index_to_bank = index_per_bank; - //thread_done[thread_in_memory] = 1'b1; - o_m_valid = 1'b1; - end - DIRTY_EVICT_GRAB_BLOCK:begin - index = 0; - found = 0; - for (i = `NW-1; i >= 0; i = i - 1) begin - if (banks_to_wb_temp[i]) begin - //index = i[`NW_M1:0]; - index = i; - found = 1; - end - end - if (found == 1) begin - banks_to_wb_temp[index] = 0; - for (i = `NW-1; i >= 0; i = i - 1) begin - if (banks_to_wb_temp[i] && banks_wb_addr[index][31:7] == banks_wb_addr[i][31:7]) begin - //index = i[`NW_M1:0]; - banks_to_wb_temp[i] = 0; - end - end - //thread_done - //thread_in_memory = threads_in_banks[index]; - //o_m_writedata[(bnk+1)*32 - 1:bnk*32] = banks_wb_data[index]; - o_m_addr = banks_wb_addr[index]; - o_m_read_or_write = 1'b1; - end - //for (bnk = 0; bnk < NUMBER_BANKS; bnk = bnk + 1) begin - //o_m_writedata[(bnk+1)*32 - 1:bnk*32] = banks_wb_data[index]; - //end - // NEXT LINE CONTAINS DATA TO WB !!!! Think need to just change this to be read data and can remove banks_wb_data - //o_m_writedata = {banks_wb_data[7],banks_wb_data[6],banks_wb_data[5],banks_wb_data[4],banks_wb_data[3],banks_wb_data[2],banks_wb_data[1],banks_wb_data[0]}; - //num_evictions_to_wb = {28'b0, $countones(banks_wb_needed)}; - rd_or_wr = 1'b0; - for (bnk = 0; bnk < NUMBER_BANKS; bnk = bnk + 1) begin - //if(thread_track_banks[bnk][t_id] == 1'b1 && bank_has_access[bnk] == 1'b0) begin - bank_has_access[bnk] = 1'b1; - bank_access_addr[bnk] = o_m_addr; - //end - end - end - RE_ACCESS:begin - //bank_states = INITIAL_ACCESS; - o_m_valid = 1'b0; - - // Before Access -// if (no_bank_misses) begin - // Dont do anything, next clock cycle it will switch back to (Fetch from mem) -// end else begin // Do logic to send requests to each bank (look through thread_track_bank regs) - //bank_has_access = banks_all_help & !(banks_to_wb) & !(banks_to_service); - for (t_id = 0; t_id <= `NT_M1; t_id = t_id + 1) begin - for (bnk = 0; bnk < NUMBER_BANKS; bnk = bnk + 1) begin - //bank_has_access[bnk] = banks_all_help[bnk] && !thread_done[threads_in_banks[bnk]]; // Not sure - bank_has_access[bnk] = banks_all_help[bnk] && !thread_done[t_id]; // Not sure - if(thread_track_banks[bnk][t_id] == 1'b1 && bank_has_access[bnk] == 1'b1) begin - //bank_has_access[bnk] = 1'b1; - bank_access_data[bnk] = i_p_writedata[t_id]; - bank_access_addr[bnk] = i_p_addr[t_id]; - threads_in_banks[bnk] = t_id[1:0]; - end - end - end +// End actual logic + - end - RE_ACCESS_PROCESSING:begin - // After Access - for (bnk = 0; bnk < NUMBER_BANKS; bnk = bnk + 1) begin - if(banks_ready[bnk]) begin // FIX to handle hits - thread_done[threads_in_banks[bnk]] = 1'b1; - o_p_readdata[threads_in_banks[bnk]] = data_from_bank[bnk]; - if(i_p_read_or_write == 1'b0) begin - o_p_readdata_valid[threads_in_banks[bnk]] = 1'b1; - end - thread_track_banks[bnk][threads_in_banks[bnk]] = 1'b0; // Update that this thread does not need to be serviced again - // Added Oct 21 - banks_to_service_temp[bnk] = 1'b0; - banks_to_wb_temp[bnk] = 1'b0; - end - end - end + assign new_state = detect_bank_miss ? DIRTY_EVICT_WB : CACHE_IDLE; - endcase - end - - always @(posedge clk) begin - banks_to_service <= banks_to_service_temp; - banks_to_wb <= banks_to_wb_temp; - end + // Handle if there is more than one miss + assign new_stored_valid = (state == CACHE_IDLE) ? ( & ~hit_per_bank); genvar bank_id; generate for (bank_id = 0; bank_id < NUMBER_BANKS; bank_id = bank_id + 1) begin - //VX_alu vx_alu( - // .in_reg_data (in_reg_data[1:0]), - // .in_1 (in_a_reg_data[index_out_reg]), - // .in_2 (in_b_reg_data[index_out_reg]), - // .in_rs2_src (in_rs2_src), - // .in_itype_immed(in_itype_immed), - // .in_upper_immed(in_upper_immed), - // .in_alu_op (in_alu_op), - // .in_csr_data (in_csr_data), - // .in_curr_PC (in_curr_PC), - // .out_alu_result(VX_exe_mem_req.alu_result[index_out_reg]) - //); -// bank VX_banks( -// .clk (clk), -// .rst (rst), -// //.state (bank_states[bank_id]), -// .state (state), -// .read_or_write (rd_or_wr), -// //.index (correct_index), -// //.tag (correct_tag), -// .addr (bank_access_addr[bank_id]), -// .writedata (bank_access_data[bank_id]), -// .fetched_write_data(i_m_readdata[(bank_id+1)*32-1 -: 32]), -// .valid (bank_has_access[bank_id]), -// .readdata (data_from_bank[bank_id]), -// .miss_cache (banks_missed[bank_id]), -// .w2m_needed (banks_wb_needed[bank_id]), -// .w2m_addr (banks_wb_addr[bank_id]), -// .e_data (o_m_writedata[(bank_id+1)*32-1 -: 32]), -// //.w2m_data (banks_wb_data[bank_id]), -// .ready (banks_ready[bank_id]) -// //.valid_data (valid_in_set) -// //.read_miss (read_miss) -// ); - + wire[31:0] bank_addr = i_p_addr[send_index_to_bank[bank_ind]]; + wire[7:0] cache_index = bank_addr[14:7]; + wire[16:0] cache_tag = bank_addr[31:15]; + wire[1:0] cache_offset = bank_addr[6:5]; VX_Cache_Bank bank_structure ( - .clk (clk), - .state (state), - .read_or_write (rd_or_wr), - .valid_in (bank_has_access[bank_id]), - .actual_index (bank_access_addr[bank_id][14:7]), // fix when size changes - .o_tag (bank_access_addr[bank_id][31:15]), // fix when size changes - .block_offset (bank_access_addr[bank_id][6:5]), - .writedata (bank_access_data[bank_id]), - //.fetched_writedata (i_m_readdata[(bank_id+1)*32-1 -: 32]), - .fetched_writedata (i_m_readdata[bank_id[3:0]]), - .readdata (data_from_bank[bank_id]), - .hit (banks_ready[bank_id]), - //.miss (banks_missed[bank_id]), - .eviction_wb (banks_wb_needed[bank_id]), - .eviction_addr (banks_wb_addr[bank_id]), - //.data_evicted (o_m_writedata[(bank_id+1)*32-1 -: 32]) - .data_evicted (o_m_writedata[bank_id[3:0]]) + .clk (clk), + .state (state), + .valid_in (valid_per_bank[bank_ind]) + .actual_index (cache_index), + .o_tag (cache_tag), + .block_offset (cache_offset), + .writedata (i_p_writedata[send_index_to_bank[bank_ind]]), + .read_or_write (rd_or_wr), + .hit (hit_per_bank[bank_ind]), + .readdata (readdata_per_bank[bank_ind]), // Data read + + .fetched_writedata(fetched_writedata), // From memory + .eviction_wb (eviction_wb), + .eviction_addr (eviction_addr), + .data_evicted (data_evicted) ); end @@ -594,9 +191,4 @@ module VX_d_cache(clk, //end -endmodule - - - - - +endmodule \ No newline at end of file diff --git a/rtl/cache/VX_d_cache_old.v b/rtl/cache/VX_d_cache_old.v new file mode 100644 index 00000000..e8361055 --- /dev/null +++ b/rtl/cache/VX_d_cache_old.v @@ -0,0 +1,568 @@ +// Cache Memory (8way 4word) // +// i_ means input port // +// o_ means output port // +// _p_ means data exchange with processor // +// _m_ means data exchange with memory // + + +// TO DO: +// - Send in a response from memory of what the data is from the test bench + +`include "VX_define.v" +//`include "VX_priority_encoder.v" +`include "VX_Cache_Bank.v" +//`include "cache_set.v" + + +module VX_d_cache(clk, + rst, + i_p_initial_request, + i_p_addr, + //i_p_byte_en, + i_p_writedata, + i_p_read_or_write, // 0 = Read | 1 = Write + i_p_valid, + //i_p_write, + o_p_readdata, + o_p_readdata_valid, + o_p_waitrequest, // 0 = all threads done | 1 = Still threads that need to + + o_m_addr, + //o_m_byte_en, + o_m_writedata, + + o_m_read_or_write, // 0 = Read | 1 = Write + o_m_valid, + //o_m_write, + i_m_readdata, + + //i_m_readdata_ready, + //i_m_waitrequest, + i_m_ready + + //cnt_r, + //cnt_w, + //cnt_hit_r, + //cnt_hit_w + //cnt_wb_r, + //cnt_wb_w + ); + + parameter NUMBER_BANKS = 8; + + localparam CACHE_IDLE = 0; // Idle + localparam SORT_BY_BANK = 1; // Determines the bank each thread will access + localparam INITIAL_ACCESS = 2; // Accesses the bank and checks if it is a hit or miss + localparam INITIAL_PROCESSING = 3; // Check to see if there were misses + localparam CONTINUED_PROCESSING = 4; // Keep checking status of banks that need to be written back or fetched + localparam DIRTY_EVICT_GRAB_BLOCK = 5; // Grab the full block of dirty data + localparam DIRTY_EVICT_WB = 6; // Write back this block into memory + localparam FETCH_FROM_MEM = 7; // Send a request to mem looking for read data + localparam FETCH2 = 8; // Stall until memory gets back with the data + localparam UPDATE_CACHE = 9; // Update the cache with the data read from mem + localparam RE_ACCESS = 10; // Access the cache after the block has been fetched from memory + localparam RE_ACCESS_PROCESSING = 11; // Access the cache after the block has been fetched from memory + + + //parameter cache_entry = 9; + input wire clk, rst; + input wire [`NT_M1:0] i_p_valid; + //input wire [`NT_M1:0][24:0] i_p_addr; // FIXME + input wire [`NT_M1:0][31:0] i_p_addr; // FIXME + input wire i_p_initial_request; + //input wire [3:0] i_p_byte_en; + input wire [`NT_M1:0][31:0] i_p_writedata; + input wire i_p_read_or_write; //, i_p_write; + output reg [`NT_M1:0][31:0] o_p_readdata; + output reg [`NT_M1:0] o_p_readdata_valid; + output wire o_p_waitrequest; + //output reg [24:0] o_m_addr; // Only one address is sent out at a time to memory -- FIXME + output reg [31:0] o_m_addr; // Address is xxxxxxxxxxoooobbbyy + output reg o_m_valid; + //output wire [255:0][31:0] evicted_data; + //output wire [3:0] o_m_byte_en; + //output reg [(NUMBER_BANKS * 32) - 1:0] o_m_writedata; + output reg[NUMBER_BANKS - 1:0][`NUM_WORDS_PER_BLOCK-1:0][31:0] o_m_writedata; + output reg o_m_read_or_write; //, o_m_write; + //input wire [(NUMBER_BANKS * 32) - 1:0] i_m_readdata; // Read Data that is passed from the memory module back to the controller + input wire[NUMBER_BANKS - 1:0][`NUM_WORDS_PER_BLOCK-1:0][31:0] i_m_readdata; + //input wire i_m_readdata_ready; + //input wire i_m_waitrequest; + input wire i_m_ready; + + //output reg [31:0] cnt_r; + //output reg [31:0] cnt_w; + //output reg [31:0] cnt_hit_r; + //output reg [31:0] cnt_hit_w; + //output reg [31:0] cnt_wb_r; + //output reg [31:0] cnt_wb_w; + + //wire [1:0] tag [`NT_M1:0]; + //wire [3:0] index [`NT_M1:0]; + //wire [2:0] bank [`NT_M1:0]; + //wire all_done; + + //integer i; + reg [`NT_M1:0] thread_done; // Maybe should have "thread_serviced" and "thread_done", serviced==checked cache + //reg [`NT_M1:0] thread_serviced; // Maybe should have "thread_serviced" and "thread_done", serviced==checked cache + reg [NUMBER_BANKS - 1:0] banks_ready; + //reg [NUMBER_BANKS - 1:0] banks_missed; + reg [NUMBER_BANKS - 1:0] banks_to_service; + reg [NUMBER_BANKS - 1:0] banks_wb_needed; + reg [NUMBER_BANKS - 1:0][31:0] banks_wb_addr; + //reg [NUMBER_BANKS - 1:0] bank_states; + //reg [NUMBER_BANKS - 1:0][31:0] banks_wb_data; + //reg [NUMBER_BANKS - 1:0][13:0] banks_in_addr; + + + reg [3:0] state; + reg [NUMBER_BANKS - 1:0][31:0] data_from_bank; + //reg got_valid_data; + //reg [31:0] data_to_write; + + + //reg [`NT_M1:0] thread_track_bank_0; + //reg [`NT_M1:0] thread_track_bank_1; + //reg [`NT_M1:0] thread_track_bank_2; + //reg [`NT_M1:0] thread_track_bank_3; + //reg [`NT_M1:0] thread_track_bank_4; + //reg [`NT_M1:0] thread_track_bank_5; + //reg [`NT_M1:0] thread_track_bank_6; + //reg [`NT_M1:0] thread_track_bank_7; + reg [NUMBER_BANKS - 1 : 0][`NT_M1:0] thread_track_banks; + reg [NUMBER_BANKS - 1 : 0] bank_has_access; // Will track if a bank has been accessed in this cycle + reg [NUMBER_BANKS - 1 : 0][31:0] bank_access_addr; + reg [NUMBER_BANKS - 1 : 0][31:0] bank_access_data; + reg [NUMBER_BANKS - 1 : 0][1:0] threads_in_banks; + + + //reg [1:0] thread_in_memory; // keeps track of threadID which is in memory + reg rd_or_wr; + //reg did_miss, needs_service; Commented out Oct 21 + + integer bnk; + integer found; + integer t_id; + //integer num_misses; + //integer num_evictions_to_wb; + integer i; //reg [1:0] correct_tag; + integer index; + //reg [3:0] correct_index; + + //assign tag = i_p_addr[13:12]; + + assign o_p_waitrequest = (thread_done == 4'hF) ? 1'b0 : 1'b1; // change thread_done to be generic + //assign did_miss = (banks_missed != 8'h0) ? 1'b1 : 1'b0; + //assign needs_service = ((banks_to_service != 8'b0 || banks_to_service_temp != 8'b0)) ? 1'b1 : 1'b0; // added banks_to_service temp + //assign w_Test1 = r_Check ? 1'b1 : 1'b0; + //for ( i = 0;i < `NT_M1;i = i + 1) begin + // assign tag[i] = i_p_addr[i][13:12]; + + // Fares +// wire no_bank_misses; +// assign no_bank_misses = banks_to_service != 8'b0; + + reg[NUMBER_BANKS - 1:0] banks_to_service_temp; + reg[NUMBER_BANKS - 1:0] banks_to_wb; + reg[NUMBER_BANKS - 1:0] banks_to_wb_temp; + reg[NUMBER_BANKS - 1:0] banks_all_help; + + + always @(posedge clk) begin + if (rst) begin + state <= CACHE_IDLE; + //banks_ready <= 8'b0; + //cnt_r <= 0; + //cnt_w <= 0; + //cnt_hit_r <= 0; + //cnt_hit_w <= 0; + //cnt_wb_r <= 0; + //cnt_wb_w <= 0; + + end else begin + // Change Logic of which state the cache is in + case (state) + CACHE_IDLE:begin + if (i_p_initial_request == 1'b1) begin + state <= SORT_BY_BANK; + end + end + SORT_BY_BANK:begin + state <= INITIAL_ACCESS; + end + INITIAL_ACCESS:begin + if (thread_done == 4'hF) begin + state <= CACHE_IDLE; + end else begin + state <= INITIAL_PROCESSING; + end + end + INITIAL_PROCESSING:begin + //if (bank_has_access == banks_ready ) begin // if all hits + if (thread_done == 4'hF) begin + state <= INITIAL_ACCESS; + end else begin + state <= CONTINUED_PROCESSING; + end + + end + CONTINUED_PROCESSING:begin + if (banks_to_wb == 8'b0 && banks_to_service == 8'b0) begin // If all threads are done, then the cache can go back into idle state (not currently fetching any requests) + //if (banks_to_wb_temp == 8'b0 && banks_to_service_temp == 8'b0) begin + state <= INITIAL_ACCESS; + //end else if (num_misses > 0) begin + end else if ((banks_to_wb != 8'b0)) begin // change 1pm + //end else if ((banks_to_wb_temp != 8'b0)) begin // change 1pm + state <= DIRTY_EVICT_GRAB_BLOCK; + //end else if (did_miss == 1'b1 || needs_service == 1'b1) begin + end else if(banks_to_service != 8'b0) begin + //end else if(banks_to_service_temp != 8'b0) begin + state <= FETCH_FROM_MEM; + // end else if (did_miss == 1'b0 && num_evictions_to_wb > 0) begin + //end else if (needs_service == 1'b0 && did_miss == 1'b0 && (banks_to_wb != 8'b0)) begin + //end else if (did_miss == 1'b0 && needs_service == 1'b0) begin + //state <= INITIAL_ACCESS; + end + end + FETCH_FROM_MEM:begin + state <= FETCH2; + end + FETCH2:begin + if (i_m_ready == 1'b1) begin + state <= UPDATE_CACHE; // Not sure about this one !!!!!! Check + end else begin + state <= FETCH2; + end + end + UPDATE_CACHE:begin + state <= RE_ACCESS; + end + RE_ACCESS:begin + state <= CONTINUED_PROCESSING; + end + RE_ACCESS_PROCESSING: begin + state <= CONTINUED_PROCESSING; + end + DIRTY_EVICT_GRAB_BLOCK:begin + state <= DIRTY_EVICT_WB; + end + DIRTY_EVICT_WB:begin + state <= CONTINUED_PROCESSING; + end + endcase + end + + //tag[`NT_M1:0] <= i_p_addr[`NT_M1:0][13:12]; + end + + // Change values which will be fed into the cache + always @(*) begin + case (state) + CACHE_IDLE:begin + thread_done = 0; + o_m_read_or_write = 0; + o_m_valid = 0; + o_m_writedata = 0; + o_p_readdata = 0; + o_p_readdata_valid = 0; + bank_has_access = 8'b0; + //bank_states = CACHE_IDLE; + //thread_track_bank_0 = 4'b0; + //thread_track_bank_1 = 4'b0; + //thread_track_bank_2 = 4'b0; + //thread_track_bank_3 = 4'b0; + //thread_track_bank_4 = 4'b0; + //thread_track_bank_5 = 4'b0; + //thread_track_bank_6 = 4'b0; + //thread_track_bank_7 = 4'b0; + for (bnk = 0; bnk < NUMBER_BANKS; bnk = bnk + 1) begin + thread_track_banks[bnk] = 4'b0; + end + end + SORT_BY_BANK:begin + //bank_states = SORT_BY_BANK; + rd_or_wr = i_p_read_or_write; + for (t_id = 0; t_id <= `NT_M1; t_id = t_id + 1) begin + //t_id = {1'b0,t_id}; + if (i_p_valid[t_id] == 1'b0) begin + thread_done[t_id] = 1'b1; + end + //if (i_p_valid[t_id] == 1'b1 && thread_done[t_id] == 1'b0) begin // Need logic for thread done + else if (i_p_addr[t_id][4:2] == 3'b000) begin + //banks_in_addr[0] = i_p_addr[t_id]; // WIll need to do this later + //thread_track_bank_0[t_id] = 1'b1; + thread_track_banks[0][t_id] = 1'b1; + end + else if (i_p_addr[t_id][4:2] == 3'b001) begin // !!!!!!! + //banks_in_addr[0] = i_p_addr[t_id]; // WIll need to do this later + //thread_track_bank_1[t_id] = 1'b1; + thread_track_banks[1][t_id] = 1'b1; + end + else if (i_p_addr[t_id][4:2] == 3'b010) begin + //banks_in_addr[0] = i_p_addr[t_id]; // WIll need to do this later + //thread_track_bank_2[t_id] = 1'b1; + thread_track_banks[2][t_id] = 1'b1; + end + else if (i_p_addr[t_id][4:2] == 3'b011) begin + //banks_in_addr[0] = i_p_addr[t_id]; // WIll need to do this later + //thread_track_bank_3[t_id] = 1'b1; + thread_track_banks[3][t_id] = 1'b1; + end + else if (i_p_addr[t_id][4:2] == 3'b100) begin + //banks_in_addr[0] = i_p_addr[t_id]; // WIll need to do this later + //thread_track_bank_4[t_id] = 1'b1; + thread_track_banks[4][t_id] = 1'b1; + end + else if (i_p_addr[t_id][4:2] == 3'b101) begin + //banks_in_addr[0] = i_p_addr[t_id]; // WIll need to do this later + //thread_track_bank_5[t_id] = 1'b1; + thread_track_banks[5][t_id] = 1'b1; + end + else if (i_p_addr[t_id][4:2] == 3'b110) begin + //banks_in_addr[0] = i_p_addr[t_id]; // WIll need to do this later + //thread_track_bank_6[t_id] = 1'b1; + thread_track_banks[6][t_id] = 1'b1; + end + else if (i_p_addr[t_id][4:2] == 3'b111) begin + //banks_in_addr[0] = i_p_addr[t_id]; // WIll need to do this later + //thread_track_bank_7[t_id] = 1'b1; + thread_track_banks[7][t_id] = 1'b1; + end + end + end + INITIAL_ACCESS:begin + //bank_states = INITIAL_ACCESS; + o_m_valid = 1'b0; + + // Before Access +// if (no_bank_misses) begin + // Dont do anything, next clock cycle it will switch back to (Fetch from mem) +// end else begin // Do logic to send requests to each bank (look through thread_track_bank regs) + bank_has_access = 8'b0; + for (t_id = 0; t_id <= `NT_M1; t_id = t_id + 1) begin + for (bnk = 0; bnk < NUMBER_BANKS; bnk = bnk + 1) begin + if(thread_track_banks[bnk][t_id] == 1'b1 && bank_has_access[bnk] == 1'b0) begin + bank_has_access[bnk] = 1'b1; + bank_access_data[bnk] = i_p_writedata[t_id]; + bank_access_addr[bnk] = i_p_addr[t_id]; + threads_in_banks[bnk] = t_id[1:0]; + end + end + //if (banks_wb_needed[bnk]) begin // need to fix this for multiple misses + //o_m_read_or_write = 1'b0; + //o_m_addr = banks_wb_addr[bnk]; + //o_m_valid = 1'b1; + //o_m_writedata = {banks_wb_data[bnk], 96'b0}; + //end + //if(thread_track_bank_0[t_id] == 1'b1 && bank_has_access[0] == 1'b0) begin + //bank_has_access[0] = 1'b1; + //bank_access_data[0] = i_p_writedata[t_id]; + //bank_access_addr[0] = i_p_addr[t_id]; + //threads_in_banks[0] = t_id; + //end + // NEED TO UPDATE HITS (STORE IN THREADS_DONE) + end + //num_misses = {28'b0, $countones(banks_missed)}; + //did_miss = (banks_missed == 4'hF); + +// end + + + end + INITIAL_PROCESSING:begin + for (bnk = 0; bnk < NUMBER_BANKS; bnk = bnk + 1) begin + if(banks_ready[bnk]) begin // FIX to handle hits + thread_done[threads_in_banks[bnk]] = 1'b1; + o_p_readdata[threads_in_banks[bnk]] = data_from_bank[bnk]; + if(i_p_read_or_write == 1'b0) begin + o_p_readdata_valid[threads_in_banks[bnk]] = 1'b1; + end + thread_track_banks[bnk][threads_in_banks[bnk]] = 1'b0; // Update that this thread does not need to be serviced again + end + end + //banks_to_service_temp = !banks_ready; // These are clean misses + for (bnk = 0; bnk < NUMBER_BANKS; bnk = bnk + 1) begin + assign banks_to_service_temp[bnk] = (banks_ready[bnk] || (bank_has_access[bnk] == 0)) ? 1'b0 : 1'b1; + assign banks_to_wb_temp[bnk] = (banks_wb_needed[bnk]); + assign banks_all_help[bnk] = banks_to_service_temp[bnk] || banks_to_wb_temp[bnk]; + end + //bank_has_access = 8'b0; // Oct 23 + end + CONTINUED_PROCESSING:begin + //for (i = `NW-1; i >= 0; i = i - 1) begin + // if (thread_done[threads_in_banks[bnk]] == 1'b1) begin // Not sure about this logic + // //index = i[`NW_M1:0]; + // banks_to_service_temp[i] = 1'b0; + // banks_to_wb_temp[i] = 1'b0; + // end + //end + + for (bnk = 0; bnk < NUMBER_BANKS; bnk = bnk + 1) begin + if(banks_ready[bnk]) begin // FIX to handle hits + thread_done[threads_in_banks[bnk]] = 1'b1; + o_p_readdata[threads_in_banks[bnk]] = data_from_bank[bnk]; + if(i_p_read_or_write == 1'b0) begin + o_p_readdata_valid[threads_in_banks[bnk]] = 1'b1; + end + thread_track_banks[bnk][threads_in_banks[bnk]] = 1'b0; // Update that this thread does not need to be serviced again + // Added Oct 21 + banks_to_service_temp[bnk] = 1'b0; + banks_to_wb_temp[bnk] = 1'b0; + end + end + bank_has_access = 8'b0; // Oct 23 + end + FETCH_FROM_MEM:begin + // NEED TO ADD LOGIC TO SEE IF MISSES GO TO SAME BLOCK + index = 0; + found = 0; + for (i = `NW-1; i >= 0; i = i - 1) begin + if (banks_to_service[i]) begin // Not sure about this logic + //index = i[`NW_M1:0]; + index = i; + found = 1; + end + end + if (found == 1) begin + //banks_missed[index] = 0; + //thread_done + + //thread_in_memory = threads_in_banks[index]; + //o_m_writedata = bank_access_data[index]; + banks_to_service_temp[index] = 0; + o_m_addr = bank_access_addr[index]; + o_m_valid = 1'b1; + o_m_read_or_write = 1'b0; + end + //bank_states = FETCH_FROM_MEM; + end + FETCH2:begin + o_m_valid = 1'b0; + end + UPDATE_CACHE:begin + for (bnk = 0; bnk < NUMBER_BANKS; bnk = bnk + 1) begin + //if(thread_track_banks[bnk][t_id] == 1'b1 && bank_has_access[bnk] == 1'b0) begin + bank_has_access[bnk] = 1'b1; + //bank_access_data[bnk] = i_m_readdata[(bnk+1)*32 - 1:bnk*32]; + bank_access_addr[bnk] = o_m_addr; + threads_in_banks[bnk] = t_id[1:0]; + //end + end + //bank_access_data = i_m_readdata; + rd_or_wr = 1'b1; + //thread_done[thread_in_memory] = 1'b1; // Removed, new cache style - Oct 21 + //o_p_readdata[thread_in_memory] = i_m_readdata[i_p_addr[thread_in_memory][9:5]]; // Removed, new cache style + end + DIRTY_EVICT_WB:begin // this begininng logic should be added to dirty evict grab block + + //thread_done[thread_in_memory] = 1'b1; + bank_has_access = 8'b0; + o_m_valid = 1'b1; + end + DIRTY_EVICT_GRAB_BLOCK:begin + index = 0; + found = 0; + for (i = `NW-1; i >= 0; i = i - 1) begin + if (banks_to_wb_temp[i]) begin + //index = i[`NW_M1:0]; + index = i; + found = 1; + end + end + if (found == 1) begin + banks_to_wb_temp[index] = 0; + for (i = `NW-1; i >= 0; i = i - 1) begin + if (banks_to_wb_temp[i] && banks_wb_addr[index][31:7] == banks_wb_addr[i][31:7]) begin + //index = i[`NW_M1:0]; + banks_to_wb_temp[i] = 0; + end + end + //thread_done + //thread_in_memory = threads_in_banks[index]; + //o_m_writedata[(bnk+1)*32 - 1:bnk*32] = banks_wb_data[index]; + o_m_addr = banks_wb_addr[index]; + o_m_read_or_write = 1'b1; + end + //for (bnk = 0; bnk < NUMBER_BANKS; bnk = bnk + 1) begin + //o_m_writedata[(bnk+1)*32 - 1:bnk*32] = banks_wb_data[index]; + //end + // NEXT LINE CONTAINS DATA TO WB !!!! Think need to just change this to be read data and can remove banks_wb_data + //o_m_writedata = {banks_wb_data[7],banks_wb_data[6],banks_wb_data[5],banks_wb_data[4],banks_wb_data[3],banks_wb_data[2],banks_wb_data[1],banks_wb_data[0]}; + //num_evictions_to_wb = {28'b0, $countones(banks_wb_needed)}; + rd_or_wr = 1'b0; + for (bnk = 0; bnk < NUMBER_BANKS; bnk = bnk + 1) begin + //if(thread_track_banks[bnk][t_id] == 1'b1 && bank_has_access[bnk] == 1'b0) begin + bank_has_access[bnk] = 1'b1; + bank_access_addr[bnk] = o_m_addr; + //end + end + end + RE_ACCESS:begin + //bank_states = INITIAL_ACCESS; + o_m_valid = 1'b0; + + // Before Access +// if (no_bank_misses) begin + // Dont do anything, next clock cycle it will switch back to (Fetch from mem) +// end else begin // Do logic to send requests to each bank (look through thread_track_bank regs) + //bank_has_access = banks_all_help & !(banks_to_wb) & !(banks_to_service); + for (t_id = 0; t_id <= `NT_M1; t_id = t_id + 1) begin + for (bnk = 0; bnk < NUMBER_BANKS; bnk = bnk + 1) begin + //bank_has_access[bnk] = banks_all_help[bnk] && !thread_done[threads_in_banks[bnk]]; // Not sure + bank_has_access[bnk] = banks_all_help[bnk] && !thread_done[t_id]; // Not sure + if(thread_track_banks[bnk][t_id] == 1'b1 && bank_has_access[bnk] == 1'b1) begin + //bank_has_access[bnk] = 1'b1; + bank_access_data[bnk] = i_p_writedata[t_id]; + bank_access_addr[bnk] = i_p_addr[t_id]; + threads_in_banks[bnk] = t_id[1:0]; + end + end + end + + + + end + RE_ACCESS_PROCESSING:begin + // After Access + + end + + endcase + end + + always @(posedge clk) begin + banks_to_service <= banks_to_service_temp; + banks_to_wb <= banks_to_wb_temp; + end + + + genvar bank_id; + generate + for (bank_id = 0; bank_id < NUMBER_BANKS; bank_id = bank_id + 1) + begin + VX_Cache_Bank bank_structure ( + .clk (clk), + .state (state), + .read_or_write (rd_or_wr), + .valid_in (bank_has_access[bank_id]), + .actual_index (bank_access_addr[bank_id][14:7]), // fix when size changes + .o_tag (bank_access_addr[bank_id][31:15]), // fix when size changes + .block_offset (bank_access_addr[bank_id][6:5]), + .writedata (bank_access_data[bank_id]), + //.fetched_writedata (i_m_readdata[(bank_id+1)*32-1 -: 32]), + .fetched_writedata (i_m_readdata[bank_id[3:0]]), + .readdata (data_from_bank[bank_id]), + .hit (banks_ready[bank_id]), + //.miss (banks_missed[bank_id]), + .eviction_wb (banks_wb_needed[bank_id]), + .eviction_addr (banks_wb_addr[bank_id]), + //.data_evicted (o_m_writedata[(bank_id+1)*32-1 -: 32]) + .data_evicted (o_m_writedata[bank_id[3:0]]) + ); + + end + endgenerate + + //end + +endmodule \ No newline at end of file