mirror of
https://github.com/openhwgroup/cve2.git
synced 2025-04-24 14:09:08 -04:00
[rtl] prefetch buffer performance fix
- The prefetch buffer needs to know when space is available in the fetch FIFO to accept a new external request. - This change updates that logic to look at what is in the FIFO and what is outstanding on the bus to decide when space is available rather than always assuming the maximum number of requests are outstanding. - This improves the usage efficiency of the FIFO and fixes #574 Signed-off-by: Tom Roberts <tomroberts@lowrisc.org>
This commit is contained in:
parent
059d3f324f
commit
4b01580a7b
2 changed files with 34 additions and 25 deletions
|
@ -15,30 +15,28 @@
|
|||
module ibex_fetch_fifo #(
|
||||
parameter int unsigned NUM_REQS = 2
|
||||
) (
|
||||
input logic clk_i,
|
||||
input logic rst_ni,
|
||||
input logic clk_i,
|
||||
input logic rst_ni,
|
||||
|
||||
// control signals
|
||||
input logic clear_i, // clears the contents of the FIFO
|
||||
input logic clear_i, // clears the contents of the FIFO
|
||||
output logic [NUM_REQS-1:0] busy_o,
|
||||
|
||||
// input port
|
||||
input logic in_valid_i,
|
||||
output logic in_ready_o,
|
||||
input logic [31:0] in_addr_i,
|
||||
input logic [31:0] in_rdata_i,
|
||||
input logic in_err_i,
|
||||
input logic in_valid_i,
|
||||
input logic [31:0] in_addr_i,
|
||||
input logic [31:0] in_rdata_i,
|
||||
input logic in_err_i,
|
||||
|
||||
// output port
|
||||
output logic out_valid_o,
|
||||
input logic out_ready_i,
|
||||
output logic [31:0] out_addr_o,
|
||||
output logic [31:0] out_rdata_o,
|
||||
output logic out_err_o,
|
||||
output logic out_err_plus2_o
|
||||
output logic out_valid_o,
|
||||
input logic out_ready_i,
|
||||
output logic [31:0] out_addr_o,
|
||||
output logic [31:0] out_rdata_o,
|
||||
output logic out_err_o,
|
||||
output logic out_err_plus2_o
|
||||
);
|
||||
|
||||
// To gain extra performance DEPTH should be increased, this is due to some inefficiencies in the
|
||||
// way the fetch fifo operates see issue #574 for more details
|
||||
localparam int unsigned DEPTH = NUM_REQS+1;
|
||||
|
||||
// index 0 is used for output
|
||||
|
@ -159,14 +157,14 @@ module ibex_fetch_fifo #(
|
|||
// The LSB of the address is unused, since all addresses are halfword aligned
|
||||
assign unused_addr_in = in_addr_i[0];
|
||||
|
||||
////////////////
|
||||
// input port //
|
||||
////////////////
|
||||
/////////////////
|
||||
// FIFO status //
|
||||
/////////////////
|
||||
|
||||
// Accept data as long as our FIFO has space to accept the maximum number of outstanding
|
||||
// requests. Note that the prefetch buffer does not count how many requests are actually
|
||||
// outstanding, so space must be reserved for the maximum number.
|
||||
assign in_ready_o = ~valid_q[DEPTH-NUM_REQS];
|
||||
// Indicate the fill level of fifo-entries. This is used to determine when a new request can be
|
||||
// made on the bus. The prefetch buffer only needs to know about the upper entries which overlap
|
||||
// with NUM_REQS.
|
||||
assign busy_o = valid_q[DEPTH-1:DEPTH-NUM_REQS];
|
||||
|
||||
/////////////////////
|
||||
// FIFO management //
|
||||
|
|
|
@ -51,6 +51,7 @@ module ibex_prefetch_buffer (
|
|||
logic [NUM_REQS-1:0] rdata_outstanding_n, rdata_outstanding_s, rdata_outstanding_q;
|
||||
logic [NUM_REQS-1:0] branch_discard_n, branch_discard_s, branch_discard_q;
|
||||
logic [NUM_REQS-1:0] rdata_pmp_err_n, rdata_pmp_err_s, rdata_pmp_err_q;
|
||||
logic [NUM_REQS-1:0] rdata_outstanding_rev;
|
||||
|
||||
logic [31:0] stored_addr_d, stored_addr_q;
|
||||
logic stored_addr_en;
|
||||
|
@ -62,6 +63,7 @@ module ibex_prefetch_buffer (
|
|||
logic fifo_valid;
|
||||
logic fifo_ready;
|
||||
logic fifo_clear;
|
||||
logic [NUM_REQS-1:0] fifo_busy;
|
||||
|
||||
////////////////////////////
|
||||
// Prefetch buffer status //
|
||||
|
@ -82,6 +84,16 @@ module ibex_prefetch_buffer (
|
|||
// altered the FENCE.I implementation may require changes.
|
||||
assign fifo_clear = branch_i;
|
||||
|
||||
// Reversed version of rdata_outstanding_q which can be overlaid with fifo fill state
|
||||
for (genvar i = 0; i < NUM_REQS; i++) begin : gen_rd_rev
|
||||
assign rdata_outstanding_rev[i] = rdata_outstanding_q[NUM_REQS-1-i];
|
||||
end
|
||||
|
||||
// The fifo is ready to accept a new request if it is not full - including space reserved for
|
||||
// requests already outstanding.
|
||||
// Overlay the fifo fill state with the outstanding requests to see if there is space.
|
||||
assign fifo_ready = ~&(fifo_busy | rdata_outstanding_rev);
|
||||
|
||||
ibex_fetch_fifo #(
|
||||
.NUM_REQS (NUM_REQS)
|
||||
) fifo_i (
|
||||
|
@ -89,13 +101,12 @@ module ibex_prefetch_buffer (
|
|||
.rst_ni ( rst_ni ),
|
||||
|
||||
.clear_i ( fifo_clear ),
|
||||
.busy_o ( fifo_busy ),
|
||||
|
||||
.in_valid_i ( fifo_valid ),
|
||||
.in_addr_i ( addr_i ),
|
||||
.in_rdata_i ( instr_rdata_i ),
|
||||
.in_err_i ( instr_or_pmp_err ),
|
||||
.in_ready_o ( fifo_ready ),
|
||||
|
||||
|
||||
.out_valid_o ( valid_o ),
|
||||
.out_ready_i ( ready_i ),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue