diff options
Diffstat (limited to '')
| -rw-r--r-- | rtl/core/fetch/prefetch.sv | 69 |
1 files changed, 69 insertions, 0 deletions
diff --git a/rtl/core/fetch/prefetch.sv b/rtl/core/fetch/prefetch.sv new file mode 100644 index 0000000..b994d8b --- /dev/null +++ b/rtl/core/fetch/prefetch.sv @@ -0,0 +1,69 @@ +`include "core/uarch.sv" + +module core_prefetch +#(parameter ORDER=2) +( + input logic clk, + stall, + flush, + fetched, + input logic[31:0] fetch_data, + + output logic[31:0] insn, + output logic[29:0] insn_pc, + next_pc, + output logic fetch +); + + localparam SIZE = (1 << ORDER) - 1; + + logic[31:0] prefetch[SIZE]; + logic[ORDER - 1:0] valid; + + assign insn = prefetch[0]; + assign next_pc = ~stall & |valid ? insn_pc + 1 : insn_pc; + + always_comb + if((valid == SIZE - 2) & fetched) + fetch = 0; + else + fetch = ~&valid; + + always_ff @(posedge clk) begin + insn_pc <= next_pc; + + if(~flush & fetched & (valid == SIZE - 1)) + prefetch[SIZE - 1] <= fetch_data; + else + prefetch[SIZE - 1] <= `NOP; + + if(flush) + valid <= 0; + else if(stall & fetched & ~&valid) + valid <= valid + 1; + else if(~stall & ~fetched & |valid) + valid <= valid - 1; + end + + genvar i; + generate + for(i = 0; i < SIZE - 1; ++i) begin + always_ff @(posedge clk) + if(flush) + prefetch[i] <= `NOP; + else if(fetched & (~(|i | |valid) | (valid == i + {{(ORDER - 1){1'b0}}, ~stall}))) + prefetch[i] <= fetch_data; + else if(~stall) + prefetch[i] <= prefetch[i + 1]; + + initial prefetch[i] = `NOP; + end + endgenerate + + initial begin + insn_pc = 0; + valid = 0; + prefetch[SIZE - 1] = `NOP; + end + +endmodule |
