rogue
Loading...
Searching...
No Matches
Xvc.cpp
Go to the documentation of this file.
1
17#include "rogue/Directives.h"
18
20
21#include <dlfcn.h>
22#include <unistd.h>
23
24#include <algorithm>
25#include <cstdlib>
26#include <cstring>
27#include <memory>
28
29#include "rogue/GeneralError.h"
30#include "rogue/GilRelease.h"
31#include "rogue/Logging.h"
36
39
40#ifndef NO_PYTHON
41 #include <boost/python.hpp>
42namespace bp = boost::python;
43#endif
44
46rpx::XvcPtr rpx::Xvc::create(uint16_t port) {
47 rpx::XvcPtr r = std::make_shared<rpx::Xvc>(port);
48 return (r);
49}
50
52rpx::Xvc::Xvc(uint16_t port) : JtagDriver(port), thread_(nullptr), threadEn_(false), mtu_(1450) {
53 // set queue capacity
54 queue_.setThold(100);
55
56 // create logger
57 log_ = rogue::Logging::create("xilinx.xvc");
58}
59
61rpx::Xvc::~Xvc() {
63}
64
66void rpx::Xvc::start() {
67 // Log starting the xvc server thread
68 log_->debug("Starting the XVC server thread");
69
70 // Start the thread
71 threadEn_ = true;
72 thread_ = new std::thread(&rpx::Xvc::runThread, this);
73}
74
76void rpx::Xvc::stop() {
77 // Log stopping the xvc server thread
78 log_->debug("Stopping the XVC server thread");
79
80 // Stop the queue
81 queue_.stop();
82
83 // Empty the queue if necessary
84 while (!queue_.empty()) auto f = queue_.pop();
85
86 // Set done flag
87 done_ = true;
88
89 // Stop the XVC server thread
90 if (threadEn_) {
91 threadEn_ = false;
92 thread_->join();
93 delete thread_;
94 }
95}
96
98void rpx::Xvc::runThread() {
99 // Max message size
100 unsigned maxMsg = 32768;
101
102 // Driver initialization
103 this->init();
104
105 // Start the XVC server on localhost
106 XvcServer s(port_, this, maxMsg);
107 s.run(threadEn_, log_);
108}
109
111void rpx::Xvc::acceptFrame(ris::FramePtr frame) {
112 // Save off frame
113 if (!queue_.busy()) queue_.push(frame);
114
115 // The XvcConnection class manages the TCP connection to Vivado.
116 // After a Vivado request is issued and forwarded to the FPGA, we wait for the response.
117 // XvcConnection will call the xfer() below to do the transfer and checks for a response.
118 // All we need to do is ensure that as soon as the new frame comes in, it's stored in the queue.
119}
120
121uint64_t rpx::Xvc::getMaxVectorSize() {
122 // MTU lim; 2*vector size + header must fit!
123 uint64_t mtuLim = (mtu_ - getWordSize()) / 2;
124
125 return mtuLim;
126}
127
128int rpx::Xvc::xfer(uint8_t* txBuffer,
129 unsigned txBytes,
130 uint8_t* hdBuffer,
131 unsigned hdBytes,
132 uint8_t* rxBuffer,
133 unsigned rxBytes) {
134 // If the XVC server is not running, skip the transaction
135 if (!threadEn_) return (0);
136
137 // Write out the tx buffer as a rogue stream
138 // Send frame to slave (e.g. UDP Client or DMA channel)
139 // Note that class Xvc is both a stream master & a stream slave (here a master)
140 ris::FramePtr frame;
141
142 log_->debug("Tx buffer has %", PRIi32, " bytes to send\n", txBytes);
143
144 // Generate frame
145 frame = reqFrame(txBytes, true);
146 frame->setPayload(txBytes);
147
148 // Copy data from transmitter buffer
149 ris::FrameIterator iter = frame->begin();
150 ris::toFrame(iter, txBytes, txBuffer);
151
152 log_->debug("Sending new frame of size %", PRIi32, frame->getSize());
153
154 // Send frame
155 if (txBytes) sendFrame(frame);
156
157 // Wait for response
158 usleep(1000);
159
160 // Read response in the rx buffer as a rogue stream
161 // Accept frame from master (e.g. UDP Client or DMA channel)
162 // Note that class Xvc is both a stream master & a stream slave (here a slave)
163
164 // Process reply when available
165 if (!queue_.empty() && (frame = queue_.pop()) != nullptr) {
166 log_->debug("Receiving new frame of size %", PRIi32, frame->getSize());
167
168 // Read received data into the hdbuf and rxb buffers
169 rogue::GilRelease noGil;
170 ris::FrameLockPtr frLock = frame->lock();
171 std::lock_guard<std::mutex> lock(mtx_);
172
173 // Populate header buffer
174 iter = frame->begin();
175 if (hdBuffer) std::copy(iter, iter + hdBytes, hdBuffer);
176
177 // Populate receiver buffer
178 if (rxBuffer) ris::fromFrame(iter += hdBytes, frame->getPayload() - hdBytes, rxBuffer);
179 }
180
181 return (0);
182}
183
184void rpx::Xvc::setup_python() {
185#ifndef NO_PYTHON
186
187 bp::class_<rpx::Xvc, rpx::XvcPtr, bp::bases<ris::Master, ris::Slave, rpx::JtagDriver>, boost::noncopyable>(
188 "Xvc",
189 bp::init<uint16_t>())
190 .def("_start", &rpx::Xvc::start)
191 .def("_stop", &rpx::Xvc::stop);
192 bp::implicitly_convertible<rpx::XvcPtr, ris::MasterPtr>();
193 bp::implicitly_convertible<rpx::XvcPtr, ris::SlavePtr>();
194 bp::implicitly_convertible<rpx::XvcPtr, rpx::JtagDriverPtr>();
195#endif
196}
RAII helper that releases the Python GIL for a scope.
Definition GilRelease.h:36
static std::shared_ptr< rogue::Logging > create(const std::string &name, bool quiet=false)
Creates a logger instance.
Definition Logging.cpp:60
void setThold(uint32_t thold)
Sets busy-threshold depth used by busy().
Definition Queue.h:84
Random-access byte iterator across a Frame payload.
Base transport driver for the AxisToJtag firmware protocol.
Definition JtagDriver.h:68
TCP listener for XVC client connections.
Definition XvcServer.h:37
virtual void run(bool &threadEn, rogue::LoggingPtr log)
Runs accept loop while thread enable flag is true.
Definition XvcServer.cpp:58
rogue::Queue< std::shared_ptr< rogue::interfaces::stream::Frame > > queue_
Definition Xvc.h:65
std::shared_ptr< rogue::Logging > log_
Definition Xvc.h:68
static void fromFrame(rogue::interfaces::stream::FrameIterator &iter, uint32_t size, void *dst)
Copies bytes from a frame iterator to a destination pointer.
std::shared_ptr< rogue::interfaces::stream::Frame > FramePtr
Shared pointer alias for Frame.
Definition Frame.h:549
static void toFrame(rogue::interfaces::stream::FrameIterator &iter, uint32_t size, void *src)
Copies bytes from a source pointer into a frame iterator.
std::shared_ptr< rogue::interfaces::stream::FrameLock > FrameLockPtr
Shared pointer alias for FrameLock.
Definition FrameLock.h:110
std::shared_ptr< rogue::protocols::xilinx::Xvc > XvcPtr
Definition Xvc.h:167