Skip to content

Commit

Permalink
Feat modifiable associativity
Browse files Browse the repository at this point in the history
  • Loading branch information
khkim6040 committed May 27, 2024
1 parent 3b4394d commit 3e4f8ac
Showing 1 changed file with 117 additions and 123 deletions.
240 changes: 117 additions & 123 deletions lab5/Cache.v
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@
`define F 3'b101

module Cache #(parameter LINE_SIZE = 16,
parameter NUM_SETS = 8,
parameter NUM_WAYS = 2) (
parameter NUM_SETS = 2,
parameter NUM_WAYS = 8) (
input reset,
input clk,

Expand All @@ -53,10 +53,10 @@ module Cache #(parameter LINE_SIZE = 16,
wire is_write_hit;
wire is_read_hit;
assign is_ready = is_data_mem_ready;
assign is_output_valid = is_input_valid && line_matched[matched_line] && line_valid[matched_line];
assign is_output_valid = line_matched[matched_line] && line_valid[matched_line];
assign dout = cache[D_set][matched_line][D_bo*32 +: 32];
assign is_read_hit = line_matched[matched_line] && line_valid[matched_line] && mem_rw == `READ;
assign is_write_hit = line_matched[matched_line] && mem_rw == `WRITE;
assign is_read_hit = is_input_valid && line_matched[matched_line] && line_valid[matched_line] && mem_rw == `READ;
assign is_write_hit = is_input_valid && line_matched[matched_line] && mem_rw == `WRITE;
assign is_hit = is_write_hit || is_read_hit;

wire [`TAG_BITS-1:0] D_tag;
Expand All @@ -66,35 +66,33 @@ module Cache #(parameter LINE_SIZE = 16,
assign D_set = addr[`D_TAG_IDX-1:`D_SET_IDX];
assign D_bo = addr[`D_SET_IDX-1:2];

reg [`WAY_BITS-1:0] line_matched;
reg [`WAY_BITS-1:0] line_valid;
reg [`WAY_BITS-1:0] lru [`WAY_BITS-1:0];
reg [NUM_WAYS-1:0] line_matched;
reg [NUM_WAYS-1:0] line_valid;
reg [`WAY_BITS-1:0] lru [NUM_WAYS-1:0];

reg [`WAY_BITS-1:0] matched_line;
reg [`WAY_BITS-1:0] old_line;

// Set matched_line, old_line and valid, lru bit information
always @(*) begin
integer i;
matched_line = 0;
old_line = 0;

for (i = 0; i < NUM_WAYS; i = i + 1) begin
line_valid[i] = cache[D_set][i][`VALID_IDX];
lru[i] = cache[D_set][i][`LRU_IDX:`LRU_IDX-`LRU_BITS+1];
line_matched[i] = cache[D_set][i][`TAG_IDX:`TAG_IDX-`TAG_BITS+1] == D_tag;

if((cache[D_set][i][`TAG_IDX:`TAG_IDX-`TAG_BITS+1] != D_tag) && (cache[D_set][i][`LRU_IDX:`LRU_IDX-`LRU_BITS+1] == `LRU_OLD)) begin
if((cache[D_set][i][`LRU_IDX:`LRU_IDX-`LRU_BITS+1] == `LRU_OLD)) begin
old_line = i[`WAY_BITS-1:0];
end
if(cache[D_set][i][`TAG_IDX:`TAG_IDX-`TAG_BITS+1] == D_tag) begin
matched_line = i[`WAY_BITS-1:0];
end
end

end



wire is_old_line_dirty;
assign is_old_line_dirty = cache[D_set][old_line][`DIRTY_IDX];

Expand All @@ -112,18 +110,11 @@ module Cache #(parameter LINE_SIZE = 16,
// if WAY_BITS == 1, cache block bits == 156
// if WAY_BITS == 2, cache block bits == 158
// if WAY_BITS == 3, cache block bits == 160
// 그냥 block size = 162로 크게 잡음
reg [161:0] cache [NUM_SETS-1:0][NUM_WAYS-1:0];

