Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- From 509359c00a59591e0dbfa5c2db3fc35fac15e38d Mon Sep 17 00:00:00 2001
- From: "Alex L. White" <[email protected]>
- Date: Thu, 19 May 2016 19:36:06 +0300
- Subject: [PATCH] Introducing saturation counter branch predictor
- ---
- rtl/verilog/mor1kx_branch_prediction.v | 84 ++++++++++++++++------
- .../mor1kx_branch_predictor_saturation_counter.v | 83 +++++++++++++++++++++
- rtl/verilog/mor1kx_branch_predictor_simple.v | 36 ++++++++++
- rtl/verilog/mor1kx_cpu_cappuccino.v | 14 +++-
- rtl/verilog/mor1kx_decode_execute_cappuccino.v | 10 +++
- 5 files changed, 204 insertions(+), 23 deletions(-)
- create mode 100644 rtl/verilog/mor1kx_branch_predictor_saturation_counter.v
- create mode 100644 rtl/verilog/mor1kx_branch_predictor_simple.v
- diff --git a/rtl/verilog/mor1kx_branch_prediction.v b/rtl/verilog/mor1kx_branch_prediction.v
- index a82c1f9..0143e87 100644
- --- a/rtl/verilog/mor1kx_branch_prediction.v
- +++ b/rtl/verilog/mor1kx_branch_prediction.v
- @@ -18,35 +18,77 @@
- module mor1kx_branch_prediction
- #(
- - parameter OPTION_OPERAND_WIDTH = 32
- + parameter OPTION_OPERAND_WIDTH = 32,
- + parameter FEATURE_BRANCH_PREDICTOR = "NONE"
- )
- (
- - input clk,
- - input rst,
- + input clk,
- + input rst,
- - // Signals belonging to the stage where the branch is predicted.
- - input op_bf_i,
- - input op_bnf_i,
- - input [9:0] immjbr_upper_i,
- - output predicted_flag_o,
- + // Signals belonging to the stage where the branch is predicted.
- + input op_bf_i, // from decode stage, brn is bf
- + input op_bnf_i, // from decode stage, brn is bnf
- + input [9:0] immjbr_upper_i, // from decode stage, imm
- + output predicted_flag_o, // to decode-execute stage, flag we predicate to be
- - // Signals belonging to the stage where the branch is resolved.
- - input prev_op_brcond_i,
- - input prev_predicted_flag_i,
- - input flag_i,
- + // Signals belonging to the stage where the branch is resolved.
- + input prev_op_brcond_i, // from decode-execute stage, prev brn was cond
- + input prev_predicted_flag_i, // from decode-execute, prev predicated flag
- + input flag_i, // from execute-ctrl stage, real flag we got
- - // Branch misprediction indicator
- - output branch_mispredict_o
- - );
- + input padv_decode_i, // is decode stage stalled
- + input execute_bf_i, // prev insn was bf
- + input execute_bnf_i, // prev insn was bnf
- +
- + // Branch misprediction indicator
- + output branch_mispredict_o // to decode-execute stage, was brn mispredicted or not
- + );
- // Compare the real flag with the previously predicted flag and signal a
- // misprediction in case of a mismatch.
- - assign branch_mispredict_o = prev_op_brcond_i &
- - (flag_i != prev_predicted_flag_i);
- + assign branch_mispredict_o = prev_op_brcond_i & (flag_i != prev_predicted_flag_i);
- - // Static branch prediction - backward branches are predicted as taken,
- - // forward branches as not taken.
- - assign predicted_flag_o = op_bf_i & immjbr_upper_i[9] |
- - op_bnf_i & !immjbr_upper_i[9];
- +generate
- +if (FEATURE_BRANCH_PREDICTOR=="SAT_COUNTER") begin : branch_predictor_saturation_counter
- + mor1kx_branch_predictor_saturation_counter
- + #(
- + .OPTION_OPERAND_WIDTH(OPTION_OPERAND_WIDTH)
- + )
- + mor1kx_branch_predictor_saturation_counter
- + (
- + // Outputs
- + .predicted_flag_o (predicted_flag_o),
- + // Inputs
- + .clk (clk),
- + .rst (rst),
- + .execute_op_bf_i (execute_op_bf_i),
- + .execute_op_bnf_i (execute_op_bnf_i),
- + .op_bf_i (op_bf_i),
- + .op_bnf_i (op_bnf_i),
- + .prev_op_brcond_i (prev_op_brcond_i),
- + .branch_mispredict_i (branch_mispredict_o));
- +
- +end else if (FEATURE_BRANCH_PREDICTOR=="SIMPLE") begin : branch_predictor_simple
- + mor1kx_branch_predictor_simple
- + #(
- + .OPTION_OPERAND_WIDTH(OPTION_OPERAND_WIDTH)
- + )
- + mor1kx_branch_predictor_simple
- + (
- + // Outputs
- + .predicted_flag_o (predicted_flag_o),
- + // Inputs
- + .op_bf_i (op_bf_i),
- + .op_bnf_i (op_bnf_i),
- + .immjbr_upper_i (immjbr_upper_i));
- +
- +end else if (FEATURE_BRANCH_PREDICTOR!="SIMPLE" &&
- + FEATURE_BRANCH_PREDICTOR!="SAT_COUNTER") begin
- + initial begin
- + $display("Error: FEATURE_PREDICTOR_TYPE, %s, not valid", FEATURE_PREDICTOR_TYPE);
- + $finish();
- + end
- +end
- +endgenerate
- endmodule
- diff --git a/rtl/verilog/mor1kx_branch_predictor_saturation_counter.v b/rtl/verilog/mor1kx_branch_predictor_saturation_counter.v
- new file mode 100644
- index 0000000..07c7efb
- --- /dev/null
- +++ b/rtl/verilog/mor1kx_branch_predictor_saturation_counter.v
- @@ -0,0 +1,83 @@
- +/******************************************************************************
- + This Source Code Form is subject to the terms of the
- + Open Hardware Description License, v. 1.0. If a copy
- + of the OHDL was not distributed with this file, You
- + can obtain one at http://juliusbaxter.net/ohdl/ohdl.txt
- +
- + Description: Branch prediction module
- + Generates a predicted flag output and compares that to the real flag
- + when it comes back in the following pipeline stage.
- + Signals are deliberately not named after the pipeline stage they belong to,
- + in order to keep this module generic.
- +
- + Copyright (C) 2013 Stefan Kristiansson <[email protected]>
- +
- + ******************************************************************************/
- +
- +`include "mor1kx-defines.v"
- +
- +module mor1kx_branch_predictor_saturation_counter
- + #(
- + parameter OPTION_OPERAND_WIDTH = 32
- + )
- + (
- + input clk,
- + input rst,
- +
- + // Signals belonging to the stage where the branch is predicted.
- + output predicted_flag_o, //result of predictor
- +
- + input execute_op_bf_i, // prev insn was bf
- + input execute_op_bnf_i, // prev insn was bnf
- + input op_bf_i, // cur insn is bf
- + input op_bnf_i, // cur insn is bnf
- + input padv_decode_i, // pipeline is moved
- +
- + // Signals belonging to the stage where the branch is resolved.
- + input prev_op_brcond_i, // prev op was cond brn
- + input branch_mispredict_i // prev brn was mispredicted
- + );
- +
- + localparam [1:0]
- + STATE_STRONGLY_NOT_TAKEN = 2'b00,
- + STATE_WEAKLY_NOT_TAKEN = 2'b01,
- + STATE_WEAKLY_TAKEN = 2'b10,
- + STATE_STRONGLY_TAKEN = 2'b11;
- +
- + reg [1:0] state = STATE_WEAKLY_TAKEN;
- +
- + assign predicted_flag_o = (state[1] && op_bf_i) || (!state[1] && op_bnf_i);
- + wire brn_taken = (execute_op_bf_i && flag_i) || (execute_op_bnf_i && !flag_i);
- +
- + always @(posedge clk) begin
- + if (rst) begin
- + // set default state to STATE_WEAKLY_TAKEN
- + state <= STATE_WEAKLY_TAKEN;
- + end else begin
- + // if previous insn was cond brn and pipe is not stalled
- + if (prev_op_brcond_i && padv_decode_i) begin
- + // if brn was not taken
- + if (!brn_taken) begin
- + // change fsm state:
- + // STATE_STRONGLY_TAKEN -> STATE_WEAKLY_TAKEN
- + // STATE_WEAKLY_TAKEN -> STATE_WEAKLY_NOT_TAKEN
- + // STATE_WEAKLY_NOT_TAKEN -> STATE_STRONGLY_NOT_TAKEN
- + // STATE_STRONGLY_NOT_TAKEN -> STATE_STRONGLY_NOT_TAKEN
- + state <= (state == STATE_STRONGLY_TAKEN) ? STATE_WEAKLY_TAKEN :
- + (state == STATE_WEAKLY_TAKEN) ? STATE_WEAKLY_NOT_TAKEN
- + : STATE_STRONGLY_NOT_TAKEN;
- + // if brn was taken
- + end else begin
- + // change fsm state:
- + // STATE_STRONGLY_NOT_TAKEN -> STATE_WEAKLY_NOT_TAKEN
- + // STATE_WEAKLY_NOT_TAKEN -> STATE_WEAKLY_TAKEN
- + // STATE_WEAKLY_TAKEN -> STATE_STRONGLY_TAKEN
- + // STATE_STRONGLY_TAKEN -> STATE_STRONGLY_TAKEN
- + state <= (state == STATE_STRONGLY_NOT_TAKEN) ? STATE_WEAKLY_NOT_TAKEN :
- + (state == STATE_WEAKLY_NOT_TAKEN) ? STATE_WEAKLY_TAKEN
- + : STATE_STRONGLY_TAKEN;
- + end
- + end
- + end
- + end
- +endmodule
- diff --git a/rtl/verilog/mor1kx_branch_predictor_simple.v b/rtl/verilog/mor1kx_branch_predictor_simple.v
- new file mode 100644
- index 0000000..8ad2f08
- --- /dev/null
- +++ b/rtl/verilog/mor1kx_branch_predictor_simple.v
- @@ -0,0 +1,36 @@
- +/******************************************************************************
- + This Source Code Form is subject to the terms of the
- + Open Hardware Description License, v. 1.0. If a copy
- + of the OHDL was not distributed with this file, You
- + can obtain one at http://juliusbaxter.net/ohdl/ohdl.txt
- +
- + Description: Branch prediction module
- + Generates a predicted flag output and compares that to the real flag
- + when it comes back in the following pipeline stage.
- + Signals are deliberately not named after the pipeline stage they belong to,
- + in order to keep this module generic.
- +
- + Copyright (C) 2013 Stefan Kristiansson <[email protected]>
- +
- + ******************************************************************************/
- +
- +`include "mor1kx-defines.v"
- +
- +module mor1kx_branch_predictor_simple
- + #(
- + parameter OPTION_OPERAND_WIDTH = 32
- + )
- + (
- + // Signals belonging to the stage where the branch is predicted.
- + input op_bf_i, // branch if flag
- + input op_bnf_i, // branch if not flag
- + input [9:0] immjbr_upper_i, // branch offset
- + output predicted_flag_o //result of predictor
- + );
- +
- + // Static branch prediction - backward branches are predicted as taken,
- + // forward branches as not taken.
- + assign predicted_flag_o = op_bf_i & immjbr_upper_i[9] |
- + op_bnf_i & !immjbr_upper_i[9];
- +
- +endmodule
- diff --git a/rtl/verilog/mor1kx_cpu_cappuccino.v b/rtl/verilog/mor1kx_cpu_cappuccino.v
- index f282374..6501e87 100644
- --- a/rtl/verilog/mor1kx_cpu_cappuccino.v
- +++ b/rtl/verilog/mor1kx_cpu_cappuccino.v
- @@ -96,7 +96,8 @@ module mor1kx_cpu_cappuccino
- parameter FEATURE_MULTICORE = "NONE",
- - parameter FEATURE_TRACEPORT_EXEC = "NONE"
- + parameter FEATURE_TRACEPORT_EXEC = "NONE",
- + parameter FEATURE_BRANCH_PREDICTOR = "SAT_COUNTER" // SIMPLE|SAT_COUNTER
- )
- (
- input clk,
- @@ -665,6 +666,8 @@ module mor1kx_cpu_cappuccino
- .execute_op_movhi_o (execute_op_movhi_o),
- .execute_op_msync_o (execute_op_msync_o),
- .execute_op_fpu_o (execute_op_fpu_o),
- + .execute_op_bf_o (execute_op_bf_o),
- + .execute_op_bnf_o (execute_op_bnf_o),
- .execute_jal_result_o (execute_jal_result_o[OPTION_OPERAND_WIDTH-1:0]),
- .execute_opc_insn_o (execute_opc_insn_o[`OR1K_OPCODE_WIDTH-1:0]),
- .decode_branch_o (decode_branch_o),
- @@ -745,6 +748,9 @@ module mor1kx_cpu_cappuccino
- /* mor1kx_branch_prediction AUTO_TEMPLATE (
- .op_bf_i (decode_op_bf_o),
- .op_bnf_i (decode_op_bnf_o),
- + .execute_bf_i (execute_op_bf_o),
- + .execute_bnf_i (execute_op_bnf_o),
- + .padv_decode_i (padv_decode_o),
- .immjbr_upper_i (decode_immjbr_upper_o),
- .prev_op_brcond_i (execute_op_brcond_o),
- .prev_predicted_flag_i (execute_predicted_flag_o),
- @@ -752,7 +758,8 @@ module mor1kx_cpu_cappuccino
- );*/
- mor1kx_branch_prediction
- #(
- - .OPTION_OPERAND_WIDTH(OPTION_OPERAND_WIDTH)
- + .OPTION_OPERAND_WIDTH(OPTION_OPERAND_WIDTH),
- + .FEATURE_BRANCH_PREDICTOR(FEATURE_BRANCH_PREDICTOR)
- )
- mor1kx_branch_prediction
- (/*AUTOINST*/
- @@ -764,6 +771,9 @@ module mor1kx_cpu_cappuccino
- .rst (rst),
- .op_bf_i (decode_op_bf_o), // Templated
- .op_bnf_i (decode_op_bnf_o), // Templated
- + .execute_bf_i (execute_op_bf_o), // Templated
- + .execute_bnf_i (execute_op_bnf_o), // Templated
- + .padv_decode_i (padv_decode_o), // Templated
- .immjbr_upper_i (decode_immjbr_upper_o), // Templated
- .prev_op_brcond_i (execute_op_brcond_o), // Templated
- .prev_predicted_flag_i (execute_predicted_flag_o), // Templated
- diff --git a/rtl/verilog/mor1kx_decode_execute_cappuccino.v b/rtl/verilog/mor1kx_decode_execute_cappuccino.v
- index beadc5d..8d48b12 100644
- --- a/rtl/verilog/mor1kx_decode_execute_cappuccino.v
- +++ b/rtl/verilog/mor1kx_decode_execute_cappuccino.v
- @@ -168,6 +168,8 @@ module mor1kx_decode_execute_cappuccino
- output reg execute_op_shift_o,
- output reg execute_op_ffl1_o,
- output reg execute_op_movhi_o,
- + output reg execute_op_bf_o,
- + output reg execute_op_bnf_o,
- output reg execute_op_msync_o,
- output [`OR1K_FPUOP_WIDTH-1:0] execute_op_fpu_o,
- @@ -218,6 +220,8 @@ module mor1kx_decode_execute_cappuccino
- // Op control signals to execute stage
- always @(posedge clk `OR_ASYNC_RST)
- if (rst) begin
- + execute_op_bf_o <= 1'b0;
- + execute_op_bnf_o <= 1'b0;
- execute_op_alu_o <= 1'b0;
- execute_op_add_o <= 1'b0;
- execute_op_mul_o <= 1'b0;
- @@ -242,6 +246,8 @@ module mor1kx_decode_execute_cappuccino
- execute_op_brcond_o <= 1'b0;
- execute_op_branch_o <= 0;
- end else if (pipeline_flush_i) begin
- + execute_op_bf_o <= 1'b0;
- + execute_op_bnf_o <= 1'b0;
- execute_op_alu_o <= 1'b0;
- execute_op_add_o <= 1'b0;
- execute_op_mul_o <= 1'b0;
- @@ -264,6 +270,8 @@ module mor1kx_decode_execute_cappuccino
- execute_op_brcond_o <= 1'b0;
- execute_op_branch_o <= 1'b0;
- end else if (padv_i) begin
- + execute_op_bf_o <= decode_op_bf_i;
- + execute_op_bnf_o <= decode_op_bnf_i;
- execute_op_alu_o <= decode_op_alu_i;
- execute_op_add_o <= decode_op_add_i;
- execute_op_mul_o <= decode_op_mul_i;
- @@ -288,6 +296,8 @@ module mor1kx_decode_execute_cappuccino
- execute_op_brcond_o <= decode_op_brcond_i;
- execute_op_branch_o <= decode_op_branch_i;
- if (decode_bubble_o) begin
- + execute_op_bf_o <= 1'b0;
- + execute_op_bnf_o <= 1'b0;
- execute_op_alu_o <= 1'b0;
- execute_op_add_o <= 1'b0;
- execute_op_mul_o <= 1'b0;
- --
- 1.9.1
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement