-
Notifications
You must be signed in to change notification settings - Fork 8
/
enc.h
93 lines (68 loc) · 1.99 KB
/
enc.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
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
#ifndef __ENC_H
#define __ENC_H
#include <iostream>
#include "gates.h"
#include "bvec-basic.h"
#include "shifter.h"
#include "hierarchy.h"
namespace chdl {
static bvec<0> PriEnc(node &valid, const bvec<1> &in, bool reverse=false) {
valid = in[0];
return bvec<0>();
}
static bvec<1> PriEnc(node &valid, const bvec<2> &in, bool reverse=false) {
HIERARCHY_ENTER();
valid = in[0] || in[1];
node ret;
if (reverse) ret = !in[0];
else ret = in[1];
HIERARCHY_EXIT();
return ret;
}
template <unsigned N>
bvec<CLOG2(N)> PriEnc(node &valid, const bvec<N> &in, bool reverse = false)
{
HIERARCHY_ENTER();
const unsigned P2N = (1<<CLOG2(N)), A = (P2N/2), B = (N - A);
bvec<A> rin(in[range<0, A-1>()]);
node rvalid;
bvec<CLOG2(A)> r(PriEnc(rvalid, rin, reverse));
bvec<B> lin(in[range<A, N-1>()]);
node lvalid;
bvec<CLOG2(A)> l(Zext<CLOG2(A)>(PriEnc(lvalid, lin, reverse)));
valid = lvalid || rvalid;
bvec<CLOG2(N)> ret;
if (reverse)
ret = Cat(!rvalid, Mux(rvalid, l, r));
else
ret = Cat(lvalid, Mux(lvalid, r, l));
HIERARCHY_EXIT();
return ret;
}
// Integer logarithm unit (find index of highest set bit); priority encoder
template <unsigned N> bvec<CLOG2(N)> Log2(const bvec<N> &x) {
HIERARCHY_ENTER();
node valid;
bvec<CLOG2(N)> ret(PriEnc(valid, x));
HIERARCHY_EXIT();
return ret;
}
template <unsigned N> bvec<CLOG2(N)> Lsb(const bvec<N> &x) {
node valid;
return PriEnc(valid, x, true);
}
// Cheap encoder, results valid only when exactly one input set
template <unsigned N> bvec<CLOG2(N)> Enc(const bvec<N> &x) {
HIERARCHY_ENTER();
vec<CLOG2(N), bvec<N>> mask;
for (unsigned i = 0; i < CLOG2(N); ++i)
for (unsigned j = 0; j < N; ++j)
mask[i][j] = Lit((j & (1 << i)) != 0);
bvec<CLOG2(N)> out;
for (unsigned i = 0; i < CLOG2(N); ++i)
out[i] = OrN(mask[i] & x);
HIERARCHY_EXIT();
return out;
}
};
#endif