diff --git a/neural_modelling/src/neuron/plasticity/stdp/timing_dependence/timing_recurrent_dual_fsm_impl.c b/neural_modelling/src/neuron/plasticity/stdp/timing_dependence/timing_recurrent_dual_fsm_impl.c index 5bc17fc434e..6fa03f71292 100644 --- a/neural_modelling/src/neuron/plasticity/stdp/timing_dependence/timing_recurrent_dual_fsm_impl.c +++ b/neural_modelling/src/neuron/plasticity/stdp/timing_dependence/timing_recurrent_dual_fsm_impl.c @@ -32,32 +32,41 @@ uint16_t post_exp_dist_lookup[STDP_FIXED_POINT_ONE]; // Global plasticity parameter data plasticity_trace_region_data_t plasticity_trace_region_data; +//! How the configuration data for dual_fsm is laid out in SDRAM. +typedef struct { + int32_t accumulator_depression_plus_one; + int32_t accumulator_potentiation_minus_one; + uint16_t pre_exp_dist_lookup[STDP_FIXED_POINT_ONE]; + uint16_t post_exp_dist_lookup[STDP_FIXED_POINT_ONE]; + uint32_t following_data[]; +} dual_fsm_config_t; + //--------------------------------------- // Functions //--------------------------------------- uint32_t *timing_initialise(address_t address) { log_info("timing_initialise: starting"); log_info("\tRecurrent dual-FSM STDP rule"); + dual_fsm_config_t *config = (dual_fsm_config_t *) address; // Copy plasticity region data from address // **NOTE** this seems somewhat safer than relying on sizeof plasticity_trace_region_data.accumulator_depression_plus_one = - (int32_t) address[0]; + config->accumulator_depression_plus_one; plasticity_trace_region_data.accumulator_potentiation_minus_one = - (int32_t) address[1]; + config->accumulator_potentiation_minus_one; log_info("\tAccumulator depression=%d, Accumulator potentiation=%d", plasticity_trace_region_data.accumulator_depression_plus_one - 1, plasticity_trace_region_data.accumulator_potentiation_minus_one + 1); // Copy LUTs from following memory - uint32_t word_size = STDP_FIXED_POINT_ONE / 2; - spin1_memcpy(pre_exp_dist_lookup, &address[2], - STDP_FIXED_POINT_ONE * sizeof(uint16_t)); - spin1_memcpy(post_exp_dist_lookup, &address[2 + word_size], - STDP_FIXED_POINT_ONE * sizeof(uint16_t)); + spin1_memcpy(pre_exp_dist_lookup, config->pre_exp_dist_lookup, + sizeof(config->pre_exp_dist_lookup)); + spin1_memcpy(post_exp_dist_lookup, config->post_exp_dist_lookup, + sizeof(config->post_exp_dist_lookup)); log_info("timing_initialise: completed successfully"); - return &address[2 + word_size + word_size]; + return config->following_data; } diff --git a/neural_modelling/src/neuron/plasticity/stdp/timing_dependence/timing_recurrent_pre_stochastic_impl.c b/neural_modelling/src/neuron/plasticity/stdp/timing_dependence/timing_recurrent_pre_stochastic_impl.c index 8d1ca9d7dcf..5db5db42b85 100644 --- a/neural_modelling/src/neuron/plasticity/stdp/timing_dependence/timing_recurrent_pre_stochastic_impl.c +++ b/neural_modelling/src/neuron/plasticity/stdp/timing_dependence/timing_recurrent_pre_stochastic_impl.c @@ -33,33 +33,41 @@ uint16_t post_exp_dist_lookup[STDP_FIXED_POINT_ONE]; //! Global plasticity parameter data plasticity_trace_region_data_t plasticity_trace_region_data; +//! How the configuration data for pre_stochastic is laid out in SDRAM. +typedef struct { + int32_t accumulator_depression_plus_one; + int32_t accumulator_potentiation_minus_one; + uint16_t pre_exp_dist_lookup[STDP_FIXED_POINT_ONE]; + uint16_t post_exp_dist_lookup[STDP_FIXED_POINT_ONE]; + uint32_t following_data[]; +} pre_stochastic_config_t; + //--------------------------------------- // Functions //--------------------------------------- address_t timing_initialise(address_t address) { log_debug("timing_initialise: starting"); log_debug("\tRecurrent pre-calculated stochastic STDP rule"); + pre_stochastic_config_t *config = (pre_stochastic_config_t *) address; // Copy plasticity region data from address // **NOTE** this seems somewhat safer than relying on sizeof plasticity_trace_region_data.accumulator_depression_plus_one = - (int32_t) address[0]; + config->accumulator_depression_plus_one; plasticity_trace_region_data.accumulator_potentiation_minus_one = - (int32_t) address[1]; + config->accumulator_potentiation_minus_one; log_debug("\tAccumulator depression=%d, Accumulator potentiation=%d", plasticity_trace_region_data.accumulator_depression_plus_one - 1, plasticity_trace_region_data.accumulator_potentiation_minus_one + 1); // Copy LUTs from following memory - // Copy LUTs from following memory - uint32_t word_size = STDP_FIXED_POINT_ONE / 2; - spin1_memcpy(pre_exp_dist_lookup, &address[2], - STDP_FIXED_POINT_ONE * sizeof(uint16_t)); - spin1_memcpy(post_exp_dist_lookup, &address[2 + word_size], - STDP_FIXED_POINT_ONE * sizeof(uint16_t)); + spin1_memcpy(pre_exp_dist_lookup, config->pre_exp_dist_lookup, + sizeof(config->pre_exp_dist_lookup)); + spin1_memcpy(post_exp_dist_lookup, config->post_exp_dist_lookup, + sizeof(config->post_exp_dist_lookup)); log_debug("timing_initialise: completed successfully"); - return &address[2 + word_size + word_size]; + return config->following_data; } diff --git a/neural_modelling/src/neuron/plasticity/stdp/timing_dependence/timing_vogels_2011_impl.c b/neural_modelling/src/neuron/plasticity/stdp/timing_dependence/timing_vogels_2011_impl.c index 18e8860d1a9..da47a12a201 100644 --- a/neural_modelling/src/neuron/plasticity/stdp/timing_dependence/timing_vogels_2011_impl.c +++ b/neural_modelling/src/neuron/plasticity/stdp/timing_dependence/timing_vogels_2011_impl.c @@ -28,18 +28,25 @@ int16_lut *tau_lookup; //! Global plasticity parameter data plasticity_trace_region_data_t plasticity_trace_region_data; +//! How the configuration data for vogels_2011 is laid out in SDRAM. +typedef struct { + int32_t alpha; + uint32_t lut_data[]; +} vogels_2011_config_t; + //--------------------------------------- // Functions //--------------------------------------- address_t timing_initialise(address_t address) { log_info("timing_initialise: starting"); log_info("\tVogels 2011 timing rule"); + vogels_2011_config_t *config = (vogels_2011_config_t *) address; // Copy parameters - plasticity_trace_region_data.alpha = (int32_t) address[0]; + plasticity_trace_region_data.alpha = config->alpha; // Copy LUTs from following memory - address_t lut_address = &address[1]; + address_t lut_address = config->lut_data; tau_lookup = maths_copy_int16_lut(&lut_address); log_info("timing_initialise: completed successfully"); diff --git a/neural_modelling/src/neuron/plasticity/stdp/weight_dependence/weight_additive_one_term_impl.c b/neural_modelling/src/neuron/plasticity/stdp/weight_dependence/weight_additive_one_term_impl.c index 39e4757b589..f0dbf524f1e 100644 --- a/neural_modelling/src/neuron/plasticity/stdp/weight_dependence/weight_additive_one_term_impl.c +++ b/neural_modelling/src/neuron/plasticity/stdp/weight_dependence/weight_additive_one_term_impl.c @@ -25,6 +25,15 @@ //! Global plasticity parameter data plasticity_weight_region_data_t *plasticity_weight_region_data; +//! \brief How the configuration data for additive_one_term is laid out in +//! SDRAM. The layout is an array of these. +typedef struct { + int32_t min_weight; + int32_t max_weight; + int32_t a2_plus; + int32_t a2_minus; +} additive_one_term_config_t; + //--------------------------------------- // Functions //--------------------------------------- @@ -36,27 +45,26 @@ address_t weight_initialise( // Copy plasticity region data from address // **NOTE** this seems somewhat safer than relying on sizeof - int32_t *plasticity_word = (int32_t *) address; - plasticity_weight_region_data = + additive_one_term_config_t *config = (additive_one_term_config_t *) address; + + plasticity_weight_region_data_t *dtcm_copy = plasticity_weight_region_data = spin1_malloc(sizeof(plasticity_weight_region_data_t) * n_synapse_types); - if (plasticity_weight_region_data == NULL) { + if (dtcm_copy == NULL) { log_error("Could not initialise weight region data"); return NULL; } - for (uint32_t s = 0; s < n_synapse_types; s++) { - plasticity_weight_region_data[s].min_weight = *plasticity_word++; - plasticity_weight_region_data[s].max_weight = *plasticity_word++; - plasticity_weight_region_data[s].a2_plus = *plasticity_word++; - plasticity_weight_region_data[s].a2_minus = *plasticity_word++; + for (uint32_t s = 0; s < n_synapse_types; s++, config++) { + dtcm_copy[s].min_weight = config->min_weight; + dtcm_copy[s].max_weight = config->max_weight; + dtcm_copy[s].a2_plus = config->a2_plus; + dtcm_copy[s].a2_minus = config->a2_minus; log_debug("\tSynapse type %u: Min weight:%d, Max weight:%d, A2+:%d, A2-:%d", - s, plasticity_weight_region_data[s].min_weight, - plasticity_weight_region_data[s].max_weight, - plasticity_weight_region_data[s].a2_plus, - plasticity_weight_region_data[s].a2_minus); + s, dtcm_copy[s].min_weight, dtcm_copy[s].max_weight, + dtcm_copy[s].a2_plus, dtcm_copy[s].a2_minus); } log_debug("weight_initialise: completed successfully"); // Return end address of region - return (address_t) plasticity_word; + return (address_t) config; } diff --git a/neural_modelling/src/neuron/plasticity/stdp/weight_dependence/weight_additive_two_term_impl.c b/neural_modelling/src/neuron/plasticity/stdp/weight_dependence/weight_additive_two_term_impl.c index e241a2bd345..7f366905de3 100644 --- a/neural_modelling/src/neuron/plasticity/stdp/weight_dependence/weight_additive_two_term_impl.c +++ b/neural_modelling/src/neuron/plasticity/stdp/weight_dependence/weight_additive_two_term_impl.c @@ -25,6 +25,17 @@ //! Global plasticity parameter data plasticity_weight_region_data_t *plasticity_weight_region_data; +//! \brief How the configuration data for additive_two_term is laid out in +//! SDRAM. The layout is an array of these. +typedef struct { + int32_t min_weight; + int32_t max_weight; + int32_t a2_plus; + int32_t a2_minus; + int32_t a3_plus; + int32_t a3_minus; +} additive_two_term_config_t; + //--------------------------------------- // Functions //--------------------------------------- @@ -36,32 +47,32 @@ address_t weight_initialise( // Copy plasticity region data from address // **NOTE** this seems somewhat safer than relying on sizeof - int32_t *plasticity_word = (int32_t *) address; - plasticity_weight_region_data = - spin1_malloc(sizeof(plasticity_weight_region_data_t) * n_synapse_types); - if (plasticity_weight_region_data == NULL) { + additive_two_term_config_t *config = (additive_two_term_config_t *) address; + + struct plasticity_weight_region_data_two_term_t *dtcm_copy = + plasticity_weight_region_data = spin1_malloc( + sizeof(struct plasticity_weight_region_data_two_term_t) * + n_synapse_types); + if (dtcm_copy == NULL) { log_error("Could not initialise weight region data"); return NULL; } - for (uint32_t s = 0; s < n_synapse_types; s++) { - plasticity_weight_region_data[s].min_weight = *plasticity_word++; - plasticity_weight_region_data[s].max_weight = *plasticity_word++; - plasticity_weight_region_data[s].a2_plus = *plasticity_word++; - plasticity_weight_region_data[s].a2_minus = *plasticity_word++; - plasticity_weight_region_data[s].a3_plus = *plasticity_word++; - plasticity_weight_region_data[s].a3_minus = *plasticity_word++; + for (uint32_t s = 0; s < n_synapse_types; s++, config++) { + dtcm_copy[s].min_weight = config->min_weight; + dtcm_copy[s].max_weight = config->max_weight; + dtcm_copy[s].a2_plus = config->a2_plus; + dtcm_copy[s].a2_minus = config->a2_minus; + dtcm_copy[s].a3_plus = config->a3_plus; + dtcm_copy[s].a3_minus = config->a3_minus; log_debug("\tSynapse type %u: Min weight:%d, Max weight:%d, A2+:%d, A2-:%d," " A3+:%d, A3-:%d", - s, plasticity_weight_region_data[s].min_weight, - plasticity_weight_region_data[s].max_weight, - plasticity_weight_region_data[s].a2_plus, - plasticity_weight_region_data[s].a2_minus, - plasticity_weight_region_data[s].a3_plus, - plasticity_weight_region_data[s].a3_minus); + s, dtcm_copy[s].min_weight, dtcm_copy[s].max_weight, + dtcm_copy[s].a2_plus, dtcm_copy[s].a2_minus, + dtcm_copy[s].a3_plus, dtcm_copy[s].a3_minus); } log_debug("weight_initialise: completed successfully"); // Return end address of region - return (address_t) plasticity_word; + return (address_t) config; } diff --git a/neural_modelling/src/neuron/plasticity/stdp/weight_dependence/weight_additive_two_term_impl.h b/neural_modelling/src/neuron/plasticity/stdp/weight_dependence/weight_additive_two_term_impl.h index 3fde5493071..1829dfdc064 100644 --- a/neural_modelling/src/neuron/plasticity/stdp/weight_dependence/weight_additive_two_term_impl.h +++ b/neural_modelling/src/neuron/plasticity/stdp/weight_dependence/weight_additive_two_term_impl.h @@ -31,7 +31,7 @@ // Structures //--------------------------------------- //! The configuration of the rule -typedef struct { +typedef struct plasticity_weight_region_data_two_term_t { int32_t min_weight; //!< Minimum weight int32_t max_weight; //!< Maximum weight diff --git a/neural_modelling/src/neuron/plasticity/stdp/weight_dependence/weight_multiplicative_impl.c b/neural_modelling/src/neuron/plasticity/stdp/weight_dependence/weight_multiplicative_impl.c index 590fec8a331..c055abf036b 100644 --- a/neural_modelling/src/neuron/plasticity/stdp/weight_dependence/weight_multiplicative_impl.c +++ b/neural_modelling/src/neuron/plasticity/stdp/weight_dependence/weight_multiplicative_impl.c @@ -27,6 +27,15 @@ plasticity_weight_region_data_t *plasticity_weight_region_data; //! Plasticity multiply shift array, in DTCM uint32_t *weight_multiply_right_shift; +//! \brief How the configuration data for multiplicative is laid out in SDRAM. +//! The layout is an array of these. +typedef struct { + int32_t min_weight; + int32_t max_weight; + int32_t a2_plus; + int32_t a2_minus; +} multiplicative_config_t; + //--------------------------------------- // Functions //--------------------------------------- @@ -38,9 +47,9 @@ address_t weight_initialise( // Copy plasticity region data from address // **NOTE** this seems somewhat safer than relying on sizeof - plasticity_weight_region_data = + plasticity_weight_region_data_t *dtcm_copy = plasticity_weight_region_data = spin1_malloc(sizeof(plasticity_weight_region_data_t) * n_synapse_types); - if (plasticity_weight_region_data == NULL) { + if (dtcm_copy == NULL) { log_error("Could not initialise weight region data"); return NULL; } @@ -51,29 +60,26 @@ address_t weight_initialise( return NULL; } - int32_t *plasticity_word = (int32_t *) address; - for (uint32_t s = 0; s < n_synapse_types; s++) { + multiplicative_config_t *config = (multiplicative_config_t *) address; + for (uint32_t s = 0; s < n_synapse_types; s++, config++) { // Copy parameters - plasticity_weight_region_data[s].min_weight = *plasticity_word++; - plasticity_weight_region_data[s].max_weight = *plasticity_word++; - plasticity_weight_region_data[s].a2_plus = *plasticity_word++; - plasticity_weight_region_data[s].a2_minus = *plasticity_word++; + dtcm_copy[s].min_weight = config->min_weight; + dtcm_copy[s].max_weight = config->max_weight; + dtcm_copy[s].a2_plus = config->a2_plus; + dtcm_copy[s].a2_minus = config->a2_minus; // Calculate the right shift required to fixed-point multiply weights - weight_multiply_right_shift[s] = + uint32_t shift = weight_multiply_right_shift[s] = 16 - (ring_buffer_to_input_buffer_left_shifts[s] + 1); log_debug("\tSynapse type %u: Min weight:%d, Max weight:%d, A2+:%d, A2-:%d," " Weight multiply right shift:%u", - s, plasticity_weight_region_data[s].min_weight, - plasticity_weight_region_data[s].max_weight, - plasticity_weight_region_data[s].a2_plus, - plasticity_weight_region_data[s].a2_minus, - weight_multiply_right_shift[s]); + s, dtcm_copy[s].min_weight, dtcm_copy[s].max_weight, + dtcm_copy[s].a2_plus, dtcm_copy[s].a2_minus, shift); } log_debug("weight_initialise: completed successfully"); // Return end address of region - return (address_t) plasticity_word; + return (address_t) config; }