Example #1
0
void func_worker_1(void* arg) {
    // Cast and load the parameter
    int worker_1_param = *((int*)arg);
    // Create the queuing ports
    spd_t * chan = mp_create_sport(MP_CHAN_1_ID, SOURCE, MP_CHAN_1_MSG_SIZE);
    if (chan == NULL) {
        DEBUGF(chan);
        abort();
    }
    volatile unsigned long long _SPM * time_sample = mp_alloc(MP_CHAN_1_MSG_SIZE);
    // Initialize the communication channels
    int retval = mp_init_ports();
    // TODO: check on retval

    slave= 1;

    for (unsigned long long start = get_cpu_usecs(); start + RUNTIME > get_cpu_usecs(); ) {
        *time_sample = get_cpu_usecs();
        mp_write(chan,time_sample);
    }

    int ret = 0;
    corethread_exit(&ret);
    return;
}
Example #2
0
void func_worker_1(void* arg) {
  mp_init();
  
  spd_t * sport2 = mp_create_sport(CHAN_ID_TWO,SINK,SAMPLE_SIZE*sizeof(short));
  spd_t * sport1 = mp_create_sport(CHAN_ID_ONE,SOURCE,SAMPLE_SIZE*sizeof(short));
  if (sport1 == NULL || sport2 == NULL) {
    //exit(1);
  }
  volatile short _SPM * sample = mp_alloc(SAMPLE_SIZE*sizeof(short));

  for (int i = 0; i < SAMPLE_SIZE; ++i) {
    sample[i] = i;
  }

  mp_init_ports();


  while(done == 0);

  for (int i = 0; i < ITERATIONS; ++i) {
      int ret = mp_read(sport2,sample);
      for (int i = 0; i < SAMPLE_SIZE; ++i) {
        if(sample[i] != i) {
          break;
        }
      }
      for (int i = 0; i < 100000; ++i)
      {
        asm volatile (""::);
      }
  }

  //for (int i = 0; i < ITERATIONS/2; ++i) {
  for (int i = 0; i < ITERATIONS*20; ++i) {
    mp_write(sport1,sample);
    for (int i = 0; i < SAMPLE_SIZE; ++i) {
      sample[i] = i;
    }
    //for (int i = 0; i < 100000; ++i) {
    //  asm volatile (""::);
    //}
    mp_write(sport1,sample);
    for (int i = 0; i < SAMPLE_SIZE; ++i) {
      sample[SAMPLE_SIZE-1-i] = i;
    }
    //for (int i = 0; i < 100000; ++i) {
    //  asm volatile (""::);
    //}
  }

  
  
  int ret = 0;
  corethread_exit(&ret);
  return;
}
Example #3
0
// The main function for the other thread on the another core
void work(void* arg) {

  // Measure execution time with the clock cycle timer
  volatile _IODEV int *timer_ptr = (volatile _IODEV int *) (PATMOS_IO_TIMER+4);

  int val, data;

  qpd_t *channel = mp_create_qport(1, SINK, BUF_SIZE, NUM_BUF);
  mp_init_ports();
  for (;;) {
    mp_recv(channel, 0);
    val = *timer_ptr;
    data = *(volatile int _SPM *) channel->read_buf;
    mp_ack(channel, 0);

    // Return time stamp and the change value in the shared variable
    end_time = val;
    field = data + 1;
  }
}
Example #4
0
//Producer Core
void producer(void *arg) {

  #ifdef MEASUREMENT_MODE
  // start initialization measurement
    timeStamps_slave1[0] = TDM_P_COUNTER;//3955 cycles
  #endif

  int id = get_cpuid();

  // Data initialization
  int volatile data_wr[MSG_SIZE];

  ///////////////////////////////////////////////////////////////////////////////
  // This section of the task handles with the initializations for buffering
  ///////////////////////////////////////////////////////////////////////////////

  // allocating the data into SPM
  qpd_t * chan1 = mp_create_qport(1, SOURCE, MP_CHAN_BUF_SIZE, MP_CHAN_NUM_BUF);
  mp_init_ports(); 

  //remote address calculation at the receiver side
  int rmt_addr_offset = (chan1->buf_size + FLAG_SIZE) * chan1->send_ptr;
  volatile void _SPM *calc_rmt_addr = &chan1->recv_addr[rmt_addr_offset];

  
  
  #ifdef MEASUREMENT_MODE
    timeStamps_slave1[1] = TDM_P_COUNTER; // stop the initialization measurement at 4888 cycles
  #endif


  for(;;){

    ///////////////////////////////////////////////////////////////////////////////
    // Computation part of the Task. Data production
    ///////////////////////////////////////////////////////////////////////////////
    
    if((TDM_P_COUNTER-TRIGGER_PROD_COMP)%PROD_PERIOD == 0 ){

        // Data production. at the moment we use dummy data
         for (int i=0;i<MSG_SIZE;i++){
          data_wr[i]=i;
        }

        // writing the data to the write buffer
        for (int i=0;i<MSG_SIZE;i++){
          *(volatile int _SPM*)((int*)chan1->write_buf+i) = data_wr[i];
        }
    } 

    ///////////////////////////////////////////////////////////////////////////////
    // Communication part of the Task. 
    ///////////////////////////////////////////////////////////////////////////////
    
      // when the communication time is triggered
      if(((TDM_P_COUNTER-TRIGGER_PROD_COMM)%PROD_PERIOD) == 0 ){
          
          #ifdef MEASUREMENT_MODE
            timeStamps_slave1[2] = TDM_P_COUNTER; //start the communication measurement
          #endif

          //nonblocking write transaction
          noc_nbwrite( (id+1),calc_rmt_addr,chan1->write_buf,chan1->buf_size + FLAG_SIZE, 0);

          #ifdef MEASUREMENT_MODE
            timeStamps_slave1[3] = TDM_P_COUNTER; //stop the communication measurement
          #endif

      }// if

   }//for

}
Example #5
0
// Consumer Core
void consumer(void *arg) {

  #ifdef MEASUREMENT_MODE
  // start initialization measurement
  timeStamps_slave2[0] = TDM_P_COUNTER; 
  #endif
  
  int id = get_cpuid();
  int cnt = get_cpucnt();

  int volatile data_rd[MSG_SIZE];

  ///////////////////////////////////////////////////////////////////////////////
  // This section of the task handles with the initializations for buffering
  ///////////////////////////////////////////////////////////////////////////////
  // allocating data to SPM
  qpd_t * chan2 = mp_create_qport(2, SINK, MP_CHAN_BUF_SIZE, MP_CHAN_NUM_BUF);
  mp_init_ports(); // mp init ports


  #ifdef MEASUREMENT_MODE
  timeStamps_slave2[1] = TDM_P_COUNTER; // stop the initialization measurement
  #endif

  for(;;){

    ///////////////////////////////////////////////////////////////////////////////
    // Communication part of the Task. 
    ///////////////////////////////////////////////////////////////////////////////
      // when the time is triggered
      if((TDM_P_COUNTER-TRIGGER_CONS_COMM)%CONS_PERIOD == 0 ){

          #ifdef MEASUREMENT_MODE
          timeStamps_slave2[2] = TDM_P_COUNTER;// start the communication measurement
            #endif

          // reading the data to the read buffer
          for (int i=0;i<MSG_SIZE;i++){

             data_rd[i] = *(volatile int _SPM*)((int*)chan2->read_buf+i); // read the data
          }

          #ifdef MEASUREMENT_MODE
          timeStamps_slave2[3] = TDM_P_COUNTER; //stop the communication measurement
          #endif
      }

    ///////////////////////////////////////////////////////////////////////////////
    // Computation part of the Task. Perhaps for an Actuator
    ///////////////////////////////////////////////////////////////////////////////

      if(((TDM_P_COUNTER-TRIGGER_CONS_COMP)%CONS_PERIOD) == 0 ){

          // make data manipulation (but for now dummy) over the data
          for(int i=0;i<MSG_SIZE;i++){
                data_rd[i] += 100;
          }


       }//if
    
    ///////////////////////////////////////////////////////////////////////////////
    //Print the received data for debuging
    ///////////////////////////////////////////////////////////////////////////////
      #define DEBUG_PRINT_CONS
      #ifdef DEBUG_PRINT_CONS

          for(int i=0;i<MSG_SIZE;i++){
              debug_print_cons[i] = data_rd[i];

          }
      #endif

  }//for
     

}
Example #6
0
// Intermediate Core
void intermediate(void *arg) {

  #ifdef MEASUREMENT
  // start initialization measurement
  timeStamps_slave2[0] = TDM_P_COUNTER;	
  #endif
  
  int id = get_cpuid();

  // Data initialization
  int volatile data[MSG_SIZE];

  ///////////////////////////////////////////////////////////////////////////////
  // This section of the task handles with the initializations for buffering
  ///////////////////////////////////////////////////////////////////////////////
  // allocating the data into SPM buffers
  qpd_t * chan1 = mp_create_qport(1, SINK, MP_CHAN_BUF_SIZE, MP_CHAN_NUM_BUF);
  qpd_t * chan2 = mp_create_qport(2, SOURCE, MP_CHAN_BUF_SIZE, MP_CHAN_NUM_BUF);
  mp_init_ports(); // mp init ports

  //remote address calculation
  int rmt_addr_offset = (chan2->buf_size + FLAG_SIZE) * chan2->send_ptr;
  volatile void _SPM *calc_rmt_addr = &chan2->recv_addr[rmt_addr_offset];


  #ifdef MEASUREMENT
  timeStamps_slave2[1] = TDM_P_COUNTER; // stop the initialization measurement
  #endif

  for(;;){

    ///////////////////////////////////////////////////////////////////////////////
    // Communication part of the Task. 
    ///////////////////////////////////////////////////////////////////////////////  
    // when the time is triggered read from read-buffer
	  if((TDM_P_COUNTER-TRIGGER_INTM_COMM_READ)%PROD_PERIOD == 0 ){

    	  	#ifdef MEASUREMENT
    	  	timeStamps_slave2[2] = TDM_P_COUNTER;// start the communication measurement
          #endif

    		  // reading the data from the read-buffer
    	  	for (int i=0;i<MSG_SIZE;i++){

    	  	   data[i] = *(volatile int _SPM*)((int*)chan1->read_buf+i); 
    	  	}

    	  	#ifdef MEASUREMENT
    	    timeStamps_slave2[3] = TDM_P_COUNTER; //stop the communication measurement
    	  	#endif

	  }

    ///////////////////////////////////////////////////////////////////////////////
    // Computation part of the Task. Data manipulation
    ///////////////////////////////////////////////////////////////////////////////

    if((TDM_P_COUNTER-TRIGGER_INTM_COMP)%PROD_PERIOD == 0 ){
          // make data manipulation (but for now dummy) over the data
          for(int i=0;i<MSG_SIZE;i++){
                data[i] += 10;
          }

         // writing the data to the write-buffer
         for (int i=0;i<MSG_SIZE;i++){
            *(volatile int _SPM*)((int*)chan2->write_buf+i) = data[i];
          } 
    }

    ///////////////////////////////////////////////////////////////////////////////
    // Communication part of the Task. 
    ///////////////////////////////////////////////////////////////////////////////
    // when the time is triggered write to write-buffer
    if((TDM_P_COUNTER-TRIGGER_INTM_COMM_WRITE)%PROD_PERIOD == 0 ){
        
          #ifdef MEASUREMENT
            timeStamps_slave2[4] = TDM_P_COUNTER; //start the communication measurement
          #endif
          //nonblocking write transaction
          noc_nbwrite( (id+1),calc_rmt_addr,chan2->write_buf,chan2->buf_size + FLAG_SIZE, 0);

          #ifdef MEASUREMENT
          timeStamps_slave2[5] = TDM_P_COUNTER; //stop the communication measurement
          #endif

    }// if

    
    ///////////////////////////////////////////////////////////////////////////////
    //Print the received data for debuging
    ///////////////////////////////////////////////////////////////////////////////
    #define DEBUG_PRINT_INTERM
    #ifdef DEBUG_PRINT_INTERM

      for(int i=0;i<MSG_SIZE;i++){
        debug_print_interm[i] = data[i];
      }
    #endif

	}//for

}
Example #7
0
int main() {

    puts("Master");
    corethread_t worker_1 = 1; // For now the core ID
    int worker_1_param = 1;

    corethread_create(&worker_1,&func_worker_1,(void*)&worker_1_param);

    // Create the queuing ports
    spd_t * chan = mp_create_sport(MP_CHAN_1_ID, SINK, MP_CHAN_1_MSG_SIZE);

    volatile unsigned long long _SPM * time_sample = mp_alloc(MP_CHAN_1_MSG_SIZE);

    if (chan == NULL || time_sample == NULL) {
        DEBUGF(chan);
        abort();
    }

    // Initialize the communication channels
    int retval = mp_init_ports();
    // TODO: check on retval

    puts("Initialized ports");

    while(slave != 1) {
        ;
    }

    puts("Slave is ready");

    unsigned long long min_time_diff = -1;
    unsigned long long max_time_diff = 0;
    unsigned long long accum_time_diff = 0;
    unsigned long long cnt_time_diff = 0;
    unsigned long long percent = 0;
    int done = 0;
    unsigned long long start = get_cpu_usecs();
    while(!done) {
        int success = mp_read(chan,time_sample);
        unsigned long long time_diff = get_cpu_usecs() - (*time_sample);
        if (success == 0) {
            printf("No sample received\n");
        } else if ((*time_sample) == 0) {
            printf("Received empty sample, newest: %u, sample size: %u\n",chan->newest,chan->sample_size);
        } else {
            if (time_diff > 2000 ) {
                // Time difference is larger than a micro second
                printf("Time sample: %llu\tdiff: %llu\n",*time_sample,time_diff);
            }
            cnt_time_diff++;
            if (time_diff < min_time_diff) {
                min_time_diff = time_diff;
            }
            if (time_diff > max_time_diff) {
                max_time_diff = time_diff;
            }
            accum_time_diff += time_diff;
        }

        if (start + percent < get_cpu_usecs()) {
            percent += RUNTIME/10;
            printf("+");
            fflush(stdout);
        }
        if ( start + RUNTIME < get_cpu_usecs())  {
            done = 1;
        }
    }
    printf("\n");

    printf("Status:\n\tMin time diff: %llu\n\tMax time diff: %llu\n\tAvg time diff: %llu\n", min_time_diff,max_time_diff,accum_time_diff/cnt_time_diff);

    int* res;
    corethread_join(worker_1,&res);

    return *res;
}
Example #8
0
int main() {
  
  corethread_t worker_1 = SLAVE_CORE; // For now the core ID
     
  corethread_create(&worker_1,&func_worker_1,(void*)&worker_1);
  puts("Corethread created");

  unsigned short int local_phase = 0;
  min_time = ULONG_MAX;
  max_time = 0;
  accum_time = 0;
  cnt_time = 0;

  unsigned long long int start = 0;
  unsigned long long int stop = 0;

  spd_t * sport1 = mp_create_sport(CHAN_ID_ONE,SINK,SAMPLE_SIZE*sizeof(short));
  spd_t * sport2 = mp_create_sport(CHAN_ID_TWO,SOURCE,SAMPLE_SIZE*sizeof(short));
  if (sport1 == NULL || sport2 == NULL) {
    //exit(1);
  }
  volatile short _SPM * sample = mp_alloc(SAMPLE_SIZE*sizeof(short));

  mp_init_ports();

  done = 1;

  int balance = 0;
  for (int i = 0; i < SAMPLE_SIZE; ++i) {
    sample[i] = i;
  }
  for (int i = 0; i < ITERATIONS/2; ++i) {
    mp_write(sport2,sample);
    for (int i = 0; i < SAMPLE_SIZE; ++i) {
      sample[i] = i;
    }
  }

  for (int i = 0; i < ITERATIONS/2; ++i) {
    mp_write(sport2,sample);
    for (int i = 0; i < SAMPLE_SIZE; ++i) {
      sample[SAMPLE_SIZE-1-i] = i;
    }
  }



  for (int i = 0; i < ITERATIONS; ++i) {
    start = get_cpu_usecs();
    int ret = mp_read(sport1,sample);
    stop = get_cpu_usecs();
    if (ret == 0)
    {
      puts("No value written yet.");
    } else {
      unsigned long long int exe_time = stop - start;
      min_time = (exe_time < min_time) ? exe_time : min_time;
      max_time = (exe_time > max_time) ? exe_time : max_time;
      accum_time += exe_time;
      cnt_time++;
      if (sample[0] == 0) {
        balance++;
        for (int i = 0; i < SAMPLE_SIZE; ++i) {
          if(sample[i] != i) {
            printf("Error: sample[%i] = %i\n",i,sample[i]);
            break;
          }
        }
      } else if (sample[0] == SAMPLE_SIZE-1) {
        balance--;
        for (int i = 0; i < SAMPLE_SIZE; ++i) {
          if(sample[SAMPLE_SIZE-1-i] != i) {
            printf("Error: sample[%i] = %i\n",i,sample[i]);
            break;
          }
        }
      } else {
        printf("Wrong sample values sample[0] = %i\n",sample[0]);
      }
    }
  }

  printf("Local phase: %d\n",local_phase);
  
  inval_dcache();

  int* res;
  corethread_join(worker_1,&res);

  printf("Balance: %i\n",balance);
  printf("Min time: %llu\tMax time: %llu\tAccumulated time: %llu\nCount time: %llu\tAverage time: %llu\n", min_time,max_time,accum_time,cnt_time,accum_time/cnt_time);

  puts("Corethread joined");

  return *res;  
}
Example #9
0
void bench_noc() {

  // Pointer to the deadline device
  volatile _IODEV int *dead_ptr = (volatile _IODEV int *) PATMOS_IO_DEADLINE;
  // Measure execution time with the clock cycle timer
  volatile _IODEV int *timer_ptr = (volatile _IODEV int *) (PATMOS_IO_TIMER+4);


  printf("Hello NoC\n");
  printf("We use %d bytes buffers\n", BUF_SIZE);
  int core_id = 1; // The core number
  corethread_create(core_id, &work, NULL); 

  int start, val;

  int data = 42;
  // create a channel
  qpd_t *channel = mp_create_qport(1, SOURCE, BUF_SIZE, NUM_BUF);
  // init
  mp_init_ports();
  start = *timer_ptr;
  // write data into the send buffer
  *(volatile int _SPM *) channel->write_buf = data;
  start = *timer_ptr;
  // send the buffer
  mp_send(channel, 0);
  printf("Data sent\n");
  printf("Returned data is: %d\n", field);
  printf("Took %d cycles\n", end_time - start - 1);

  int min = 999999;
  int max = 0;

  printf("NoC in a loop:\n");
  for (int i=0; i<CNT; ++i) {
    start = *timer_ptr;
    *(volatile int _SPM *) channel->write_buf = i;
    start = *timer_ptr;
    mp_send(channel, 0);
    *dead_ptr = 10000; // some delay to see the result
    val = *dead_ptr;
    val = end_time - start - 1;
//    printf("%d ", val);
    if (min>val) min = val;
    if (max<val) max = val;
  }
  printf("\n");
  printf("Min: %d max: %d\n", min, max);

  min = 999999;
  max = 0;
  do_delay_times();

  printf("NoC in a loop with random delay:\n");
  for (int i=0; i<CNT; ++i) {
    start = *timer_ptr;
    *(volatile int _SPM *) channel->write_buf = i;
    *dead_ptr = data_spm[i];
    val = *dead_ptr; // delay by a random value
    start = *timer_ptr;
    mp_send(channel, 0);
    *dead_ptr = 3000; // some delay to see the result
    val = *dead_ptr;
    val = end_time - start;
    // printf("%d ", val);
    if (min>val) min = val;
    if (max<val) max = val;
  }
  printf("\n");
  printf("Min: %d max: %d\n", min, max);

  // not really as the worker runs forever
  int* res;
  corethread_join( core_id, (void *) &res );
}