2222#include <filter_info.h>
2323#include <circular_buffer.h>
2424#include <wfi.h>
25- #include < population_table/population_table.h>
25+ #include " population_table/population_table.h"
2626
2727enum {
2828
@@ -68,6 +68,8 @@ typedef struct {
6868 uint32_t n_spikes_invalid_app_id ;
6969 //! The number of times the spike input queue was full (these are lost)
7070 uint32_t n_times_queue_overflowed ;
71+ //! The number of times the filter stopped a packet from being sent
72+ uint32_t n_times_filter_stopped_packet ;
7173} filter_provenance_t ;
7274
7375typedef struct {
@@ -95,6 +97,12 @@ typedef struct {
9597 bit_field_t data ;
9698} bit_field_filter_info_t ;
9799
100+ static uint32_t time = UINT32_MAX ;
101+
102+ static uint32_t n_timesteps ;
103+
104+ static uint32_t run_forever ;
105+
98106static filter_config_t * config ;
99107
100108static circular_buffer input_queue ;
@@ -109,14 +117,14 @@ static volatile bool running = false;
109117
110118static inline bool check_app_id (uint32_t spike , uint32_t * app_id ) {
111119 * app_id = (spike & config -> app_id_mask ) >> config -> app_id_shift ;
112- return (app_id <= config -> app_id_max ) && (app_id >= config -> app_id_min );
120+ return (* app_id <= config -> app_id_max ) && (* app_id >= config -> app_id_min );
113121}
114122
115123//! \brief Get the source core index from a spike
116124//! \param[in] filter: The filter info for the spike
117125//! \param[in] spike: The spike received
118126//! \return the source core index in the list of source cores
119- static inline uint32_t get_core_index (bit_field_filter_info_t filter ,
127+ static inline uint32_t get_filter_core_index (bit_field_filter_info_t filter ,
120128 spike_t spike ) {
121129 return (spike >> filter .core_shift ) & filter .core_mask ;
122130}
@@ -125,18 +133,18 @@ static inline uint32_t get_core_index(bit_field_filter_info_t filter,
125133//! \param[in] filter: The filter info for the spike
126134//! \param[in] spike: The spike received
127135//! \return the base neuron number of this core
128- static inline uint32_t get_core_sum (bit_field_filter_info_t filter ,
136+ static inline uint32_t get_filter_core_sum (bit_field_filter_info_t filter ,
129137 spike_t spike ) {
130- return get_core_index (filter , spike ) * filter .n_neurons ;
138+ return get_filter_core_index (filter , spike ) * filter .n_neurons ;
131139}
132140
133141//! \brief Get the neuron id of the neuron on the source core
134142//! \param[in] filter: the filter info for the spike
135143//! \param[in] spike: the spike received
136144//! \return the source neuron id local to the core
137- static inline uint32_t get_local_neuron_id ( bit_field_filter_info_t filter ,
138- spike_t spike ) {
139- return spike & filter .mask ;
145+ static inline uint32_t get_filter_local_neuron_id (
146+ bit_field_filter_info_t filter , spike_t spike ) {
147+ return ( spike & filter .mask ) >> filter . n_colour_bits ;
140148}
141149
142150static inline bool accepted (uint32_t app_id , uint32_t spike ) {
@@ -149,12 +157,17 @@ static inline bool accepted(uint32_t app_id, uint32_t spike) {
149157 if (filters [pos ].all_ones ) {
150158 return true;
151159 }
152- uint32_t neuron_id = get_core_sum (filters [pos ], spike )
153- + get_local_neuron_id (filters [pos ], spike );
154- return bit_field_get (bit_field , neuron_id );
160+ uint32_t neuron_id = get_filter_core_sum (filters [pos ], spike )
161+ + get_filter_local_neuron_id (filters [pos ], spike );
162+ if (bit_field_test (bit_field , neuron_id )) {
163+ return true;
164+ } else {
165+ prov .n_times_filter_stopped_packet += 1 ;
166+ return false;
167+ }
155168}
156169
157- static inline uint32_t get_key () {
170+ static inline uint32_t get_key (void ) {
158171 uint32_t target = next_target ;
159172 next_target = (next_target + 1 );
160173 if (next_target >= config -> n_targets ) {
@@ -164,15 +177,15 @@ static inline uint32_t get_key() {
164177}
165178
166179static inline void process_spike (void ) {
167- uint32_t spike ;
168- circular_buffer_pop (input_queue , & spike );
180+ uint32_t spike = 0 ;
181+ circular_buffer_get_next (input_queue , & spike );
169182
170- // Check against the bitfield
183+ // Check against the bit-field
171184 uint32_t app_id ;
172185 if (!check_app_id (spike , & app_id )) {
173186 // Not in range, drop
174187 prov .n_spikes_invalid_app_id += 1 ;
175- continue ;
188+ return ;
176189 }
177190
178191 // If accepted, forward to the targets
@@ -183,7 +196,8 @@ static inline void process_spike(void) {
183196 }
184197}
185198
186- void start_callback (void ) {
199+ void start_callback (UNUSED uint unused0 , UNUSED uint unused1 ) {
200+ log_info ("Running" );
187201 running = true;
188202 while (running ) {
189203 // Get the next packet
@@ -200,45 +214,61 @@ void start_callback(void) {
200214 process_spike ();
201215 }
202216 }
217+ log_info ("Exiting Run loop" );
203218}
204219
205- void exit_callback (void ) {
206- running = false;
220+ void timer_callback (UNUSED uint unused0 , UNUSED uint unused1 ) {
221+ time ++ ;
222+ log_debug ("Time is %u" , time );
223+ if (time == 0 ) {
224+ spin1_schedule_callback (start_callback , 0 , 0 , 1 );
225+ }
226+ if (simulation_is_finished ()) {
227+ simulation_handle_pause_resume (NULL );
228+ running = false;
229+ simulation_ready_to_read ();
230+ }
207231}
208232
209- void store_provenance_data (void * prov_region_addr ) {
233+ void store_provenance_data (uint32_t * prov_region_addr ) {
210234 // Copy across the provenance data
211235 spin1_memcpy (prov_region_addr , & prov , sizeof (filter_provenance_t ));
212236}
213237
214238void receive_spike_callback (uint key , uint payload ) {
215239 // Try to put the spike in the input queue
216- prov .n_spikes_received += 1 ;
217- if (!circular_buffer_push (input_queue , key )) {
218- // Queue overflowed
219- prov .n_times_queue_overflowed += 1 ;
240+ if (payload == 0 ) {
241+ // No payload = 0, which means 1 spike
242+ payload = 1 ;
243+ }
244+ prov .n_spikes_received += payload ;
245+ for (uint32_t i = 0 ; i < payload ; i ++ ) {
246+ if (!circular_buffer_add (input_queue , key )) {
247+ // Queue overflowed
248+ prov .n_times_queue_overflowed += 1 ;
249+ }
220250 }
221251}
222252
223- bool initialise () {
253+ static bool initialise (void ) {
224254 data_specification_metadata_t * ds = data_specification_get_data_address ();
225255 if (!data_specification_read_header (ds )) {
226256 log_error ("Failed to read data specification header" );
227257 return false;
228258 }
229259
230260 // set up the simulation interface
231- uint32_t n_steps ;
232- bool run_forever ;
233- uint32_t step ;
234- if (!simulation_steps_initialise (
261+ uint32_t timer_period ;
262+ if (!simulation_initialise (
235263 data_specification_get_region (FILTER_REGION_SYSTEM , ds ),
236- APPLICATION_NAME_HASH , & n_steps , & run_forever , & step , 0 , -2 )) {
264+ APPLICATION_NAME_HASH , & timer_period , & n_timesteps , & run_forever ,
265+ & time , 0 , -2 )) {
237266 return false;
238267 }
239268 simulation_set_provenance_function (
240269 store_provenance_data ,
241270 data_specification_get_region (FILTER_REGION_PROVENANCE , ds ));
271+ spin1_set_timer_tick (timer_period );
242272
243273 // Read in the filter configuration
244274 filter_config_t * sdram_config = data_specification_get_region (
@@ -305,7 +335,7 @@ bool initialise() {
305335 uint32_t size = get_bit_field_size (
306336 filters_sdram [i ].n_atoms ) * sizeof (uint32_t );
307337 filters [pos ].data = spin1_malloc (size );
308- if (filters [pos ] == NULL ) {
338+ if (filters [pos ]. data == NULL ) {
309339 log_error ("Failed to allocate bit field of %u atoms for app id %u" ,
310340 filters_sdram [i ].n_atoms , app_id );
311341 return false;
@@ -319,13 +349,12 @@ bool initialise() {
319349//! \brief The entry point for this model.
320350void c_main (void ) {
321351 // initialise the model
322- if (!initialize ()) {
352+ if (!initialise ()) {
323353 rt_error (RTE_SWERR );
324354 }
325355
326- simulation_set_exit_function (exit_callback );
327- simulation_set_start_function (start_callback );
328- simulation_set_uses_timer (false);
329356 spin1_callback_on (MC_PACKET_RECEIVED , receive_spike_callback , -1 );
357+ spin1_callback_on (MCPL_PACKET_RECEIVED , receive_spike_callback , -1 );
358+ spin1_callback_on (TIMER_TICK , timer_callback , 0 );
330359 simulation_run ();
331360}
0 commit comments