summaryrefslogtreecommitdiff
path: root/verilog/tbalu.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'verilog/tbalu.cpp')
-rw-r--r--verilog/tbalu.cpp342
1 files changed, 342 insertions, 0 deletions
diff --git a/verilog/tbalu.cpp b/verilog/tbalu.cpp
new file mode 100644
index 0000000..4351766
--- /dev/null
+++ b/verilog/tbalu.cpp
@@ -0,0 +1,342 @@
+// For std::unique_ptr
+#include <memory>
+
+#include<iostream>
+#include<bitset>
+
+// Include common routines
+#include <verilated.h>
+
+// Include model header, generated from Verilating "top.v"
+#include "Valu.h"
+
+#include "tbalu.h"
+
+
+int shift_right_a(const std::unique_ptr<Valu> & dut, const std::unique_ptr<VerilatedContext> & contextp);
+int shift_right_l(const std::unique_ptr<Valu> & dut, const std::unique_ptr<VerilatedContext> & contextp);
+int shift_left(const std::unique_ptr<Valu> & dut, const std::unique_ptr<VerilatedContext> & contextp);
+int add(const std::unique_ptr<Valu> & dut, const std::unique_ptr<VerilatedContext> & contextp);
+int sub(const std::unique_ptr<Valu> & dut, const std::unique_ptr<VerilatedContext> & contextp);
+int slt(const std::unique_ptr<Valu> & dut, const std::unique_ptr<VerilatedContext> & contextp);
+int sltu(const std::unique_ptr<Valu> & dut, const std::unique_ptr<VerilatedContext> & contextp);
+
+int shift_right_a(const std::unique_ptr<Valu> & dut, const std::unique_ptr<VerilatedContext> & contextp) {
+ // Set Vtop's input signals
+ dut->A = 0x80080080;
+ dut->B = 0x00000000;
+ dut->OP = SRA;
+
+ // Simulate until $finish
+ // while (!contextp->gotFinish()) {
+ int mistake = 0;
+ for (int i = 0; i < 32; i++) {
+ dut->B = i;
+ contextp->timeInc(1);
+ int A = (int) dut->A;
+ int B = (int) dut->B;
+ int D = (int) A >> B;
+
+ dut->eval();
+ if (D != dut->C) {
+ std::cout << "TEST FAILED SRA\n";
+ std::bitset<32> x(dut->A);
+ std::bitset<32> y(dut->B);
+ std::bitset<32> z(dut->C);
+ std::bitset<32> a(D);
+ std::cout << "Current: " << x << " >>> " << y << " = " << z << '\n';
+ std::cout << "Expected: " << x << " >>> " << y << " = " << a << '\n';
+ mistake = 1;
+ }
+ }
+
+ if(!mistake) {
+ std::cout << "PASSED SRA\n";
+ }
+ return mistake;
+}
+
+int shift_right_l(const std::unique_ptr<Valu> & dut, const std::unique_ptr<VerilatedContext> & contextp) {
+ // Set Vtop's input signals
+ dut->A = 0x80000000;
+ dut->B = 0x00000000;
+ dut->OP = SRL;
+
+ // Simulate until $finish
+ // while (!contextp->gotFinish()) {
+ int mistake = 0;
+ for (int i = 0; i < 32; i++) {
+ dut->B = i;
+ contextp->timeInc(1);
+ unsigned int A = (unsigned int) dut->A;
+ unsigned int B = (unsigned int) dut->B;
+ unsigned int D = (unsigned int) A >> B;
+
+ dut->eval();
+ if (D != dut->C) {
+ std::cout << "TEST FAILED SRL\n";
+ std::bitset<32> x(dut->A);
+ std::bitset<32> y(dut->B);
+ std::bitset<32> z(dut->C);
+ std::bitset<32> a(D);
+ std::cout << "Current: " << x << " >>> " << y << " = " << z << '\n';
+ std::cout << "Expected: " << x << " >>> " << y << " = " << a << '\n';
+ mistake = 1;
+ }
+ }
+
+ if(!mistake) {
+ std::cout << "PASSED SRL\n";
+ }
+ return mistake;
+}
+
+int shift_left(const std::unique_ptr<Valu> & dut, const std::unique_ptr<VerilatedContext> & contextp) {
+ // Set Vtop's input signals
+ dut->A = 0x00000001;
+ dut->B = 0x00000000;
+ dut->OP = SLL;
+
+ // Simulate until $finish
+ // while (!contextp->gotFinish()) {
+ int mistake = 0;
+ for (int i = 0; i < 32; i++) {
+ dut->B = i;
+ contextp->timeInc(1);
+ int A = (int) dut->A;
+ int B = (int) dut->B;
+ int D = (int) A << B;
+
+ dut->eval();
+ if (D != dut->C) {
+ std::cout << "TEST FAILED SL\n";
+ std::bitset<32> x(dut->A);
+ std::bitset<32> y(dut->B);
+ std::bitset<32> z(dut->C);
+ std::bitset<32> a(D);
+ std::cout << "Current: " << x << " <<< " << y << " = " << z << '\n';
+ std::cout << "Expected: " << x << " <<< " << y << " = " << a << '\n';
+ mistake = 1;
+ }
+ }
+
+ if(!mistake) {
+ std::cout << "PASSED SL\n";
+ }
+ return mistake;
+}
+
+
+int add(const std::unique_ptr<Valu> & dut, const std::unique_ptr<VerilatedContext> & contextp) {
+ // Set Vtop's input signals
+ dut->A = 0x00000000;
+ dut->B = 0x00000000;
+ dut->OP = ADD;
+
+ int mistake = 0;
+ for (int i = -(32 * 32); i < 32 * 32; i++) {
+ dut->A = i % 32;
+ dut->B = i / 32;
+ contextp->timeInc(1);
+ int A = (int) dut->A;
+ int B = (int) dut->B;
+ int D = (int) A + B;
+
+ dut->eval();
+ if (D != dut->C) {
+ std::cout << "TEST FAILED ADD\n";
+ std::bitset<32> x(dut->A);
+ std::bitset<32> y(dut->B);
+ std::bitset<32> z(dut->C);
+ std::bitset<32> a(D);
+ std::cout << "Current: " << x << " + " << y << " = " << z << '\n';
+ std::cout << "Expected: " << x << " + " << y << " = " << a << '\n';
+ mistake = 1;
+ }
+ }
+
+ if(!mistake) {
+ std::cout << "PASSED ADD\n";
+ }
+ return mistake;
+}
+
+int sub(const std::unique_ptr<Valu> & dut, const std::unique_ptr<VerilatedContext> & contextp) {
+ // Set Vtop's input signals
+ dut->A = 0x00000000;
+ dut->B = 0x00000000;
+ dut->OP = SUB;
+
+ int mistake = 0;
+ for (int i = -(32 * 32); i < 32 * 32; i++) {
+ dut->A = i % 32;
+ dut->B = i / 32;
+ contextp->timeInc(1);
+ int A = (int) dut->A;
+ int B = (int) dut->B;
+ int D = (int) A - B;
+
+ dut->eval();
+ if (D != dut->C) {
+ std::cout << "TEST FAILED SUB\n";
+ std::bitset<32> x(dut->A);
+ std::bitset<32> y(dut->B);
+ std::bitset<32> z(dut->C);
+ std::bitset<32> a(D);
+ std::cout << "Current: " << x << " + " << y << " = " << z << '\n';
+ std::cout << "Expected: " << x << " + " << y << " = " << a << '\n';
+ mistake = 1;
+ }
+ }
+
+ if(!mistake) {
+ std::cout << "PASSED SUB\n";
+ }
+ return mistake;
+}
+
+int slt(const std::unique_ptr<Valu> & dut, const std::unique_ptr<VerilatedContext> & contextp) {
+ // Set Vtop's input signals
+ dut->A = 0x00000000;
+ dut->B = 0x00000000;
+ dut->OP = SLT;
+
+ int mistake = 0;
+ for (int i = -(32 * 32); i < 32 * 32; i++) {
+ dut->A = i % 32;
+ dut->B = i / 32;
+ contextp->timeInc(1);
+ int A = (int) dut->A;
+ int B = (int) dut->B;
+ int D = (int) (A < B ? 1 : 0);
+
+ dut->eval();
+ if (D != dut->C) {
+ std::cout << "TEST FAILED SLT\n";
+ std::bitset<32> x(dut->A);
+ std::bitset<32> y(dut->B);
+ std::bitset<32> z(dut->C);
+ std::bitset<32> a(D);
+ std::cout << "Current: " << x << " ? " << y << " = " << z << '\n';
+ std::cout << "Expected: " << x << " ? " << y << " = " << a << '\n';
+ mistake = 1;
+ }
+ }
+
+ if(!mistake) {
+ std::cout << "PASSED SLT\n";
+ }
+ return mistake;
+}
+
+int sltu(const std::unique_ptr<Valu> & dut, const std::unique_ptr<VerilatedContext> & contextp) {
+ // Set Vtop's input signals
+ dut->A = 0x00000000;
+ dut->B = 0x00000000;
+ dut->OP = SLTU;
+
+ int mistake = 0;
+ for (int i = -(32 * 32); i < 32 * 32; i++) {
+ dut->A = i % 32;
+ dut->B = i / 32;
+ contextp->timeInc(1);
+ unsigned int A = (unsigned int) dut->A;
+ unsigned int B = (unsigned int) dut->B;
+ unsigned int D = (unsigned int) (A < B ? 1 : 0);
+
+ dut->eval();
+ if (D != dut->C) {
+ std::cout << "TEST FAILED SLTU\n";
+ std::bitset<32> x(dut->A);
+ std::bitset<32> y(dut->B);
+ std::bitset<32> z(dut->C);
+ std::bitset<32> a(D);
+ std::cout << "Current: " << x << " ?u " << y << " = " << z << '\n';
+ std::cout << "Expected: " << x << " ?u " << y << " = " << a << '\n';
+ mistake = 1;
+ }
+ }
+
+ if(!mistake) {
+ std::cout << "PASSED SLTU\n";
+ }
+ return mistake;
+}
+
+
+
+
+
+int main(int argc, char** argv, char** env) {
+ // This is a more complicated example, please also see the simpler examples/make_hello_c.
+
+ // Prevent unused variable warnings
+ if (false && argc && argv && env) {}
+
+ // Create logs/ directory in case we have traces to put under it
+ Verilated::mkdir("logs");
+
+ // Construct a VerilatedContext to hold simulation time, etc.
+ // Multiple modules (made later below with Vtop) may share the same
+ // context to share time, or modules may have different contexts if
+ // they should be independent from each other.
+
+ // Using unique_ptr is similar to
+ // "VerilatedContext* contextp = new VerilatedContext" then deleting at end.
+ const std::unique_ptr<VerilatedContext> contextp{new VerilatedContext};
+ // Do not instead make Vtop as a file-scope static variable, as the
+ // "C++ static initialization order fiasco" may cause a crash
+
+ // Set debug level, 0 is off, 9 is highest presently used
+ // May be overridden by commandArgs argument parsing
+ contextp->debug(0);
+
+ // Randomization reset policy
+ // May be overridden by commandArgs argument parsing
+ contextp->randReset(2);
+
+ // Verilator must compute traced signals
+ contextp->traceEverOn(true);
+
+ // Pass arguments so Verilated code can see them, e.g. $value$plusargs
+ // This needs to be called before you create any model
+ contextp->commandArgs(argc, argv);
+
+ // Construct the Verilated model, from Vtop.h generated from Verilating "top.v".
+ // Using unique_ptr is similar to "Vtop* top = new Vtop" then deleting at end.
+ // "TOP" will be the hierarchical name of the module.
+ const std::unique_ptr<Valu> dut{new Valu{contextp.get(), "ALU"}};
+
+ int test;
+ if (shift_right_a(dut, contextp)) {
+ return 0;
+ }
+ if (shift_right_l(dut, contextp)) {
+ return 0;
+ }
+ if (shift_left(dut, contextp)) {
+ return 0;
+ }
+ if (add(dut, contextp)) {
+ return 0;
+ }
+ if (sub(dut, contextp)) {
+ return 0;
+ }
+ if (slt(dut,contextp)) {
+ return 0;
+ }
+ if (sltu(dut,contextp)) {
+ return 0;
+ }
+ dut->eval();
+
+
+ // Final model cleanup
+ dut->final();
+
+ // Return good completion status
+ // Don't use exit() or destructor won't get called
+ return 0;
+}
+