// 최대 크기 160으로 hard-coded
reg [159:0] cache [NUM_SETS-1:0][NUM_WAYS-1:0];
reg [2:0] state;

integer i, j;

// HIT case: index > tag matched > valid > hit and return data > set LRU to 0(younger) > set other LRU to 1(older)
// MISS case: index > tag not matched > retrieve data from memory > put data into cache > first, put data into cache line where valid = 0, second put data into cache line where LRU = 1
// > set LRU to 0(younger) > set other LRU to 1(older)


always @(posedge clk) begin
// Initialize Cache
if(reset) begin
Expand All @@ -132,120 +123,122 @@ module Cache #(parameter LINE_SIZE = 16,
cache[i][j] <= 0;
end
end
state <= `A;
state <= `B;
miss_count <= 0;
end

C_is_input_valid <= 0;
C_mem_read <= 0;
C_mem_write <= 0;
C_addr <= 0;
C_din <= 0;

$display("state: %b", state);
//$display("mem_rw: %b", mem_rw);

// STATE A
if (state == `A) begin
if (is_input_valid)
state <= `B;
else
state <= `A;
end
// STATE B
else if (state == `B) begin
if(is_input_valid) begin
// Compare Tag
if (mem_rw == `WRITE) begin
if (is_write_hit) begin
// LRU setting
cache[D_set][matched_line][`LRU_IDX:`LRU_IDX-`LRU_BITS+1] <= `LRU_NEW;
for(i=0; i<NUM_WAYS; i=i+1) begin
if((i[`WAY_BITS-1:0] != matched_line) && (lru[i] > `LRU_OLD))
cache[D_set][i][`LRU_IDX:`LRU_IDX-`LRU_BITS+1] <= lru[i] - 1;
else begin
// $display("state: %b", state);
// $display("mem_rw: %b", mem_rw);
C_is_input_valid <= 0;
C_mem_read <= 0;
C_mem_write <= 0;
C_addr <= 0;
C_din <= 0;

