aboutsummaryrefslogtreecommitdiff
path: root/multiplier/tb_multiplier.cpp
blob: 040df80bcd686d69e98715c598777bab98cb524e (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
#include <iostream>
#include <iomanip>
#include <bitset>
#include <cstdint>

#include "Vmultiplier.h"
#include "verilated.h"

#define BITWIDTH 32

int main(int argc, char** argv, char** env) {

	if (false && argc && argv && env) {}

	Verilated::mkdir("logs");
	VerilatedContext* contextp = new VerilatedContext;

	contextp->debug(0);
	contextp->randReset(2);
	contextp->traceEverOn(true);
	contextp->commandArgs(argc, argv);

	Vmultiplier* dut = new Vmultiplier{contextp};

	uint32_t testsize = 0x1000;

	for (int i = 0; i < testsize; i++) {
		for (int j = 0; j < testsize; j++) {
			dut->a = (uint32_t) i;
			dut->b = (uint32_t) j;
			unsigned int answer = (unsigned int) (i * j);

			dut->eval();
			if (answer != dut->c) {
				std::bitset<BITWIDTH> in1(dut->a);
				std::bitset<BITWIDTH> in2(dut->b);
				std::bitset<BITWIDTH*2> expected(answer);
				std::bitset<BITWIDTH*2> actual(dut->c);
				std::cout << "Inputs: 1: " << in1 << " 2: " << in2 << '\n';
				std::cout << "Expected: " << expected << '\n';
				std::cout << "Actual: " << actual << '\n';
				return -1;
			}
		}
	}


	std::cout << "LOWER HALF PASSED\n";

	uint64_t top = 1;
	for (int i = 1; i < BITWIDTH; i++) {
		top <<= 1;
		top |= 1;
	}
	uint64_t bottom = top - testsize;

	for (uint64_t i = bottom; i < top; i++) {
		for (uint64_t j = bottom; j < top; j++) {

			dut->a = (uint32_t) i;
			dut->b = (uint32_t) j;

			uint64_t answer = i * j;

			dut->eval();
			if (answer != dut->c) {
				std::bitset<BITWIDTH> in1(dut->a);
				std::bitset<BITWIDTH> in2(dut->b);
				std::bitset<BITWIDTH*2> expected(answer);
				std::bitset<BITWIDTH*2> actual(dut->c);
				std::cout << "In 1: " << in1 << '\n';
				std::cout << "In 2: " << in2 << '\n';
				std::cout << "Expected: " << expected << '\n';
				std::cout << "Actual:   " << actual << '\n';

				std::cout << "In 1: " << std::hex << (uint32_t) dut->a  << '\n';
				std::cout << "In 2: " << std::hex << (uint32_t) dut->b << '\n';
				std::cout << "Expected: " << std::hex << (uint64_t) answer << '\n';
				std::cout << "Actual:   " << std::hex << (uint64_t) dut->c << '\n';
				return -1;
			}
		}
	}

	std::cout << "UPPER HALF PASSED\n";


	std::cout << "Test Passed for " << BITWIDTH <<  " bit multiplier\n";

	delete dut;
	delete contextp;
	return 0;
}