Update cache
Some checks are pending
continuous-integration/drone/push Build is pending

This commit is contained in:
Mario Romero 2023-02-28 14:22:02 -03:00
parent 1ce2a36712
commit 9a3727f1dd
5 changed files with 159 additions and 116 deletions

View File

@ -7,7 +7,7 @@ module cache_memory #(
parameter int BLOCK_SIZE = 32
) (
input logic clk,
rst,
input logic rst,
input logic [WaySize - 1:0] way,
input logic [SetSize - 1:0] set,
input logic [TagSize - 1:0] tag,
@ -29,7 +29,7 @@ module cache_memory #(
logic valid;
} cache_line_t;
typedef cache_line [NUM_SETS - 1:0] cache_way;
typedef cache_line_t [NUM_SETS - 1:0] cache_way;
cache_way [NUM_WAYS - 1:0] ways;
assign read_data = ways[way][set].data;
@ -39,8 +39,8 @@ module cache_memory #(
// Reset valid flags
for (int i = 0; i < NUM_WAYS; i++) begin
for (int j = 0; j < NUM_SETS; j++) begin
ways[i][j].data <= 'dx;
ways[i][j].tag <= 'dx;
ways[i][j].data <= BLOCK_SIZE'('dx);
ways[i][j].tag <= TagSize'('dx);
ways[i][j].valid <= 0;
end
end

View File

@ -1,77 +1,78 @@
`include "timescale.sv"
module two_way_lru_cache #(
parameter ADDR_SIZE = 32,
parameter NUM_SETS = 16,
parameter BLOCK_SIZE = 32
)(
input logic clk, rst,
input logic[ADDR_SIZE - 1:0] addr,
parameter int ADDR_SIZE = 32,
parameter int NUM_SETS = 16,
parameter int BLOCK_SIZE = 32
) (
input logic clk,
input logic rst,
input logic [ADDR_SIZE - 1:0] addr,
input logic write_enable,
input logic[BLOCK_SIZE - 1:0] write_data,
output logic[BLOCK_SIZE - 1:0] read_data,
input logic [BLOCK_SIZE - 1:0] write_data,
output logic [BLOCK_SIZE - 1:0] read_data,
output logic hit
);
localparam NUM_WAYS = 2;
localparam NUM_BLOCK_BYTES = BLOCK_SIZE / 4;
localparam BYTE_OFFSET_SIZE = $clog2(NUM_BLOCK_BYTES);
localparam WAY_SIZE = $clog2(NUM_WAYS);
localparam SET_SIZE = $clog2(NUM_SETS);
localparam TAG_SIZE = ADDR_SIZE - SET_SIZE - BYTE_OFFSET_SIZE;
logic[NUM_WAYS - 1:0] valid_flags;
logic[NUM_WAYS - 1:0] hits;
logic[WAY_SIZE - 1:0] way;
logic[SET_SIZE - 1:0] set;
logic[TAG_SIZE - 1:0] tag;
CacheMemory #(
ADDR_SIZE,
NUM_SETS,
NUM_WAYS,
BLOCK_SIZE
) cache_memory(
clk,
rst,
way,
set,
tag,
write_enable,
write_data,
read_data,
hits,
valid_flags
);
TwoWayLRUCRU #(
ADDR_SIZE,
NUM_SETS,
BLOCK_SIZE
) cache_replace_unit(
clk,
rst,
addr,
cru_enable,
replace_preferred_way
);
CacheController #(
ADDR_SIZE,
NUM_SETS,
NUM_WAYS,
BLOCK_SIZE
) cache_controller (
clk,
addr,
write_enable,
replace_preferred_way,
hits,
valid_flags,
set,
tag,
way,
hit,
cru_enable
);
localparam int NumWays = 2;
localparam int NumBlockBytes = BLOCK_SIZE / 4;
localparam int ByteOffsetSize = $clog2(NUM_BLOCK_BYTES);
localparam int WaySize = $clog2(NUM_WAYS);
localparam int SetSize = $clog2(NUM_SETS);
localparam int TagSize = ADDR_SIZE - SET_SIZE - BYTE_OFFSET_SIZE;
logic [NUM_WAYS - 1:0] valid_flags;
logic [NUM_WAYS - 1:0] hits;
logic [WAY_SIZE - 1:0] way;
logic [SET_SIZE - 1:0] set;
logic [TAG_SIZE - 1:0] tag;
cache_memory #(
.ADDR_SIZE (ADDR_SIZE),
.NUM_SETS (NUM_SETS),
.NUM_WAYS (NumWays),
.BLOCK_SIZE(BLOCK_SIZE)
) cache_memory (
.clk(clk),
.rst(rst),
.way(way),
.set(set),
.tag(tag),
.write_enable(write_enable),
.write_data(write_data),
.read_data(read_data),
.hits(hits),
.valid_flags(valid_flags)
);
two_way_lru_cru #(
.ADDR_SIZE (ADDR_SIZE),
.NUM_SETS (NUM_SETS),
.BLOCK_SIZE
) cache_replace_unit (
.clk(clk),
.rst(rst),
.addr(addr),
.replace(cru_enable),
.preferred(replace_preferred_way)
);
cache_controller #(
.ADDR_SIZE (ADDR_SIZE),
.NUM_SETS (NUM_SETS),
.NUM_WAYS (NUM_WAYS),
.BLOCK_SIZE(BLOCK_SIZE)
) cache_controller (
.clk(clk),
.addr(addr),
.write_enable(write_enable),
.replace_way(replace_preferred_way),
.hits(hits),
.valid_flags(valid_flags),
.set(set),
.tag(tag),
.way(way),
.hit(hit),
.cru_enable(cru_enable)
);
endmodule

View File

@ -1,37 +1,37 @@
`include "timescale.sv"
module two_way_lru_cru #(
parameter ADDR_SIZE = 32,
parameter NUM_SETS = 16,
parameter BLOCK_SIZE = 32
parameter int ADDR_SIZE = 32,
parameter int NUM_SETS = 16,
parameter int BLOCK_SIZE = 32
) (
input logic clk, rst,
input logic[ADDR_SIZE - 1:0] addr,
input logic clk,
input logic rst,
input logic [ADDR_SIZE - 1:0] addr,
input logic replace,
output logic preferred
);
localparam NUM_BLOCK_BYTES = BLOCK_SIZE / 4;
localparam BYTE_OFFSET_SIZE = $clog2(NUM_BLOCK_BYTES);
localparam SET_SIZE = $clog2(NUM_SETS);
localparam TAG_SIZE = ADDR_SIZE - SET_SIZE - BYTE_OFFSET_SIZE;
typedef struct packed {
logic[BYTE_OFFSET_SIZE - 1:0] byte_offset;
logic[SET_SIZE - 1:0] set;
logic[TAG_SIZE - 1:0] tag;
} cache_addr;
cache_addr packed_addr;
assign packed_addr = cache_addr'(addr);
logic[NUM_SETS - 1:0] lru;
assign preferred = lru[packed_addr.set];
always_ff @(posedge clk) begin
if (rst)
lru[packed_addr.set] <= 0;
else if (replace) begin
lru[packed_addr.set] <= !lru[packed_addr.set];
end
localparam int NumBlocksBytes = BLOCK_SIZE / 4;
localparam int ByteOffsetSize = $clog2(NumBlocksBytes);
localparam int SetSize = $clog2(NumSets);
localparam int TagSize = ADDR_SIZE - SetSize - ByteOffSetSize;
typedef struct packed {
logic [ByteOffsetSize - 1:0] byte_offset;
logic [SetSize - 1:0] set;
logic [TagSize - 1:0] tag;
} cache_addr_t;
cache_addr_t packed_addr;
assign packed_addr = cache_addr_t'(addr);
logic [NUM_SETS - 1:0] lru;
assign preferred = lru[packed_addr.set];
always_ff @(posedge clk) begin
if (rst) lru[packed_addr.set] <= 0;
else if (replace) begin
lru[packed_addr.set] <= !lru[packed_addr.set];
end
end
endmodule

