void c_main (void) { spin1_callback_on(SDP_PACKET_RX, hSDP, 0); spin1_schedule_callback(initiate, 0, 0, 1); spin1_start(SYNC_NOWAIT); }
/****f* main.c/c_main * * SUMMARY * This function is called at application start-up. The application programmer * must implement the function body to configure hardware, register callbacks, * and finally begin the simulation. * * SYNOPSIS * int c_main() * * SOURCE */ void c_main() { io_printf(IO_STD, "Hello, World!\nBooting application...\n"); // Set the number of chips in the simulation spin1_set_core_map(64, (uint *)(0x74220000)); // FIXME make the number of chips dynamic // Set timer tick (in microseconds) spin1_set_timer_tick(1000*1); // Configure simulation load_application_data(); load_mc_routing_tables(); configure_app_frame(); #ifdef STDP load_stdp_config_data(); alloc_stdp_post_TS_mem(); #endif // Register callbacks spin1_callback_on(DMA_TRANSFER_DONE, dma_callback, 0); spin1_callback_on(TIMER_TICK, timer_callback, 2); spin1_callback_on(SDP_PACKET_RX, sdp_packet_callback, 1); // Go! // scheduling a callback at t=0 to evaluate the first time step spin1_schedule_callback(timer_callback, 0, 0, 2); io_printf(IO_STD, "Application booted!\nStarting simulation...\n"); spin1_start(); }
void hTimer(uint tick, uint Unused) { if(tick==1) { io_printf(IO_STD, "Collecting all workers ID\n"); spin1_schedule_callback(pingWorkers, 0,0,PRIORITY_PROCESSING); } // after 3 ticks, all workers should have reported else if(tick==3) { io_printf(IO_STD, "Total workers: %d\n", workers.tAvailable); for(int i=0; i<workers.tAvailable; i++) { io_printf(IO_STD, "worker-%d is core-%d\n", i, workers.wID[i]); } } else if(tick==5) { io_printf(IO_STD, "Distributing workload...\n"); // send worker's block ID, except to leadAp uint check, key, payload; for(uint i=1; i<workers.tAvailable; i++) { key = workers.wID[i]; payload = workers.tAvailable << 16; payload += i; check = spin1_send_mc_packet(key, payload, WITH_PAYLOAD); if(check==SUCCESS) io_printf(IO_BUF, "Sending id-%d to core-%d\n", payload, key); else io_printf(IO_BUF, "Fail sending id-%d to core-%d\n", payload, key); } io_printf(IO_STD, "Ready for image...\n"); spin1_callback_off(TIMER_TICK); } }
void init_Handlers() { spin1_callback_on(SDP_PACKET_RX, hSDP, SCP_PRIORITY_VAL); spin1_callback_on(MCPL_PACKET_RECEIVED, hMCPL, MCPL_PRIORITY_VAL); spin1_set_timer_tick(TIMER_TICK_PERIOD_US); spin1_callback_on(TIMER_TICK, hTimer, TIMER_PRIORITY_VAL); spin1_callback_on(USER_EVENT, collectData, SCHEDULED_PRIORITY_VAL); init_sdp_container(); //initIPTag(); --> replaced with initiateIPTagReading() spin1_schedule_callback(initiateIPTagReading, 0, 0, 1); }
/****f* simple.c/count_packets * * SUMMARY * This function is used as a callback for packet received events. * It counts the number of received packets and triggers dma transfers. * * SYNOPSIS * void count_packets (uint key, uint payload) * * INPUTS * uint key: packet routing key - provided by the RTS * uint payload: packet payload - provided by the RTS * * SOURCE */ void count_packets (uint key, uint payload) { /* count packets */ packets++; /* if testing DMA trigger transfer requests at the right time */ if (test_DMA) { /* schedule task (with priority 1) to trigger DMA */ spin1_schedule_callback(do_transfer, payload, 0, 1); } }
/* // Let's use: // port-7 for receiving configuration and command: // cmd_rc == SDP_CMD_CONFIG --> // arg1.high == img_width, arg1.low == img_height // arg2.high : 0==gray, 1==colour(rgb) // seq.high == isGray: 1==gray, 0==colour(rgb) // seq.low == type_of_operation: // 1 = sobel_no_filtering // 2 = sobel_with_filtering // 3 = laplace_no_filtering // 4 = laplace_with_filtering // cmd_rc == SDP_CMD_PROCESS // cmd_rc == SDP_CMD_CLEAR If leadAp detects filtering, first it ask workers to do filtering only. Then each worker will start filtering. Once finished, each worker will report to leadAp about this filtering. Once leadAp received filtering report from all workers, leadAp trigger the edge detection */ void hSDP(uint mBox, uint port) { sdp_msg_t *msg = (sdp_msg_t *)mBox; // if host send SDP_CONFIG, means the image has been // loaded into sdram via ybug operation if(port==SDP_PORT_CONFIG) { if(msg->cmd_rc == SDP_CMD_CONFIG) { blkInfo.isGrey = msg->seq >> 8; //1=Gray, 0=color blkInfo.wImg = msg->arg1 >> 16; blkInfo.hImg = msg->arg1 & 0xFFFF; blkInfo.nodeBlockID = msg->arg2 >> 16; blkInfo.maxBlock = msg->arg2 & 0xFF; switch(msg->seq & 0xFF) { case IMG_OP_SOBEL_NO_FILT: blkInfo.opFilter = IMG_NO_FILTERING; blkInfo.opType = IMG_SOBEL; break; case IMG_OP_SOBEL_WITH_FILT: blkInfo.opFilter = IMG_WITH_FILTERING; blkInfo.opType = IMG_SOBEL; break; case IMG_OP_LAP_NO_FILT: blkInfo.opFilter = IMG_NO_FILTERING; blkInfo.opType = IMG_LAPLACE; break; case IMG_OP_LAP_WITH_FILT: blkInfo.opFilter = IMG_WITH_FILTERING; blkInfo.opType = IMG_LAPLACE; break; } imageInfoRetrieved = 1; // and then distribute to all workers spin1_schedule_callback(infoSzImgWorkers, 0, 0, PRIORITY_PROCESSING); spin1_schedule_callback(infoBlkImgWorkers, 0, 0, PRIORITY_PROCESSING); // after receiving block info, workers will compute their working region // for leadAp, it should be implicitely instructed here: spin1_schedule_callback(computeMyRegion, 0, 0, PRIORITY_PROCESSING); } else if(msg->cmd_rc == SDP_CMD_PROCESS) {
void hSDP(uint mBox, uint port) { sdp_msg_t *msg = (sdp_msg_t *)mBox; if(port==7) spin1_schedule_callback(terminate, 0, 0, 1); else { pktCntr++; ushort tmpSrcA = msg->srce_addr; uchar tmpSrcP = msg->srce_port; msg->tag = 1; msg->srce_addr = msg->dest_addr; msg->srce_port = msg->dest_port; msg->dest_addr = tmpSrcA; msg->dest_port = tmpSrcP; spin1_send_sdp_msg(msg, 10); } spin1_msg_free(msg); }
// ------------------------------------------------------------------------ // process received packets (stop, FORWARD and BACKPROP types) // ------------------------------------------------------------------------ void s_receivePacket (uint key, uint payload) { // check if stop packet if ((key & SPINN_TYPE_MASK) == SPINN_STOP_KEY) { // stop packet received #ifdef DEBUG stp_recv++; #endif // STOP decision arrived tick_stop = key & SPINN_STPD_MASK; #ifdef DEBUG_VRB io_printf (IO_BUF, "sc:%x\n", tick_stop); #endif // check if all threads done if (sf_thrds_done == 0) { // if done initialise semaphore sf_thrds_done = 1; // and advance tick spin1_schedule_callback (sf_advance_tick, NULL, NULL, SPINN_S_TICK_P); } else { // if not done report processing thread done sf_thrds_done -= 1; } } // check if network stop packet else if ((key & SPINN_TYPE_MASK) == SPINN_STPN_KEY) { // network stop packet received #ifdef DEBUG stn_recv++; #endif //done spin1_exit (SPINN_NO_ERROR); return; } else { #ifdef DEBUG pkt_recv++; #endif // check if space in packet queue, uint new_tail = (s_pkt_queue.tail + 1) % SPINN_SUM_PQ_LEN; if (new_tail == s_pkt_queue.head) { // if queue full exit and report failure spin1_exit (SPINN_QUEUE_FULL); } else { // if not full queue packet, s_pkt_queue.queue[s_pkt_queue.tail].key = key; s_pkt_queue.queue[s_pkt_queue.tail].payload = payload; s_pkt_queue.tail = new_tail; // and schedule processing thread -- if not active already if (!s_active) { s_active = TRUE; spin1_schedule_callback (s_process, NULL, NULL, SPINN_S_PROCESS_P); } } } }