From 678a4877f8cf49184b8993acc427b1d9acda54a5 Mon Sep 17 00:00:00 2001 From: ShinyMiraidon <114675487+ShinyMiraidon@users.noreply.github.com> Date: Tue, 7 Nov 2023 14:11:15 -0500 Subject: [PATCH] add(Branch_Predictor.sv, branch_predictor.cpp) (#111) --- .../01_Module_Docs/16_Branch_Predictor.md | 16 +-- dv/CMakeLists.txt | 4 +- dv/branch_predictor.cpp | 102 ++++++++++++++++++ rtl/Branch_Predictor.sv | 39 +++++++ rtl/CMakeLists.txt | 2 +- 5 files changed, 153 insertions(+), 10 deletions(-) create mode 100644 dv/branch_predictor.cpp create mode 100644 rtl/Branch_Predictor.sv diff --git a/Documentation/01_Module_Docs/16_Branch_Predictor.md b/Documentation/01_Module_Docs/16_Branch_Predictor.md index 8d4d0627..5f2ed30b 100644 --- a/Documentation/01_Module_Docs/16_Branch_Predictor.md +++ b/Documentation/01_Module_Docs/16_Branch_Predictor.md @@ -1,12 +1,15 @@ # Branch Predictor # ## Contents -* [Inputs](#inputs) -* [Outputs](#outputs) -* [Functionality](#functionality) - * [Registers](#registers) - * [Clk](#on-posedge-clk) - * [Active low reset](#asynchronous-active-low-reset) +- [Branch Predictor](#branch-predictor) + - [Contents](#contents) + - [Inputs](#inputs) + - [Outputs](#outputs) + - [Functionality](#functionality) + - [Registers](#registers) + - [Combinational](#combinational) + - [On posedge clk](#on-posedge-clk) + - [Asynchronous active low reset on rstn\_h](#asynchronous-active-low-reset-on-rstn_h) ## Inputs |Name|Bits wide| @@ -35,7 +38,6 @@ |```branch_occr[1] == 0```|```branch_taken = branch_occr[0]```| |```branch_occr[1] == 1```|```branch_taken = curr_pred```| ### On posedge clk - - Use a table when necessary if statements are used: - ```branch_cond```, ```pred_taken```, ```act_taken``` |```condition```|```curr_pred```|```incorrect_pred```| |---|---|---| diff --git a/dv/CMakeLists.txt b/dv/CMakeLists.txt index a434972b..f1ae3ce1 100644 --- a/dv/CMakeLists.txt +++ b/dv/CMakeLists.txt @@ -3,11 +3,11 @@ find_package(nyu-util REQUIRED CONFIG) add_executable(tests) target_sources(tests PRIVATE - alu.cpp branch_eval.cpp pc.cpp ifid.cpp memwb.cpp gpr.cpp exmem.cpp branch_addr_calc.cpp idex.cpp + alu.cpp branch_eval.cpp pc.cpp ifid.cpp memwb.cpp gpr.cpp exmem.cpp branch_addr_calc.cpp idex.cpp branch_predictor.cpp ) nyu_link_sv(tests PRIVATE core) nyu_target_verilate(tests - TOP_MODULES Alu Branch_Eval PC IFID MEMWB GPR EXMEM Branch_Addr_Calc IDEX + TOP_MODULES Alu Branch_Eval PC IFID MEMWB GPR EXMEM Branch_Addr_Calc IDEX Branch_Predictor ARGS COVERAGE ) target_link_libraries(tests PRIVATE Catch2::Catch2WithMain nyu::covrecorder) diff --git a/dv/branch_predictor.cpp b/dv/branch_predictor.cpp new file mode 100644 index 00000000..72a4fff3 --- /dev/null +++ b/dv/branch_predictor.cpp @@ -0,0 +1,102 @@ +#include +#include +#include +#include +#include + + +TEST_CASE("Non Prediction Instruction") { + + VBranch_Predictor model; + + uint8_t branch_occr; + bool act_taken; + bool pred_taken; + uint8_t branch_cond; + + //Initialize Module + model.rstn_h = 1; + model.clk = 0; + model.eval(); + model.rstn_h = 0; + model.eval(); + + + + //Test Module + for (int i = 0; i < 1000; i++) { + branch_occr = rand() % (int) (pow(2, 1) - 1); + act_taken = rand() % (int) (pow(2, 1) - 1); + pred_taken = rand() % (int) (pow(2, 1) - 1); + branch_cond = rand() % (int) (pow(2, 2) - 1); + + model.clk = 0; + model.eval(); + + model.clk = 1; + model.rstn_h = 1; + model.branch_occr = branch_occr; + model.act_taken = act_taken; + model.pred_taken = pred_taken; + model.branch_cond = branch_cond; + model.eval(); + REQUIRE ((bool) model.branch_taken == (bool) branch_occr); + } +} + +TEST_CASE("Prediction Instruction") { + + VBranch_Predictor model; + + uint8_t branch_occr; + bool act_taken; + bool pred_taken; + uint8_t branch_cond; + + //Initialize Module + model.rstn_h = 1; + model.clk = 0; + model.eval(); + model.rstn_h = 0; + model.eval(); + + //Initialize Register Tracker Variables + bool curr_pred = 0; + bool incorrect_pred = 0; + + //Test Module + for (int i = 0; i < 1000; i++) { + branch_occr = 2 + rand() % (int) (pow(2, 1) - 1); + act_taken = rand() % (int) (pow(2, 1) - 1); + pred_taken = rand() % (int) (pow(2, 1) - 1); + branch_cond = rand() % (int) (pow(2, 2) - 1); + + model.clk = 0; + model.eval(); + + model.clk = 1; + model.rstn_h = 1; + model.branch_occr = branch_occr; + model.act_taken = act_taken; + model.pred_taken = pred_taken; + model.branch_cond = branch_cond; + + if (__builtin_parity(branch_cond) == 0) { + break; + } + else if ((act_taken ^ pred_taken) == 0) { + incorrect_pred = 0; + } + else if (incorrect_pred == 1) { + curr_pred = ~curr_pred; + incorrect_pred = 1; + } + else { + incorrect_pred = 1; + } + + model.eval(); + + REQUIRE ((bool) model.branch_taken == (bool) curr_pred); + } +} \ No newline at end of file diff --git a/rtl/Branch_Predictor.sv b/rtl/Branch_Predictor.sv new file mode 100644 index 00000000..3dcdcf62 --- /dev/null +++ b/rtl/Branch_Predictor.sv @@ -0,0 +1,39 @@ +module Branch_Predictor ( + input clk, rstn_h, act_taken, pred_taken, + input [1:0] branch_occr, branch_cond, + output logic branch_taken +); +logic curr_pred, incorrect_pred; + +always @ (posedge clk or negedge rstn_h) begin + if (!rstn_h) begin + curr_pred <= 0; + incorrect_pred <= 0; + end + else begin + if (^branch_cond == 0) begin + curr_pred <= curr_pred; + incorrect_pred <= incorrect_pred; + end + else if (act_taken ^ pred_taken == 0) begin + curr_pred <= curr_pred; + incorrect_pred <= 0; + end + else if (incorrect_pred) begin + curr_pred <= ~curr_pred; + incorrect_pred <= 1; + end + else begin + curr_pred <= curr_pred; + incorrect_pred <= 1; + end + end +end +always_comb begin + case(branch_occr[1]) + 0: branch_taken = branch_occr[0]; + 1: branch_taken = curr_pred; + default branch_taken = 0; + endcase +end +endmodule \ No newline at end of file diff --git a/rtl/CMakeLists.txt b/rtl/CMakeLists.txt index a3ab9f82..f4e37d16 100644 --- a/rtl/CMakeLists.txt +++ b/rtl/CMakeLists.txt @@ -1,3 +1,3 @@ nyu_add_sv(core - Alu.sv Branch_Eval.sv PC.sv IFID.sv MEMWB.sv GPR.sv EXMEM.sv Branch_Addr_Calc.sv IDEX.sv + Alu.sv Branch_Eval.sv PC.sv IFID.sv MEMWB.sv GPR.sv EXMEM.sv Branch_Addr_Calc.sv IDEX.sv Branch_Predictor.sv )