#include "Valu.h" #include "verilated.h" #include const std::string ANSI_RESET = "\033[0m"; const std::string ANSI_GREEN = "\033[38;5;2m"; const std::string ANSI_RED = "\033[38;5;1m"; const std::string ANSI_YELLOW = "\033[38;5;11m"; class Tester { private: int succeeded, failed; std::string name; public: Tester(std::string test_name) : name(test_name), succeeded(0), failed(0) { printf("[ %s ] - %sstarting%s\n", name.c_str(), ANSI_YELLOW.c_str(), ANSI_RESET.c_str()); } template void assert_eq(std::string test_name, T got, U expected) { printf("[ %s ] - %30s - ", name.c_str(), test_name.c_str()); if (got == expected) { printf("%ssuccess%s\n", ANSI_GREEN.c_str(), ANSI_RESET.c_str()); succeeded++; } else { printf("%sfailed%s - got %08x, expected %08x\n", ANSI_RED.c_str(), ANSI_RESET.c_str(), got, expected); failed++; } } ~Tester() { finish(); } void finish() { if (failed == 0) { printf("[ %s ] - %sall succeeded%s, out of %d total\n", name.c_str(), ANSI_GREEN.c_str(), ANSI_RESET.c_str(), succeeded + failed); } else { printf("[ %s ] - %s%d failed, %d succeeded%s, out of %d total\n", name.c_str(), ANSI_RED.c_str(), failed, succeeded, ANSI_RESET.c_str(), succeeded + failed); } } }; int main(int argc, char **argv) { VerilatedContext *vctx = new VerilatedContext; Valu *valu = new Valu(vctx); { Tester add_t("add"); valu->op = 0b000; valu->A = 0x2137; valu->B = 0x1234; valu->eval(); add_t.assert_eq("0x2137 + 0x1234 == 0x336b", valu->O, 0x336b); add_t.assert_eq("0x2137 + 0x1234 no overflow", valu->Fflow, 0x0); add_t.assert_eq("0x2137 + 0x1234 no Fzero", valu->Fzero, 0x0); valu->op = 0b000; valu->A = 0x9; valu->B = 0x10; valu->eval(); add_t.assert_eq("0x9 + 0x10 == 0x19", valu->O, 0x19); add_t.assert_eq("0x9 + 0x10 no overflow", valu->Fflow, 0x0); add_t.assert_eq("0x9 + 0x10 no Fzero", valu->Fzero, 0x0); valu->op = 0b000; valu->A = 0xffffffff; valu->B = 0x1; valu->eval(); add_t.assert_eq("0xffffffff + 0x1 == 0x0", valu->O, 0x0); add_t.assert_eq("0xffffffff + 0x1 has overflow", valu->Fflow, 0x1); add_t.assert_eq("0xffffffff + 0x1 has Fzero", valu->Fzero, 0x1); } { Tester add_t("sub"); valu->op = 0b001; valu->A = 0x2137; valu->B = 0x0420; valu->eval(); add_t.assert_eq("0x2137 - 0x0420 == 0x1d17", valu->O, 0x1d17); add_t.assert_eq("0x2137 - 0x1234 no underflow", valu->Fflow, 0x0); add_t.assert_eq("0x2137 - 0x1234 no Fzero", valu->Fzero, 0x0); valu->op = 0b001; valu->A = 0x100; valu->B = 0x200; valu->eval(); add_t.assert_eq("0x100 - 0x200 == 0xffffff00", valu->O, 0xffffff00); add_t.assert_eq("0x100 - 0x200 has underflow", valu->Fflow, 0x1); add_t.assert_eq("0x100 - 0x200 no Fzero", valu->Fzero, 0x0); valu->op = 0b001; valu->A = 0x0; valu->B = 0x1; valu->eval(); add_t.assert_eq("0x0 - 0x1 == 0xffffffff", valu->O, 0xffffffff); add_t.assert_eq("0x0 - 0x1 has underflow", valu->Fflow, 0x1); add_t.assert_eq("0x0 - 0x1 no Fzero", valu->Fzero, 0x0); valu->op = 0b001; valu->A = 0x20; valu->B = 0x20; valu->eval(); add_t.assert_eq("0x20 - 0x20 == 0x0", valu->O, 0x0); add_t.assert_eq("0x20 - 0x20 no underflow", valu->Fflow, 0x0); add_t.assert_eq("0x20 - 0x20 has Fzero", valu->Fzero, 0x1); } }