コード例 #1
0
void _lowpass_filter_step(uint32_t n_dims, value_t *input,
                          value_t *output, void *pars)
{
  // Cast the params
  lowpass_state_t *params = (lowpass_state_t *) pars;
  register int32_t a = bitsk(params->a);
  register int32_t b = bitsk(params->b);

  // Apply the filter to every dimension (realised as a Direct Form I digital
  // filter).
  for (uint32_t d = 0; d < n_dims; d++)
  {
    // The following is equivalent to:
    //
    //    output[d] *= params->a;
    //    output[d] += input[d] * params->b;

    // Compute the next value in a register
    register int64_t next_output;

    // Perform the first multiply
    int32_t current_output = bitsk(output[d]);
    next_output = __smull(current_output, a);

    // Perform the multiply accumulate
    int32_t current_input = bitsk(input[d]);
    next_output = __smlal(next_output, current_input, b);

    // Scale the result back down to store it
    output[d] = kbits(convert_s32_30_s16_15(next_output));
  }
}
コード例 #2
0
ファイル: synapses.c プロジェクト: Paul92/sPyNNaker
static inline void _print_inputs() {
#if LOG_LEVEL >= LOG_DEBUG
    log_debug("Inputs\n");

    bool empty = true;
    for (index_t i = 0; i < n_neurons; i++) {
        empty = empty
                && (bitsk(synapse_types_get_excitatory_input(input_buffers, i)
                    - synapse_types_get_inhibitory_input(input_buffers, i))
                        == 0);
    }

    if (!empty) {
        log_debug("-------------------------------------\n");

        for (index_t i = 0; i < n_neurons; i++) {
            input_t input =
                synapse_types_get_excitatory_input(input_buffers, i)
                - synapse_types_get_inhibitory_input(input_buffers, i);
            if (bitsk(input) != 0) {
                log_debug("%3u: %12.6k (= ", i, input);
                synapse_types_print_input(input_buffers, i);
                log_debug(")\n");
            }
        }
        log_debug("-------------------------------------\n");
    }
#endif // LOG_LEVEL >= LOG_DEBUG
}
コード例 #3
0
void _lti_filter_step(uint32_t n_dims, value_t *input,
                      value_t *output, void *s)
{
  // Cast the state
  lti_state_t *state = (lti_state_t *) s;

  // Apply the filter to every dimension (realised as a Direct Form I digital
  // filter).
  for (uint32_t d = n_dims, dd = n_dims - 1; d > 0; d--, dd--)
  {
    // Point to the correct previous x and y values.
    ab_t *xy = &state->xyz[dd * state->order];

    // Create the new output value for this dimension
    register int64_t output_val = 0;

    // Direct Form I filter
    // `m` acts as an index into the ring buffer of historic input and output.
    for (uint32_t k=0, m = state->n; k < state->order; k++)
    {
      // Update the index into the ring buffer, if this would go negative it
      // wraps to the top of the buffer.
      if (m == 0)
      {
        m += state->order;
      }
      m--;

      // Apply this part of the filter
      // Equivalent to:
      //     output[dd] += ab.a * xyz.a;
      //     output[dd] += ab.b * xyz.b;
      ab_t ab = state->abs[k];
      ab_t xyz = xy[m];
      output_val = __smlal(output_val, bitsk(ab.a), bitsk(xyz.a));
      output_val = __smlal(output_val, bitsk(ab.b), bitsk(xyz.b));
    }

    // Include the initial new input
    xy[state->n].b = input[dd];

    // Save the current output for later steps
    output[dd] = kbits(convert_s32_30_s16_15(output_val));
    xy[state->n].a = output[dd];
  }

  // Rotate the ring buffer by moving the starting pointer, if the starting
  // pointer would go beyond the end of the buffer it is returned to the start.
  if (++state->n == state->order)
  {
    state->n = 0;
  }
}
コード例 #4
0
ファイル: filter_main.c プロジェクト: hunse/nengo_spinnaker
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);
    }
  }
}