sc_neurocore_engine/neurons/hardware/
spinnaker2.rs1#[derive(Clone, Debug)]
11pub struct SpiNNaker2Neuron {
12 pub v: i32,
13 pub v_rest: i32,
14 pub v_reset: i32,
15 pub v_threshold: i32,
16 pub decay_mult: i32,
17 pub decay_shift: i32,
18 pub refrac_steps: i32,
19 pub refrac_count: i32,
20}
21
22impl SpiNNaker2Neuron {
23 pub fn new() -> Self {
24 Self {
25 v: 0,
26 v_rest: 0,
27 v_reset: 0,
28 v_threshold: 1024,
29 decay_mult: 243,
30 decay_shift: 8,
31 refrac_steps: 2,
32 refrac_count: 0,
33 }
34 }
35 pub fn step(&mut self, current: i32) -> i32 {
36 if self.refrac_count > 0 {
37 self.refrac_count -= 1;
38 return 0;
39 }
40 self.v = ((self.v - self.v_rest).wrapping_mul(self.decay_mult) >> self.decay_shift)
41 + self.v_rest
42 + current;
43 if self.v >= self.v_threshold {
44 self.v = self.v_reset;
45 self.refrac_count = self.refrac_steps;
46 1
47 } else {
48 0
49 }
50 }
51 pub fn reset(&mut self) {
52 self.v = self.v_rest;
53 self.refrac_count = 0;
54 }
55}
56impl Default for SpiNNaker2Neuron {
57 fn default() -> Self {
58 Self::new()
59 }
60}
61
62#[cfg(test)]
63mod tests {
64 use super::*;
65
66 #[test]
67 fn spinnaker2_fires() {
68 let mut n = SpiNNaker2Neuron::new();
69 let t: i32 = (0..200).map(|_| n.step(100)).sum();
70 assert!(t > 0);
71 }
72 #[test]
73 fn spinnaker2_silent() {
74 let mut n = SpiNNaker2Neuron::new();
75 let t: i32 = (0..200).map(|_| n.step(0)).sum();
76 assert_eq!(t, 0);
77 }
78 #[test]
79 fn spinnaker2_reset() {
80 let mut n = SpiNNaker2Neuron::new();
81 for _ in 0..50 {
82 n.step(100);
83 }
84 n.reset();
85 }
86 #[test]
87 fn spinnaker2_bounded() {
88 let mut n = SpiNNaker2Neuron::new();
89 for _ in 0..1000 {
90 n.step(10000);
91 }
92 }
93}