Skip to content

Commit 34eccfe

Browse files
committed
change(sgdma): get_full_buffers(), add read_buffers()
1 parent f825729 commit 34eccfe

5 files changed

Lines changed: 63 additions & 46 deletions

File tree

example/demo_cpp/src/axi_dma_demo.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -118,12 +118,12 @@ int main(int argc, char* argv[]) {
118118
auto mem_sgdma = std::make_unique<UioMemSgdma>(target_hw_consts::axi_bram_ctrl);
119119
auto traffic_gen = std::make_unique<UioTrafficGen>(target_hw_consts::axi_traffic_gen);
120120

121-
std::unique_ptr<DmaBufferAbstract> udmabuf;
121+
std::shared_ptr<DmaBufferAbstract> udmabuf;
122122
if (mode == DmaMode::UIO) {
123-
udmabuf = std::make_unique<UDmaBuf>();
123+
udmabuf = std::make_shared<UDmaBuf>();
124124
} else {
125125
udmabuf =
126-
std::make_unique<FpgaMemBufferOverXdma>(dev_path, target_hw_consts::fpga_mem_phys_addr);
126+
std::make_shared<FpgaMemBufferOverXdma>(dev_path, target_hw_consts::fpga_mem_phys_addr);
127127
}
128128

129129
const size_t pkt_size = pkt_len * target_hw_consts::lfsr_bytes_per_beat;
@@ -136,7 +136,7 @@ int main(int argc, char* argv[]) {
136136
auto fut = std::async(std::launch::async, std::ref(data_handler));
137137

138138
constexpr int nr_buffers = 32;
139-
mem_sgdma->init_buffers(*udmabuf, nr_buffers, pkt_size);
139+
mem_sgdma->init_buffers(udmabuf, nr_buffers, pkt_size);
140140

141141
uintptr_t first_desc = mem_sgdma->get_first_desc_addr();
142142
axi_dma->start(first_desc);

inc/udmaio/UioMemSgdma.hpp

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#pragma once
1313

1414
#include <cstddef>
15+
#include <memory>
1516

1617
#include "DmaBufferAbstract.hpp"
1718
#include "RegAccessor.hpp"
@@ -78,6 +79,8 @@ class UioMemSgdma : public UioIf {
7879
std::vector<uint64_t> _buf_addrs;
7980
size_t _buf_size;
8081

82+
std::shared_ptr<DmaBufferAbstract> _mem;
83+
8184
void write_cyc_mode(const std::vector<UioRegion>& dst_bufs);
8285

8386
public:
@@ -87,7 +90,7 @@ class UioMemSgdma : public UioIf {
8790
/// @param mem Memory receiving the SGDMA data
8891
/// @param num_buffers Number of descriptors / SGDMA blocks
8992
/// @param buf_size Size of each SGDMA block
90-
void init_buffers(DmaBufferAbstract& mem, size_t num_buffers, size_t buf_size);
93+
void init_buffers(std::shared_ptr<DmaBufferAbstract> mem, size_t num_buffers, size_t buf_size);
9194

9295
/// @brief Print SGDMA descriptor
9396
/// @param desc SGDMA descriptor
@@ -101,8 +104,10 @@ class UioMemSgdma : public UioIf {
101104
uintptr_t get_first_desc_addr() const;
102105

103106
/// @brief Get full SGDMA buffers
104-
/// @return Vector of UioRegion pointing into full buffers
105-
std::vector<UioRegion> get_full_buffers();
107+
/// @return Vector of indices of full buffers
108+
std::vector<size_t> get_full_buffers();
109+
110+
std::vector<uint8_t> read_buffers(const std::vector<size_t> indices);
106111
};
107112

108113
std::ostream& operator<<(std::ostream& os, const UioRegion& buf_info);

src/DataHandlerAbstract.cpp

Lines changed: 4 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -58,25 +58,14 @@ void DataHandlerAbstract::_handle_input(const boost::system::error_code& ec) {
5858
uint32_t irq_count = _dma.clear_interrupt();
5959
BOOST_LOG_SEV(_lg, bls::trace) << "irq count = " << irq_count;
6060

61-
std::vector<UioRegion> full_bufs = _desc.get_full_buffers();
62-
std::vector<uint8_t> bytes;
63-
61+
auto full_bufs = _desc.get_full_buffers();
6462
if (full_bufs.empty()) {
6563
BOOST_LOG_SEV(_lg, bls::trace) << "spurious event, got no data";
66-
goto done;
64+
} else {
65+
auto bytes = _desc.read_buffers(full_bufs);
66+
process_data(std::move(bytes));
6767
}
6868

69-
// Assuming all buffers are equally big, we need number of buffers times buffer size
70-
// Reserving enough space in advance to avoid re-allocation / copying
71-
bytes.reserve(full_bufs.size() * full_bufs[0].size);
72-
73-
for (auto& buf : full_bufs) {
74-
_mem.append_from_buf(buf, bytes);
75-
}
76-
77-
process_data(std::move(bytes));
78-
79-
done:
8069
_start_read();
8170
}
8271

src/UioMemSgdma.cpp

Lines changed: 44 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,14 @@
1111

1212
#include "udmaio/UioMemSgdma.hpp"
1313

14+
#include <cstddef>
1415
#include <cstdint>
16+
#include <memory>
17+
#include <stdexcept>
18+
#include <string>
19+
#include <vector>
20+
21+
#include "udmaio/DmaBufferAbstract.hpp"
1522

1623
namespace udmaio {
1724

@@ -43,12 +50,16 @@ void UioMemSgdma::write_cyc_mode(const std::vector<UioRegion>& dst_bufs) {
4350
}
4451
}
4552

46-
void UioMemSgdma::init_buffers(DmaBufferAbstract& mem, size_t num_buffers, size_t buf_size) {
53+
void UioMemSgdma::init_buffers(std::shared_ptr<DmaBufferAbstract> mem,
54+
size_t num_buffers,
55+
size_t buf_size) {
56+
_mem = mem;
57+
4758
// FIXME: enforce alignment constraints?
4859
std::vector<UioRegion> dst_bufs;
4960
_buf_addrs.clear();
5061
for (size_t i = 0; i < num_buffers; i++) {
51-
uint64_t addr = mem.get_phys_region().addr + i * buf_size;
62+
uint64_t addr = mem->get_phys_region().addr + i * buf_size;
5263
dst_bufs.push_back({
5364
.addr = addr,
5465
.size = buf_size,
@@ -97,8 +108,8 @@ std::ostream& operator<<(std::ostream& os, const UioRegion& buf_info) {
97108
return os;
98109
}
99110
100-
std::vector<UioRegion> UioMemSgdma::get_full_buffers() {
101-
std::vector<UioRegion> bufs;
111+
std::vector<size_t> UioMemSgdma::get_full_buffers() {
112+
std::vector<size_t> result;
102113
103114
for (size_t i = 0; i < _nr_cyc_desc; i++) {
104115
auto stat = desc_statuses[_next_readable_buf].rd();
@@ -107,29 +118,42 @@ std::vector<UioRegion> UioMemSgdma::get_full_buffers() {
107118
}
108119
109120
if ((!stat.rxeof && (stat.num_stored_bytes != _buf_size)) || stat.num_stored_bytes == 0) {
110-
BOOST_LOG_SEV(_lg, bls::error)
111-
<< "Descriptor #" << i << " size mismatch (expected " << _buf_size << ", received "
112-
<< stat.num_stored_bytes << "), skipping";
113-
114-
print_desc(descriptors[_next_readable_buf].rd());
115-
continue;
121+
throw std::runtime_error("Descriptor #" + std::to_string(i) +
122+
" size mismatch (expected " + std::to_string(_buf_size) +
123+
", received " + std::to_string(stat.num_stored_bytes) + ")");
116124
}
117125

118-
stat.cmplt = 0;
119-
desc_statuses[_next_readable_buf].wr(stat);
120-
121-
const uint64_t buf_addr = _buf_addrs[_next_readable_buf];
122-
bufs.emplace_back(UioRegion{static_cast<uintptr_t>(buf_addr), stat.num_stored_bytes});
123-
124-
BOOST_LOG_SEV(_lg, bls::trace)
125-
<< "save buf #" << _next_readable_buf << " (" << stat.num_stored_bytes << " bytes) @ 0x"
126-
<< std::hex << buf_addr;
126+
result.push_back(_next_readable_buf);
127127

128128
_next_readable_buf++;
129129
_next_readable_buf %= _nr_cyc_desc;
130130
}
131131

132-
return bufs;
132+
return result;
133+
}
134+
135+
std::vector<uint8_t> UioMemSgdma::read_buffers(const std::vector<size_t> indices) {
136+
// Read statuses for all buffers
137+
std::vector<S2mmDescStatus> stats{indices.size()};
138+
size_t result_size = 0;
139+
for (size_t i = 0; i < indices.size(); i++) {
140+
stats[i] = desc_statuses[indices[i]].rd();
141+
result_size += stats[i].num_stored_bytes;
142+
}
143+
144+
std::vector<uint8_t> result;
145+
// Reserve enough space in advance to avoid re-allocation / copying
146+
result.reserve(result_size);
147+
for (size_t i = 0; i < indices.size(); i++) {
148+
auto region = UioRegion{_buf_addrs[indices[i]], stats[i].num_stored_bytes};
149+
BOOST_LOG_SEV(_lg, bls::trace) << "save buf #" << indices[i] << " (" << region.size
150+
<< " bytes) @ 0x" << std::hex << region.addr;
151+
_mem->append_from_buf(region, result);
152+
// Clear complete flag after having read the data
153+
stats[i].cmplt = 0;
154+
desc_statuses[indices[i]].wr(stats[i]);
155+
}
156+
return result;
133157
}
134158

135159
} // namespace udmaio

tests/test_UioMemSgdma.cpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,13 @@ struct UioMemSgdmaTest : public Logger {
1919
UioMemSgdma sgdma;
2020

2121
HwAccessorPtr hw_fpga_mem;
22-
FpgaMemBufferOverAxi fpga_mem;
22+
std::shared_ptr<FpgaMemBufferOverAxi> fpga_mem;
2323

2424
UioMemSgdmaTest()
2525
: hw_sgdma{std::make_shared<udmaio::HwAccessorMock>(16 * 1024)}
2626
, sgdma{UioDeviceLocation{hw_sgdma}}
2727
, hw_fpga_mem{std::make_shared<HwAccessorMock>(16 * 1024)}
28-
, fpga_mem{UioDeviceLocation{hw_fpga_mem}}
28+
, fpga_mem{std::make_shared<FpgaMemBufferOverAxi>(UioDeviceLocation{hw_fpga_mem})}
2929
, descriptors{sgdma.descriptors}
3030
, Logger("UioMemSgdmaTest") {}
3131
~UioMemSgdmaTest() {}
@@ -81,8 +81,7 @@ BOOST_FIXTURE_TEST_CASE(full_buffers, UioMemSgdmaTest) {
8181
auto bufs = sgdma.get_full_buffers();
8282
BOOST_CHECK_MESSAGE(bufs.size() == 1, "Expected one full buffer, received " << bufs.size());
8383

84-
std::vector<uint8_t> data;
85-
fpga_mem.append_from_buf(bufs[0], data);
84+
std::vector<uint8_t> data = sgdma.read_buffers(bufs);
8685
BOOST_CHECK_MESSAGE(data.size() == buf_size, "Buffer size mismatch");
8786
check_buffer(data);
8887
}

0 commit comments

Comments
 (0)