address_t system_load_sram() { // Get pointer to 1st virtual processor info struct in SRAM vcpu_t *sark_virtual_processor_info = (vcpu_t*)SV_VCPU; log_info("%08x", &sark_virtual_processor_info[spin1_get_core_id()].user0); // Get the address this core's DTCM data starts at from the user data member of the structure associated with this virtual processor address_t address = (address_t)sark_virtual_processor_info[spin1_get_core_id()].user0; simulation_ticks = sark_virtual_processor_info[spin1_get_core_id()].user1; log_info("SDRAM data begins at address:%08x Simulation should run for:%d ticks", address, simulation_ticks); return address; }
void c_main (void) { uint coreID = spin1_get_core_id(); uint chipID = spin1_get_chip_id(); if(chipID == 0 && coreID == 1) { io_printf (IO_STD, "Hello world! (via SDP)\n"); io_printf (IO_BUF, "Hello world! (via the terminal)\n"); if(spin_devin_init() == 0) { io_printf(IO_BUF, "Error: could not connect to the SpiNNaker!\n"); } spin_devin_send_motor(2000 << 16 | 2000); uint cam = spin_devin_get_camera(); io_printf(IO_BUF, "camera: %08x\n", cam); spin1_set_timer_tick(10000); spin1_callback_on(TIMER_TICK, upd, 0); spin_devin_dispose(); } spin1_start(); }
/****f* simple.c/c_main * * SUMMARY * This function is called at application start-up. * It is used to register event callbacks and begin the simulation. * * SYNOPSIS * int c_main() * * SOURCE */ void c_main() { io_printf (IO_STD, ">> simple\n"); /* get this core's IDs */ coreID = spin1_get_core_id(); chipID = spin1_get_chip_id(); /* TODO: Works on 4-chip board only! */ /* set the core map for the simulation */ if (NUMBER_OF_CHIPS > 0) core_map[0] = CORE_MAP_00; if (NUMBER_OF_CHIPS > 1) core_map[1] = CORE_MAP_01; if (NUMBER_OF_CHIPS > 2) core_map[2] = CORE_MAP_10; if (NUMBER_OF_CHIPS > 3) core_map[3] = CORE_MAP_11; spin1_set_core_map(NUMBER_OF_CHIPS, core_map); /* set timer tick value (in microseconds) */ spin1_set_timer_tick(TIMER_TICK_PERIOD); /* register callbacks */ spin1_callback_on(MC_PACKET_RECEIVED, count_packets, -1); spin1_callback_on(DMA_TRANSFER_DONE, check_memcopy, 0); spin1_callback_on(USER_EVENT, send_packets, 2); spin1_callback_on(TIMER_TICK, flip_led, 3); /* initialize application */ app_init(); /* go */ spin1_start(); /* report results */ app_done(); }
/** * A function which will load the configuration (for this core only) from the * shared SDRAM into the core-local variables above. * * Note that this is currently implemented the slow way using memcpy rather than * DMA to simplify programing as the penalty for the one-off copy is not too * significant. */ void load_config(void) { // Load the core-map for this core uint *core_map_root = CORE_MAP_SDRAM_ADDR; system_width = core_map_root[0]; system_height = core_map_root[1]; spin1_memcpy(core_map, &(core_map_root[2]), sizeof(uint)*system_width*system_height); // Load the config_root for this core config_root_t *config_root_sdram_addr = CONFIG_ROOT_SDRAM_ADDR(spin1_get_core_id()); spin1_memcpy(&config_root, config_root_sdram_addr, sizeof(config_root_t)); // Seed the random number generator spin1_srand(config_root.seed); // Calculate the address of the source & sink arrays and copy them across. config_source_t *config_sources_sdram_addr = (config_source_t *)( ((uint)config_root_sdram_addr) + sizeof(config_root_t) ); config_sink_t *config_sinks_sdram_addr = (config_sink_t *)( ((uint)config_root_sdram_addr) + sizeof(config_root_t) + sizeof(config_source_t) * config_root.num_sources ); config_router_entry_t *config_router_entries_sdram_addr = (config_router_entry_t *)( ((uint)config_root_sdram_addr) + sizeof(config_root_t) + sizeof(config_source_t) * config_root.num_sources + sizeof(config_sink_t) * config_root.num_sinks ); spin1_memcpy( &config_sources , config_sources_sdram_addr , sizeof(config_source_t) * config_root.num_sources ); spin1_memcpy( &config_sinks , config_sinks_sdram_addr , sizeof(config_sink_t) * config_root.num_sinks ); spin1_memcpy( &config_router_entries , config_router_entries_sdram_addr , sizeof(config_router_entry_t) * config_root.num_router_entries ); io_printf( IO_BUF, "Loaded root config from 0x%08x with %d sources, %d sinks and %d router entries and %d/%d warmup/experiment cycles.\n" , (uint)config_root_sdram_addr , config_root.num_sources , config_root.num_sinks , config_root.num_router_entries , config_root.warmup_duration , config_root.duration ); }
/** * A function which will store a copy of the results in SDRAM, overwriting the * original configuration. * * Note that this is currently implemented the slow way using memcpy rather than * DMA to simplify programing as the penalty for the one-off copy is not too * significant. */ void store_results(void) { // Turn on LED until results written if (leadAp) spin1_led_control(LED_ON(BLINK_LED)); // Copy source results back. config_source_t *config_sources_sdram_addr = (config_source_t *)( ((uint)CONFIG_ROOT_SDRAM_ADDR(spin1_get_core_id())) + sizeof(config_root_t) ) ; spin1_memcpy( config_sources_sdram_addr , &config_sources , sizeof(config_source_t) * config_root.num_sources ); // Copy sink results back. config_sink_t *config_sinks_sdram_addr = (config_sink_t *)( ((uint)CONFIG_ROOT_SDRAM_ADDR(spin1_get_core_id())) + sizeof(config_root_t) + sizeof(config_source_t) * config_root.num_sources ) ; spin1_memcpy( config_sinks_sdram_addr , &config_sinks , sizeof(config_sink_t) * config_root.num_sinks ); // Record router counters config_root.result_forwarded_packets = rtr_unbuf[FWD_CNTR_CNT]; config_root.result_dropped_packets = rtr_unbuf[DRP_CNTR_CNT]; // Copy root config results back last so that the completion_state is only // updated when most of the data is coppied back. config_root_t *config_root_sdram_addr = CONFIG_ROOT_SDRAM_ADDR(spin1_get_core_id()); spin1_memcpy(config_root_sdram_addr, &config_root, sizeof(config_root_t)); // Note that routes are not copied back because they aren't changed. io_printf( IO_BUF, "Stored results back into 0x%08x.\n" , (uint)config_root_sdram_addr ); // Turn off LED on completion. if (leadAp) spin1_led_control(LED_OFF(BLINK_LED)); }
void timer_callback(uint key, uint payload) { chipID = spin1_get_chip_id(); coreID = spin1_get_core_id(); uint newID; uint newKey; if (nIterations == 1 && chipID == 0 && coreID == 1) { io_printf(IO_STD, "Switching to Spomnibot project\n"); spin1_send_mc_packet(0x111007F1, 2, 1); } if (nIterations == 2 && chipID == 0 && coreID == 1) { spin1_send_mc_packet(0x111002b7, 0, 1); io_printf(IO_STD, "Beep!\n"); } if (nIterations == 10 && chipID == 0 && coreID == 1) { spin1_send_mc_packet(0x111002c3, 10, 1); // 10Hz io_printf(IO_STD, "Setting up sensor streaming\n"); spin1_send_mc_packet(0x111002c2, 1<<4|1 , 1); // bump + compass } if (nIterations == 50 && chipID == 0 && coreID == 1) { spin1_send_mc_packet(0x111002a0, 0x30, 1); //driving forward io_printf(IO_STD, "driving forward\n"); } if (nIterations == 200 && chipID == 0 && coreID == 1) { spin1_send_mc_packet(0x111002a7, 0x00, 1); //stop all io_printf(IO_STD, "stopping now\n"); } if (chipID == 0 && coreID == 1) { io_printf(IO_STD, "iteration %d\n", nIterations); nIterations++; } //updateNeurons(); }
// The idea is to set a communication system whose purpose // is to exchange data from a virtual master node (situated // at core 0, chip 0) and all the other cores situated on all // the other chips. From master node to other nodes we use multicast // messages, whereas from a node to master node we use sdp messages. void c_main (void) { // simulation initialization coreID = spin1_get_core_id(); chipID = spin1_get_chip_id(); if(chipID == 0 && coreID == 1) { io_printf(IO_BUF,"CoreID is %u, ChipID is %u\n",coreID, chipID); spin1_set_timer_tick(TICK_TIME); // end of simulation initialization spin1_callback_on(TIMER_TICK, update, 1); spin_devin_init(); } spin1_start(); }
/* sending an mc packet to the application monitoring processor */ void send_special_mc_packet(unsigned short population_id, unsigned short instruction_code, int value) { uint key = spin1_get_chip_id() << 16 | 1 << 15 | // spike/no spike spin1_get_core_id()-1 << 11 | 1 << 10 | // system/application population_id << 4 | instruction_code; /* io_printf(IO_STD, "key: %8x x: %u y: %u s: %u core_id : %u a: %u popid : %u ic : %u\n", */ /* key,*/ /* (key >> 24) & 0xFF,*/ /* (key >> 16) & 0xFF, */ /* (key >> 15) & 0x1,*/ /* (key >> 11) & 0xF, */ /* (key >> 10) & 0x1, // system/application*/ /* (key >> 4) & 0x3F, */ /* (key & 0xF)); */ spin1_send_mc_packet(key, value, 1); }
void c_main (void) { io_printf (IO_STD, "Starting communication test.\n"); // get this core's ID coreID = spin1_get_core_id(); chipID = spin1_get_chip_id(); // get this chip's coordinates for core map my_x = chipID >> 8; my_y = chipID & 0xff; my_chip = (my_x * NUMBER_OF_YCHIPS) + my_y; // operate only if in core map! if ((core_map[my_x][my_y] & (1 << coreID)) == 0) { io_printf (IO_STD, "Stopping comm. (Not in core map)\n"); return; } // set the core map for the simulation spin1_application_core_map(NUMBER_OF_XCHIPS, NUMBER_OF_YCHIPS, core_map); spin1_set_timer_tick (TIMER_TICK_PERIOD); // register callbacks spin1_callback_on (MC_PACKET_RECEIVED, receive_data, 0); spin1_callback_on (TIMER_TICK, update, 0); spin1_callback_on (SDP_PACKET_RX, host_data, 0); // Initialize routing tables routing_table_init (); // Initialize SDP message buffer sdp_init (); // go spin1_start(); }
void c_main (void) { int chipIDs[] = {0, 1, 256, 257}; chipID = spin1_get_chip_id(); coreID = spin1_get_core_id(); spikeNumber = 0; //io_printf(IO_STD, "Simulation starting on (chip: %d, core: %d)...\n", chipID, coreID); // Set the number of chips in the simulation //spin1_set_core_map(64, (uint *)(0x74220000)); // set the core map for the simulation //spin1_application_core_map(2, 2, core_map); //spin1_set_core_map(4, (uint *)(core_map)); // initialise routing entries // set a MC routing table entry to send my packets back to me if (chipID == 0 && coreID == 1) { /* ------------------------------------------------------------------- */ /* initialise routing entries */ /* ------------------------------------------------------------------- */ /* set a MC routing table entry to send my packets back to me */ io_printf(IO_STD, "Setting routing table on (chip: %d, core: %d)...\n", chipID, coreID); uint e = rtr_alloc (1); if (e == 0) rt_error (RTE_ABORT); rtr_mc_set (e, // entry 0x11100001, // key 0xFFFF0001, // mask SOUTH_WEST ); e = rtr_alloc (1); if (e == 0) rt_error (RTE_ABORT); rtr_mc_set (e, // entry 0x11100000, // key 0xFFFF0001, // mask SOUTH_WEST ); e = rtr_alloc (1); if (e == 0) rt_error (RTE_ABORT); rtr_mc_set (e, 0x80000000 | 9 << 7 | 0 << 2, 0x80000000 | 15 << 7 | 31 << 2, CORE(2) // core 2 handles bump sensor ); e = rtr_alloc (1); if (e == 0) rt_error (RTE_ABORT); rtr_mc_set (e, 0x80000000 | 9 << 7 | 4 << 2 | 2, 0x80000000 | 15 << 7 | 31 << 2 | 3, CORE(3) // core 3 handles compass sensor ); e = rtr_alloc (1); if (e == 0) rt_error (RTE_ABORT); rtr_mc_set (e, 0x80000000 , //| 9 << 7 | 0 << 2, 0x80000000 , //| 15 << 7 | 0 << 2, CORE(4) // core 4 logs data ); } // Call hardware and simulation configuration functions spin1_set_timer_tick(TIME_STEP_MICROSEC); if (chipID == 0 && coreID == 1) //core1 handles time-based stuff { spin1_callback_on(TIMER_TICK, timer_callback, TIMER_PRIORITY); } if (chipID == 0 && coreID == 2) { spin1_callback_on(MCPL_PACKET_RECEIVED, bump_received, MC_PACKET_EVENT_PRIORITY); } if (chipID == 0 && coreID == 3) { spin1_callback_on(MC_PACKET_RECEIVED, enable_packet_received, MC_PACKET_EVENT_PRIORITY); } if (chipID == 0 && coreID == 4) { // Register callbacks spin1_callback_on(MC_PACKET_RECEIVED, multiCastPacketReceived_callback, MC_PACKET_EVENT_PRIORITY); spin1_callback_on(MCPL_PACKET_RECEIVED, multiCastPacketReceived_with_payload_callback, MC_PACKET_EVENT_PRIORITY); } // transfer control to the run-time kernel //if (chipID == 0 && coreID == 1) { spin1_start(0); } }
void c_main (void) { // simulation initialization coreID = spin1_get_core_id(); chipID = spin1_get_chip_id(); spin1_set_timer_tick(TICK_TIME); // the intrachip communication is totally independent from a // chip to another. chips do not interfere with each other (good point) if(chipID == 0) { // 0, 0 // in this chip, we test master to nodes, then nodes to master // results: performance is good // from master to nodes spin1_set_mc_table_entry(0x6, ERROR_MSG, 0xFFFFFFFF, ALL_NODES_MASTER_CHIP); // froms nodes to master spin1_set_mc_table_entry(0x7, UPD_MSG, 0xFFFFFFFF, MASTER_CORE); if(coreID == 1) { // master core // events setting spin1_callback_on(MC_PACKET_RECEIVED,eventMaster_chip0,0); spin1_callback_on(TIMER_TICK, update_chip0, 0); } else { // nodes // events setting spin1_callback_on(MC_PACKET_RECEIVED,eventNode_chip0,0); } } else if(chipID == 1) { // 0, 1 // in this chip, we test parallel message sending (core 1 to 2, core 3 to 4 and core 5 to 6, independently) // results: performance good spin1_set_mc_table_entry(0x2, 0x2, 0xFFFFFFFF, CORE(2)); spin1_set_mc_table_entry(0x4, 0x4, 0xFFFFFFFF, CORE(4)); spin1_set_mc_table_entry(0x6, 0x6, 0xFFFFFFFF, CORE(6)); if(coreID == 3 | coreID == 1 | coreID == 5) { // sending cores spin1_callback_on(TIMER_TICK, update_chip1, -2); } else { // receiving cores spin1_callback_on(MC_PACKET_RECEIVED,eventRec_chip1,-1); } } else if(chipID == 256) { // 1, 0 // ... } else if(chipID == 257) { // 1, 1 // ... } // Note that calling io_printf in the functions slows down a lot the system. // Therefore tests should be performed without calling this function // (or calling it not so often) spin1_start(); }