`include "../VX_define.v" module VX_cache_data_per_index #( parameter CACHE_WAYS = 1, parameter NUM_IND = 8, parameter CACHE_WAY_INDEX = 1, parameter NUM_WORDS_PER_BLOCK = 4, parameter TAG_SIZE_START = 0, parameter TAG_SIZE_END = 16, parameter IND_SIZE_START = 0, parameter IND_SIZE_END = 7 ) ( input wire clk, // Clock input wire rst, input wire valid_in, input wire [3:0] state, // Addr input wire[IND_SIZE_END:IND_SIZE_START] addr, // WE input wire[NUM_WORDS_PER_BLOCK-1:0][3:0] we, input wire evict, input wire[CACHE_WAY_INDEX-1:0] way_to_update, // Data input wire[NUM_WORDS_PER_BLOCK-1:0][31:0] data_write, // Update Data input wire[TAG_SIZE_END:TAG_SIZE_START] tag_write, output wire[TAG_SIZE_END:TAG_SIZE_START] tag_use, output wire[NUM_WORDS_PER_BLOCK-1:0][31:0] data_use, output wire valid_use, output wire dirty_use ); //localparam NUMBER_BANKS = CACHE_BANKS; //localparam CACHE_BLOCK_PER_BANK = (CACHE_BLOCK / CACHE_BANKS); // localparam NUM_WORDS_PER_BLOCK = CACHE_BLOCK / (CACHE_BANKS*4); //localparam NUMBER_INDEXES = `DCACHE_NUM_IND; wire [CACHE_WAYS-1:0][TAG_SIZE_END:TAG_SIZE_START] tag_use_per_way; wire [CACHE_WAYS-1:0][NUM_WORDS_PER_BLOCK-1:0][31:0] data_use_per_way; wire [CACHE_WAYS-1:0] valid_use_per_way; wire [CACHE_WAYS-1:0] dirty_use_per_way; wire [CACHE_WAYS-1:0] hit_per_way; // reg [CACHE_WAY_INDEX-1:0] eviction_way_index; wire [CACHE_WAYS-1:0][NUM_WORDS_PER_BLOCK-1:0][3:0] we_per_way; wire [CACHE_WAYS-1:0][NUM_WORDS_PER_BLOCK-1:0][31:0] data_write_per_way; wire [CACHE_WAYS-1:0] write_from_mem_per_way; wire invalid_found; wire [CACHE_WAY_INDEX-1:0] way_index; wire [CACHE_WAY_INDEX-1:0] invalid_index; localparam CACHE_IDLE = 0; // Idle localparam SEND_MEM_REQ = 1; // Write back this block into memory localparam RECIV_MEM_RSP = 2; if(CACHE_WAYS != 1) begin VX_generic_priority_encoder #(.N(CACHE_WAYS)) valid_index ( .valids(~valid_use_per_way), .index (invalid_index), .found (invalid_found) ); VX_generic_priority_encoder #(.N(CACHE_WAYS)) way_indexing ( .valids(hit_per_way), .index (way_index), .found () ); end else begin assign way_index = 0; assign invalid_found = (valid_use_per_way == 1'b0) ? 1 : 0; assign invalid_index = 0; end // wire hit = |hit_per_way; // wire miss = ~hit; // wire update = |we && !miss; // wire valid = &valid_use_per_way; wire[CACHE_WAY_INDEX-1:0] way_use_Qual; assign way_use_Qual = (state != CACHE_IDLE) ? way_to_update : way_index; assign tag_use = tag_use_per_way[way_use_Qual]; assign data_use = data_use_per_way[way_use_Qual]; assign valid_use = valid_use_per_way[way_use_Qual]; assign dirty_use = dirty_use_per_way[way_use_Qual]; // assign tag_use = hit ? tag_use_per_way[way_index] : (valid ? tag_use_per_way[eviction_way_index] : (invalid_found ? tag_use_per_way[invalid_index] : 0)); // assign data_use = hit ? data_use_per_way[way_index] : (valid ? data_use_per_way[eviction_way_index] : (invalid_found ? data_use_per_way[invalid_index] : 0)); // assign valid_use = hit ? valid_use_per_way[way_index] : (valid ? valid_use_per_way[eviction_way_index] : (invalid_found ? valid_use_per_way[invalid_index] : 0)); // assign dirty_use = hit ? dirty_use_per_way[way_index] : (valid ? dirty_use_per_way[eviction_way_index] : (invalid_found ? dirty_use_per_way[invalid_index] : 0)); genvar ways; for(ways=0; ways < CACHE_WAYS; ways = ways + 1) begin : each_way assign hit_per_way[ways] = ((valid_use_per_way[ways] == 1'b1) && (tag_use_per_way[ways] == tag_write)) ? 1'b1 : 0; assign write_from_mem_per_way[ways] = evict && (ways == way_use_Qual); assign we_per_way[ways] = (ways == way_use_Qual) ? (we) : 0; assign data_write_per_way[ways] = data_write; // assign hit_per_way[ways] = ((valid_use_per_way[ways] == 1'b1) && (tag_use_per_way[ways] == tag_write)) ? 1'b1 : 0; // assign we_per_way[ways] = (evict == 1'b1) || (update == 1'b1) ? ((ways == way_use_Qual) ? (we) : 0) : 0; // assign data_write_per_way[ways] = (evict == 1'b1) || (update == 1'b1) ? ((ways == way_use_Qual) ? data_write : 0) : 0; // assign write_from_mem_per_way[ways] = (evict == 1'b1) ? ((ways == way_use_Qual) ? 1 : 0) : 0; VX_cache_data #( .NUM_IND (NUM_IND), .NUM_WORDS_PER_BLOCK (NUM_WORDS_PER_BLOCK), .TAG_SIZE_START (TAG_SIZE_START), .TAG_SIZE_END (TAG_SIZE_END), .IND_SIZE_START (IND_SIZE_START), .IND_SIZE_END (IND_SIZE_END)) data_structures( .clk (clk), .rst (rst), // Inputs .addr (addr), .we (we_per_way[ways]), .evict (write_from_mem_per_way[ways]), .data_write(data_write_per_way[ways]), .tag_write (tag_write), // Outputs .tag_use (tag_use_per_way[ways]), .data_use (data_use_per_way[ways]), .valid_use (valid_use_per_way[ways]), .dirty_use (dirty_use_per_way[ways]) ); end // always @(posedge clk or posedge rst) begin // if (rst) begin // eviction_way_index <= 0; // end else begin // // if((miss && dirty_use && valid_use && !evict && valid_in)) begin // can be either evict or invalid cache entries // if((state == SEND_MEM_REQ)) begin // can be either evict or invalid cache entries // if((eviction_way_index+1) == CACHE_WAYS) begin // eviction_way_index <= 0; // end else begin // eviction_way_index <= (eviction_way_index + 1); // end // end // end // end endmodule