Update cache
This commit is contained in:
parent
9a3727f1dd
commit
f4f81db925
@ -6,17 +6,14 @@ module cache_controller #(
|
||||
parameter int NUM_WAYS = 4,
|
||||
parameter int BLOCK_SIZE = 32
|
||||
) (
|
||||
input logic clk,
|
||||
input logic [ADDR_SIZE - 1:0] addr,
|
||||
input logic write_enable,
|
||||
input logic replace_way,
|
||||
input logic [NUM_WAYS - 1:0] hits,
|
||||
input logic [NUM_WAYS - 1:0] valid_flags,
|
||||
output logic [SetSize - 1:0] set,
|
||||
output logic [TagSize - 1:0] tag,
|
||||
output logic [WaySize - 1:0] way,
|
||||
output logic hit,
|
||||
output logic cru_enable
|
||||
input logic [$clog2(NUM_WAYS) - 1:0] replace_way,
|
||||
input logic [$clog2(NUM_WAYS) - 1:0] populate_way,
|
||||
output logic cru_enable,
|
||||
output logic [$clog2(NUM_WAYS) - 1:0] write_way,
|
||||
output logic [$clog2(NUM_SETS) - 1:0] set,
|
||||
output logic [ADDR_SIZE - $clog2(NUM_SETS) - $clog2(BLOCK_SIZE / 4) - 1:0] tag
|
||||
);
|
||||
localparam int NumBlockBytes = BLOCK_SIZE / 4;
|
||||
localparam int ByteOffsetSize = $clog2(NumBlockBytes);
|
||||
@ -32,61 +29,40 @@ module cache_controller #(
|
||||
|
||||
typedef enum logic [1:0] {
|
||||
READ = 'b00,
|
||||
WRITE_UNVALID = 'b10,
|
||||
REPLACE = 'b11
|
||||
WRITE_POPULATE = 'b10,
|
||||
WRITE_REPLACE = 'b11
|
||||
} cache_state_t;
|
||||
|
||||
cache_addr packed_addr;
|
||||
cache_addr_t packed_addr;
|
||||
cache_state_t state;
|
||||
|
||||
logic [WaySize - 1:0] valid_encode, next_unvalid_way;
|
||||
PriorityEncoder #(
|
||||
.N(WaySize)
|
||||
) valid_flags_encoder (
|
||||
.data_in(valid_flags),
|
||||
.data_out(valid_encode),
|
||||
.valid(valid_flags_encoder_valid)
|
||||
);
|
||||
PriorityEncoder #(
|
||||
.N(WaySize)
|
||||
) read_way_encoder (
|
||||
.data_in(hits),
|
||||
.data_out(read_way),
|
||||
.valid(read_way_encoder_valid)
|
||||
);
|
||||
|
||||
logic [WaySize - 1:0] next_populate_way;
|
||||
|
||||
logic valid;
|
||||
always_comb begin
|
||||
packed_addr = cache_addr'(addr);
|
||||
packed_addr = cache_addr_t'(addr);
|
||||
set = packed_addr.set;
|
||||
tag = packed_addr.tag;
|
||||
|
||||
hit = |hits;
|
||||
valid = &valid_flags;
|
||||
|
||||
state = cache_state_t'{write_enable, valid};
|
||||
|
||||
case (state)
|
||||
READ: begin
|
||||
cru_enable = 0;
|
||||
if (read_way_encoder_valid) way = read_way;
|
||||
else way = 'd0;
|
||||
write_way = 'dx;
|
||||
end
|
||||
WRITE_UNVALID: begin
|
||||
WRITE_POPULATE: begin
|
||||
cru_enable = 0;
|
||||
way = next_unvalid_way;
|
||||
write_way = next_populate_way;
|
||||
end
|
||||
REPLACE: begin
|
||||
WRITE_REPLACE: begin
|
||||
cru_enable = 1;
|
||||
way = replace_way;
|
||||
write_way = replace_way;
|
||||
end
|
||||
default: begin
|
||||
cru_enable = 0;
|
||||
way = 'dx;
|
||||
write_way = 'dx;
|
||||
end
|
||||
endcase
|
||||
|
||||
if (valid_flags_encoder_valid) next_unvalid_way = valid_encode + 'd1;
|
||||
else next_unvalid_way = 'd0;
|
||||
next_populate_way = populate_way + 'd1;
|
||||
end
|
||||
endmodule
|
||||
|
@ -8,20 +8,36 @@ module cache_memory #(
|
||||
) (
|
||||
input logic clk,
|
||||
input logic rst,
|
||||
input logic [WaySize - 1:0] way,
|
||||
input logic [SetSize - 1:0] set,
|
||||
input logic [TagSize - 1:0] tag,
|
||||
input logic [$clog2(NUM_WAYS) - 1:0] write_way,
|
||||
input logic [$clog2(NUM_SETS) - 1:0] set,
|
||||
input logic [ADDR_SIZE - $clog2(NUM_SETS) - $clog2(BLOCK_SIZE / 4) - 1:0] tag,
|
||||
input logic write_enable,
|
||||
input logic [BLOCK_SIZE - 1:0] write_data,
|
||||
output logic [BLOCK_SIZE - 1:0] read_data,
|
||||
output logic [NUM_WAYS - 1:0] hits,
|
||||
output logic [NUM_WAYS - 1:0] valid_flags
|
||||
output logic [$clog2(NUM_WAYS) - 1:0] populate_way,
|
||||
output logic hit
|
||||
);
|
||||
localparam int NumBlockBytes = BLOCK_SIZE / 4;
|
||||
localparam int ByteOffsetSize = $clog2(NumBlockBytes);
|
||||
localparam int WaySize = $clog2(NUM_WAYS);
|
||||
localparam int SetSize = $clog2(NUM_SETS);
|
||||
localparam int TagSize = ADDR_SIZE - SetSize - ByteOffsetSize;
|
||||
|
||||
logic [NUM_WAYS - 1:0] hits;
|
||||
logic [WaySize-1:0] way;
|
||||
logic [WaySize-1:0] read_way;
|
||||
priority_encoder #(.N(WaySize)) read_way_encoder (
|
||||
.data_in(hits),
|
||||
.data_out(read_way),
|
||||
.valid(hit)
|
||||
);
|
||||
|
||||
always_comb begin
|
||||
if(write_enable)
|
||||
way = write_way;
|
||||
else
|
||||
way = read_way;
|
||||
end
|
||||
|
||||
typedef struct packed {
|
||||
logic [BLOCK_SIZE - 1:0] data;
|
||||
@ -50,10 +66,18 @@ module cache_memory #(
|
||||
ways[way][set].valid <= 1;
|
||||
end
|
||||
end
|
||||
|
||||
logic [NUM_WAYS - 1:0] valid_flags;
|
||||
always_comb begin
|
||||
for (int i = 0; i < NUM_WAYS; i++) begin
|
||||
valid_flags[i] = ways[i][set].valid;
|
||||
hits[i] = ways[i][set].valid && (tag == ways[i][set].tag);
|
||||
end
|
||||
end
|
||||
|
||||
priority_encoder #(.N(WaySize)) populate_way_encoder (
|
||||
.data_in(valid_flags),
|
||||
.data_out(populate_way),
|
||||
.valid('dz)
|
||||
);
|
||||
endmodule
|
||||
|
@ -15,17 +15,17 @@ module two_way_lru_cache #(
|
||||
);
|
||||
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 ByteOffsetSize = $clog2(NumBlockBytes);
|
||||
localparam int WaySize = $clog2(NumWays);
|
||||
localparam int SetSize = $clog2(NUM_SETS);
|
||||
localparam int TagSize = ADDR_SIZE - SET_SIZE - BYTE_OFFSET_SIZE;
|
||||
localparam int TagSize = ADDR_SIZE - SetSize - ByteOffsetSize;
|
||||
|
||||
logic [NUM_WAYS - 1:0] valid_flags;
|
||||
logic [NUM_WAYS - 1:0] hits;
|
||||
logic [$clog2(NumWays) - 1:0] populate_way;
|
||||
logic read_valid;
|
||||
|
||||
logic [WAY_SIZE - 1:0] way;
|
||||
logic [SET_SIZE - 1:0] set;
|
||||
logic [TAG_SIZE - 1:0] tag;
|
||||
logic [WaySize - 1:0] way;
|
||||
logic [SetSize - 1:0] set;
|
||||
logic [TagSize - 1:0] tag;
|
||||
|
||||
cache_memory #(
|
||||
.ADDR_SIZE (ADDR_SIZE),
|
||||
@ -35,20 +35,20 @@ module two_way_lru_cache #(
|
||||
) cache_memory (
|
||||
.clk(clk),
|
||||
.rst(rst),
|
||||
.way(way),
|
||||
.write_way(write_way),
|
||||
.set(set),
|
||||
.tag(tag),
|
||||
.write_enable(write_enable),
|
||||
.write_data(write_data),
|
||||
.read_data(read_data),
|
||||
.hits(hits),
|
||||
.valid_flags(valid_flags)
|
||||
.populate_way(populate_way),
|
||||
.hit(hit)
|
||||
);
|
||||
|
||||
two_way_lru_cru #(
|
||||
.ADDR_SIZE (ADDR_SIZE),
|
||||
.NUM_SETS (NUM_SETS),
|
||||
.BLOCK_SIZE
|
||||
.BLOCK_SIZE(BLOCK_SIZE)
|
||||
) cache_replace_unit (
|
||||
.clk(clk),
|
||||
.rst(rst),
|
||||
@ -60,19 +60,16 @@ module two_way_lru_cache #(
|
||||
cache_controller #(
|
||||
.ADDR_SIZE (ADDR_SIZE),
|
||||
.NUM_SETS (NUM_SETS),
|
||||
.NUM_WAYS (NUM_WAYS),
|
||||
.NUM_WAYS (NumWays),
|
||||
.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),
|
||||
.populate_way(populate_way),
|
||||
.cru_enable(cru_enable),
|
||||
.write_way(write_way),
|
||||
.set(set),
|
||||
.tag(tag),
|
||||
.way(way),
|
||||
.hit(hit),
|
||||
.cru_enable(cru_enable)
|
||||
.tag(tag)
|
||||
);
|
||||
endmodule
|
||||
|
@ -13,8 +13,8 @@ module two_way_lru_cru #(
|
||||
);
|
||||
localparam int NumBlocksBytes = BLOCK_SIZE / 4;
|
||||
localparam int ByteOffsetSize = $clog2(NumBlocksBytes);
|
||||
localparam int SetSize = $clog2(NumSets);
|
||||
localparam int TagSize = ADDR_SIZE - SetSize - ByteOffSetSize;
|
||||
localparam int SetSize = $clog2(NUM_SETS);
|
||||
localparam int TagSize = ADDR_SIZE - SetSize - ByteOffsetSize;
|
||||
|
||||
typedef struct packed {
|
||||
logic [ByteOffsetSize - 1:0] byte_offset;
|
||||
|
7
scripts/vivado.tcl
Normal file
7
scripts/vivado.tcl
Normal file
@ -0,0 +1,7 @@
|
||||
# Script to initialize a Xilinx Vivado project
|
||||
# Make sure to run this script from the project root directory
|
||||
create_project RVSCC project
|
||||
create_fileset -blockset rtl
|
||||
create_fileset -blockset fw
|
||||
add_files -fileset rtl rtl
|
||||
add_files -fileset sim_1 test
|
@ -4,14 +4,14 @@ module test_cache_memory ();
|
||||
logic clk;
|
||||
logic rst;
|
||||
|
||||
logic [dut.WaySize-1:0] way;
|
||||
logic [dut.WaySize-1:0] write_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;
|
||||
logic read_valid;
|
||||
logic [dut.WaySize-1:0] populate_way;
|
||||
cache_memory #(
|
||||
.ADDR_SIZE (32),
|
||||
.NUM_SETS (4),
|
||||
@ -20,30 +20,28 @@ module test_cache_memory ();
|
||||
) dut (
|
||||
.clk(clk),
|
||||
.rst(rst),
|
||||
.way(way),
|
||||
.write_way(write_way),
|
||||
.set(set),
|
||||
.tag(tag),
|
||||
.write_enable(write_enable),
|
||||
.write_data(write_data),
|
||||
.read_data(read_data),
|
||||
.hits(hits),
|
||||
.valid_flags(valid_flags)
|
||||
.read_valid(read_valid),
|
||||
.populate_way(populate_way)
|
||||
);
|
||||
|
||||
localparam int ClockCycle = 2;
|
||||
always #ClockCycle clk = !clk;
|
||||
always #(ClockCycle/2) clk = !clk;
|
||||
|
||||
logic [31:0] write_value;
|
||||
|
||||
initial begin
|
||||
$dumpfile("cache.vcd");
|
||||
$dumpvars;
|
||||
clk = 0;
|
||||
rst = 1;
|
||||
#ClockCycle;
|
||||
rst = 0;
|
||||
|
||||
way = 0;
|
||||
write_way = 0;
|
||||
set = 0;
|
||||
tag = 27'($urandom);
|
||||
write_enable = 1;
|
||||
@ -52,11 +50,13 @@ module test_cache_memory ();
|
||||
#ClockCycle;
|
||||
write_enable = 0;
|
||||
tag += 1;
|
||||
assert (valid_flags == 'b00)
|
||||
else $error("Valid flags does not match");
|
||||
#1;
|
||||
assert (read_valid == 0)
|
||||
else $error("Valid flags does not match");
|
||||
#ClockCycle;
|
||||
tag -= 1;
|
||||
assert (valid_flags == 'b01)
|
||||
#1;
|
||||
assert (read_valid == 1)
|
||||
else $error("Valid flags does not match");
|
||||
$finish;
|
||||
end
|
||||
|
Loading…
Reference in New Issue
Block a user