summaryrefslogtreecommitdiff
path: root/rtl/core/core_prefetch.sv
diff options
context:
space:
mode:
authorAlejandro Soto <alejandro@34project.org>2024-01-21 06:23:46 -0600
committerAlejandro Soto <alejandro@34project.org>2024-02-20 11:11:17 -0600
commitf3b18ead59ae02f95dabbf0a1dea40873a816975 (patch)
tree8979e50f2a37f66a4cd27e937b480efe60d72cf7 /rtl/core/core_prefetch.sv
parenta8bc5a353ea997f73209b39377ee15a73e471237 (diff)
rtl: refactor filenames and directory hierarchy
Diffstat (limited to 'rtl/core/core_prefetch.sv')
-rw-r--r--rtl/core/core_prefetch.sv84
1 files changed, 84 insertions, 0 deletions
diff --git a/rtl/core/core_prefetch.sv b/rtl/core/core_prefetch.sv
new file mode 100644
index 0000000..719ad95
--- /dev/null
+++ b/rtl/core/core_prefetch.sv
@@ -0,0 +1,84 @@
+`include "core/uarch.sv"
+
+module core_prefetch
+#(parameter ORDER=2)
+(
+ input logic clk,
+ rst_n,
+ stall,
+ flush,
+ fault,
+ fetched,
+ input word fetch_data,
+ input ptr head,
+
+ output word insn,
+ output ptr insn_pc,
+ output logic fetch,
+ nop,
+ insn_abort
+);
+
+ localparam SIZE = (1 << ORDER) - 1;
+
+ ptr next_pc;
+ logic faults[SIZE];
+ logic[31:0] prefetch[SIZE];
+ logic[ORDER - 1:0] valid;
+
+ assign nop = flush ? 1 : ~|valid;
+ assign insn = flush ? `NOP : prefetch[0];
+ assign fetch = !stall || ~&valid;
+ assign next_pc = ~stall & |valid ? insn_pc + 1 : insn_pc;
+ assign insn_abort = flush ? 0 : faults[0];
+
+ always_ff @(posedge clk or negedge rst_n)
+ if(!rst_n) begin
+ valid <= 0;
+ insn_pc <= 0;
+
+ faults[SIZE - 1] <= 0;
+ prefetch[SIZE - 1] <= `NOP;
+ end else begin
+ insn_pc <= flush ? head : next_pc;
+
+ if(flush) begin
+ faults[SIZE - 1] <= 0;
+ prefetch[SIZE - 1] <= `NOP;
+ end else if(fetched && valid == SIZE - 1 + {{(ORDER - 1){1'b0}}, !stall}) begin
+ faults[SIZE - 1] <= fault;
+ prefetch[SIZE - 1] <= fetch_data;
+ end else if(!stall) begin
+ faults[SIZE - 1] <= 0;
+ prefetch[SIZE - 1] <= `NOP;
+ end
+
+ if(flush)
+ valid <= 0;
+ else if(fetched & ((stall & ~&valid) | ~|valid))
+ valid <= valid + 1;
+ else if(~stall & ~fetched & |valid)
+ valid <= valid - 1;
+ end
+
+ genvar i;
+ generate
+ for(i = 0; i < SIZE - 1; ++i) begin: prefetch_slots
+ always_ff @(posedge clk or negedge rst_n)
+ if(!rst_n) begin
+ faults[i] <= 0;
+ prefetch[i] <= `NOP;
+ end else if(flush) begin
+ faults[i] <= 0;
+ prefetch[i] <= `NOP;
+ end else if(fetched & (~(|i | |valid) | (valid == i + {{(ORDER - 1){1'b0}}, ~stall}))) begin
+ faults[i] <= fault;
+ prefetch[i] <= fetch_data;
+ end else if(~stall) begin
+ faults[i] <= faults[i + 1];
+ prefetch[i] <= prefetch[i + 1];
+ end
+ end
+ endgenerate
+
+endmodule