void compass_received(uint key, uint payload) { io_printf(IO_STD, "this was a compass message: %08x,%08x \n", key, payload); if ( abs(heading - payload) > 100000) { spin1_send_mc_packet(0x111002a0,0x40,1); // slowly forwards io_printf(IO_STD, "Go forwards again.\n"); spin1_send_mc_packet(0x111002a2,0,1); // no roll spin1_callback_off(MCPL_PACKET_RECEIVED); // deregister my callback heading = -1; //reset heading } }
// chip 0 void update_chip0(uint sim_time, uint none) { io_printf(IO_STD,"sending error\n"); uint key = ERROR_MSG; spin1_send_mc_packet(key, 0, WITH_PAYLOAD); }
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 filter_update(uint ticks, uint arg1) { use(arg1); if (simulation_ticks != UINT32_MAX && ticks >= simulation_ticks) { spin1_exit(0); } // Update the filters input_filter_step(&g_input, true); // Apply the transform to the input to get the output for (uint j = 0; j < g_filter.size_out; j++) { g_filter.output[j] = 0.0k; for (uint k = 0; k < g_filter.size_in; k++) { g_filter.output[j] += g_filter.transform[j*g_filter.size_in + k] * g_filter.input[k]; } } // Increment the counter and transmit if necessary delay_remaining--; if(delay_remaining == 0) { delay_remaining = g_filter.transmission_delay; uint val = 0x0000; for(uint d = 0; d < g_filter.size_out; d++) { val = bitsk(g_filter.output[d]); spin1_send_mc_packet(g_filter.keys[d], val, WITH_PAYLOAD); spin1_delay_us(g_filter.interpacket_pause); } } }
void send_spike_callback(uint time_ms, uint time_us) { uint time = time_ms * 1000 + time_us; #ifdef DEBUG io_printf(IO_STD, "Event sender callback at time %u ms\n", time); io_printf(IO_STD, "Ring state :\n"); io_printf(IO_STD, "\tstart : %u\n", spike_ring->ring_start); io_printf(IO_STD, "\tend : %u\n", spike_ring->ring_end); io_printf(IO_STD, "\tempty : %d\n", spike_ring->ring_empty); io_printf(IO_STD, "\tring addr : 0x%x\n", spike_ring->ring); #endif // Process all events that should already have been sent while (spike_ring->ring_empty != 1 && spike_ring->ring[spike_ring->ring_start].ts <= time) { spin1_send_mc_packet(spike_ring->ring[spike_ring->ring_start].key, NULL, NO_PAYLOAD); events_sent++; spike_ring->ring_start = (spike_ring->ring_start + 1) % SPIKE_QUEUE_SIZE; if (spike_ring->ring_start == spike_ring->ring_end) { spike_ring->ring_empty = 1; } } // Queue the next event in the ring if it exists if (!spike_ring->ring_empty) { #ifdef DEBUG io_printf(IO_STD, "Scheduling next event in %u us.\n", spike_ring->ring[spike_ring->ring_start].ts - time); #endif schedule_trigger_timer2(send_spike_callback, spike_ring->ring[spike_ring->ring_start].ts - time); } }
void input_spikes(uint length, uint *key) { for(uint i = 0; i < length; i++) { /* io_printf(IO_STD, "Received key %d\n", key[i]);*/ spin1_send_mc_packet(key[i], NULL, FALSE); } }
// chip 1 void update_chip1(uint sim_time, uint none) { int i = 0; io_printf(IO_STD,"sending 64 msg\n"); for(i = 0; i < 64; i++) { spin1_send_mc_packet(coreID + 1, 0, WITH_PAYLOAD); } }
static inline void send(uint32_t direction, uint32_t speed) { uint32_t direction_key = direction | key; while (!spin1_send_mc_packet(direction_key, speed, WITH_PAYLOAD)) { spin1_delay_us(1); } if (delay_time > 0) { spin1_delay_us(delay_time); } }
/****f* simple.c/send_packets * * SUMMARY * This function is used by a core to send packets to itself. * It's used to test the triggering of USER_EVENT * * SYNOPSIS * void send_packets (uint null_a, uint null_b) * * INPUTS * uint null_a: padding - all callbacks must have two uint arguments! * uint null_b: padding - all callbacks must have two uint arguments! * * SOURCE */ void send_packets (uint ticks, uint none) { uint i; /* send packets */ for (i=0; i<ITER_TIMES; i++) { if (!spin1_send_mc_packet(coreID, ticks, 1)) pfailed++; } }
void transmit_packet_region(uint* packets_region) { // Transmit each packet in turn mc_packet_t *packets = (mc_packet_t *) (&packets_region[1]); for (uint i = 0; i < packets_region[0]; i++) { spin1_send_mc_packet(packets[i].key, packets[i].payload, packets[i].with_payload); io_printf(IO_BUF, "\tTime %d, Key 0x%08x, Payload 0x%08x\n", packets[i].timestamp, packets[i].key, packets[i].payload); spin1_delay_us(1); } }
void tick_callback (uint ticks, uint dummy) { if (ticks%250 == (myKey&255)) // Every 0.25 secs, time skewed for SDP { alive = (count[gen]|alive)==3; // Life automaton rule count[gen] = 0; // clear count for next gen gen = !gen; // onto next generation spin1_send_mc_packet (myKey, gen+(alive<<1), WITH_PAYLOAD); // send state to neighbours char *s = (alive) ? "white" : "black"; // Make a colour string io_printf (IO_STD, "#%s;#fill;\n", s); // And print it } }
void hMCPL(uint key, uint payload) { if(key==MCPL_BCAST_INFO_KEY) { // leadAp sends "0" for ping, worker replys with its core if(payload==0) spin1_send_mc_packet(MCPL_PING_REPLY, myCoreID, WITH_PAYLOAD); else blkInfo = (block_info_t *)payload; } else if(key==myCoreID) { workers.tAvailable = payload >> 16; workers.subBlockID = payload & 0xFFFF; }
//! \brief handles spreading of Poisson spikes for even packet reception at //! destination //! \param[in] spike_key: the key to transmit //! \return None void _send_spike(uint spike_key, uint timer_count) { // Wait until the expected time to send while ((ticks == timer_count) && (tc[T1_COUNT] > expected_time)) { // Do Nothing } expected_time -= global_parameters.time_between_spikes; // Send the spike log_debug("Sending spike packet %x at %d\n", spike_key, time); while (!spin1_send_mc_packet(spike_key, 0, NO_PAYLOAD)) { spin1_delay_us(1); } }
void bump_received(uint key, uint payload) { io_printf(IO_STD, "this was a bump! %08x.%08x \n", key, payload); if (payload & 23) //react to front facing bumpers { spin1_send_mc_packet(0x80000000 | 9 << 7 | 4 << 2 |2,0,0); // notify core 3 (compass guard) io_printf(IO_STD, "sending an enable message in return.\n"); spin1_send_mc_packet(0x111002b6,0,1); // beep io_printf(IO_STD, "Beep.\n"); spin1_send_mc_packet(0x111002a0,0xFFFFFFF0,1); // slowly backwards io_printf(IO_STD, "Go backwards.\n"); spin1_send_mc_packet(0x111002a2,0x18,1); //turn around io_printf(IO_STD, "And turn!\n"); } if (payload & 18) //react to rear facing bumper { spin1_send_mc_packet(0x111002a7, 0x00, 1); } }
// Callback TIMER_TICK void update (uint a, uint b) { io_printf (IO_STD, "tick %d\n", data_to_send); // send data to neighbor(s) spin1_send_mc_packet(my_key, data_to_send, WITH_PAYLOAD); // report data to host if (leadAp) { // copy temperatures into msg buffer and set message length uint len = 16 * sizeof(uint); spin1_memcpy (my_msg.data, (void *) data_to_send, len); my_msg.length = sizeof (sdp_hdr_t) + sizeof (cmd_hdr_t) + len; // and send SDP message! (void) spin1_send_sdp_msg (&my_msg, 100); // 100ms timeout } }
void generate_packet(uint source_index) { if (!simulation_warmup) config_sources[source_index].result_packets_generated ++; if (spin1_send_mc_packet(config_sources[source_index].routing_key, 0u, false)) { if (!simulation_warmup) config_sources[source_index].result_packets_sent ++; } else { io_printf(IO_BUF, "Could not generate packet with key 0x%08x at time %d (%s).\n" , config_sources[source_index].routing_key , simulation_ticks , simulation_warmup ? "warmup" : "post-warmup" ); config_root.completion_state = COMPLETION_STATE_FAILIURE; } }
/* 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 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(); }
// network communication void send_err(uint x_pos, uint y_pos) { uint key = ERROR_MSG | (x_pos << 8) | y_pos; uint payload = 0; if(error_x < 0.0) { key = key | (1 << 17); payload = payload | (((int)(-error_x*10000.0)) << 16); } else { payload = payload | (((int)(error_x*10000.0)) << 16); } if(error_y < 0.0) { key = key | (1 << 16); payload = payload | (int)(-error_y*10000.0); } else { payload = payload | (int)(error_y*10000.0); } counter = (counter + 1) % 50; key = key | (counter << 20); spin1_send_mc_packet(key, payload, WITH_PAYLOAD); }
//! \executes all the updates to neural parameters when a given timer period //! has occurred. //! \param[in] time the timer tic value currently being executed //! \return nothing void neuron_do_timestep_update(timer_t time) { use(time); // update each neuron individually for (index_t neuron_index = 0; neuron_index < n_neurons; neuron_index++) { // Get the parameters for this neuron neuron_pointer_t neuron = &neuron_array[neuron_index]; input_type_pointer_t input_type = &input_type_array[neuron_index]; threshold_type_pointer_t threshold_type = &threshold_type_array[neuron_index]; additional_input_pointer_t additional_input = &additional_input_array[neuron_index]; state_t voltage = neuron_model_get_membrane_voltage(neuron); // If we should be recording potential, record this neuron parameter if (recording_is_channel_enabled(recording_flags, e_recording_channel_neuron_potential)) { recording_record(e_recording_channel_neuron_potential, &voltage, sizeof(state_t)); } // Get excitatory and inhibitory input from synapses and convert it // to current input input_t exc_input_value = input_type_get_input_value( synapse_types_get_excitatory_input(input_buffers, neuron_index), input_type); input_t inh_input_value = input_type_get_input_value( synapse_types_get_inhibitory_input(input_buffers, neuron_index), input_type); input_t exc_input = input_type_convert_excitatory_input_to_current( exc_input_value, input_type, voltage); input_t inh_input = input_type_convert_inhibitory_input_to_current( inh_input_value, input_type, voltage); // Get external bias from any source of intrinsic plasticity input_t external_bias = synapse_dynamics_get_intrinsic_bias(time, neuron_index) + additional_input_get_input_value_as_current( additional_input, voltage); // If we should be recording input, record the values if (recording_is_channel_enabled(recording_flags, e_recording_channel_neuron_gsyn)) { recording_record(e_recording_channel_neuron_gsyn, &exc_input_value, sizeof(input_t)); recording_record(e_recording_channel_neuron_gsyn, &inh_input_value, sizeof(input_t)); } // update neuron parameters state_t result = neuron_model_state_update( exc_input, inh_input, external_bias, neuron); // determine if a spike should occur bool spike = threshold_type_is_above_threshold(result, threshold_type); // If the neuron has spiked if (spike) { log_debug("the neuron %d has been determined to spike", neuron_index); // Tell the neuron model neuron_model_has_spiked(neuron); // Tell the additional input additional_input_has_spiked(additional_input); // Do any required synapse processing synapse_dynamics_process_post_synaptic_event(time, neuron_index); // Record the spike out_spikes_set_spike(neuron_index); // Send the spike while (use_key && !spin1_send_mc_packet(key | neuron_index, 0, NO_PAYLOAD)) { spin1_delay_us(1); } } else { log_debug("the neuron %d has been determined to not spike", neuron_index); } } // do logging stuff if required out_spikes_print(); _print_neurons(); // Record any spikes this timestep out_spikes_record(recording_flags); out_spikes_reset(); }
//! \executes all the updates to neural parameters when a given timer period //! has occurred. //! \param[in] time the timer tick value currently being executed void neuron_do_timestep_update(timer_t time) { // update each neuron individually for (index_t neuron_index = 0; neuron_index < n_neurons; neuron_index++) { // Get the parameters for this neuron neuron_pointer_t neuron = &neuron_array[neuron_index]; input_type_pointer_t input_type = &input_type_array[neuron_index]; threshold_type_pointer_t threshold_type = &threshold_type_array[neuron_index]; additional_input_pointer_t additional_input = &additional_input_array[neuron_index]; state_t voltage = neuron_model_get_membrane_voltage(neuron); // If we should be recording potential, record this neuron parameter voltages->states[neuron_index] = voltage; // Get excitatory and inhibitory input from synapses and convert it // to current input input_t exc_input_value = input_type_get_input_value( synapse_types_get_excitatory_input(input_buffers, neuron_index), input_type); input_t inh_input_value = input_type_get_input_value( synapse_types_get_inhibitory_input(input_buffers, neuron_index), input_type); input_t exc_input = input_type_convert_excitatory_input_to_current( exc_input_value, input_type, voltage); input_t inh_input = input_type_convert_inhibitory_input_to_current( inh_input_value, input_type, voltage); // Get external bias from any source of intrinsic plasticity input_t external_bias = synapse_dynamics_get_intrinsic_bias(time, neuron_index) + additional_input_get_input_value_as_current( additional_input, voltage); // If we should be recording input, record the values inputs->inputs[neuron_index].exc = exc_input_value; inputs->inputs[neuron_index].inh = inh_input_value; // update neuron parameters state_t result = neuron_model_state_update( exc_input, inh_input, external_bias, neuron); //if ((time>=7000) && (time<=7500)) // if ((exc_input_value>0) || (inh_input_value>0)) // io_printf(IO_BUF,"%dms, voltage=%d inh_input_value=%d\n", time, result, inh_input_value); //io_printf(IO_BUF,"%dms, voltage=%d exc_input_value=%d inh_input_value=%d\n", time, neuron_model_get_membrane_voltage(neuron), exc_input_value, inh_input_value); // determine if a spike should occur bool spike = threshold_type_is_above_threshold(result, threshold_type); // If the neuron has spiked if (spike) { log_debug("neuron %u spiked at time %u", neuron_index, time); //if ((time>5500) && (time<9000)) // io_printf(IO_BUF,"%dms, neuron spiked!\n", time); // Tell the neuron model neuron_model_has_spiked(neuron); // Tell the additional input additional_input_has_spiked(additional_input); // Do any required synapse processing synapse_dynamics_process_post_synaptic_event(time, neuron_index); // Record the spike out_spikes_set_spike(neuron_index); // Send the spike while (use_key && !spin1_send_mc_packet(key | neuron_index, 0, NO_PAYLOAD)) { spin1_delay_us(1); } } else { log_debug("the neuron %d has been determined to not spike", neuron_index); } } // record neuron state (membrane potential) if needed if (recording_is_channel_enabled(recording_flags, V_RECORDING_CHANNEL)) { voltages->time = time; recording_record(V_RECORDING_CHANNEL, voltages, voltages_size); } // record neuron inputs if needed if (recording_is_channel_enabled( recording_flags, GSYN_RECORDING_CHANNEL)) { inputs->time = time; recording_record(GSYN_RECORDING_CHANNEL, inputs, input_size); } // do logging stuff if required out_spikes_print(); _print_neurons(); // Record any spikes this timestep if (recording_is_channel_enabled( recording_flags, SPIKE_RECORDING_CHANNEL)) { out_spikes_record(SPIKE_RECORDING_CHANNEL, time); } out_spikes_reset(); }
void timer_callback(uint unused0, uint unused1) { use(unused0); use(unused1); time++; log_debug("Timer tick %u", time); // If a fixed number of simulation ticks are specified and these have passed if (simulation_ticks != UINT32_MAX && time >= simulation_ticks) { log_info("Simulation complete.\n"); spin1_exit(0); } // Loop through delay stages for (uint32_t d = 0; d < num_delay_stages; d++) { // If any neurons emit spikes after this delay stage bit_field_t delay_stage_config = neuron_delay_stage_config[d]; if (nonempty_bit_field(delay_stage_config, neuron_bit_field_words)) { // Get key mask for this delay stage and it's time slot uint32_t delay_stage_delay = (d + 1) * DELAY_STAGE_LENGTH; uint32_t delay_stage_time_slot = ((time - delay_stage_delay) & num_delay_slots_mask); uint8_t *delay_stage_spike_counters = spike_counters[delay_stage_time_slot]; log_debug("Checking time slot %u for delay stage %u", delay_stage_time_slot, d); // Loop through neurons for (uint32_t n = 0; n < num_neurons; n++) { // If this neuron emits a spike after this stage if (bit_field_test(delay_stage_config, n)) { // Calculate key all spikes coming from this neuron will be // sent with uint32_t spike_key = ((d * num_neurons) + n) | key; #if LOG_LEVEL >= LOG_DEBUG if (delay_stage_spike_counters[n] > 0) { log_debug("Neuron %u sending %u spikes after delay" "stage %u with key %x", n, delay_stage_spike_counters[n], d, spike_key); } #endif // DEBUG // Loop through counted spikes and send for (uint32_t s = 0; s < delay_stage_spike_counters[n]; s++) { while (!spin1_send_mc_packet(spike_key, 0, NO_PAYLOAD)) { spin1_delay_us(1); } } } } } } // Zero all counters in current time slot uint32_t current_time_slot = time & num_delay_slots_mask; uint8_t *current_time_slot_spike_counters = spike_counters[current_time_slot]; memset(current_time_slot_spike_counters, 0, sizeof(uint8_t) * num_neurons); }
void eventNode_chip0(uint key, uint payload) { if((key) == ERROR_MSG) { uint key = UPD_MSG; spin1_send_mc_packet(key, 0, WITH_PAYLOAD); } }