bool nonempty_out_spikes (void) { return (nonempty_bit_field (out_spikes, out_spikes_size)); }
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); }