Skip to content

Commit 39f0acc

Browse files
committed
Merge branch 'hotfix/condition-fpga-programming'
2 parents a4ddeda + c50356d commit 39f0acc

File tree

7 files changed

+100
-37
lines changed

7 files changed

+100
-37
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: 20 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
@@ -208,5 +209,22 @@ class IHardware {
208209
*/
209210
static std::shared_ptr<IHardware> Create(const HardwareArchitecture hw,
210211
const std::string &config);
212+
213+
/**
214+
* @brief Create method
215+
* Factory method to create a hardware-specific subclasses for accelerators
216+
* and data movers. The configuration of the FPGA is not performed by using
217+
* this constructor, since this assumes that there is none bitstream to load.
218+
*
219+
* @param hw One of the values in the HardwareArchitecture enum class
220+
* present in the enums.hpp file that should correspond to the device being
221+
* used.
222+
*
223+
* @return std::shared_ptr<IHardware>
224+
* Returns an IAccelerator pointer with reference counting. It should be
225+
* thread-safe.
226+
*
227+
*/
228+
static std::shared_ptr<IHardware> Create(const HardwareArchitecture hw);
211229
};
212230
} // namespace cynq

include/cynq/ultrascale/hardware.hpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,9 +86,12 @@ class UltraScale : public IHardware {
8686
*/
8787
UltraScale(const std::string &bitstream_file, const std::string &xclbin_file);
8888
/**
89-
* No default constructor required
89+
* @brief Construct a new UltraScale object
90+
*
91+
* Configure the hardware platform without loading a bitstream nor xclbin.
92+
* This is useful for already configured FPGAs.
9093
*/
91-
UltraScale() = delete;
94+
UltraScale();
9295
/**
9396
* @brief ~UltraScale destructor method
9497
* Destroy the UltraScale object.

meson.build

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
#
88

99

10-
project('cynq',['c','cpp'],version : '0.2.0',
10+
project('cynq',['c','cpp'],version : '0.3.1',
1111
default_options : ['warning_level=3',
1212
'cpp_std=c++17',
1313
'cpp_args=-Werror'])

src/cynq/dma/datamover.cpp

Lines changed: 45 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,9 @@ DMADataMover::DMADataMover(const uint64_t addr,
4747
params->hw_params_ = hwparams;
4848

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

5355
std::shared_ptr<IMemory> DMADataMover::GetBuffer(const size_t size, const int,
@@ -95,7 +97,9 @@ DMADataMover::~DMADataMover() {
9597
/* The assumption is that at this point, it is ok */
9698
auto params =
9799
dynamic_cast<DMADataMoverParameters *>(data_mover_params_.get());
98-
PYNQ_closeDMA(&params->dma_);
100+
if (static_cast<uint64_t>(0ul) != params->addr_) {
101+
PYNQ_closeDMA(&params->dma_);
102+
}
99103
}
100104

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

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-
135133
/* Issue transaction */
136-
PYNQ_SHARED_MEMORY pmem;
137-
pmem.physical_address = (uint64_t)(ptr.get()); // NOLINT
138-
pmem.pointer = nullptr;
134+
if (static_cast<uint64_t>(0ul) != params->addr_) {
135+
/* Get device pointer */
136+
std::shared_ptr<uint8_t> ptr = mem->DeviceAddress<uint8_t>();
137+
if (!ptr) {
138+
return Status{Status::INVALID_PARAMETER, "Device pointer is null"};
139+
}
139140

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

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

148154
/* Synchronise if needed */
@@ -177,21 +183,25 @@ Status DMADataMover::Download(const std::shared_ptr<IMemory> mem,
177183
meta->bo_->sync(XCL_BO_SYNC_BO_FROM_DEVICE, size, offset);
178184
}
179185

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-
186186
/* 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);
187+
if (static_cast<uint64_t>(0ul) != params->addr_) {
188+
std::shared_ptr<uint8_t> ptr = mem->DeviceAddress<uint8_t>();
191189

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

197207
/* Synchronise if needed */
@@ -203,11 +213,15 @@ Status DMADataMover::Download(const std::shared_ptr<IMemory> mem,
203213
}
204214

205215
Status DMADataMover::Sync(const SyncType type) {
206-
int ret = PYNQ_SUCCESS;
207-
208216
auto params =
209217
dynamic_cast<DMADataMoverParameters *>(data_mover_params_.get());
210218

219+
if (static_cast<uint64_t>(0ul) == params->addr_) {
220+
return Status{};
221+
}
222+
223+
int ret = PYNQ_SUCCESS;
224+
211225
if (SyncType::HostToDevice == type) {
212226
ret = PYNQ_waitForDMAComplete(&params->dma_, AXI_DMA_WRITE);
213227
} else {

src/cynq/hardware.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,15 @@ std::shared_ptr<IHardware> IHardware::Create(const HardwareArchitecture hw,
3838
}
3939
}
4040

41+
std::shared_ptr<IHardware> IHardware::Create(const HardwareArchitecture hw) {
42+
switch (hw) {
43+
case HardwareArchitecture::UltraScale:
44+
return std::make_shared<UltraScale>();
45+
default:
46+
return nullptr;
47+
}
48+
}
49+
4150
std::shared_ptr<IExecutionGraph> IHardware::GetExecutionStream(
4251
const std::string& name, const IExecutionGraph::Type type,
4352
const std::shared_ptr<ExecutionGraphParameters> params) {

src/cynq/ultrascale/hardware.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,23 @@ UltraScale::UltraScale(const std::string &bitstream_file,
126126
GetClocksInformation();
127127
}
128128

129+
UltraScale::UltraScale()
130+
: parameters_{std::make_shared<UltraScaleParameters>()} {
131+
/* For the UltraScale, there is only a single device. It is possible to
132+
load either a bitstream or a xclbin. */
133+
Status st{};
134+
135+
/* Configure the buses accordingly to the default design */
136+
st = LoadXclBin(EXAMPLE_KRIA_DEFAULT_XCLBIN_LOCATION);
137+
if (st.code != Status::OK) {
138+
std::string msg = "Error while configuring the buses: ";
139+
msg += st.msg;
140+
throw std::runtime_error(msg);
141+
}
142+
143+
GetClocksInformation();
144+
}
145+
129146
Status UltraScale::LoadBitstream(const std::string &bitstream_file) {
130147
/* FIXME: This is a temporal implementation while we are coding our own
131148
implementation. Use with caution */

0 commit comments

Comments
 (0)