void doFor() { int l1, l2; char name; match('f'); l1 = newLabel(); l2 = newLabel(); name = getName(); match('='); expression(); emit("DEC AX"); emit("MOV [%c], AX", name); expression(); emit("PUSH AX"); postLabel(l1); emit("MOV AX, [%c]", name); emit("INC AX"); emit("MOV [%c], AX", name); emit("POP BX"); emit("PUSH BX"); emit("CMP AX, BX"); emit("JG L%d", l2); block(l2); match('e'); emit("JMP L%d", l1); postLabel(l2); emit("POP AX"); }
/* analisa e traduz um comando LOOP*/ void doLoop() { int l1, l2; match('p'); l1 = newLabel(); l2 = newLabel(); postLabel(l1); block(l2); match('e'); emit("JMP L%d", l1); postLabel(l2); }
/* analisa e traduz um REPEAT-UNTIL*/ void doRepeat() { int l1, l2; match('r'); l1 = newLabel(); l2 = newLabel(); postLabel(l1); block(l2); match('u'); condition(); emit("JZ L%d", l1); postLabel(l2); }
/* analisa e traduz um comando WHILE */ void doWhile() { int l1, l2; match('w'); l1 = newLabel(); l2 = newLabel(); postLabel(l1); condition(); emit("JZ L%d", l2); block(l2); match('e'); emit("JMP L%d", l1); postLabel(l2); }
void work(void) { auto outputPort = this->output(0); //message production if (_enableMessages) { outputPort->postMessage(Pothos::Object()); } //buffer production if (_enableBuffers) { size_t bytes = outputPort->elements(); if (_bufferMTU != 0) bytes = std::min(bytes, _bufferMTU); outputPort->produce(bytes); //label production if (_enableLabels) { Pothos::Label label; label.index = 0; outputPort->postLabel(label); } } }
void work(void) { auto inputPort = this->input(0); auto outputPort = this->output(0); while (inputPort->hasMessage()) { auto m = inputPort->popMessage(); outputPort->postMessage(m); } const auto &buffer = inputPort->buffer(); if (buffer.length != 0) { outputPort->postBuffer(buffer); inputPort->consume(inputPort->elements()); for (size_t i = 0; i < inputPort->elements(); i++) { if (std::generate_canonical<double, 10>(_gen) <= _probability) { Pothos::Label label; label.index = i; label.width = buffer.dtype.size(); if (not _ids.empty()) label.id = _ids.at(_randomId(_gen)); outputPort->postLabel(label); } } } }
void propagateLabels(const Pothos::InputPort *port) { auto outPort = this->output(0); for (const auto &label : port->labels()) { outPort->postLabel(label.toAdjusted(1, _mod)); } }
/* analisa e traduz um comando DO*/ void doDo() { int l1, l2; match('d'); l1 = newLabel(); l2 = newLabel(); expression(); emit("MOV CX, AX"); postLabel(l1); emit("PUSH CX"); block(l2); emit("POP CX"); emit("LOOP L%d", l1); emit("PUSH CX"); postLabel(l2); emit("POP CX"); }
/* analisa e traduz um comando IF */ void doIf(int exitLabel) { int l1, l2; match('i'); condition(); l1 = newLabel(); l2 = l1; emit("JZ L%d", l1); block(exitLabel); if (look == 'l') { match('l'); l2 = newLabel(); emit("JMP L%d", l2); postLabel(l1); block(exitLabel); //passa o label para realizar o break } match('e'); postLabel(l2); }
void work(void) { auto inputPort = this->input(0); auto outputPort = this->output(0); //extract message if (not inputPort->hasMessage()) return; auto msg = inputPort->popMessage(); //forward non-packet messages if (msg.type() != typeid(Pothos::Packet)) { outputPort->postMessage(msg); return; } const auto &packet = msg.extract<Pothos::Packet>(); //post output labels for (auto label : packet.labels) { outputPort->postLabel(label.toAdjusted( packet.payload.dtype.size(), 1)); //elements to bytes } //post start of frame label if (not _frameStartId.empty()) { outputPort->postLabel(Pothos::Label(_frameStartId, Pothos::Object(), 0, packet.payload.dtype.size())); } //post end of frame label if (not _frameEndId.empty()) { outputPort->postLabel(Pothos::Label(_frameEndId, Pothos::Object(), packet.payload.length-1, packet.payload.dtype.size())); } //post the payload outputPort->postBuffer(packet.payload); }
void NetworkSource::work(void) { const auto timeout = Poco::Timespan(this->workInfo().maxTimeoutNs/1000); auto outputPort = this->output(0); //recv the header, use output buffer when possible for zero-copy Poco::UInt16 type; Poco::UInt64 index; auto buffer = outputPort->buffer(); _ep.recv(type, index, buffer, timeout); //handle the output if (type == PothosPacketTypeBuffer) { _nextExpectedIndex = index + buffer.length; outputPort->popBuffer(buffer.length); outputPort->postBuffer(buffer); } else if (type == PothosPacketTypeMessage) { std::istringstream iss(std::string(buffer.as<char *>(), buffer.length)); Pothos::Object msg; msg.deserialize(iss); outputPort->postMessage(msg); } else if (type == PothosPacketTypeLabel) { std::istringstream iss(std::string(buffer.as<char *>(), buffer.length)); Pothos::Label label; label.index = index + outputPort->totalElements() - _nextExpectedIndex; label.data.deserialize(iss); outputPort->postLabel(label); } else this->yield(); }
void DemoController::work(void) { auto inputPort = this->input(0); auto outputPort = this->output(0); //this block's work routine only reacts to input data if (inputPort->elements() == 0) return; bool sawRxEnd = false; //Handle the input labels, check for time, and end of burst. for (const auto &label : inputPort->labels()) { if (label.id == "rxTime") { //updating the time-stamped hardware time this->handleHardwareTime(label.data.convert<long long>()); //time tracking using the absolute element count _lastRxHardwareTimeNs = label.data.convert<long long>(); _rxTimeLabelIndex = inputPort->totalElements()+label.index; } else if (label.id == "rxRate") { _lastKnownRxRate = label.data.convert<double>(); poco_notice_f1(Poco::Logger::get("DemoController"), "RX rate is %s Msps", std::to_string(_lastKnownRxRate/1e6)); } else if (label.id == "rxEnd") { sawRxEnd = true; } } poco_notice_f2(Poco::Logger::get("DemoController"), "Got %s RX elements @ %s seconds", std::to_string(inputPort->elements()), std::to_string(this->getStreamElementTime(inputPort->totalElements())/1e9)); //The user should do something meaningful with the rx buffer... //const auto &rxBuff = inputPort->buffer(); //consume the entire receive buffer inputPort->consume(inputPort->elements()); //Use the rx end of burst event to trigger new actions: if (sawRxEnd) { //perform a timed tune 0.5 seconds from the end of this burst const auto commandIndex = inputPort->totalElements() + inputPort->elements() + size_t(_lastKnownRxRate/2); const auto commandTimeNs = this->getStreamElementTime(commandIndex); this->callVoid("setCommandTime", commandTimeNs); this->callVoid("setFrequency", 1e9); this->callVoid("setCommandTime", 0); //clear //request a timed burst 1.0 seconds from the end of this burst const auto streamIndex = inputPort->totalElements() + inputPort->elements() + size_t(_lastKnownRxRate); const auto burstTimeNs = this->getStreamElementTime(streamIndex); this->callVoid("streamControl", "ACTIVATE_BURST_AT", burstTimeNs, 100); /*************************************************************** * Transmit an output burst at the same time as the input burst: * The following code shows how to get access to the tx buffer, * and post labels for both transmit time and end of burst. **************************************************************/ //the user should fill tx buffer with something meaningful... const auto numElems = std::min<size_t>(outputPort->elements(), 100); auto &txBuff = outputPort->buffer(); std::memset(txBuff.as<void *>(), 0, numElems*outputPort->dtype().size()); //create a time label at the first index of the buffer outputPort->postLabel(Pothos::Label("txTime", burstTimeNs, 0)); //create an end label at the last index of the buffer outputPort->postLabel(Pothos::Label("txEnd", true, numElems-1)); //produce num elements of the transmit buffer outputPort->produce(numElems); //Alternative custom transmit buffer option: //allocate a buffer: Pothos::BufferChunk txBuff(outputPort->dtype, numElems); //fill the buffer and create labels as usual... //post the buffer: outputPort->postBuffer(txBuff); } }
void work(void) { auto inputPort = this->input(0); auto outputPort = this->output(0); size_t consumed = 0; //get input buffer auto inBuff = inputPort->buffer(); if (inBuff.length == 0) return; //label propagation offset incremented as preambles are posted size_t labelIndexOffset = 0; //track the index of the last found frame start label int lastFoundIndex = -1; for (auto &label : inputPort->labels()) { // Skip any label that doesn't yet appear in the data buffer if (label.index >= inputPort->elements()) continue; Pothos::Label outLabel(label); //modified and posted below //increment the offset as soon as we are past the last found index if (lastFoundIndex != -1 and size_t(lastFoundIndex) != label.index) { lastFoundIndex = -1; labelIndexOffset += _preambleBuff.elements(); } if (label.id == _frameStartId) { //post everything before this label Pothos::BufferChunk headBuff = inBuff; size_t headElems = label.index - consumed; headBuff.length = headElems*sizeof(Type); if (headBuff.length != 0) outputPort->postBuffer(headBuff); //fill the preamble buffer Pothos::BufferChunk newPreambleBuff(typeid(Type), _preambleBuff.elements()); std::memcpy(newPreambleBuff.as<void *>(), _preambleBuff.as<const void *>(), _preambleBuff.length); auto p = newPreambleBuff.as<Type *>() + _syncWordWidth; //encode the header field into bits char headerBits[NUM_HEADER_BITS]; FrameHeaderFields headerFields; headerFields.id = _headerId; headerFields.length = 0; if (label.data.canConvert(typeid(size_t))) { headerFields.length = label.data.template convert<size_t>()*label.width; } headerFields.chksum = headerFields.doChecksum(); encodeHeaderWord(headerBits, headerFields); //encode header fields as BPSK into the preamble buffer const auto sym = _preamble.back(); for (size_t i = 0; i < NUM_HEADER_BITS; i++) { *p++ = (headerBits[i] != 0)?+sym:-sym; } //post the preamble buffer outputPort->postBuffer(newPreambleBuff); //remove header from the remaining buffer inBuff.length -= headBuff.length; inBuff.address += headBuff.length; consumed += headBuff.elements(); //mark for increment on next label index lastFoundIndex = label.index; } else if (label.id == _frameEndId) { //post everything before this label Pothos::BufferChunk headBuff = inBuff; size_t headElems = label.index + label.width - consumed; //place at end of width headBuff.length = headElems*sizeof(Type); headBuff.length = std::min(headBuff.length, inBuff.length); //bounds check if (headBuff.length != 0) outputPort->postBuffer(headBuff); //post the buffer outputPort->postBuffer(_paddingBuff); //remove header from the remaining buffer inBuff.length -= headBuff.length; inBuff.address += headBuff.length; consumed += headBuff.elements(); //increment index for insertion of padding labelIndexOffset += _paddingBuff.elements(); } //propagate labels here with the offset outLabel.index += labelIndexOffset; outputPort->postLabel(outLabel); } //post the remaining bytes if (inBuff.length != 0) outputPort->postBuffer(inBuff); //consume the entire buffer inputPort->consume(inputPort->elements()); }