// To Do: Change way_id_out to an internal register which holds when in between access and finished. // Also add a bit about wheter the "Way ID" is valid / being held or if it is just default // Also make sure all possible output states are transmitted back to the bank correctly // `include "VX_define.v" module cache_set(clk, rst, // These next 4 are possible modes that the Set could be in, I am making them 4 different variables for indexing purposes access, // First find_evict, write_from_mem, idle, // entry, o_tag, writedata, //byte_en, write, //word_en, //way_id_in, //way_id_out, readdata, //wb_addr, hit, eviction_wb, eviction_tag, //eviction_data, //modify, miss //valid_data //read_miss ); parameter cache_entry = 14; parameter ways_per_set = 4; input wire clk, rst; input wire access; input wire find_evict; input wire write_from_mem; input wire idle; //input wire [cache_entry-1:0] entry; input wire [1:0] o_tag; input wire [31:0] writedata; //input wire [3:0] byte_en; input wire write; // 0 == False //input wire [3:0] word_en; //input wire read_miss; //input wire [1:0] way_id_in; //output reg [1:0] way_id_out; output reg [31:0] readdata; //output reg [3:0] hit; output reg hit; output reg miss; output wire eviction_wb; output wire [1:0] eviction_tag; reg [31:0] eviction_data; //output wire [22:0] wb_addr; //output wire modify, valid_data; //wire [2:0] i_tag; //wire dirty; //wire [24-cache_entry:0] write_tag_data; // Table for one set reg [2:0] counter; // Determines which to evict reg valid [ways_per_set-1:0]; reg [1:0] tag [ways_per_set-1:0]; reg clean [ways_per_set-1:0]; reg [31:0] data [ways_per_set-1:0]; assign eviction_wb = miss && clean[counter[1:0]] != 1'b1 && valid[counter[1:0]] == 1'b1; assign eviction_tag = tag[counter[1:0]]; //assign eviction_data = data[counter[1:0]]; //assign hit = valid_data && (o_tag == i_tag); //assign modify = valid_data && (o_tag != i_tag) && dirty; //assign miss = !valid_data || ((o_tag != i_tag) && !dirty); //assign wb_addr = {i_tag, entry}; always @(posedge clk) begin if (rst) begin end if (find_evict) begin if (tag[0] == o_tag && valid[0]) begin readdata <= data[0]; end else if (tag[1] == o_tag && valid[1]) begin readdata <= data[1]; end else if (tag[2] == o_tag && valid[2]) begin readdata <= data[2]; end else if (tag[3] == o_tag && valid[3]) begin readdata <= data[3]; end end else if (access) begin //tag[`NT_M1:0] <= i_p_addr[`NT_M1:0][13:12]; counter <= ((counter + 1) ^ 3'b100); // Counter determining which to evict in the event of miss only increment when miss !!! NEED TO FIX LOGIC // Hit in First Column if (tag[0] == o_tag && valid[0]) begin if (write == 1'b0) begin // if it is a read if (clean[0] == 1'b1 ) begin //hit <= 4'b0001; hit <= 1'b1; readdata <= data[0]; miss <= 1'b0; end else begin //hit <= 4'b0000; // SHOULD PROBABLY TRACK WHERE THIS MISS IS IN A DIFFERENT VARIABLE hit <= 1'b0; readdata <= 32'b0; miss <= 1'b1; end end else if (write == 1'b1) begin data[0] <= writedata; clean[0] <= 1'b0; //hit <= 4'b0001; hit <= 1'b1; end end // Hit in Second Column else if (tag[1] == o_tag && valid[1]) begin if (write == 1'b0) begin // if it is a read if (clean[1] == 1'b1 ) begin //hit <= 4'b0010; hit <= 1'b1; readdata <= data[1]; miss <= 1'b0; end else begin //hit <= 4'b0000; hit <= 1'b0; readdata <= 32'b0; miss <= 1'b1; end end else if (write == 1'b1) begin data[1] <= writedata; clean[1] <= 1'b0; //hit <= 4'b0010; hit <= 1'b1; end end // Hit in Third Column else if (tag[2] == o_tag && valid[2]) begin if (write == 1'b0) begin // if it is a read if (clean[2] == 1'b1 ) begin //hit <= 4'b0100; hit <= 1'b1; readdata <= data[2]; miss <= 1'b0; end else begin //hit <= 4'b0000; hit <= 1'b0; readdata <= 32'b0; miss <= 1'b1; end end else if (write == 1'b1) begin data[2] <= writedata; clean[2] <= 1'b0; //hit <= 4'b0100; hit <= 1'b1; end end // Hit in Fourth Column else if (tag[3] == o_tag && valid[3]) begin if (write == 1'b0) begin // if it is a read if (clean[3] == 1'b1 ) begin //hit <= 4'b1000; hit <= 1'b1; readdata <= data[3]; miss <= 1'b0; end else begin //hit <= 4'b0000; hit <= 1'b0; readdata <= 32'b0; miss <= 1'b1; end end else if (write == 1'b1) begin data[3] <= writedata; clean[3] <= 1'b0; //hit <= 4'b1000; hit <= 1'b1; end end // Miss else begin //way_id_out <= counter; miss <= 1'b1; if (write == 1'b0) begin // Read Miss clean[counter[1:0]] <= 1'b1; data[counter[1:0]] <= 32'h7FF; // FIX WITH ACTUAL MEMORY ACCESS end else if (write == 1'b1) begin // Write Miss clean[counter[1:0]] <= 1'b1; data[counter[1:0]] <= writedata; end end end if (write_from_mem) begin tag[counter[1:0]] <= o_tag; valid[counter[1:0]] <= 1'b1; hit <= 1'b1; if (write == 1'b0) begin // Read Miss clean[counter[1:0]] <= 1'b1; data[counter[1:0]] <= 32'h7FF; // FIX WITH ACTUAL MEMORY ACCESS end else if (write == 1'b1) begin // Write Miss clean[counter[1:0]] <= 1'b0; data[counter[1:0]] <= writedata; end end if (idle) begin // Set "way" register equal to invalid value hit <= 1'b1; // set to know it is ready miss <= 1'b0; readdata <= 32'hFFFFFFFF; end if (find_evict) begin // Keep "way" value the same !!!! Fix. Need to send back data with matching tag. Also need to ensure evicted data doesnt get lost if (tag[3] == o_tag && valid[3]) begin readdata <= data[3]; end else if (tag[1] == o_tag && valid[1]) begin readdata <= data[1]; end else if (tag[2] == o_tag && valid[2]) begin readdata <= data[2]; end else if (tag[0] == o_tag && valid[0]) begin readdata <= data[0]; end else begin readdata <= eviction_data; end hit <= 1'b1; miss <= 1'b0; end counter <= ((counter + 1) ^ 3'b100); // Counter determining which to evict in the event of miss only increment when miss !!! NEED TO FIX LOGIC eviction_data <= data[counter[1:0]]; end endmodule