diff --git a/dv/CMakeLists.txt b/dv/CMakeLists.txt index f1ae3ce1..db245153 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 branch_predictor.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 pipeline_reset.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 Branch_Predictor + TOP_MODULES Alu Branch_Eval PC IFID MEMWB GPR EXMEM Branch_Addr_Calc IDEX Branch_Predictor Pipeline_Reset ARGS COVERAGE ) target_link_libraries(tests PRIVATE Catch2::Catch2WithMain nyu::covrecorder) diff --git a/dv/branch_manager.cpp b/dv/branch_manager.cpp index 170f4bc9..8b228f47 100644 --- a/dv/branch_manager.cpp +++ b/dv/branch_manager.cpp @@ -31,8 +31,8 @@ TEST_CASE("Flush") { 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); + pred_pc = rand() % (int) (pow(2, 32) - 1); + pred_addr = rand() % (int) (pow(2, 32) - 1); model.clk = 0; model.eval(); @@ -78,8 +78,8 @@ TEST_CASE("Incorrect Prediction") { 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); + pred_pc = rand() % (int) (pow(2, 32) - 1); + pred_addr = rand() % (int) (pow(2, 32) - 1); model.clk = 0; model.eval(); @@ -128,8 +128,8 @@ TEST_CASE("Correct Prediction") { 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); + pred_pc = rand() % (int) (pow(2, 32) - 1); + pred_addr = rand() % (int) (pow(2, 32) - 1); model.clk = 0; model.eval(); diff --git a/dv/pipeline_reset.cpp b/dv/pipeline_reset.cpp new file mode 100644 index 00000000..82026b03 --- /dev/null +++ b/dv/pipeline_reset.cpp @@ -0,0 +1,55 @@ +#include +#include +#include +#include +#include + +/* +Note: +The tests do not currently distinguish between High Z and 0 due to limitations of Verilator. +The module could be modified to provide a test output that is 0 when rstn is 0 and 1 when rstn is High Z, +but given the simplicity of this module that doesn't seem warrented at this point. + */ + + +TEST_CASE("flush == 0") { + VPipeline_Reset model; + + uint32_t npc_in; + uint32_t npc_corr; + + for (int i = 0; i < 1000; i++) { + npc_in = rand() % (int) (pow(2, 32) - 1); + npc_corr = rand() % (int) (pow(2, 32) - 1); + + model.flush = 0; + model.npc_in = npc_in; + model.npc_corr = npc_corr; + model.eval(); + + REQUIRE((uint32_t) model.npc == (uint32_t) npc_in); + REQUIRE(model.rstn == 0); //Verilator translates High Z outputs to 0 + + } +} + +TEST_CASE("flush == 1") { + VPipeline_Reset model; + + uint32_t npc_in; + uint32_t npc_corr; + + for (int i = 0; i < 1000; i++) { + npc_in = rand() % (int) (pow(2, 32) - 1); + npc_corr = rand() % (int) (pow(2, 32) - 1); + + model.flush = 1; + model.npc_in = npc_in; + model.npc_corr = npc_corr; + model.eval(); + + REQUIRE((uint32_t) model.npc == (uint32_t) npc_corr); + REQUIRE(model.rstn == 0); //Expect actual 0 output here, not High Z + + } +} diff --git a/rtl/CMakeLists.txt b/rtl/CMakeLists.txt index f4e37d16..023c0de6 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 Branch_Predictor.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 Pipeline_Reset.sv ) diff --git a/rtl/Pipeline_Reset.sv b/rtl/Pipeline_Reset.sv new file mode 100644 index 00000000..590d5cb9 --- /dev/null +++ b/rtl/Pipeline_Reset.sv @@ -0,0 +1,22 @@ +module Pipeline_Reset #( + WordSize = 32 +)( + input [WordSize - 1:0] npc_in, npc_corr, + input flush, + output logic [WordSize - 1:0] npc, + output logic rstn +); + +always_comb begin +case(flush) +0: begin + npc = npc_in; + rstn = 1'bZ; +end +1: begin + npc = npc_corr; + rstn = 0; +end +endcase +end +endmodule \ No newline at end of file