mirror of
https://github.com/openhwgroup/cva6.git
synced 2025-04-22 21:27:10 -04:00
Break npc and mis-predict path between pcgen/if
This commit is contained in:
parent
3b4f20ade6
commit
9fbe447e09
2 changed files with 25 additions and 19 deletions
|
@ -522,14 +522,14 @@ module lsu_bypass (
|
|||
lsu_ctrl_t [1:0] mem_n, mem_q;
|
||||
logic read_pointer_n, read_pointer_q;
|
||||
logic write_pointer_n, write_pointer_q;
|
||||
int status_cnt_n, status_cnt_q;
|
||||
logic [1:0] status_cnt_n, status_cnt_q;
|
||||
|
||||
logic empty;
|
||||
assign empty = (status_cnt_q == 0);
|
||||
assign ready_o = empty;
|
||||
|
||||
always_comb begin
|
||||
automatic int status_cnt = status_cnt_q;
|
||||
automatic logic [1:0] status_cnt = status_cnt_q;
|
||||
automatic logic write_pointer = write_pointer_q;
|
||||
automatic logic read_pointer = read_pointer_q;
|
||||
|
||||
|
|
40
src/pcgen.sv
40
src/pcgen.sv
|
@ -44,6 +44,7 @@ module pcgen (
|
|||
);
|
||||
|
||||
logic [63:0] npc_n, npc_q;
|
||||
// the PC was set to a new region by a higher priority input (e.g.: exception, debug, ctrl return from exception)
|
||||
logic set_pc_n, set_pc_q;
|
||||
branchpredict_sbe branch_predict_btb;
|
||||
// branch-predict input register -> this path is critical
|
||||
|
@ -74,21 +75,32 @@ module pcgen (
|
|||
// 5. Return from exception
|
||||
// 6. Pipeline Flush because of CSR side effects
|
||||
always_comb begin : npc_select
|
||||
// set fetch address
|
||||
fetch_address_o = npc_q;
|
||||
automatic logic [63:0] fetch_address = npc_q;
|
||||
|
||||
branch_predict_o = branch_predict_btb;
|
||||
fetch_valid_o = 1'b1;
|
||||
// this tells us whether it is a consecutive PC or a completely new PC
|
||||
set_pc_n = 1'b0;
|
||||
|
||||
// -------------------------------
|
||||
// 3. Control flow change request
|
||||
// -------------------------------
|
||||
// check if had a mis-predict the cycle earlier and if we can reset the PC (e.g.: it was a predicted or consecutive PC
|
||||
// which was set a cycle earlier)
|
||||
if (resolved_branch_q.is_mispredict && !set_pc_q) begin
|
||||
// we already got the correct target address
|
||||
fetch_address = resolved_branch_q.target_address;
|
||||
end
|
||||
|
||||
// -------------------------------
|
||||
// 0. Default assignment
|
||||
// -------------------------------
|
||||
// default is a consecutive PC
|
||||
if (if_ready_i && fetch_enable_i)
|
||||
npc_n = {npc_q[63:2], 2'b0} + 64'h4;
|
||||
// but operate on the current fetch address
|
||||
npc_n = {fetch_address[63:2], 2'b0} + 64'h4;
|
||||
else // or keep the PC stable if IF is not ready
|
||||
npc_n = npc_q;
|
||||
npc_n = npc_q;
|
||||
// we only need to stall the consecutive and predicted case since in any other case we will flush at least
|
||||
// the front-end which means that the IF stage will always be ready to accept a new request
|
||||
|
||||
|
@ -105,30 +117,20 @@ module pcgen (
|
|||
// 2. Debug
|
||||
// -------------------------------
|
||||
|
||||
// -------------------------------
|
||||
// 3. Control flow change request
|
||||
// -------------------------------
|
||||
// check if had a mis-predict the cycle earlier and if we can reset the PC (e.g.: it was a predicted or consecutive PC
|
||||
// which was set a cycle earlier)
|
||||
if (resolved_branch_q.is_mispredict && !set_pc_q) begin
|
||||
// we already got the correct target address
|
||||
fetch_address_o = resolved_branch_q.target_address;
|
||||
end
|
||||
|
||||
// -------------------------------
|
||||
// 4. Exception
|
||||
// -------------------------------
|
||||
if (ex_i.valid) begin
|
||||
npc_n = trap_vector_base_i;
|
||||
branch_predict_o.valid = 1'b0;
|
||||
set_pc_n = 1'b1;
|
||||
set_pc_n = 1'b1;
|
||||
end
|
||||
|
||||
// -------------------------------
|
||||
// 5. Return from exception
|
||||
// -------------------------------
|
||||
if (eret_i) begin
|
||||
npc_n = epc_i;
|
||||
npc_n = epc_i;
|
||||
set_pc_n = 1'b1;
|
||||
end
|
||||
|
||||
|
@ -141,7 +143,7 @@ module pcgen (
|
|||
// we came here from a flush request of a CSR instruction,
|
||||
// as CSR instructions do not exist in a compressed form
|
||||
// we can unconditionally do PC + 4 here
|
||||
npc_n = pc_commit_i + 64'h4;
|
||||
npc_n = pc_commit_i + 64'h4;
|
||||
set_pc_n = 1'b1;
|
||||
end
|
||||
|
||||
|
@ -149,6 +151,10 @@ module pcgen (
|
|||
if (!fetch_enable_i) begin
|
||||
fetch_valid_o = 1'b0;
|
||||
end
|
||||
|
||||
// set fetch address
|
||||
fetch_address_o = fetch_address;
|
||||
|
||||
end
|
||||
// -------------------
|
||||
// Sequential Process
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue