new cache states

This commit is contained in:
felsabbagh3 2019-10-23 15:07:14 -04:00
parent b4d921f49a
commit 6340ffcc2a
4 changed files with 661 additions and 480 deletions

View file

@ -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

23
rtl/cache/VX_cache_bank_valid.v vendored Normal file
View file

@ -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

538
rtl/cache/VX_d_cache.v vendored
View file

@ -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

568
rtl/cache/VX_d_cache_old.v vendored Normal file
View file

@ -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