diff options
Diffstat (limited to 'verilog/tbalu.cpp')
-rw-r--r-- | verilog/tbalu.cpp | 342 |
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; +} + |