`timescale 1ns/1ps module lru ( input clk, input reset, input enable, input [31:0] data, output reg[31:0] out1, output reg[31:0] out2, output reg[31:0] out3, output reg[31:0] out4, output reg[31:0] out5, output reg[31:0] out6, output reg[31:0] out7, output reg[31:0] out8 ); reg[2:0] state = 0; reg[3:0] ages[0:7]; reg[3:0] max_age = 0, preempted_index = 8; reg[3:0] amount_empty_spaces = 8; reg[3:0] hit_cache_index = 8; reg is_value_in_cache = 0; reg is_value_setted_to_cache = 0; parameter INITIAL = 0, IDLE = 1, VALUE_IN_CACHE = 2, NO_VALUE_IN_CACHE_ENOUGH_SPACE = 3, NO_VALUE_IN_CACHE_NO_ENOUGH_SPACE = 4, DONE = 5; integer i; always @(posedge reset) begin if (reset) begin out1 <= 32'hffffffff; out2 <= 32'hffffffff; out3 <= 32'hffffffff; out4 <= 32'hffffffff; out5 <= 32'hffffffff; out6 <= 32'hffffffff; out7 <= 32'hffffffff; out8 <= 32'hffffffff; for (i = 0; i < 8; i = i + 1) begin ages[i] <= 8; end state <= IDLE; end end always @(posedge clk) begin case (state) INITIAL: begin out1 <= 32'hffffffff; out2 <= 32'hffffffff; out3 <= 32'hffffffff; out4 <= 32'hffffffff; out5 <= 32'hffffffff; out6 <= 32'hffffffff; out7 <= 32'hffffffff; out8 <= 32'hffffffff; for (i = 0; i < 8; i = i + 1) begin ages[i] <= 8; end state <= IDLE; end IDLE : begin if (enable) begin if (out1 == data) begin hit_cache_index = 0; state <= VALUE_IN_CACHE; is_value_in_cache = 1; end if (out2 == data) begin hit_cache_index = 1; state <= VALUE_IN_CACHE; is_value_in_cache = 1; end if (out3 == data) begin hit_cache_index = 2; state <= VALUE_IN_CACHE; is_value_in_cache = 1; end if (out4 == data) begin hit_cache_index = 3; state <= VALUE_IN_CACHE; is_value_in_cache = 1; end if (out5 == data) begin hit_cache_index = 4; state <= VALUE_IN_CACHE; is_value_in_cache = 1; end if (out6 == data) begin hit_cache_index = 5; state <= VALUE_IN_CACHE; is_value_in_cache = 1; end if (out7 == data) begin hit_cache_index = 6; state <= VALUE_IN_CACHE; is_value_in_cache = 1; end if (out8 == data) begin hit_cache_index = 7; state <= VALUE_IN_CACHE; is_value_in_cache = 1; end if (amount_empty_spaces && is_value_in_cache == 0) state <= NO_VALUE_IN_CACHE_ENOUGH_SPACE; else state <= NO_VALUE_IN_CACHE_NO_ENOUGH_SPACE; is_value_in_cache = 0; end end VALUE_IN_CACHE : begin for (i = 0; i < 8; i = i + 1) begin if (i == hit_cache_index) begin ages[i] <= 0; end else if (ages[i] != 8) begin ages[i] <= ages[i] + 1; end end hit_cache_index <= 8; state <= DONE; end NO_VALUE_IN_CACHE_ENOUGH_SPACE : begin for (i = 0; i < 8; i = i + 1) begin if (ages[i] != 8) begin ages[i] <= ages[i] + 1; end end for (i = 0; i < 8; i = i + 1) begin if (ages[i] >= 8 && is_value_setted_to_cache != 1) begin ages[i] <= 0; case (i) 0: begin out1 <= data; is_value_setted_to_cache = 1; end 1: begin out2 <= data; is_value_setted_to_cache = 1; end 2: begin out3 <= data; is_value_setted_to_cache = 1; end 3: begin out4 <= data; is_value_setted_to_cache = 1; end 4: begin out5 <= data; is_value_setted_to_cache = 1; end 5: begin out6 <= data; is_value_setted_to_cache = 1; end 6: begin out7 <= data; is_value_setted_to_cache = 1; end 7: begin out8 <= data; is_value_setted_to_cache = 1; end endcase end end is_value_setted_to_cache = 0; amount_empty_spaces <= amount_empty_spaces - 1; state <= DONE; end NO_VALUE_IN_CACHE_NO_ENOUGH_SPACE : begin for (i = 0; i < 8; i = i + 1) begin if (ages[i] != 8) begin ages[i] <= ages[i] + 1; end end $display("ages = [%d, %d, %d, %d, %d, %d, %d, %d]", ages[0], ages[1], ages[2], ages[3], ages[4], ages[5], ages[6], ages[7]); $display("max_age: %d", max_age); for (i = 0; i < 8; i = i + 1) begin if (ages[i] > max_age) begin max_age = ages[i]; preempted_index = i; end end $display("max_age: %d", max_age); $display("preempted_index: %d", preempted_index); case (preempted_index) 0: begin out1 <= data; end 1: begin out2 <= data; end 2: begin out3 <= data; end 3: begin out4 <= data; end 4: begin out5 <= data; end 5: begin out6 <= data; end 6: begin out7 <= data; end 7: begin out8 <= data; end endcase ages[preempted_index] <= 0; preempted_index <= 8; max_age <= 0; state <= DONE; end DONE : begin state <= IDLE; end endcase end endmodule