mirror of
https://github.com/openhwgroup/cva6.git
synced 2025-04-22 21:27:10 -04:00
Basic branching in place
This commit is contained in:
parent
2b790db79b
commit
742fb2b307
7 changed files with 99 additions and 36 deletions
|
@ -206,6 +206,10 @@ module ariane
|
|||
|
||||
// * -> CTRL
|
||||
logic flush_csr_ctrl;
|
||||
logic flush_unissued_instr_ctrl_id;
|
||||
logic flush_scoreboard_ctrl_id;
|
||||
logic flush_ctrl_if;
|
||||
|
||||
// TODO: Preliminary signal assignments
|
||||
logic flush_tlb;
|
||||
assign flush_tlb = 1'b0;
|
||||
|
@ -232,7 +236,7 @@ module ariane
|
|||
// IF
|
||||
// ---------
|
||||
if_stage if_stage_i (
|
||||
.flush_i ( flush ),
|
||||
.flush_i ( flush_ctrl_if ),
|
||||
.req_i ( fetch_enable ),
|
||||
.if_busy_o ( ), // ?
|
||||
.id_ready_i ( ready_id_if ),
|
||||
|
@ -269,6 +273,8 @@ module ariane
|
|||
id_stage_i (
|
||||
.test_en_i ( test_en_i ),
|
||||
.flush_i ( flush ),
|
||||
.flush_unissued_instr_i ( flush_unissued_instr_ctrl_id ),
|
||||
.flush_scoreboard_i ( flush_scoreboard_ctrl_id ),
|
||||
.instruction_i ( instr_rdata_if_id ),
|
||||
.instruction_valid_i ( instr_valid_if_id ),
|
||||
.is_compressed_i ( is_compressed_if_id ),
|
||||
|
@ -434,11 +440,18 @@ module ariane
|
|||
logic branchpredict_i;
|
||||
|
||||
controller controller_i (
|
||||
.clk_i ( clk_i ),
|
||||
.rst_ni ( rst_ni ),
|
||||
.flush_commit_i ( flush_commit_i ),
|
||||
.flush_csr_i ( flush_csr_ctrl ),
|
||||
.branchpredict_i ( branchpredict )
|
||||
.flush_bp_o ( ),
|
||||
.flush_scoreboard_o ( flush_scoreboard_ctrl_id ),
|
||||
.flush_unissued_instr_o ( flush_unissued_instr_ctrl_id ),
|
||||
.flush_if_o ( flush_ctrl_if ),
|
||||
.flush_id_o ( ),
|
||||
.flush_ex_o ( ),
|
||||
|
||||
.flush_ready_lsu_i ( ),
|
||||
.flush_commit_i ( flush_commit_i ),
|
||||
.flush_csr_i ( flush_csr_ctrl ),
|
||||
.branchpredict_i ( branchpredict ),
|
||||
.*
|
||||
);
|
||||
|
||||
|
||||
|
|
|
@ -23,12 +23,30 @@ module controller (
|
|||
input logic clk_i, // Clock
|
||||
input logic rst_ni, // Asynchronous reset active low
|
||||
|
||||
input logic flush_commit_i, // flush request from commit stage in
|
||||
output logic flush_bp_o, // flush branch prediction data structures
|
||||
output logic flush_unissued_instr_o,
|
||||
output logic flush_scoreboard_o,
|
||||
output logic flush_if_o,
|
||||
output logic flush_id_o,
|
||||
output logic flush_ex_o,
|
||||
|
||||
input logic flush_ready_lsu_i, // we need to wait for this signal from LSU
|
||||
input logic flush_commit_i, // flush request from commit stage in
|
||||
input logic flush_csr_i,
|
||||
input branchpredict branchpredict_i
|
||||
);
|
||||
assign flush_bp_o = 1'b0;
|
||||
|
||||
// flush on mispredict
|
||||
always_comb begin : flush_ctrl
|
||||
flush_unissued_instr_o = 1'b0;
|
||||
flush_scoreboard_o = 1'b0;
|
||||
flush_if_o = 1'b0;
|
||||
// flush on mispredict
|
||||
if (branchpredict_i.is_mispredict) begin
|
||||
flush_unissued_instr_o = 1'b1;
|
||||
flush_if_o = 1'b1;
|
||||
end
|
||||
|
||||
// flush on exception
|
||||
end
|
||||
// flush on exception
|
||||
endmodule
|
||||
|
|
|
@ -28,6 +28,8 @@ module id_stage #(
|
|||
input logic test_en_i, // Test Enable
|
||||
|
||||
input logic flush_i,
|
||||
input logic flush_unissued_instr_i,
|
||||
input logic flush_scoreboard_i,
|
||||
// from IF
|
||||
input logic [31:0] instruction_i,
|
||||
input logic instruction_valid_i,
|
||||
|
@ -167,7 +169,7 @@ module id_stage #(
|
|||
scoreboard_i
|
||||
(
|
||||
.full_o ( full ),
|
||||
.flush_i ( flush_i ),
|
||||
.flush_i ( flush_scoreboard_i ),
|
||||
.rd_clobber_o ( rd_clobber_sb_iro ),
|
||||
.rs1_i ( rs1_iro_sb ),
|
||||
.rs1_o ( rs1_sb_iro ),
|
||||
|
|
|
@ -97,8 +97,8 @@ module if_stage (
|
|||
// Pre-fetch buffer, caches a fixed number of instructions
|
||||
prefetch_buffer prefetch_buffer_i (
|
||||
.clk ( clk_i ),
|
||||
.rst_n ( rst_ni ),
|
||||
|
||||
.rst_n ( rst_ni ),
|
||||
.flush_i ( flush_i ),
|
||||
.req_i ( req_i ),
|
||||
|
||||
.branch_i ( branch_req ), // kill everything
|
||||
|
@ -209,24 +209,38 @@ module if_stage (
|
|||
end
|
||||
else
|
||||
begin
|
||||
offset_fsm_cs <= offset_fsm_ns;
|
||||
branch_valid_q <= branch_valid_n;
|
||||
predict_address_q <= predict_address_n;
|
||||
predict_taken_q <= predict_taken_n;
|
||||
if (flush_i) begin
|
||||
// offset FSM state
|
||||
offset_fsm_cs <= IDLE;
|
||||
instr_valid_id_o <= 1'b0;
|
||||
instr_rdata_id_o <= '0;
|
||||
illegal_c_insn_id_o <= 1'b0;
|
||||
is_compressed_id_o <= 1'b0;
|
||||
pc_id_o <= '0;
|
||||
ex_o <= '{default: 0};
|
||||
branch_valid_q <= 1'b0;
|
||||
predict_address_q <= 64'b0;
|
||||
predict_taken_q <= 1'b0;
|
||||
end else begin
|
||||
|
||||
if (if_valid) begin
|
||||
instr_valid_id_o <= 1'b1;
|
||||
instr_rdata_id_o <= instr_decompressed;
|
||||
illegal_c_insn_id_o <= illegal_c_insn;
|
||||
is_compressed_id_o <= instr_compressed_int;
|
||||
pc_id_o <= pc_if_o;
|
||||
ex_o.cause <= 64'b0; // TODO: Output exception
|
||||
ex_o.tval <= 64'b0; // TODO: Output exception
|
||||
ex_o.valid <= 1'b0; // TODO: Output exception
|
||||
end else if (clear_instr_valid_i) begin
|
||||
instr_valid_id_o <= 1'b0;
|
||||
offset_fsm_cs <= offset_fsm_ns;
|
||||
branch_valid_q <= branch_valid_n;
|
||||
predict_address_q <= predict_address_n;
|
||||
predict_taken_q <= predict_taken_n;
|
||||
|
||||
if (if_valid) begin
|
||||
instr_valid_id_o <= 1'b1;
|
||||
instr_rdata_id_o <= instr_decompressed;
|
||||
illegal_c_insn_id_o <= illegal_c_insn;
|
||||
is_compressed_id_o <= instr_compressed_int;
|
||||
pc_id_o <= pc_if_o;
|
||||
ex_o.cause <= 64'b0; // TODO: Output exception
|
||||
ex_o.tval <= 64'b0; // TODO: Output exception
|
||||
ex_o.valid <= 1'b0; // TODO: Output exception
|
||||
end else if (clear_instr_valid_i) begin
|
||||
instr_valid_id_o <= 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -84,6 +84,12 @@ module pcgen (
|
|||
end
|
||||
// 1.Debug
|
||||
|
||||
// 3. Control flow change request
|
||||
if (branchpredict_i.is_mispredict) begin
|
||||
set_pc_n = 1'b1;
|
||||
// we already got the correct target address
|
||||
npc_n = branchpredict_i.target_address;
|
||||
end
|
||||
// 2. Exception
|
||||
if (ex_i.valid) begin
|
||||
npc_n = trap_vector_base_i;
|
||||
|
|
|
@ -26,6 +26,7 @@ module prefetch_buffer
|
|||
(
|
||||
input logic clk,
|
||||
input logic rst_n,
|
||||
input logic flush_i,
|
||||
|
||||
input logic req_i,
|
||||
|
||||
|
@ -97,11 +98,8 @@ module prefetch_buffer
|
|||
//---------------
|
||||
|
||||
assign fetch_addr = {instr_addr_q[63:2], 2'b00} + 64'd4;
|
||||
assign fifo_clear = branch_i || flush_i;
|
||||
|
||||
always_comb
|
||||
begin
|
||||
fifo_clear = branch_i;
|
||||
end
|
||||
|
||||
//-------------------------
|
||||
// Instruction fetch FSM
|
||||
|
|
|
@ -29,7 +29,8 @@ module scoreboard #(
|
|||
input logic clk_i, // Clock
|
||||
input logic rst_ni, // Asynchronous reset active low
|
||||
output logic full_o, // We can't take anymore data
|
||||
input logic flush_i,
|
||||
input logic flush_i, // flush whole scoreboard
|
||||
input logic flush_unissued_instr_i,
|
||||
// list of clobbered registers to issue stage
|
||||
output fu_t [31:0] rd_clobber_o,
|
||||
|
||||
|
@ -199,8 +200,12 @@ always_comb begin : push_instruction_and_wb
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
// flush signal
|
||||
// flush all instructions which are not issued, e.g. set the top pointer back to the issue pointer
|
||||
// -> everything we decoded so far was garbage
|
||||
if (flush_unissued_instr_i) begin
|
||||
top_pointer_n = issue_pointer_q;
|
||||
end
|
||||
// flush signal, e.g.: flush everything we need to backtrack after an exception
|
||||
if (flush_i)
|
||||
mem_n = '{default: 0};
|
||||
|
||||
|
@ -246,6 +251,10 @@ always_comb begin : issue_instruction
|
|||
issue_pointer_n = issue_pointer_q + 1;
|
||||
end
|
||||
|
||||
// if we are flushing we should not issue the current instruction
|
||||
if (flush_unissued_instr_i)
|
||||
issue_instr_valid_o = 1'b0;
|
||||
|
||||
end
|
||||
|
||||
// commit instruction: remove from scoreboard, advance pointer
|
||||
|
@ -279,7 +288,10 @@ always_ff @(posedge clk_i or negedge rst_ni) begin : sequential
|
|||
top_pointer_q <= top_pointer_n;
|
||||
mem_q <= mem_n;
|
||||
if (decoded_instr_valid_i && ~full_o) // only advance if we decoded instruction and we are not full
|
||||
top_pointer_qq <= top_pointer_q;
|
||||
if (flush_unissued_instr_i)
|
||||
top_pointer_qq <= top_pointer_n;
|
||||
else
|
||||
top_pointer_qq <= top_pointer_q;
|
||||
end
|
||||
end
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue