aboutsummaryrefslogtreecommitdiff
path: root/rv64cpu/tb
diff options
context:
space:
mode:
Diffstat (limited to 'rv64cpu/tb')
-rw-r--r--rv64cpu/tb/CMakeLists.txt16
-rw-r--r--rv64cpu/tb/unit/tb_alu.cc67
2 files changed, 75 insertions, 8 deletions
diff --git a/rv64cpu/tb/CMakeLists.txt b/rv64cpu/tb/CMakeLists.txt
index 8679562..73df088 100644
--- a/rv64cpu/tb/CMakeLists.txt
+++ b/rv64cpu/tb/CMakeLists.txt
@@ -30,14 +30,14 @@ file(GLOB_RECURSE ALL_RTL_SOURCES
#
# Uncomment and fill in as you implement each module, for example:
#
-# add_verilator_target(
-# NAME tb_alu
-# TOP_MODULE alu
-# SOURCES ${RTL_CORE_DIR}/include/rv64_pkg.sv
-# ${RTL_CORE_DIR}/alu.sv
-# INCLUDE_DIRS ${RTL_COMMON_INCLUDES}
-# TB_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/unit/tb_alu.cpp
-# )
+add_verilator_target(
+ NAME tb_alu
+ TOP_MODULE alu
+ SOURCES ${RTL_CORE_DIR}/include/rv64_pkg.sv
+ ${RTL_CORE_DIR}/alu.sv
+ INCLUDE_DIRS ${RTL_COMMON_INCLUDES}
+ TB_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/unit/tb_alu.cc
+)
#
# add_verilator_target(
# NAME tb_decoder
diff --git a/rv64cpu/tb/unit/tb_alu.cc b/rv64cpu/tb/unit/tb_alu.cc
new file mode 100644
index 0000000..b783815
--- /dev/null
+++ b/rv64cpu/tb/unit/tb_alu.cc
@@ -0,0 +1,67 @@
+#include "Valu.h"
+#include <cassert>
+#include <cstdint>
+#include <iostream>
+#include <verilated.h>
+
+enum AluOp {
+ ALU_ADD = 0b0000,
+ ALU_SUB = 0b1000,
+ ALU_SLL = 0b0001,
+ ALU_SLT = 0b0010,
+ ALU_SLTU = 0b0011,
+ ALU_XOR = 0b0100,
+ ALU_SRL = 0b0101,
+ ALU_SRA = 0b1101,
+ ALU_OR = 0b0110,
+ ALU_AND = 0b0111
+};
+
+void test_alu(Valu* alu, uint8_t op, uint64_t rs1, uint64_t rs2, uint64_t expected, const char* test_name) {
+ alu->alu_op = op;
+ alu->rs1_val = rs1;
+ alu->rs2_val = rs2;
+
+ alu->eval();
+
+ if (alu->alu_res == expected) {
+ std::cout << "\033[32m";
+ std::cout << "[PASS] " << test_name << " | "
+ << rs1 << " op " << rs2 << " = " << expected << std::endl;
+ std::cout << "\033[0m";
+ } else {
+ std::cout << "\033[31m";
+ std::cerr << "[FAIL] " << test_name << " | "
+ << "Expected: " << expected << ", Got: " << alu->alu_res << std::endl;
+ std::cout << "\033[0m";
+ assert(false);
+ }
+}
+
+int main(int argc, char** argv) {
+ Verilated::commandArgs(argc, argv);
+ Valu* alu = new Valu;
+
+ std::cout << "Running ALU Unit Test ..." << std::endl;
+
+ test_alu(alu, ALU_ADD, 100, 50, 150, "ADD_Positive");
+ test_alu(alu, ALU_SUB, 100, 50, 50, "SUB_Positive");
+
+ test_alu(alu, ALU_ADD, (uint64_t)-5, 10, 5, "ADD_Negative");
+
+ test_alu(alu, ALU_AND, 0xFF00, 0x0F0F, 0x0F00, "AND_Mask");
+ test_alu(alu, ALU_XOR, 0xAAAA, 0xFFFF, 0x5555, "XOR_Invert");
+
+ test_alu(alu, ALU_SLL, 1, 10, 1024, "SLL_By_10");
+
+ uint64_t minus_one = (uint64_t)-1;
+ uint64_t five = 5;
+
+ test_alu(alu, ALU_SLTU, minus_one, five, 0, "SLTU (Unsigned: -1 < 5 is False)");
+ test_alu(alu, ALU_SLT, minus_one, five, 1, "SLT (Signed: -1 < 5 is True)");
+
+ std::cout << "All tests passed!" << std::endl;
+
+ delete alu;
+ return 0;
+} \ No newline at end of file