Basic branching in place

This commit is contained in:
Florian Zaruba 2017-05-11 13:26:20 +02:00
parent 2b790db79b
commit 742fb2b307
7 changed files with 99 additions and 36 deletions

View file

@ -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 ),
.*
);

View file

@ -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

View file

@ -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 ),

View file

@ -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

View file

@ -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;

View file

@ -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

View file

@ -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