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);
}
예제 #5
0
    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);
            }
        }
    }
예제 #6
0
    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);
                }
            }
        }
    }
예제 #7
0
 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);
}
예제 #10
0
    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);
    }
예제 #11
0
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();
}
예제 #12
0
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);
    }
}
예제 #13
0
    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());
    }