Add some stuff related to cache
This commit is contained in:
0
sim/application_wrapper/application_wrapper.yaml
Normal file
0
sim/application_wrapper/application_wrapper.yaml
Normal file
19
sim/application_wrapper/cache/application_wrapper_cache_l1_test.py
vendored
Normal file
19
sim/application_wrapper/cache/application_wrapper_cache_l1_test.py
vendored
Normal file
@@ -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")
|
||||||
7
sim/application_wrapper/cache/cache.yaml
vendored
Normal file
7
sim/application_wrapper/cache/cache.yaml
vendored
Normal file
@@ -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
|
||||||
1
sim/application_wrapper/cache/sources.list
vendored
Normal file
1
sim/application_wrapper/cache/sources.list
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
../../../src/application_wrapper/sources.list
|
||||||
3
src/application_wrapper/application_wrapper_top.sv
Normal file
3
src/application_wrapper/application_wrapper_top.sv
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
module application_wrapper_top();
|
||||||
|
|
||||||
|
endmodule
|
||||||
108
src/application_wrapper/cache/application_wrapper_cache_l1.sv
vendored
Normal file
108
src/application_wrapper/cache/application_wrapper_cache_l1.sv
vendored
Normal file
@@ -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
|
||||||
13
src/application_wrapper/cache/application_wrapper_cache_pkg.sv
vendored
Normal file
13
src/application_wrapper/cache/application_wrapper_cache_pkg.sv
vendored
Normal file
@@ -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
|
||||||
0
src/application_wrapper/cache/application_wrapper_cache_top.sv
vendored
Normal file
0
src/application_wrapper/cache/application_wrapper_cache_top.sv
vendored
Normal file
21
src/application_wrapper/cache/application_wrapper_mmu.sv
vendored
Normal file
21
src/application_wrapper/cache/application_wrapper_mmu.sv
vendored
Normal file
@@ -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
|
||||||
6
src/application_wrapper/sources.list
Normal file
6
src/application_wrapper/sources.list
Normal file
@@ -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
|
||||||
Reference in New Issue
Block a user