From 62a3408eb737014ff229800e02b420713e96ca97 Mon Sep 17 00:00:00 2001 From: Byron Lathi Date: Sat, 16 May 2026 16:55:21 -0700 Subject: [PATCH] Add some stuff related to cache --- .../application_wrapper.yaml | 0 .../application_wrapper_cache_l1_test.py | 19 +++ sim/application_wrapper/cache/cache.yaml | 7 ++ sim/application_wrapper/cache/sources.list | 1 + .../application_wrapper_top.sv | 3 + .../cache/application_wrapper_cache_l1.sv | 108 ++++++++++++++++++ .../cache/application_wrapper_cache_pkg.sv | 13 +++ .../cache/application_wrapper_cache_top.sv | 0 .../cache/application_wrapper_mmu.sv | 21 ++++ src/application_wrapper/sources.list | 6 + 10 files changed, 178 insertions(+) create mode 100644 sim/application_wrapper/application_wrapper.yaml create mode 100644 sim/application_wrapper/cache/application_wrapper_cache_l1_test.py create mode 100644 sim/application_wrapper/cache/cache.yaml create mode 100644 sim/application_wrapper/cache/sources.list create mode 100644 src/application_wrapper/application_wrapper_top.sv create mode 100644 src/application_wrapper/cache/application_wrapper_cache_l1.sv create mode 100644 src/application_wrapper/cache/application_wrapper_cache_pkg.sv create mode 100644 src/application_wrapper/cache/application_wrapper_cache_top.sv create mode 100644 src/application_wrapper/cache/application_wrapper_mmu.sv create mode 100644 src/application_wrapper/sources.list diff --git a/sim/application_wrapper/application_wrapper.yaml b/sim/application_wrapper/application_wrapper.yaml new file mode 100644 index 0000000..e69de29 diff --git a/sim/application_wrapper/cache/application_wrapper_cache_l1_test.py b/sim/application_wrapper/cache/application_wrapper_cache_l1_test.py new file mode 100644 index 0000000..68d69f4 --- /dev/null +++ b/sim/application_wrapper/cache/application_wrapper_cache_l1_test.py @@ -0,0 +1,19 @@ +import cocotb +from cocotb.handle import Immediate + +from cocotb.clock import Clock +from cocotb.triggers import Timer, RisingEdge, FallingEdge, with_timeout + + +CLK_PERIOD = 5 + +@cocotb.test +async def sanity_test(dut): + cocotb.start_soon(Clock(dut.i_clk, CLK_PERIOD, unit="ns").start()) + + dut.i_rst.value = Immediate(1) + for _ in range(10): + await RisingEdge(dut.i_clk) + dut.i_rst.value = 0 + + await Timer(1, "us") \ No newline at end of file diff --git a/sim/application_wrapper/cache/cache.yaml b/sim/application_wrapper/cache/cache.yaml new file mode 100644 index 0000000..d6bd069 --- /dev/null +++ b/sim/application_wrapper/cache/cache.yaml @@ -0,0 +1,7 @@ +tests: + - name: "application_wrapper_cache_l1_test" + toplevel: "application_wrapper_cache_l1" + modules: + - "application_wrapper_cache_l1_test" + sources: "sources.list" + waves: True \ No newline at end of file diff --git a/sim/application_wrapper/cache/sources.list b/sim/application_wrapper/cache/sources.list new file mode 100644 index 0000000..905e7a3 --- /dev/null +++ b/sim/application_wrapper/cache/sources.list @@ -0,0 +1 @@ +../../../src/application_wrapper/sources.list \ No newline at end of file diff --git a/src/application_wrapper/application_wrapper_top.sv b/src/application_wrapper/application_wrapper_top.sv new file mode 100644 index 0000000..2364d6d --- /dev/null +++ b/src/application_wrapper/application_wrapper_top.sv @@ -0,0 +1,3 @@ +module application_wrapper_top(); + +endmodule \ No newline at end of file diff --git a/src/application_wrapper/cache/application_wrapper_cache_l1.sv b/src/application_wrapper/cache/application_wrapper_cache_l1.sv new file mode 100644 index 0000000..e156738 --- /dev/null +++ b/src/application_wrapper/cache/application_wrapper_cache_l1.sv @@ -0,0 +1,108 @@ +import application_wrapper_cache_pkg::*; + +module application_wrapper_cache_l1 #( + parameter CACHELINE_SIZE = 64, + parameter CACHELINE_COUNT = 64, + localparam ADDR_WIDTH = 32 +)( + input logic i_clk, + input logic i_rst, + + /* CPU Interface */ + input logic [ADDR_WIDTH-1:0] i_addr, + input logic i_we, + input logic [7:0] i_data, + output logic [7:0] o_data, + + input logic i_rdy, + output logic o_rdy, + + /* MMU Interface */ + input logic [ADDR_WIDTH-1:0] i_phys_address, + output page_table_entry_t i_table_entry, + input logic i_mmu_valid, + + /* Higher level cache interface */ + output logic [ADDR_WIDTH-1:0] o_addr, + output logic [1:0] o_cache_cmd, + output logic o_cache_valid, + + output logic [63:0] o_cache_data, + input logic [31:0] i_cache_data, + input logic i_cache_rdy +); + +// we have 32 bit addresses, 64 byte cache lines, and 64 total lines. +// Thats 6 bit for offset, 6 bit for index, and 20 bit for cache. + +// cache is virtually indexed, physically tagged + +localparam OFFSET_W = $clog2(CACHELINE_SIZE); +localparam INDEX_W = $clog2(CACHELINE_COUNT); +localparam TAG_W = ADDR_WIDTH - INDEX_W - OFFSET_W; +localparam META_W = 3; // valid, unique, clean + +logic [OFFSET_W-1:0] offset; +logic [INDEX_W-1:0] index; +logic [TAG_W-1:0] tag; + +assign offset = i_addr[OFFSET_W-1:0]; +assign index = i_addr[INDEX_W+OFFSET_W-1:OFFSET_W]; +assign tag = i_addr[INDEX_W+OFFSET_W+TAG_W-1:INDEX_W+OFFSET_W]; + +// cacheline size is in bytes, not bits +// direct mapped cache, read one line so we have data ready if its a hit. +logic [CACHELINE_SIZE*8-1:0] data_array [CACHELINE_COUNT]; +logic [META_W+TAG_W-1:0] meta_tag_array [CACHELINE_COUNT]; + +enum logic [1:0] {IDLE, READY, EVICT, READ} state, state_next; + +always_ff @(posedge i_clk) begin + if (i_rst) begin + state <= IDLE; + end else begin + state <= state_next; + end +end + +always_comb begin + state_next = state; + + o_rdy = '0; + + case (state) + IDLE: begin + state_next = READY; + end + + READY: begin + o_rdy = '1; + end + + EVICT: begin + + end + + READ: begin + + end + endcase +end + +/* + + In the ready state, we read from the data array and if the line is valid + and the tag matches with the address, we present the data to the cpu. + Otherwise, we lower o_rdy and send the request to the higher level cache. + + If what we read was valid but the tag didn't match, then we need to evict it. + If the line was not valid, then we don't need to evict it and can just request + the new data. + + One thing that we also need is an MMU. The TLB can be 1 cycle, then if the TLB + says that we are allowed to read from the cache, we can read from the cache. +*/ + + + +endmodule \ No newline at end of file diff --git a/src/application_wrapper/cache/application_wrapper_cache_pkg.sv b/src/application_wrapper/cache/application_wrapper_cache_pkg.sv new file mode 100644 index 0000000..5f035f6 --- /dev/null +++ b/src/application_wrapper/cache/application_wrapper_cache_pkg.sv @@ -0,0 +1,13 @@ +package application_wrapper_cache_pkg; + + typedef struct { + logic cache_disable; + logic read_eanble; + logic write_enable; + logic execute_enable; + logic supervisor; + logic present; + logic write_through; + } page_table_entry_t; + +endpackage \ No newline at end of file diff --git a/src/application_wrapper/cache/application_wrapper_cache_top.sv b/src/application_wrapper/cache/application_wrapper_cache_top.sv new file mode 100644 index 0000000..e69de29 diff --git a/src/application_wrapper/cache/application_wrapper_mmu.sv b/src/application_wrapper/cache/application_wrapper_mmu.sv new file mode 100644 index 0000000..4e36f2e --- /dev/null +++ b/src/application_wrapper/cache/application_wrapper_mmu.sv @@ -0,0 +1,21 @@ +import application_wrapper_cache_pkg::*; + +module application_wrapper_mmu #( + parameter TLB_COUNT = 32, + parameter ADDR_WIDTH = 32, + parameter LOG2_PAGE_SIZE = 12 +) ( + input logic i_clk, + input logic i_rst, + + input logic [ADDR_WIDTH-1:0] i_cpu_addr, + input i_we, + input i_rdy, + input o_rdy, + + output logic [ADDR_WIDTH-1:0] o_phys_address, + output page_table_entry_t o_table_entry, + output logic o_mmu_valid +); + +endmodule \ No newline at end of file diff --git a/src/application_wrapper/sources.list b/src/application_wrapper/sources.list new file mode 100644 index 0000000..638ba6b --- /dev/null +++ b/src/application_wrapper/sources.list @@ -0,0 +1,6 @@ +cache/application_wrapper_cache_pkg.sv +cache/application_wrapper_cache_l1.sv +cache/application_wrapper_mmu.sv +cache/application_wrapper_cache_top.sv + +application_wrapper_top.sv \ No newline at end of file