forked from cdkersey/chdl
-
Notifications
You must be signed in to change notification settings - Fork 1
/
adder.h
66 lines (57 loc) · 1.73 KB
/
adder.h
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
// Instantiate an N-bit Kogge-Stone adder
#ifndef __ADDER_H
#define __ADDER_H
#include <vector>
#include "gateops.h"
#include "bvec-basic.h"
#include "hierarchy.h"
#include "shifter.h" // for CLOG2
namespace chdl {
template <unsigned N> bvec<N> Adder(bvec<N> a, bvec<N> b, node cin = Lit(0)) {
HIERARCHY_ENTER();
vec<CLOG2(N)+3, bvec<N+1>> g, p, i;
bvec<N> s;
g[0][0] = cin;
p[0][0] = Lit(0);
for (unsigned j = 0; j < N; ++j) p[0][j+1] = Xor(a[j], b[j]);
for (unsigned j = 0; j < N; ++j) g[0][j+1] = a[j] && b[j];
unsigned k;
for (k = 0; (1l<<k) < 2*N; ++k) {
for (unsigned j = 0; j < N+1; ++j) {
if (j < (1l<<k)) {
g[k+1][j] = g[k][j];
p[k+1][j] = p[k][j];
} else {
i[k+1][j] = p[k][j] && g[k][j - (1l<<k)];
g[k+1][j] = i[k+1][j] || g[k][j];
p[k+1][j] = p[k][j] && p[k][j - (1l<<k)];
}
}
}
for (unsigned j = 0; j < N; ++j) s[j] = Xor(p[0][j+1], g[k][j]);
HIERARCHY_EXIT();
return s;
}
template <unsigned N>
bvec<N> operator+(bvec<N> a, bvec<N> b)
{ return Adder<N>(a, b); }
template <unsigned N>
bvec<N> operator-(bvec<N> a, bvec<N> b)
{ return Adder<N>(a, Not(b), Lit(1)); }
template <unsigned N>
bvec<N> operator-(bvec<N> x)
{ return Lit<N>(0) - x; }
template <unsigned N>
node operator<(bvec<N> a, bvec<N> b) // Unsigned by default
{ return (Cat(Lit(0), a) - Cat(Lit(0), b))[N]; }
template <unsigned N>
node operator>(bvec<N> a, bvec<N> b)
{ return b<a; }
template <unsigned N>
node operator>=(bvec<N> a, bvec<N> b)
{ return !(a < b); }
template <unsigned N>
node operator<=(bvec<N> a, bvec<N> b)
{ return !(a > b); }
};
#endif