Compare commits

...

2 Commits

Author SHA1 Message Date
03c30636e9 Merge branch 'main' of https://git.1159.cl/Mario1159/RVSCC
Some checks are pending
continuous-integration/drone/push Build is pending
2023-03-02 16:57:58 -03:00
f4f81db925 Update cache 2023-03-02 16:56:34 -03:00
6 changed files with 87 additions and 83 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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
View 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

View File

@ -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