Loading files
This file is pinned to the selected release. Download the original to open it in your design tool.
// Copyright 2018 ETH Zurich and University of Bologna.
// Copyright and related rights are licensed under the Solderpad Hardware
// License, Version 0.51 (the "License"); you may not use this file except in
// compliance with the License. You may obtain a copy of the License at
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
// or agreed to in writing, software, hardware and materials distributed under
// this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.
////////////////////////////////////////////////////////////////////////////////
// Engineer: Andreas Traber - atraber@iis.ee.ethz.ch //
// //
// Design Name: Prefetcher Buffer for 32 bit memory interface //
// Project Name: RI5CY //
// Language: SystemVerilog //
// //
// Description: Prefetch Buffer that caches instructions. This cuts overly //
// long critical paths to the instruction cache //
// //
////////////////////////////////////////////////////////////////////////////////
// input port: send address one cycle before the data
// clear_i clears the FIFO for the following cycle. in_addr_i can be sent in
// this cycle already
module cv32e40p_prefetch_buffer #(
parameter PULP_OBI = 0, // Legacy PULP OBI behavior
parameter COREV_PULP = 1 // PULP ISA Extension (including PULP specific CSRs and hardware loop, excluding p.elw)
) (
input logic clk,
input logic rst_n,
input logic req_i,
input logic branch_i,
input logic [31:0] branch_addr_i,
input logic hwlp_jump_i,
input logic [31:0] hwlp_target_i,
input logic fetch_ready_i,
output logic fetch_valid_o,
output logic [31:0] fetch_rdata_o,
// goes to instruction memory / instruction cache
output logic instr_req_o,
input logic instr_gnt_i,
output logic [31:0] instr_addr_o,
input logic [31:0] instr_rdata_i,
input logic instr_rvalid_i,
input logic instr_err_i, // Not used yet (future addition)
input logic instr_err_pmp_i, // Not used yet (future addition)
// Prefetch Buffer Status
output logic busy_o
);
// FIFO_DEPTH controls also the number of outstanding memory requests
// FIFO_DEPTH must be greater than 1 to respect assertion in prefetch controller
// FIFO_DEPTH must be a power of 2 (because of the FIFO implementation)
localparam FIFO_DEPTH = 2; //must be greater or equal to 2 //Set at least to 3 to avoid stalls compared to the master branch
localparam int unsigned FIFO_ADDR_DEPTH = $clog2(FIFO_DEPTH);
// Transaction request (between cv32e40p_prefetch_controller and cv32e40p_obi_interface)
logic trans_valid;
logic trans_ready;
logic [ 31:0] trans_addr;
logic fifo_flush;
logic fifo_flush_but_first;
logic [FIFO_ADDR_DEPTH:0] fifo_cnt; // fifo_cnt should count from 0 to FIFO_DEPTH!
logic [ 31:0] fifo_rdata;
logic fifo_push;
logic fifo_pop;
logic fifo_empty;
// Transaction response interface (between cv32e40p_obi_interface and cv32e40p_fetch_fifo)
logic resp_valid;
logic [ 31:0] resp_rdata;
logic resp_err; // Unused for now
//////////////////////////////////////////////////////////////////////////////
// Prefetch Controller
//////////////////////////////////////////////////////////////////////////////
cv32e40p_prefetch_controller #(
.DEPTH (FIFO_DEPTH),
.PULP_OBI (PULP_OBI),
.COREV_PULP(COREV_PULP)
) prefetch_controller_i (
.clk (clk),
.rst_n(rst_n),
.req_i (req_i),
.branch_i (branch_i),
.branch_addr_i(branch_addr_i),
.busy_o (busy_o),
.hwlp_jump_i (hwlp_jump_i),
.hwlp_target_i(hwlp_target_i),
.trans_valid_o(trans_valid),
.trans_ready_i(trans_ready),
.trans_addr_o (trans_addr),
.resp_valid_i(resp_valid),
.fetch_ready_i(fetch_ready_i),
.fetch_valid_o(fetch_valid_o),
.fifo_push_o (fifo_push),
.fifo_pop_o (fifo_pop),
.fifo_flush_o (fifo_flush),
.fifo_flush_but_first_o(fifo_flush_but_first),
.fifo_cnt_i (fifo_cnt),
.fifo_empty_i (fifo_empty)
);
//////////////////////////////////////////////////////////////////////////////
// Fetch FIFO && fall-through path
//////////////////////////////////////////////////////////////////////////////
cv32e40p_fifo #(
.FALL_THROUGH(1'b0),
.DATA_WIDTH (32),
.DEPTH (FIFO_DEPTH)
) fifo_i (
.clk_i (clk),
.rst_ni (rst_n),
.flush_i (fifo_flush),
.flush_but_first_i(fifo_flush_but_first),
.testmode_i (1'b0),
.full_o (),
.empty_o (fifo_empty),
.cnt_o (fifo_cnt),
.data_i (resp_rdata),
.push_i (fifo_push),
.data_o (fifo_rdata),
.pop_i (fifo_pop)
);
// First POP from the FIFO if it is not empty.
// Otherwise, try to fall-through it.
assign fetch_rdata_o = fifo_empty ? resp_rdata : fifo_rdata;
//////////////////////////////////////////////////////////////////////////////
// OBI interface
//////////////////////////////////////////////////////////////////////////////
cv32e40p_obi_interface #(
.TRANS_STABLE(0) // trans_* is NOT guaranteed stable during waited transfers;
// this is ignored for legacy PULP behavior (not compliant to OBI)
) // Keep this parameter stuck to 0 to make HWLP work
instruction_obi_i
(
.clk (clk),
.rst_n(rst_n),
.trans_valid_i(trans_valid),
.trans_ready_o(trans_ready),
.trans_addr_i ({trans_addr[31:2], 2'b00}),
.trans_we_i (1'b0), // Instruction interface (never write)
.trans_be_i (4'b1111), // Corresponding obi_be_o not used
.trans_wdata_i(32'b0), // Corresponding obi_wdata_o not used
.trans_atop_i (6'b0), // Atomics not used on instruction bus
.resp_valid_o(resp_valid),
.resp_rdata_o(resp_rdata),
.resp_err_o (resp_err), // Unused for now
.obi_req_o (instr_req_o),
.obi_gnt_i (instr_gnt_i),
.obi_addr_o (instr_addr_o),
.obi_we_o (), // Left unconnected on purpose
.obi_be_o (), // Left unconnected on purpose
.obi_wdata_o (), // Left unconnected on purpose
.obi_atop_o (), // Left unconnected on purpose
.obi_rdata_i (instr_rdata_i),
.obi_rvalid_i(instr_rvalid_i),
.obi_err_i (instr_err_i)
);
//----------------------------------------------------------------------------
// Assertions
//----------------------------------------------------------------------------
`ifdef CV32E40P_ASSERT_ON
// FIFO_DEPTH must be greater than 1. Otherwise, the property
// p_hwlp_end_already_gnt_when_hwlp_branch in cv32e40p_prefetch_controller
// is not verified, since the prefetcher cannot ask for HWLP_END the cycle
// in which HWLP_END-4 is being absorbed by ID.
property p_fifo_depth_gt_1;
@(posedge clk) (FIFO_DEPTH > 1);
endproperty
a_fifo_depth_gt_1 :
assert property (p_fifo_depth_gt_1);
// Check that branch target address is half-word aligned (RV32-C)
property p_branch_halfword_aligned;
@(posedge clk) (branch_i) |-> (branch_addr_i[0] == 1'b0);
endproperty
a_branch_halfword_aligned :
assert property (p_branch_halfword_aligned);
// Check that bus interface transactions are word aligned
property p_instr_addr_word_aligned;
@(posedge clk) (1'b1) |-> (instr_addr_o[1:0] == 2'b00);
endproperty
a_instr_addr_word_aligned :
assert property (p_instr_addr_word_aligned);
// Check that a taken branch can only occur if fetching is requested
property p_branch_implies_req;
@(posedge clk) (branch_i) |-> (req_i);
endproperty
a_branch_implies_req :
assert property (p_branch_implies_req);
// Check that after a taken branch the initial FIFO output is not accepted
property p_branch_invalidates_fifo;
@(posedge clk) (branch_i) |-> (!(fetch_valid_o && fetch_ready_i));
endproperty
a_branch_invalidates_fifo :
assert property (p_branch_invalidates_fifo);
// External instruction bus errors are not supported yet. PMP errors are not supported yet.
//
// Note: Once PMP is re-introduced please consider to make instr_err_pmp_i a 'data' signal
// that is qualified with instr_req_o && instr_gnt_i (instead of suppressing instr_gnt_i
// as is currently done. This will keep the instr_req_o/instr_gnt_i protocol intact.
//
// JUST RE-ENABLING the PMP VIA ITS USE_PMP LOCALPARAM WILL NOT WORK BECAUSE OF THE
// GRANT SUPPRESSION IN THE PMP.
property p_no_error;
@(posedge clk) (1'b1) |-> ((instr_err_i == 1'b0) && (instr_err_pmp_i == 1'b0));
endproperty
a_no_error :
assert property (p_no_error);
`endif
endmodule // cv32e40p_prefetch_buffer
dd1f8e446This file is pinned to the selected release. Download the original to open it in your design tool.