Beispiel #1
0
void
CPersStream::PersStream()
{
    if (PR_htValid) {
        switch (PR_htInst) {

        // Main entry point from Host (htmain call)
        // P_rcvData => 0 (init)
        case STRM_RECV:
        {
            if (RecvHostDataBusy()) {
                HtRetry();
                break;
            }

            // Receive data until we see a DataMarker from the host
            if (RecvHostDataMarker()) {
                HtContinue(STRM_RTN);
            } else {
                // Store received data into private variable recvData
                P_rcvData = RecvHostData();
                HtContinue(STRM_ECHO);
            }
        }
        break;

        case STRM_ECHO:
        {
            if (SendHostDataBusy()) {
                HtRetry();
                break;
            }

            // Echo data to back host
            SendHostData(PR_rcvData);
            HtContinue(STRM_RECV);
        }
        break;

        case STRM_RTN:
        {
            if (SendReturnBusy_htmain()) {
                HtRetry();
                break;
            }

            // Return number of bytes seen to the host
            SendReturn_htmain();
        }
        break;

        default:
            assert(0);
        }
    }
}
Beispiel #2
0
void CPersCtl::PersCtl() {
	if (PR_htValid) {
		switch (PR_htInst) {

		// Main Entry Point from Host -> CTL_ENTRY
		// Check if AU is unused (lastIdx == -1) and return if so
		// P_rcvAu is technically created here, but never used (is in for debug if needed)
		// Continue to CTL_RECV to listen for Host Data
		case CTL_ENTRY: {
			if (P_lastIdx == -1) {
				HtContinue(CTL_RTN);
			}

			HtContinue(CTL_RECV);
		}
		break;

		// Store Received Host Data into P_rcvIdx
		// Dispatch threads to process the received Index
		// Continue listening until P_rcvIdx == S_lastIdx, at which point
		//   wait for all threads to return before continuing to CTL_RTN
		case CTL_RECV: {
			if (RecvHostDataBusy() || SendCallBusy_process()) {
				HtRetry();
				break;
			}

			P_rcvIdx = (uint32_t)RecvHostData();

			if (P_rcvIdx != (uint32_t)P_lastIdx) {
				SendCallFork_process(CTL_SEND, P_rcvIdx);
				HtContinue(CTL_RECV);
			} else {
				SendCallFork_process(CTL_SEND, P_rcvIdx);
				RecvReturnPause_process(CTL_RTN);
			}

		}
		break;

		// Join spawned Process threads
		// The P_sndIdx and P_errRcv variables are passed in as these threads return,
		//   send that back to the Host to signal that index being completed
		// Accumulate errors from the returning thread
		// P_sndIdx should be the same as P_rcvIdx for that thread
		case CTL_SEND: {
			if (SendHostDataBusy()) {
				HtRetry();
				break;
			}

			P_errs += P_errRcv;
			SendHostData((uint64_t)P_sndIdx);
			RecvReturnJoin_process();
		}
		break;

		// Done with all work for this AU
		// Return to the Host with the number of total errors seen
		case CTL_RTN: {
			if (SendReturnBusy_htmain()) {
				HtRetry();
				break;
			}

			SendReturn_htmain(P_errs);
		}
		break;

		default:
			assert(0);

		}
	}
}
Beispiel #3
0
void
CPersStream::PersStream()
{
	if (PR_htValid) {
		switch (PR_htInst) {

		// Main entry point from Main.cpp
		// P_rcvAu, P_rcvCnt are populated through call.
		case STRM_IDLE:
		{
			if (SendReturnBusy_htmain()) {
				HtRetry();
				break;
			}

#ifndef _HTV
			printf("SysC:  AU %2d - Processing\n", P_rcvAu);
#endif

			if (P_rcvCnt) {
				HtContinue(STRM_RECV);
			} else {
				// There are no calls to receive...simply return
				SendReturn_htmain(0);
			}
		}
		break;

		case STRM_RECV:
		{
			if (RecvHostDataBusy()) {
				HtRetry();
				break;
			}

			// Store received data into pricate variable recvData
			P_recvData = RecvHostData();

			HtContinue(STRM_SEND);
		}
		break;

		case STRM_SEND:
		{
			if (SendHostDataBusy() || SendReturnBusy_htmain()) {
				HtRetry();
				break;
			}

			// Generate an expected value to compare against received data
			uint64_t expectedData = 0LL;
			expectedData |= (uint64_t)((uint64_t)P_rcvAu << 48);
			expectedData |= (uint64_t)(P_wordCnt + 1);

			if (expectedData != P_recvData) {
#ifndef _HTV
			  printf("SysC:  WARNING - Expected Data did not match Received data!\n");
			  printf("         0x%016llx != 0x%016llx\n",
				 (unsigned long long)expectedData, (unsigned long long)P_recvData);
#endif
				P_errs += 1;
			}
			HtAssert(!P_errs, 0);

			// Send generated data back to the host
			// More error checking will be done there
			SendHostData(expectedData);

			P_wordCnt += 1;

			// Check count so far..
			// Either return to Main.cpp or continue reading in values
			if (P_wordCnt == P_rcvCnt) {
				SendReturn_htmain(P_errs);
			} else {
				HtContinue(STRM_RECV);
			}
		}
		break;
		default:
			assert(0);
		}
	}
}
Beispiel #4
0
void
CPersEcho::PersEcho()
{
	if (PR_htValid) {
		switch (PR_htInst) {
		case ECHO_INIT:
		{
			if (ReadMemBusy()) {
				HtRetry();
				break;
			}

			// Set address for reading memory response data
			P_arrayMemRdPtr = 2;
			P_dataCnt = 0;

			sc_uint<MEM_ADDR_W> memRdAddr = (sc_uint<MEM_ADDR_W>)r_arrayAddr;

			// Issue read request to memory
			ReadMem_arrayMem(memRdAddr, 2);

			ReadMemPause(ECHO_DATA);
		}
		break;
		case ECHO_DATA:
		{
			if (ReadMemBusy() || SendReturnBusy_echo() || RecvHostDataBusy() || SendHostDataBusy()) {
				HtRetry();
				break;
			}

			// handle adding value to popped queue data and pushing to output queue

			if (RecvHostDataMarker()) {
				SendHostDataMarker();

				// Return to host interface
				SendReturn_echo(P_dataCnt);
			} else {
				uint64_t inData = PeekHostData();

				RecvHostData();

				uint64_t outData = inData + GR_arrayMem.data;

				SendHostData(outData);

				P_dataCnt += 1;

				// Calculate memory read address
				sc_uint<MEM_ADDR_W> memRdAddr = (sc_uint<MEM_ADDR_W>)(r_arrayAddr + (P_dataCnt << 3));

				// Issue read request to memory
				ReadMem_arrayMem(memRdAddr, 2);

				ReadMemPause(ECHO_DATA);
			}
		}
		break;
		default:
			assert(0);
		}
	}
}