Skip to content

Commit bf38291

Browse files
committed
Add DMA with zero address
Conditionally creates the DMA engine
1 parent 1863ed6 commit bf38291

File tree

3 files changed

+52
-34
lines changed

3 files changed

+52
-34
lines changed

include/cynq/dma/datamover.hpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,9 @@ class DMADataMover : public IDataMover {
4242
* This constructs a data mover that uses DMA to execute the transfers
4343
* between the host and the device. Moreover, it uses XRT buffer object as
4444
* memory buffers.
45-
* @param addr DMA address in the physical memory map
45+
* @param addr DMA address in the physical memory map. if 0, DMA engine for
46+
* AXI Stream is not instantiated but the memory map functionality will still
47+
* work.
4648
* @param hwparams Hardware-specific params
4749
*/
4850
DMADataMover(const uint64_t addr,

include/cynq/hardware.hpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,8 +70,9 @@ class IHardware {
7070
*
7171
* @param address a unsigned integer of 64 bits representing an address.
7272
* In the case of ZYNQ boards, it corresponds to the base address of the
73-
* accelerator BAR (Bank Address Register). In the case of Alveo boards,
74-
* it is unused.
73+
* accelerator BAR (Bank Address Register). In the case of Alveo boards or
74+
* already configured devices (UltraScale default construction), it is
75+
* unused.
7576
*
7677
* @return std::shared_ptr<IDataMover>
7778
* Returns an IDataMover pointer with reference counting. It should be

src/cynq/dma/datamover.cpp

Lines changed: 46 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,12 @@ DMADataMover::DMADataMover(const uint64_t addr,
4545

4646
params->addr_ = addr;
4747
params->hw_params_ = hwparams;
48+
params->dma_ = nullptr;
4849

4950
/* Create the DMA accessor */
50-
PYNQ_openDMA(&params->dma_, addr);
51+
if (static_cast<uint64_t>(0ul) != addr) {
52+
PYNQ_openDMA(&params->dma_, addr);
53+
}
5154
}
5255

5356
std::shared_ptr<IMemory> DMADataMover::GetBuffer(const size_t size, const int,
@@ -95,7 +98,9 @@ DMADataMover::~DMADataMover() {
9598
/* The assumption is that at this point, it is ok */
9699
auto params =
97100
dynamic_cast<DMADataMoverParameters *>(data_mover_params_.get());
98-
PYNQ_closeDMA(&params->dma_);
101+
if (params->dma_) {
102+
PYNQ_closeDMA(&params->dma_);
103+
}
99104
}
100105

101106
/* TODO: All implementations below can be implemented cleverly. However, it
@@ -126,23 +131,25 @@ Status DMADataMover::Upload(const std::shared_ptr<IMemory> mem,
126131
meta->bo_->sync(XCL_BO_SYNC_BO_TO_DEVICE, size, offset);
127132
}
128133

129-
/* Get device pointer */
130-
std::shared_ptr<uint8_t> ptr = mem->DeviceAddress<uint8_t>();
131-
if (!ptr) {
132-
return Status{Status::INVALID_PARAMETER, "Device pointer is null"};
133-
}
134-
135134
/* Issue transaction */
136-
PYNQ_SHARED_MEMORY pmem;
137-
pmem.physical_address = (uint64_t)(ptr.get()); // NOLINT
138-
pmem.pointer = nullptr;
135+
if (params->dma_) {
136+
/* Get device pointer */
137+
std::shared_ptr<uint8_t> ptr = mem->DeviceAddress<uint8_t>();
138+
if (!ptr) {
139+
return Status{Status::INVALID_PARAMETER, "Device pointer is null"};
140+
}
139141

140-
ret =
141-
PYNQ_issueDMATransfer(&params->dma_, &pmem, offset, size, AXI_DMA_WRITE);
142+
PYNQ_SHARED_MEMORY pmem;
143+
pmem.physical_address = (uint64_t)(ptr.get()); // NOLINT
144+
pmem.pointer = nullptr;
142145

143-
/* Check transaction */
144-
if (PYNQ_SUCCESS != ret) {
145-
return Status{Status::REGISTER_IO_ERROR, "Cannot issue the transfer"};
146+
ret = PYNQ_issueDMATransfer(&params->dma_, &pmem, offset, size,
147+
AXI_DMA_WRITE);
148+
149+
/* Check transaction */
150+
if (PYNQ_SUCCESS != ret) {
151+
return Status{Status::REGISTER_IO_ERROR, "Cannot issue the transfer"};
152+
}
146153
}
147154

148155
/* Synchronise if needed */
@@ -177,21 +184,25 @@ Status DMADataMover::Download(const std::shared_ptr<IMemory> mem,
177184
meta->bo_->sync(XCL_BO_SYNC_BO_FROM_DEVICE, size, offset);
178185
}
179186

180-
/* Get device pointer */
181-
std::shared_ptr<uint8_t> ptr = mem->DeviceAddress<uint8_t>();
182-
if (!ptr) {
183-
return Status{Status::INVALID_PARAMETER, "Device pointer is null"};
184-
}
185-
186187
/* Issue transaction */
187-
PYNQ_SHARED_MEMORY pmem;
188-
pmem.physical_address = (uint64_t)(ptr.get()); // NOLINT
189-
pmem.pointer = nullptr;
190-
ret = PYNQ_issueDMATransfer(&params->dma_, &pmem, offset, size, AXI_DMA_READ);
188+
if (params->dma_) {
189+
std::shared_ptr<uint8_t> ptr = mem->DeviceAddress<uint8_t>();
191190

192-
/* Check transaction */
193-
if (PYNQ_SUCCESS != ret) {
194-
return Status{Status::REGISTER_IO_ERROR, "Cannot issue the transfer"};
191+
/* Get device pointer */
192+
if (!ptr) {
193+
return Status{Status::INVALID_PARAMETER, "Device pointer is null"};
194+
}
195+
196+
PYNQ_SHARED_MEMORY pmem;
197+
pmem.physical_address = (uint64_t)(ptr.get()); // NOLINT
198+
pmem.pointer = nullptr;
199+
ret =
200+
PYNQ_issueDMATransfer(&params->dma_, &pmem, offset, size, AXI_DMA_READ);
201+
202+
/* Check transaction */
203+
if (PYNQ_SUCCESS != ret) {
204+
return Status{Status::REGISTER_IO_ERROR, "Cannot issue the transfer"};
205+
}
195206
}
196207

197208
/* Synchronise if needed */
@@ -203,11 +214,15 @@ Status DMADataMover::Download(const std::shared_ptr<IMemory> mem,
203214
}
204215

205216
Status DMADataMover::Sync(const SyncType type) {
206-
int ret = PYNQ_SUCCESS;
207-
208217
auto params =
209218
dynamic_cast<DMADataMoverParameters *>(data_mover_params_.get());
210219

220+
if (!params->dma_) {
221+
return Status{};
222+
}
223+
224+
int ret = PYNQ_SUCCESS;
225+
211226
if (SyncType::HostToDevice == type) {
212227
ret = PYNQ_waitForDMAComplete(&params->dma_, AXI_DMA_WRITE);
213228
} else {

0 commit comments

Comments
 (0)