// STATE A
if (state == `A) begin
if (is_input_valid)
state <= `B;
else
state <= `A;
end
// STATE B
else if (state == `B) begin
if(is_input_valid) begin
// Compare Tag
if (mem_rw == `WRITE) begin
if (is_write_hit) begin
// LRU setting
cache[D_set][matched_line][`LRU_IDX:`LRU_IDX-`LRU_BITS+1] <= `LRU_NEW;
cache[D_set][matched_line][D_bo*32 +: 32] <= din;
cache[D_set][matched_line][`DIRTY_IDX] <= 1;
for(i=0; i<NUM_WAYS; i=i+1) begin
if((i[`WAY_BITS-1:0] != matched_line) && (lru[i] > `LRU_OLD))
cache[D_set][i][`LRU_IDX:`LRU_IDX-`LRU_BITS+1] <= lru[i] - 1;
end
state <= `B;
end
state <= `A;
end
else if (is_old_line_dirty) begin
state <= `C;
miss_count <= miss_count + 1;
end
else begin
state <= `D;
miss_count <= miss_count + 1;
end
end
else if (mem_rw == `READ) begin
if (is_read_hit) begin
// LRU setting
cache[D_set][matched_line][`LRU_IDX:`LRU_IDX-`LRU_BITS+1] <= `LRU_NEW;
for(i=0; i<NUM_WAYS; i=i+1) begin
if((i[`WAY_BITS-1:0] != matched_line) && (lru[i] > `LRU_OLD))
cache[D_set][i][`LRU_IDX:`LRU_IDX-`LRU_BITS+1] <= lru[i] - 1;
else if (is_old_line_dirty) begin
state <= `C;
miss_count <= miss_count + 1;
end
else begin
state <= `D;
miss_count <= miss_count + 1;
end
state <= `A;
end
else if (is_old_line_dirty) begin
state <= `C;
miss_count <= miss_count + 1;
end
else begin
state <= `D;
miss_count <= miss_count + 1;
else if (mem_rw == `READ) begin
if (is_read_hit && is_output_valid) begin
// LRU setting
cache[D_set][matched_line][`LRU_IDX:`LRU_IDX-`LRU_BITS+1] <= `LRU_NEW;
for(i=0; i<NUM_WAYS; i=i+1) begin
if((i[`WAY_BITS-1:0] != matched_line) && (lru[i] > `LRU_OLD))
cache[D_set][i][`LRU_IDX:`LRU_IDX-`LRU_BITS+1] <= lru[i] - 1;
end
state <= `B;
end
else if (is_old_line_dirty) begin
state <= `C;
miss_count <= miss_count + 1;
end
else begin
state <= `D;
miss_count <= miss_count + 1;
end
end
end
else
state <= `B;
end
else
state <= `B;
end
// STATE C
else if (state == `C) begin
C_is_input_valid <= 1;
C_mem_write <= 1;
C_addr <= {cache[D_set][old_line][`TAG_IDX:`TAG_IDX-`TAG_BITS+1], D_set, 4'b0};
C_din <= cache[D_set][old_line][4*`DATA_BITS-1:0];
if (is_data_mem_ready)
state <= `E;
else
state <= `C;
end
// STATE D
else if (state == `D) begin
C_is_input_valid <= 1;
C_mem_read <= 1;
C_addr <= addr;
if (is_data_mem_ready)
state <= `F;
else
state <= `D;
end
else if (state == `E) begin
C_is_input_valid <= 1;
C_mem_write <= 1;
if(is_data_mem_ready) begin
cache[D_set][old_line][`DIRTY_IDX] <= 0;
state <= `D;
// STATE C
else if (state == `C) begin
C_is_input_valid <= 1;
C_mem_write <= 1;
C_addr <= {cache[D_set][old_line][`TAG_IDX:`TAG_IDX-`TAG_BITS+1], D_set, 4'b0};
C_din <= cache[D_set][old_line][4*`DATA_BITS-1:0];
if (is_data_mem_ready)
state <= `E;
else
state <= `C;
end
else
state <= `E;
end
else if (state == `F) begin
C_is_input_valid <= 1;
C_mem_read <= 1;
if(M_is_output_valid) begin
cache[D_set][old_line][4*`DATA_BITS-1:0] <= M_dout;
cache[D_set][old_line][`DIRTY_IDX] <= 0;
cache[D_set][old_line][`VALID_IDX] <= 1;
cache[D_set][old_line][`TAG_IDX:`TAG_IDX-`TAG_BITS+1] <= D_tag;
state <= `B;
// STATE D
else if (state == `D) begin
C_is_input_valid <= 1;
C_mem_read <= 1;
C_addr <= addr;
if (is_data_mem_ready)
state <= `F;
else
state <= `D;
end
// STATE E
else if (state == `E) begin
C_is_input_valid <= 1;
C_mem_read <= 1;
if(is_data_mem_ready) begin
cache[D_set][old_line][`DIRTY_IDX] <= 0;
state <= `D;
end
else
state <= `E;
end
// STATE F
else if (state == `F) begin
C_is_input_valid <= 1;
C_mem_read <= 1;
if(M_is_output_valid) begin
cache[D_set][old_line][4*`DATA_BITS-1:0] <= M_dout;
cache[D_set][old_line][`DIRTY_IDX] <= 0;
cache[D_set][old_line][`VALID_IDX] <= 1;
cache[D_set][old_line][`TAG_IDX:`TAG_IDX-`TAG_BITS+1] <= D_tag;
state <= `B;
end
else
state <= `F;
end
else
state <= `F;
end
end



// Instantiate data memory
DataMemory #(.BLOCK_SIZE(LINE_SIZE)) data_mem(
.reset(reset),
Expand All @@ -264,4 +257,5 @@ module Cache #(parameter LINE_SIZE = 16,
// is data memory ready to accept request?
.mem_ready(is_data_mem_ready)
);

endmodule

0 comments on commit 3e4f8ac

Please sign in to comment.