Skip to content

Commit

Permalink
add(Branch_Manager.sv, branch_manager.cpp): Added Branch Manager Modu…
Browse files Browse the repository at this point in the history
…le and Tests (#116)

* add(branch_manager.cpp, Branch_Manager.sv)

* test(branch_manager): Added more to test

* module(Branch Manager): Finished Tests
  • Loading branch information
ShinyMiraidon authored Nov 14, 2023
1 parent 4cf5421 commit 2bf2efa
Show file tree
Hide file tree
Showing 2 changed files with 185 additions and 0 deletions.
151 changes: 151 additions & 0 deletions dv/branch_manager.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
#include <catch2/catch_test_macros.hpp>
#include <VBranch_Manager.h>
#include <cstdint>
#include <stdlib.h>
#include <math.h>

TEST_CASE("Flush") {

VBranch_Manager model;

//Initialize Module
model.rstn = 1;
model.clk = 0;
model.eval();
model.rstn_h = 0;
model.eval();

//Move out of starting conditions
model.clk = 0;
model.eval();
model.clk = 1;
model.rstn = 1;
model.eval();

bool pred_taken;
bool act_taken;
uint32_t pred_pc;
uint32_t pred_addr;

//Test Module
for (int i = 0; i < 1000; i++) {
pred_taken = rand() % (int) (pow(2, 1) - 1);
act_taken = rand() % (int) (pow(2, 1) - 1);
pred_pc = rand() % (int) (pow(32, 1) - 1);
pred_addr = rand() % (int) (pow(32, 1) - 1);

model.clk = 0;
model.eval();

model.clk = 1;
model.rstn = 1;

model.pred_taken = pred_taken;
model.act_taken = act_taken;
model.pred_pc = pred_pc;
model.pred_addr = pred_addr;
model.eval();

REQUIRE((bool) model.flush == (bool) (pred_taken ^ act_taken));
}
}

TEST_CASE("Incorrect Prediction") {

VBranch_Manager model;

//Initialize Module
model.rstn = 1;
model.clk = 0;
model.eval();
model.rstn_h = 0;
model.eval();

//Move out of starting conditions
model.clk = 0;
model.eval();
model.clk = 1;
model.rstn = 1;
model.eval();

bool pred_taken;
bool act_taken;
uint32_t npc;
uint32_t pred_pc;
uint32_t pred_addr;

//Test Module
for (int i = 0; i < 1000; i++) {
pred_taken = rand() % (int) (pow(2, 1) - 1);
act_taken = ~pred_taken;
pred_pc = rand() % (int) (pow(32, 1) - 1);
pred_addr = rand() % (int) (pow(32, 1) - 1);

model.clk = 0;
model.eval();

model.clk = 1;
model.rstn = 1;

model.pred_taken = pred_taken;
model.act_taken = act_taken;
model.pred_pc = pred_pc;
model.pred_addr = pred_addr;
model.eval();

if (act_taken) npc = pred_pc;
else npc = pred_pc + 4;

REQUIRE((uint32_t) model.npc == (uint32_t) (npc));
}
}

TEST_CASE("Correct Prediction") {

VBranch_Manager model;

//Initialize Module
model.rstn = 1;
model.clk = 0;
model.eval();
model.rstn_h = 0;
model.eval();

//Move out of starting conditions
model.clk = 0;
model.eval();
model.clk = 1;
model.rstn = 1;
model.eval();

bool pred_taken;
bool act_taken;
uint32_t npc;
uint32_t pred_pc;
uint32_t pred_addr;

//Test Module
for (int i = 0; i < 1000; i++) {
pred_taken = rand() % (int) (pow(2, 1) - 1);
act_taken = pred_taken;
pred_pc = rand() % (int) (pow(32, 1) - 1);
pred_addr = rand() % (int) (pow(32, 1) - 1);

model.clk = 0;
model.eval();

model.clk = 1;
model.rstn = 1;

model.pred_taken = pred_taken;
model.act_taken = act_taken;
model.pred_pc = pred_pc;
model.pred_addr = pred_addr;
model.eval();

if (pred_taken) npc = pred_pc;
else npc = pred_pc + 4;

REQUIRE((uint32_t) model.npc == (uint32_t) (npc));
}
}
34 changes: 34 additions & 0 deletions rtl/Branch_Manager.sv
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
module Branch_Manager (
input clk, rstn, pred_taken, act_taken
input [WordSize - 1:0] pred_pc, pred_addr
output logic flush
output logic [WordSize - 1:0] npc
);

logic restart;

always @ (posedge clk or negedge rstn_h) begin
if (!rstn) begin
restart <= 1;
flush <= 0;
npc <= 0;
end
else begin
if ((pred_taken != act_taken) && !restart) begin
flush <= 1;
case(act_taken)
0: npc <= pred_pc + 4
1: npc <= pred_addr
endcase
end
else begin
flush <= 0;
case(pred_taken)
0: npc <= pred_pc + 4
1: npc <= pred_addr
endcase
end
if (restart) restart <= 0;
end
end
endmodule

0 comments on commit 2bf2efa

Please sign in to comment.