From d4bcfb9f9e5bd8dc6138b5c50c8a4eafe73b37ed Mon Sep 17 00:00:00 2001 From: Filip Leonarski Date: Sat, 9 Sep 2023 18:41:05 +0200 Subject: [PATCH] hls_burst_maxi.h: Allow for multiple operations on the same channel --- fpga/include/hls_burst_maxi.h | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/fpga/include/hls_burst_maxi.h b/fpga/include/hls_burst_maxi.h index 627b965b..9d8541fb 100644 --- a/fpga/include/hls_burst_maxi.h +++ b/fpga/include/hls_burst_maxi.h @@ -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> WriteRespQ; }; -// A global map between pointer and MAXAccessRecord. -std::map MAXIPointer2AccessRecordMap __attribute__((weak)); - template 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> 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 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; }