View File

@ -96,3 +96,10 @@ rvscc_add_test(
${PROJECT_SOURCE_DIR}/rtl/hazard_unit.sv
${PROJECT_SOURCE_DIR}/test/test_five_stage_pipeline_core.sv
)
rvscc_add_test(
NAME cache-memory
TOP test_cache_memory
SOURCES ${PROJECT_SOURCE_DIR}/rtl/cache_memory.sv
${PROJECT_SOURCE_DIR}/test/test_cache_memory.sv
)

View File

@ -1,29 +1,64 @@
`timescale 1ns / 1ps
`include "timescale.sv"
module test_cache_memory ();
logic clk;
logic rst;
logic [31:0] addr, write_data, read_data;
logic clk, rst, write_enable;
CacheMemory cache_memory (
logic [dut.WaySize-1:0] way;
logic [dut.SetSize-1:0] set;
logic [dut.TagSize-1:0] tag;
logic write_enable;
logic [31:0] write_data;
logic [31:0] read_data;
logic [1:0] hits;
logic [1:0] valid_flags;
cache_memory #(
.ADDR_SIZE (32),
.NUM_SETS (4),
.NUM_WAYS (2),
.BLOCK_SIZE(32)
) dut (
.clk(clk),
.rst(rst),
write_enable,
write_data,
read_data
.way(way),
.set(set),
.tag(tag),
.write_enable(write_enable),
.write_data(write_data),
.read_data(read_data),
.hits(hits),
.valid_flags(valid_flags)
);
always #5 clk = ~clk;
localparam int ClockCycle = 2;
always #ClockCycle clk = !clk;
logic [31:0] write_value;
initial begin
$dumpfile("cache.vcd");
$dumpvars;
clk = 0;
rst = 1;
write_enable = 0;
#25 rst = 0;
addr = 'd7;
#ClockCycle;
rst = 0;
way = 0;
set = 0;
tag = 27'($urandom);
write_enable = 1;
write_data = 'd10;
#25 write_enable = 0;
write_value = $urandom;
write_data = write_value;
#ClockCycle;
write_enable = 0;
tag += 1;
assert (valid_flags == 'b00)
else $error("Valid flags does not match");
#1;
tag -= 1;
assert (valid_flags == 'b01)
else $error("Valid flags does not match");
$finish;
end
endmodule