Skip to content

Commit

Permalink
test(Alu): Fix alu test, demonstrate testing style
Browse files Browse the repository at this point in the history
  • Loading branch information
nickelpro committed Feb 7, 2024
1 parent 44066ae commit 3213819
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 95 deletions.
2 changes: 1 addition & 1 deletion dv/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
148 changes: 55 additions & 93 deletions dv/alu.cpp
Original file line number Diff line number Diff line change
@@ -1,116 +1,78 @@
#include <cstdint>

#include <catch2/catch_test_macros.hpp>
#include <NyuTestUtil.hpp>

#include <VAlu.h>
#include <cstdint>
#include <stdlib.h>
#include <math.h>

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<VAlu>()};
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);
});
}
2 changes: 1 addition & 1 deletion vcpkg.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
"registries": [
{
"kind": "git",
"baseline": "b6a23db783c5c5c2da5b9dbdcd3f852df94b83d4",
"baseline": "7a6b61ca47ca041f1c6558c649cbc2ddbf11d57a",
"repository": "https://github.com/NYU-Processor-Design/nyu-registry.git",
"packages": [
"nyu-*"
Expand Down

0 comments on commit 3213819

Please sign in to comment.