hls_burst_maxi.h: Allow for multiple operations on the same channel
This commit is contained in:
@@ -1,4 +1,9 @@
|
||||
// 67d7842dbbe25473c3c32b93c0da8047785f30d78e8a024de1b57352245f9689
|
||||
|
||||
// Modified by Filip Leonarski (Paul Scherrer Institute
|
||||
// to allow for multiple parallel bursts to the same pointer
|
||||
// (via independent HBM channels)
|
||||
|
||||
#ifndef X_HLS_BURST_MAXI_SIM_H
|
||||
#define X_HLS_BURST_MAXI_SIM_H
|
||||
|
||||
@@ -27,9 +32,6 @@ struct MAXIAccessRecord {
|
||||
std::list<std::pair<size_t, unsigned>> WriteRespQ;
|
||||
};
|
||||
|
||||
// A global map between pointer and MAXAccessRecord.
|
||||
std::map<void *, MAXIAccessRecord> MAXIPointer2AccessRecordMap __attribute__((weak));
|
||||
|
||||
template<typename T>
|
||||
class burst_maxi {
|
||||
public:
|
||||
@@ -38,7 +40,6 @@ public:
|
||||
assert(bitwidth != 0 && !(bitwidth & (bitwidth - 1)) &&
|
||||
"Error: bit width of hls::burst_maxi is not poower-of-2.");
|
||||
// Reset the MAXI access record to this pointer
|
||||
MAXIAccessRecord &R = MAXIPointer2AccessRecordMap[p];
|
||||
R.read_disp = 0;
|
||||
R.write_disp = 0;
|
||||
R.ReadQ.clear();
|
||||
@@ -48,7 +49,6 @@ public:
|
||||
|
||||
void read_request(size_t offset, unsigned len) {
|
||||
assert(len > 0);
|
||||
MAXIAccessRecord &R = MAXIPointer2AccessRecordMap[Ptr];
|
||||
R.ReadQ.push_back(std::make_pair(offset, len));
|
||||
std::list<std::pair<size_t, unsigned>> CurrentWriteQ = R.WriteQ;
|
||||
CurrentWriteQ.insert(CurrentWriteQ.end(),
|
||||
@@ -62,8 +62,7 @@ public:
|
||||
}
|
||||
|
||||
T read() {
|
||||
MAXIAccessRecord &R = MAXIPointer2AccessRecordMap[Ptr];
|
||||
assert(!R.ReadQ.empty() && "Error: MAXI read without request.");
|
||||
assert(!R.ReadQ.empty() && "Error: MAXI read without request.");
|
||||
auto Pair = R.ReadQ.front();
|
||||
T V = Ptr[Pair.first + (R.read_disp++)];
|
||||
if (R.read_disp == Pair.second) {
|
||||
@@ -75,7 +74,6 @@ public:
|
||||
|
||||
void write_request(size_t offset, unsigned len) {
|
||||
assert(len > 0);
|
||||
MAXIAccessRecord &R = MAXIPointer2AccessRecordMap[Ptr];
|
||||
for (auto Pair : R.ReadQ) {
|
||||
if (overlap(offset, len, Pair.first, Pair.second)) {
|
||||
std::cerr << "Error: MAXI write request(offset = " << offset << ", len = " << len << ") overlaps with previous read request(offset = " << Pair.first << ", len = " << Pair.second << ")." << std::endl;
|
||||
@@ -86,8 +84,7 @@ public:
|
||||
}
|
||||
|
||||
void write(const T &val, ap_int<sizeof(T)> byte_enable_mask = -1) {
|
||||
MAXIAccessRecord &R = MAXIPointer2AccessRecordMap[Ptr];
|
||||
assert(!R.WriteQ.empty() && "Error: MAXI write without request.");
|
||||
assert(!R.WriteQ.empty() && "Error: MAXI write without request.");
|
||||
auto Pair = R.WriteQ.front();
|
||||
T *DstP = &Ptr[Pair.first + R.write_disp++];
|
||||
T Src = val;
|
||||
@@ -104,13 +101,13 @@ public:
|
||||
}
|
||||
|
||||
void write_response() {
|
||||
MAXIAccessRecord &R = MAXIPointer2AccessRecordMap[Ptr];
|
||||
assert(!R.WriteRespQ.empty() && "Error: bad MAXI write response. Possible: 1) no corresponding write request; 2) some data still not written.");
|
||||
R.WriteRespQ.pop_front();
|
||||
}
|
||||
|
||||
private:
|
||||
T *Ptr;
|
||||
MAXIAccessRecord R;
|
||||
bool overlap(size_t a, unsigned a_len, size_t b, unsigned b_len) {
|
||||
return a <= b ? a + a_len > b : b + b_len > a;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user