Skip to main content

sc_neurocore_engine/neurons/hardware/
truenorth.rs

1// SPDX-License-Identifier: AGPL-3.0-or-later
2// Commercial license available
3// © Concepts 1996–2026 Miroslav Šotek. All rights reserved.
4// © Code 2020–2026 Miroslav Šotek. All rights reserved.
5// ORCID: 0009-0009-3560-0851
6// Contact: www.anulum.li | protoscience@anulum.li
7// SC-NeuroCore — TrueNorth Neuron Emulator
8
9/// TrueNorth — IBM TrueNorth digital crossbar neuron. Merolla et al. 2014.
10#[derive(Clone, Debug)]
11pub struct TrueNorthNeuron {
12    pub v: i32,
13    pub leak: i32,
14    pub threshold: i32,
15    pub v_reset: i32,
16}
17
18impl TrueNorthNeuron {
19    pub fn new(threshold: i32) -> Self {
20        Self {
21            v: 0,
22            leak: 0,
23            threshold,
24            v_reset: 0,
25        }
26    }
27    pub fn step(&mut self, weighted_input: i32) -> i32 {
28        self.v += weighted_input - self.leak;
29        if self.v >= self.threshold {
30            self.v = self.v_reset;
31            1
32        } else {
33            0
34        }
35    }
36    pub fn reset(&mut self) {
37        self.v = 0;
38    }
39}
40impl Default for TrueNorthNeuron {
41    fn default() -> Self {
42        Self::new(100)
43    }
44}
45
46#[cfg(test)]
47mod tests {
48    use super::*;
49
50    #[test]
51    fn truenorth_fires() {
52        let mut n = TrueNorthNeuron::default();
53        let t: i32 = (0..10).map(|_| n.step(50)).sum();
54        assert!(t > 0);
55    }
56    #[test]
57    fn truenorth_silent() {
58        let mut n = TrueNorthNeuron::default();
59        let t: i32 = (0..100).map(|_| n.step(0)).sum();
60        assert_eq!(t, 0);
61    }
62    #[test]
63    fn truenorth_reset() {
64        let mut n = TrueNorthNeuron::default();
65        for _ in 0..10 {
66            n.step(50);
67        }
68        n.reset();
69        assert_eq!(n.v, 0);
70    }
71}