-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathap_vector.h
91 lines (78 loc) · 2.68 KB
/
ap_vector.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
//
// Created by akira on 2023/04/07.
// ap_vector.h v1.0.0
//
#pragma once
#include <ap_int.h>
template <unsigned LENGTH, int _AP_W, bool _AP_S = true>
class ap_vector {
public:
// Internal representation of the ap_vector
ap_int_base<_AP_W, _AP_S> data[LENGTH];
// Default constructor
ap_vector() {}
// Constructor from ap_uint with total bit width
ap_vector(const ap_uint<LENGTH * _AP_W> &value) {
for (int i = 0; i < LENGTH; ++i) {
data[i] = value.range((i + 1) * _AP_W - 1, i * _AP_W);
}
}
// Constructor from another ap_vector with different bit width
template <int SRC_AP_W, bool SRC_AP_S>
ap_vector(const ap_vector<LENGTH, SRC_AP_W, SRC_AP_S> &src) {
for (int i = 0; i < LENGTH; ++i) {
data[i] = src[i];
}
}
// Read/Write access to individual elements
ap_int_base<_AP_W, _AP_S> &operator[](int index) {
return data[index];
}
const ap_int_base<_AP_W, _AP_S> &operator[](int index) const {
return data[index];
}
// Conversion to ap_uint with total bit width
operator ap_uint<LENGTH * _AP_W>() const {
ap_uint<LENGTH * _AP_W> result;
for (int i = 0; i < LENGTH; ++i) {
result.range((i + 1) * _AP_W - 1, i * _AP_W) = data[i];
}
return result;
}
};
// Arithmetic and shift operations between ap_vectors
#define AP_VECTOR_OP(OP) \
template<unsigned LENGTH, int _AP_W, bool _AP_S, int RHS_AP_W, bool RHS_AP_S> \
ap_vector<LENGTH, decltype(ap_int_base<_AP_W, _AP_S>() OP ap_int_base<RHS_AP_W, RHS_AP_S>())::width, _AP_S> operator OP(const ap_vector<LENGTH, _AP_W, _AP_S> &lhs, const ap_vector<LENGTH, RHS_AP_W, RHS_AP_S> &rhs) { \
ap_vector<LENGTH, decltype(ap_int_base<_AP_W, _AP_S>() OP ap_int_base<RHS_AP_W, RHS_AP_S>())::width, _AP_S> result; \
for (int i = 0; i < LENGTH; ++i) { \
result[i] = lhs[i] OP rhs[i]; \
} \
return result; \
}
AP_VECTOR_OP(+)
AP_VECTOR_OP(-)
AP_VECTOR_OP(*)
AP_VECTOR_OP(/)
AP_VECTOR_OP(%)
AP_VECTOR_OP(<<)
AP_VECTOR_OP(>>)
#undef AP_VECTOR_OP
// Macro to define arithmetic and shift operations between ap_vector and constant values
#define AP_INT_OP(OP) \
template <unsigned LENGTH, int _AP_W, bool _AP_S, typename T> \
inline ap_vector<LENGTH, decltype(ap_int_base<_AP_W, _AP_S>() OP T())::width, _AP_S> operator OP(const ap_vector<LENGTH, _AP_W, _AP_S>& lhs, T rhs) { \
ap_vector<LENGTH, decltype(ap_int_base<_AP_W, _AP_S>() OP T())::width, _AP_S> result; \
for (int i = 0; i < LENGTH; ++i) { \
result[i] = lhs[i] OP rhs; \
} \
return result; \
}
AP_INT_OP(+)
AP_INT_OP(-)
AP_INT_OP(*)
AP_INT_OP(/)
AP_INT_OP(%)
AP_INT_OP(<<)
AP_INT_OP(>>)
#undef AP_INT_OP