-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add(Branch_Manager.sv, branch_manager.cpp): Added Branch Manager Modu…
…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
1 parent
4cf5421
commit 2bf2efa
Showing
2 changed files
with
185 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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)); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |