File size: 4,979 Bytes
e4cdd5f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
// ============================================================================
// Neuron Core
// ============================================================================
//
// Copyright 2026 Henry Arthur Shulayev Barnes / Catalyst Neuromorphic Ltd
// Company No. 17054540 — UK Patent Application No. 2602902.6
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ============================================================================

module neuron_core #(
    parameter NUM_NEURONS = 4,
    parameter DATA_WIDTH  = 16,
    parameter THRESHOLD   = 16'd1000,
    parameter LEAK_RATE   = 16'd2
)(
    input  wire                    clk,
    input  wire                    rst_n,
    input  wire                    enable,

    input  wire signed [DATA_WIDTH-1:0] ext_input_0,
    input  wire signed [DATA_WIDTH-1:0] ext_input_1,
    input  wire signed [DATA_WIDTH-1:0] ext_input_2,
    input  wire signed [DATA_WIDTH-1:0] ext_input_3,

    input  wire signed [DATA_WIDTH-1:0] weight_00, weight_01, weight_02, weight_03,
    input  wire signed [DATA_WIDTH-1:0] weight_10, weight_11, weight_12, weight_13,
    input  wire signed [DATA_WIDTH-1:0] weight_20, weight_21, weight_22, weight_23,
    input  wire signed [DATA_WIDTH-1:0] weight_30, weight_31, weight_32, weight_33,

    output wire [NUM_NEURONS-1:0] spikes,

    output wire [DATA_WIDTH-1:0] membrane_0,
    output wire [DATA_WIDTH-1:0] membrane_1,
    output wire [DATA_WIDTH-1:0] membrane_2,
    output wire [DATA_WIDTH-1:0] membrane_3
);

    wire signed [DATA_WIDTH-1:0] syn_current [0:3][0:3];
    wire signed [DATA_WIDTH-1:0] total_input [0:3];
    wire signed [DATA_WIDTH-1:0] weights [0:3][0:3];

    assign weights[0][0] = weight_00; assign weights[0][1] = weight_01;
    assign weights[0][2] = weight_02; assign weights[0][3] = weight_03;
    assign weights[1][0] = weight_10; assign weights[1][1] = weight_11;
    assign weights[1][2] = weight_12; assign weights[1][3] = weight_13;
    assign weights[2][0] = weight_20; assign weights[2][1] = weight_21;
    assign weights[2][2] = weight_22; assign weights[2][3] = weight_23;
    assign weights[3][0] = weight_30; assign weights[3][1] = weight_31;
    assign weights[3][2] = weight_32; assign weights[3][3] = weight_33;

    wire signed [DATA_WIDTH-1:0] ext_inputs [0:3];
    assign ext_inputs[0] = ext_input_0;
    assign ext_inputs[1] = ext_input_1;
    assign ext_inputs[2] = ext_input_2;
    assign ext_inputs[3] = ext_input_3;

    genvar src, dst;
    generate
        for (src = 0; src < NUM_NEURONS; src = src + 1) begin : syn_src
            for (dst = 0; dst < NUM_NEURONS; dst = dst + 1) begin : syn_dst
                synapse #(
                    .DATA_WIDTH(DATA_WIDTH)
                ) syn_inst (
                    .clk         (clk),
                    .rst_n       (rst_n),
                    .pre_spike   (spikes[src]),
                    .weight      (weights[src][dst]),
                    .post_current(syn_current[src][dst])
                );
            end
        end
    endgenerate

    assign total_input[0] = ext_inputs[0] + syn_current[0][0] + syn_current[1][0] + syn_current[2][0] + syn_current[3][0];
    assign total_input[1] = ext_inputs[1] + syn_current[0][1] + syn_current[1][1] + syn_current[2][1] + syn_current[3][1];
    assign total_input[2] = ext_inputs[2] + syn_current[0][2] + syn_current[1][2] + syn_current[2][2] + syn_current[3][2];
    assign total_input[3] = ext_inputs[3] + syn_current[0][3] + syn_current[1][3] + syn_current[2][3] + syn_current[3][3];

    generate
        for (dst = 0; dst < NUM_NEURONS; dst = dst + 1) begin : neurons
            lif_neuron #(
                .DATA_WIDTH (DATA_WIDTH),
                .THRESHOLD  (THRESHOLD),
                .LEAK_RATE  (LEAK_RATE)
            ) neuron_inst (
                .clk            (clk),
                .rst_n          (rst_n),
                .enable         (enable),
                .synaptic_input (total_input[dst]),
                .spike          (spikes[dst]),
                .membrane_pot   ()
            );
        end
    endgenerate

    assign membrane_0 = neurons[0].neuron_inst.membrane_pot;
    assign membrane_1 = neurons[1].neuron_inst.membrane_pot;
    assign membrane_2 = neurons[2].neuron_inst.membrane_pot;
    assign membrane_3 = neurons[3].neuron_inst.membrane_pot;

endmodule