summaryrefslogtreecommitdiff
path: root/rtl/cache/routing.sv
diff options
context:
space:
mode:
authorAlejandro Soto <alejandro@34project.org>2023-09-24 20:58:04 -0600
committerAlejandro Soto <alejandro@34project.org>2023-09-24 22:14:57 -0600
commit15230c6cd2190a1efd61c2758bf56de37f3fe8da (patch)
tree9d8a04daadb4192cf4aeb44b8e86389a9ba130d3 /rtl/cache/routing.sv
parent146168ca340e435eae6e30e99c06d752719089e3 (diff)
rtl/cache: implement
Diffstat (limited to '')
-rw-r--r--rtl/cache/routing.sv107
1 files changed, 107 insertions, 0 deletions
diff --git a/rtl/cache/routing.sv b/rtl/cache/routing.sv
new file mode 100644
index 0000000..4857e08
--- /dev/null
+++ b/rtl/cache/routing.sv
@@ -0,0 +1,107 @@
+`include "cache/defs.sv"
+
+module cache_routing
+(
+ input logic clk,
+ rst_n,
+
+ input word core_address,
+ input logic core_read,
+ core_write,
+ input line core_writedata_line,
+ input line_be core_byteenable_line,
+ output logic core_waitrequest,
+ output line core_readdata_line,
+
+ output addr_tag core_tag,
+ output addr_index core_index,
+ output addr_offset core_offset,
+
+ input line data_rd,
+ input logic cache_core_waitrequest,
+ output logic cache_core_read,
+ cache_core_write,
+
+ input word cache_mem_address,
+ input logic cache_mem_read,
+ cache_mem_write,
+ input line cache_mem_writedata,
+ output logic cache_mem_waitrequest,
+
+ input logic mem_waitrequest,
+ input line mem_readdata,
+ output word mem_address,
+ output logic mem_read,
+ mem_write,
+ output line mem_writedata,
+ output line_be mem_byteenable
+);
+
+ word core_address_line;
+ logic cached, cache_mem, transition;
+ addr_mbz mbz;
+ addr_io_region io;
+
+ enum int unsigned
+ {
+ IDLE,
+ CACHE,
+ BYPASS
+ } state;
+
+ assign cached = io == 3'b000;
+ assign cache_mem = cache_mem_read || cache_mem_write;
+
+ assign {io, core_tag, core_index, core_offset, mbz} = core_address;
+ assign core_address_line = {io, core_tag, core_index, 4'b0000};
+ assign core_readdata_line = cached ? data_rd : mem_readdata;
+
+ assign cache_core_read = core_read && cached;
+ assign cache_core_write = core_write && cached;
+
+ always_comb begin
+ transition = 0;
+ core_waitrequest = cache_core_waitrequest;
+ cache_mem_waitrequest = 1;
+
+ unique case (state)
+ IDLE:
+ transition = cache_mem || (!cached && (core_read || core_write));
+
+ CACHE:
+ cache_mem_waitrequest = mem_waitrequest;
+
+ BYPASS:
+ core_waitrequest = mem_waitrequest;
+ endcase
+ end
+
+ always_ff @(posedge clk or negedge rst_n)
+ if (!rst_n) begin
+ state <= IDLE;
+ mem_read <= 0;
+ mem_write <= 0;
+ end else unique case (state)
+ IDLE:
+ if (transition) begin
+ state <= cache_mem ? CACHE : BYPASS;
+ mem_read <= cache_mem ? cache_mem_read : core_read;
+ mem_write <= cache_mem ? cache_mem_write : core_write;
+ end
+
+ CACHE, BYPASS:
+ if (!mem_waitrequest) begin
+ state <= IDLE;
+ mem_read <= 0;
+ mem_write <= 0;
+ end
+ endcase
+
+ always_ff @(posedge clk)
+ if (transition) begin
+ mem_address <= cache_mem ? cache_mem_address : core_address_line;
+ mem_writedata <= cache_mem ? cache_mem_writedata : core_writedata_line;
+ mem_byteenable <= cache_mem ? 16'hff : core_byteenable_line;
+ end
+
+endmodule