stage_fetch.sv (2467B)
1 module stage_fetch 2 (input logic clk, 3 input logic rstN, 4 input logic flush_i, // from fence.i 5 input logic [31:0] pc, 6 input logic [31:0] imem_data, 7 input logic imem_valid, 8 output logic [31:0] imem_addr, 9 output logic [31:0] inst); 10 11 `define USE_ICACHE 12 `ifdef USE_ICACHE 13 14 localparam CACHE_SIZE = 2048; // words 15 localparam IDX_WIDTH = $clog2(CACHE_SIZE); 16 localparam TAG_WIDTH = 32 - IDX_WIDTH - 2; // only be byte offset 17 localparam TAG_INVALID = {TAG_WIDTH+1{1'b1}}; 18 19 (* ram_style = "block" *) logic [31:0] cache [0:CACHE_SIZE-1]; 20 (* ram_style = "block" *) logic [TAG_WIDTH:0] tag_mem [0:CACHE_SIZE-1]; 21 logic [IDX_WIDTH-1:0] idx; 22 logic [TAG_WIDTH-1:0] tag_pc; 23 logic [31:0] cache_data; 24 logic [IDX_WIDTH-1:0] resp_idx; 25 logic [TAG_WIDTH-1:0] resp_tag; 26 logic [TAG_WIDTH:0] cache_tagv; // {valid,tag} registered read 27 logic resp_valid; 28 logic flush_active; 29 logic [IDX_WIDTH-1:0] flush_cnt; 30 logic hit; 31 32 always_comb begin 33 imem_addr = pc; 34 idx = pc[IDX_WIDTH+1:2]; 35 tag_pc = pc[31:IDX_WIDTH+2]; 36 37 hit = resp_valid && cache_tagv[TAG_WIDTH] && (cache_tagv[TAG_WIDTH-1:0] == resp_tag); 38 inst = hit ? cache_data : imem_data; 39 end 40 41 always_ff @(posedge clk or negedge rstN) begin 42 if (!rstN) begin // async flush 43 flush_active <= 1'b1; 44 flush_cnt <= '0; 45 cache_data <= '0; 46 resp_valid <= 0; 47 end else if (flush_active) begin // sweep invalidation writes 48 tag_mem[flush_cnt] <= TAG_INVALID; 49 if (flush_cnt == IDX_WIDTH'(CACHE_SIZE-1)) begin 50 flush_active <= 1'b0; 51 flush_cnt <= '0; 52 end else begin 53 flush_cnt <= flush_cnt + 1'b1; 54 end 55 resp_valid <= 1'b0; 56 end else if (flush_i) begin // sync flush (fence.i) 57 flush_active <= 1'b1; 58 flush_cnt <= '0; 59 resp_valid <= 1'b0; 60 end else begin 61 // fill using the registered backing-memory response 62 if (resp_valid && imem_valid && !hit) begin 63 cache[resp_idx] <= imem_data; 64 tag_mem[resp_idx] <= {1'b1, resp_tag}; 65 end 66 67 // registered cache read for the current fetch request 68 cache_data <= cache[idx]; 69 cache_tagv <= tag_mem[idx]; 70 resp_idx <= idx; 71 resp_tag <= tag_pc; 72 resp_valid <= 1; 73 end 74 end 75 76 `else 77 78 assign imem_addr = pc; 79 assign inst = imem_data; 80 81 `endif 82 83 endmodule: stage_fetch