From f4f81db925bfb369f9fdafa7d88226b778bc2015 Mon Sep 17 00:00:00 2001 From: Mario1159 Date: Thu, 2 Mar 2023 16:56:34 -0300 Subject: [PATCH] Update cache --- rtl/cache_controller.sv | 62 ++++++++++++--------------------------- rtl/cache_memory.sv | 34 +++++++++++++++++---- rtl/two_way_lru_cache.sv | 37 +++++++++++------------ rtl/two_way_lru_cru.sv | 4 +-- scripts/vivado.tcl | 7 +++++ test/test_cache_memory.sv | 26 ++++++++-------- 6 files changed, 87 insertions(+), 83 deletions(-) create mode 100644 scripts/vivado.tcl diff --git a/rtl/cache_controller.sv b/rtl/cache_controller.sv index ec35c73..f76e2d4 100644 --- a/rtl/cache_controller.sv +++ b/rtl/cache_controller.sv @@ -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 diff --git a/rtl/cache_memory.sv b/rtl/cache_memory.sv index cee5f4d..73dce75 100644 --- a/rtl/cache_memory.sv +++ b/rtl/cache_memory.sv @@ -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 diff --git a/rtl/two_way_lru_cache.sv b/rtl/two_way_lru_cache.sv index 4159d2c..64710d8 100644 --- a/rtl/two_way_lru_cache.sv +++ b/rtl/two_way_lru_cache.sv @@ -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 diff --git a/rtl/two_way_lru_cru.sv b/rtl/two_way_lru_cru.sv index b66d455..1114bae 100644 --- a/rtl/two_way_lru_cru.sv +++ b/rtl/two_way_lru_cru.sv @@ -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; diff --git a/scripts/vivado.tcl b/scripts/vivado.tcl new file mode 100644 index 0000000..7c655fd --- /dev/null +++ b/scripts/vivado.tcl @@ -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 \ No newline at end of file diff --git a/test/test_cache_memory.sv b/test/test_cache_memory.sv index a52358a..5257e45 100644 --- a/test/test_cache_memory.sv +++ b/test/test_cache_memory.sv @@ -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