From 3213819ca678b27b5d32ae38451fbfac1d0df1f6 Mon Sep 17 00:00:00 2001 From: Vito Gamberini Date: Tue, 6 Feb 2024 22:29:00 -0500 Subject: [PATCH] test(Alu): Fix alu test, demonstrate testing style --- dv/CMakeLists.txt | 2 +- dv/alu.cpp | 148 +++++++++++++++++----------------------------- vcpkg.json | 2 +- 3 files changed, 57 insertions(+), 95 deletions(-) diff --git a/dv/CMakeLists.txt b/dv/CMakeLists.txt index 89d7fc67..f8e78da9 100644 --- a/dv/CMakeLists.txt +++ b/dv/CMakeLists.txt @@ -3,7 +3,7 @@ find_package(nyu-util REQUIRED CONFIG) add_executable(tests) target_sources(tests PRIVATE -con_ex.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 branch_manager.cpp + con_ex.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 branch_manager.cpp ) nyu_link_sv(tests PRIVATE core) nyu_target_verilate(tests diff --git a/dv/alu.cpp b/dv/alu.cpp index f827fe08..8c023618 100644 --- a/dv/alu.cpp +++ b/dv/alu.cpp @@ -1,116 +1,78 @@ +#include + #include +#include + #include -#include -#include -#include - -uint32_t test(uint32_t a, uint32_t b, uint8_t op) { - VAlu model; - model.alu_mode = op; - model.a = a; - model.b = b; - model.eval(); - return model.alu_out; + +static void eval(std::uint8_t op, std::uint32_t opA, std::uint32_t opB, + std::uint32_t (*f)(std::uint32_t, std::uint32_t)) { + auto& alu {nyu::getDUT()}; + alu.alu_mode = op; + alu.a = opA; + alu.b = opB; + nyu::eval(alu); + + std::uint32_t result {f(opA, opB)}; + INFO("Testing " << opA << " and " << opB); + REQUIRE(result == alu.alu_out); +} + +static void test(std::uint8_t op, + std::uint32_t (*f)(std::uint32_t, std::uint32_t)) { + for(std::uint32_t opA {0}; opA < 8; ++opA) + for(std::uint32_t opB {0}; opB < 8; ++opB) + eval(op, opA, opB, f); + + for(std::uint32_t opA {1}; opA; opA <<= 1) + for(std::uint32_t opB {1}; opB; opB <<= 1) + eval(op, opA, opB, f); } -TEST_CASE("ADD") { - for (int i = 0; i < 1000; i++) { - uint32_t a = rand() % (int) (pow(2, 32)); - uint32_t b = rand() % (int) (pow(2, 32)); - uint32_t result = test(a, b, 0x0); - REQUIRE(result == (uint32_t) (a + b)); - } +TEST_CASE("ALU, ADD") { + test(0x00, [](std::uint32_t opA, std::uint32_t opB) { return opA + opB; }); } -TEST_CASE("SUB") { - for (int i = 0; i < 1000; i++) { - uint32_t a = rand() % (int) (pow(2, 32)); - uint32_t b = rand() % (int) (pow(2, 32)); - uint32_t result = test(a, b, 0x20); - REQUIRE(result == (uint32_t) (a + (~b + 1))); - } +TEST_CASE("ALU, SUB") { + test(0x20, [](std::uint32_t opA, std::uint32_t opB) { return opA - opB; }); } -TEST_CASE("XOR") { - for (int i = 0; i < 1000; i++) { - uint32_t a = rand() % (int) (pow(2, 32)); - uint32_t b = rand() % (int) (pow(2, 32)); - uint32_t result = test(a, b, 0x04); - REQUIRE(result == (a ^ b)); - } +TEST_CASE("ALU, XOR") { + test(0x04, [](std::uint32_t opA, std::uint32_t opB) { return opA ^ opB; }); } -TEST_CASE("OR") { - for (int i = 0; i < 1000; i++) { - uint32_t a = rand() % (int) (pow(2, 32)); - uint32_t b = rand() % (int) (pow(2, 32)); - uint32_t result = test(a, b, 0x06); - REQUIRE(result == (a | b)); - } +TEST_CASE("ALU, OR") { + test(0x06, [](std::uint32_t opA, std::uint32_t opB) { return opA | opB; }); } -TEST_CASE("AND") { - for (int i = 0; i < 1000; i++) { - uint32_t a = rand() % (int) (pow(2, 32)); - uint32_t b = rand() % (int) (pow(2, 32)); - uint32_t result = test(a, b, 0x07); - REQUIRE(result == (a & b)); - } +TEST_CASE("ALU, AND") { + test(0x07, [](std::uint32_t opA, std::uint32_t opB) { return opA & opB; }); } -TEST_CASE("LLS") { - for (int i = 0; i < 1000; i++) { - uint32_t a = rand() % (int) (pow(2, 32)); - uint32_t b = rand() % (int) (pow(2, 32)); - uint32_t result = test(a, b, 0x01); - REQUIRE(result == (a << (b & 31))); - } +TEST_CASE("ALU, LLS") { + test(0x01, + [](std::uint32_t opA, std::uint32_t opB) { return opA << (opB & 0x1F); }); } -TEST_CASE("LRS") { - for (int i = 0; i < 1000; i++) { - uint32_t a = rand() % (int) (pow(2, 32)); - uint32_t b = rand() % (int) (pow(2, 32)); - uint32_t result = test(a, b, 0x05); - REQUIRE(result == (a >> (b & 31))); - } +TEST_CASE("ALU, LRS") { + test(0x05, + [](std::uint32_t opA, std::uint32_t opB) { return opA >> (opB & 0x1F); }); } -TEST_CASE("ARS") { - for (int i = 0; i < 1000; i++) { - uint32_t a = rand() % (int) (pow(2, 32)); - uint32_t b = rand() % (int) (pow(2, 32) ); - uint32_t result = test(a, b, 0x25); - uint32_t expected; - if (a >> 31) { - expected = (a >> (b & 31)); - for (int i = 32 - (b & 31); i < 32; i++) { - expected += 1 << i; - } - } - else { - expected = (a >> (b & 31)); - } - - REQUIRE(result == expected); - } - +TEST_CASE("ALU, ARS") { + test(0x25, [](std::uint32_t opA, std::uint32_t opB) { + return (std::uint32_t)(((std::int32_t) opA) >> (opB & 0x1F)); + }); } -TEST_CASE("SSLT") { - for (int i = 0; i < 1000; i++) { - uint32_t a = rand() % (int) (pow(2, 32)); - uint32_t b = rand() % (int) (pow(2, 32)); - uint32_t result = test(a, b, 0x02); - REQUIRE(result == (((a & (1 << 31)) & ~(b & (1 << 31)))? 1 : (~(a & (1 << 31)) & (b & (1 << 31))) ? 0 : a < b)); - } +TEST_CASE("ALU, SSLT") { + test(0x02, [](std::uint32_t opA, std::uint32_t opB) { + return (std::uint32_t)(((std::int32_t) opA) < ((std::int32_t) opB)); + }); } -TEST_CASE("USLT") { - for (int i = 0; i < 1000; i++) { - uint32_t a = rand() % (int) (pow(2, 32)); - uint32_t b = rand() % (int) (pow(2, 32) ); - uint32_t result = test(a, b, 0x03); - REQUIRE(result == (a < b)); - } +TEST_CASE("ALU, USLT") { + test(0x03, [](std::uint32_t opA, std::uint32_t opB) { + return (std::uint32_t)(opA < opB); + }); } diff --git a/vcpkg.json b/vcpkg.json index 56023ee6..20ac43d4 100644 --- a/vcpkg.json +++ b/vcpkg.json @@ -19,7 +19,7 @@ "registries": [ { "kind": "git", - "baseline": "b6a23db783c5c5c2da5b9dbdcd3f852df94b83d4", + "baseline": "7a6b61ca47ca041f1c6558c649cbc2ddbf11d57a", "repository": "https://github.com/NYU-Processor-Design/nyu-registry.git", "packages": [ "nyu-*"